Compare commits
No commits in common. "c2ca6d284d1d56daa5f6998bc878f904b2097413" and "4018f26998c8ca9b4217ac9201af5012a722318f" have entirely different histories.
c2ca6d284d
...
4018f26998
|
@ -1,6 +1,3 @@
|
||||||
penny_dreadful_downloader/legality_data/
|
penny_dreadful_downloader/legality_data/
|
||||||
a_scanner_dorkly/.venv/
|
|
||||||
scantap/images/
|
|
||||||
sevenkeys/sevenkeys
|
|
||||||
MTG-Card-Identifier_v5.pdf
|
MTG-Card-Identifier_v5.pdf
|
||||||
info.txt
|
info.txt
|
||||||
|
|
|
@ -4,4 +4,3 @@ find_package( OpenCV REQUIRED )
|
||||||
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||||
add_executable( AScannerDarkly main.cpp )
|
add_executable( AScannerDarkly main.cpp )
|
||||||
target_link_libraries( AScannerDarkly ${OpenCV_LIBS} )
|
target_link_libraries( AScannerDarkly ${OpenCV_LIBS} )
|
||||||
target_link_libraries( AScannerDarkly -llept -ltesseract )
|
|
||||||
|
|
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 5.0 KiB |
|
@ -1,10 +1,7 @@
|
||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
#include <tesseract/baseapi.h>
|
|
||||||
#include <leptonica/allheaders.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const std::string SCANNER_WINDOW_NAME = "A Scanner Darkly";
|
const std::string WINDOW_NAME = "A Scanner Darkly";
|
||||||
const std::string CARD_WINDOW_NAME = "Detected Card";
|
|
||||||
|
|
||||||
const std::string CANNY_LOWER_THRESHOLD_TRACKBAR_NAME = "Canny: Lower Threshold";
|
const std::string CANNY_LOWER_THRESHOLD_TRACKBAR_NAME = "Canny: Lower Threshold";
|
||||||
|
|
||||||
|
@ -13,112 +10,9 @@ const std::string ASPECT_RATIO_TOLERANCE_TRACKBAR_NAME = "Aspect Ratio Tolerance
|
||||||
int g_aspect_ratio_tolerance = 1;
|
int g_aspect_ratio_tolerance = 1;
|
||||||
const int MAX_ASPECT_RATIO_TOLERANCE = 100;
|
const int MAX_ASPECT_RATIO_TOLERANCE = 100;
|
||||||
|
|
||||||
int g_Canny_lower_threshold = 195;
|
int g_Canny_lower_threshold = 110;
|
||||||
const int CANNY_UPPER_THRESHOLD = 255;
|
const int CANNY_UPPER_THRESHOLD = 255;
|
||||||
|
|
||||||
cv::Mat cropImageToRoi(cv::Mat img, cv::Rect roi) {
|
|
||||||
return img(roi);
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat detectCardInFrame(cv::Mat frame) {
|
|
||||||
cv::Mat grayscaleFrame, blurFrame, cannyFrame, cardFrame;
|
|
||||||
|
|
||||||
// Perform edge detection
|
|
||||||
cv::cvtColor(frame, grayscaleFrame, cv::COLOR_BGR2GRAY);
|
|
||||||
cv::GaussianBlur(grayscaleFrame, blurFrame, cv::Size(5, 5), 2, 2);
|
|
||||||
cv::Canny(blurFrame, cannyFrame, g_Canny_lower_threshold, CANNY_UPPER_THRESHOLD);
|
|
||||||
|
|
||||||
// Perform contour detection
|
|
||||||
std::vector<std::vector<cv::Point>> contours;
|
|
||||||
std::vector<cv::Vec4i> hierarchy;
|
|
||||||
cv::findContours(cannyFrame, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
|
|
||||||
|
|
||||||
// Detect convex hulls
|
|
||||||
std::vector<std::vector<cv::Point>> hull(contours.size());
|
|
||||||
for(size_t i = 0; i < contours.size(); i++) {
|
|
||||||
cv::convexHull(contours[i], hull[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect RotatedRects
|
|
||||||
std::vector<cv::RotatedRect> minRect(contours.size());
|
|
||||||
for(size_t i = 0; i < contours.size(); i++) {
|
|
||||||
minRect[i] = cv::minAreaRect(contours[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw lines around RotatedRects
|
|
||||||
/*
|
|
||||||
cv::Scalar rectangleColor(255, 0, 0, 0);
|
|
||||||
cv::Point2f rect_points[4];
|
|
||||||
minRect[i].points(rect_points);
|
|
||||||
for (int j = 0; j < 4; j++) {
|
|
||||||
cv::line(frame, rect_points[j], rect_points[(j + 1) % 4], rectangleColor);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Find possible cards
|
|
||||||
std::vector<cv::RotatedRect> possibleCards(contours.size());
|
|
||||||
int possibleCount = 0;
|
|
||||||
for (size_t i = 0; i < minRect.size(); i++) {
|
|
||||||
float aspectRatio = minRect[i].size.height / minRect[i].size.width;
|
|
||||||
float aspectRatioTolerance = g_aspect_ratio_tolerance / 100.0f;
|
|
||||||
if (aspectRatio < (CARD_ASPECT_RATIO - aspectRatioTolerance) || aspectRatio > (CARD_ASPECT_RATIO + aspectRatioTolerance)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::putText(frame, std::to_string(minRect[i].angle), minRect[i].center, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0, 0));
|
|
||||||
|
|
||||||
possibleCards[possibleCount] = minRect[i];
|
|
||||||
possibleCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (possibleCount == 1) {
|
|
||||||
return cropImageToRoi(frame, possibleCards[0].boundingRect());
|
|
||||||
} else if (possibleCount > 1) {
|
|
||||||
// If we have more than one possible match, take the largest one
|
|
||||||
int largestCardIndex = 0;
|
|
||||||
int largestCardSize = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < possibleCards.size(); i++) {
|
|
||||||
float size = possibleCards[i].size.width * possibleCards[i].size.height;
|
|
||||||
if (size >= largestCardSize) {
|
|
||||||
largestCardIndex = i;
|
|
||||||
largestCardSize = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some basic error checking to ensure the RotatedRect is roughly card-sized
|
|
||||||
if (largestCardSize >= 14400 && largestCardSize <= 200000) {
|
|
||||||
return cropImageToRoi(frame, possibleCards[largestCardIndex].boundingRect());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cv::Mat();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* readTextFromImage(cv::InputArray img) {
|
|
||||||
const char* tempFilename = "temp.bmp";
|
|
||||||
|
|
||||||
// Initialize Tesseract api
|
|
||||||
tesseract::TessBaseAPI* tess = new tesseract::TessBaseAPI();
|
|
||||||
tess->Init(NULL, "eng");
|
|
||||||
tess->SetPageSegMode(tesseract::PSM_SPARSE_TEXT);
|
|
||||||
|
|
||||||
// Load image into Tesseract
|
|
||||||
cv::imwrite(tempFilename, img);
|
|
||||||
Pix* pixd = pixRead(tempFilename);
|
|
||||||
tess->SetImage(pixd);
|
|
||||||
tess->Recognize(0);
|
|
||||||
|
|
||||||
// Perform OCR
|
|
||||||
const char* out = tess->GetUTF8Text();
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
pixDestroy(&pixd);
|
|
||||||
std::remove(tempFilename);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv ) {
|
int main(int argc, char** argv ) {
|
||||||
cv::VideoCapture cap;
|
cv::VideoCapture cap;
|
||||||
cap.open(0);
|
cap.open(0);
|
||||||
|
@ -128,34 +22,71 @@ int main(int argc, char** argv ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::namedWindow(SCANNER_WINDOW_NAME);
|
std::cout << "Card aspect ratio: " << CARD_ASPECT_RATIO << std::endl;
|
||||||
|
|
||||||
cv::createTrackbar(CANNY_LOWER_THRESHOLD_TRACKBAR_NAME, SCANNER_WINDOW_NAME, &g_Canny_lower_threshold, CANNY_UPPER_THRESHOLD, NULL);
|
cv::namedWindow(WINDOW_NAME);
|
||||||
cv::createTrackbar(ASPECT_RATIO_TOLERANCE_TRACKBAR_NAME, SCANNER_WINDOW_NAME, &g_aspect_ratio_tolerance, MAX_ASPECT_RATIO_TOLERANCE, NULL);
|
|
||||||
|
|
||||||
cv::Mat frame, cardFrame;
|
cv::createTrackbar(CANNY_LOWER_THRESHOLD_TRACKBAR_NAME, WINDOW_NAME, &g_Canny_lower_threshold, CANNY_UPPER_THRESHOLD, NULL);
|
||||||
|
cv::createTrackbar(ASPECT_RATIO_TOLERANCE_TRACKBAR_NAME, WINDOW_NAME, &g_aspect_ratio_tolerance, MAX_ASPECT_RATIO_TOLERANCE, NULL);
|
||||||
|
|
||||||
|
cv::Mat frame, grayscaleFrame, blurFrame, cannyFrame;
|
||||||
while (true) {
|
while (true) {
|
||||||
cap >> frame;
|
cap >> frame;
|
||||||
//cardFrame = detectCardInFrame(frame);
|
|
||||||
cv::imshow(SCANNER_WINDOW_NAME, frame);
|
|
||||||
|
|
||||||
/*
|
cv::cvtColor(frame, grayscaleFrame, cv::COLOR_BGR2GRAY);
|
||||||
if (cardFrame.size().width > 0) {
|
cv::GaussianBlur(grayscaleFrame, blurFrame, cv::Size(5, 5), 2, 2);
|
||||||
printf("Card detected\n");
|
cv::Canny(blurFrame, cannyFrame, g_Canny_lower_threshold, CANNY_UPPER_THRESHOLD);
|
||||||
while (true) {
|
|
||||||
cv::imshow(CARD_WINDOW_NAME, cardFrame);
|
std::vector<std::vector<cv::Point> > contours;
|
||||||
char c = (char)cv::waitKey(33);
|
std::vector<cv::Vec4i> hierarchy;
|
||||||
if (c == 27) {
|
cv::findContours(cannyFrame, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
|
||||||
cv::destroyWindow(CARD_WINDOW_NAME);
|
|
||||||
break;
|
std::vector<std::vector<cv::Point>> hull(contours.size());
|
||||||
|
for(size_t i = 0; i < contours.size(); i++) {
|
||||||
|
cv::convexHull(contours[i], hull[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<cv::RotatedRect> minRect(contours.size());
|
||||||
|
for(size_t i = 0; i < contours.size(); i++) {
|
||||||
|
minRect[i] = cv::minAreaRect(contours[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//cv::Scalar contourColor = cv::Scalar(255, 0, 0);
|
||||||
|
cv::Scalar hullColor = cv::Scalar(0, 255, 0);
|
||||||
|
cv::Scalar rectangleColor = cv::Scalar(0, 0, 255);
|
||||||
|
|
||||||
|
for (size_t i = 0; i< contours.size(); i++) {
|
||||||
|
//cv::drawContours(frame, contours, (int)i, contourColor, 2, cv::LINE_8, hierarchy, 0);
|
||||||
|
//cv::drawContours(frame, hull, (int)i, hullColor, 2, cv::LINE_8);
|
||||||
|
|
||||||
|
// TODO: A purely aspect-ratio-based detection method returns too many false positives
|
||||||
|
// inside of a card, even after screwing around with various algorithm parameters.
|
||||||
|
// We have two potential options to fix this:
|
||||||
|
// - Only take the largest detected RotatedRect with the correct aspect ratio
|
||||||
|
// - Perform the camera calibration necessary to take accurate real-world measurements
|
||||||
|
float aspectRatio = minRect[i].size.height / minRect[i].size.width;
|
||||||
|
float aspectRatioTolerance = g_aspect_ratio_tolerance / 100.0f;
|
||||||
|
if (aspectRatio < (CARD_ASPECT_RATIO - aspectRatioTolerance) || aspectRatio > (CARD_ASPECT_RATIO + aspectRatioTolerance)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
cv::Point2f rect_points[4];
|
||||||
|
minRect[i].points(rect_points);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
cv::line(frame, rect_points[j], rect_points[(j + 1) % 4], rectangleColor);
|
||||||
|
}
|
||||||
|
cv::putText(frame, std::to_string(aspectRatio), minRect[i].center, cv::FONT_HERSHEY_COMPLEX, 1, hullColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::imshow(WINDOW_NAME, frame);
|
||||||
|
|
||||||
char c = (char)cv::waitKey(33);
|
char c = (char)cv::waitKey(33);
|
||||||
if (c == 27) {
|
if (c == 27) {
|
||||||
break;
|
break;
|
||||||
|
} else if (c == 's') {
|
||||||
|
cv::imwrite("output.png", frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::destroyWindow(WINDOW_NAME);
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 301 KiB |
|
@ -1,24 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import cv2
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
mouse_raw = (0, 0)
|
|
||||||
|
|
||||||
def clickEvent(event, x, y, flags, params):
|
|
||||||
global mouse_raw
|
|
||||||
|
|
||||||
if event == cv2.EVENT_LBUTTONDOWN:
|
|
||||||
mouse_raw = (x, y)
|
|
||||||
print(mouse_raw)
|
|
||||||
|
|
||||||
cap = cv2.VideoCapture(0)
|
|
||||||
cv2.namedWindow("image")
|
|
||||||
cv2.setMouseCallback("image", clickEvent)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
success, img = cap.read()
|
|
||||||
cv2.imshow("image", img)
|
|
||||||
cv2.waitKey(0)
|
|
||||||
|
|
||||||
cv2.destroyAllWindows()
|
|
|
@ -1,8 +0,0 @@
|
||||||
USE sevenkeys;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS CardScan (
|
|
||||||
Id INT PRIMARY KEY AUTO_INCREMENT,
|
|
||||||
StorageAreaId INT NOT NULL,
|
|
||||||
FOREIGN KEY (StorageAreaId) REFERENCES StorageArea(Id),
|
|
||||||
Position INT NOT NULL
|
|
||||||
);
|
|
|
@ -1,59 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
mysql --user=root --password="$(pass show sevenkeys/mysql)" <createtable.sql
|
|
||||||
|
|
||||||
printf "scantap: Enter name of storage box: "
|
|
||||||
read storageAreaName
|
|
||||||
|
|
||||||
storageAreaId="$(mysql --silent --silent --user=root --password="$(pass show sevenkeys/mysql)" -e "USE sevenkeys; SELECT Id FROM StorageArea WHERE Name = '$storageAreaName';")"
|
|
||||||
if test -z "$storageAreaId"; then
|
|
||||||
echo "scantap: No storage area named \"$storageAreaName\"" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
startPosition="$(mysql --silent --silent --user=root --password="$(pass show sevenkeys/mysql)" -e "USE sevenkeys; SELECT Position FROM CardScan WHERE StorageAreaId = '$storageAreaId' ORDER BY Position DESC LIMIT 1;")"
|
|
||||||
if test "$?" -ne "0"; then
|
|
||||||
echo "scantap: Failed to establish starting position" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
position=$((startPosition + 1))
|
|
||||||
|
|
||||||
printf "scantap: Enter mode (foil/nonfoil): "
|
|
||||||
read foilMode
|
|
||||||
outputDir="images/$foilMode"
|
|
||||||
mkdir -p "$outputDir"
|
|
||||||
|
|
||||||
ADD_CARDS=0
|
|
||||||
echo "scantap: Beginning scan loop"
|
|
||||||
while true; do
|
|
||||||
scanimage --format=png --batch=tmp%d.png --batch-count=2 --source "ADF Duplex" --mode Color --page-width 63mm --page-height 88mm 2>/dev/null
|
|
||||||
|
|
||||||
# scanimage exits with code 7 if no documents are available in scanner
|
|
||||||
if test $? -eq 7; then
|
|
||||||
if test $ADD_CARDS -eq 0; then
|
|
||||||
ADD_CARDS=1
|
|
||||||
echo "scantap: No more cards in feeder" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
ADD_CARDS=0
|
|
||||||
|
|
||||||
if ! test -e tmp1.png || ! test -e tmp2.png; then
|
|
||||||
echo "scantap: Failed to create temporary image files" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
key="$(mysql --silent --silent --user=root --password="$(pass show sevenkeys/mysql)" -e "USE sevenkeys; INSERT INTO CardScan (StorageAreaId, Position) VALUES ('$storageAreaId', '$position'); SELECT Id FROM CardScan ORDER BY Id DESC LIMIT 1;")"
|
|
||||||
if test "$?" -ne "0"; then
|
|
||||||
echo "scantap: Failed to get key from database" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
position=$((position + 1))
|
|
||||||
|
|
||||||
convert -rotate 180 tmp1.png tmp1.png
|
|
||||||
convert -rotate 180 tmp2.png tmp2.png
|
|
||||||
|
|
||||||
mv tmp1.png "$outputDir/${key}_back.png"
|
|
||||||
mv tmp2.png "$outputDir/${key}_front.png"
|
|
||||||
done
|
|
|
@ -1,3 +1,2 @@
|
||||||
cache/
|
cache/
|
||||||
cmd/database/config.json
|
cmd/database/config.json
|
||||||
sevenkeys.sql
|
|
||||||
|
|
|
@ -3,5 +3,3 @@ createdb:
|
||||||
removedb:
|
removedb:
|
||||||
rm -rf cache/
|
rm -rf cache/
|
||||||
mysql --user=root --password=$(shell pass show sevenkeys/mysql) <database/sql/removedb.sql
|
mysql --user=root --password=$(shell pass show sevenkeys/mysql) <database/sql/removedb.sql
|
||||||
connect:
|
|
||||||
mysql --user=root --password=$(shell pass show sevenkeys/mysql)
|
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"sevenkeys/database"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
)
|
|
||||||
|
|
||||||
var output string
|
|
||||||
|
|
||||||
func showOutput() {
|
|
||||||
if output != "" {
|
|
||||||
fmt.Println(output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func MainCliLoop(db *sql.DB) {
|
|
||||||
var command string
|
|
||||||
var selectedStorageArea database.StorageArea
|
|
||||||
var cardLocation database.CardLocation
|
|
||||||
|
|
||||||
for {
|
|
||||||
ShowSplashScreen()
|
|
||||||
showStorageInfo(os.Stdout, selectedStorageArea)
|
|
||||||
showSearchCriteria()
|
|
||||||
showSelectedCard()
|
|
||||||
showCopiesInserted()
|
|
||||||
|
|
||||||
command = GetStringResponse("SEVENKEYS $")
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch command {
|
|
||||||
case "q", "quit":
|
|
||||||
return
|
|
||||||
case "n", "newstorage":
|
|
||||||
var storageArea database.StorageArea
|
|
||||||
storageArea.Name = GetStringResponse("Storage area name:")
|
|
||||||
storageArea.StorageType = GetStringResponse("Storage area type (Binder/Box):")
|
|
||||||
err = logic.CreateStorageArea(db, storageArea)
|
|
||||||
logic.Check(err)
|
|
||||||
break
|
|
||||||
case "a", "area":
|
|
||||||
area, err := logic.SelectStorageArea(db)
|
|
||||||
logic.Check(err)
|
|
||||||
selectedStorageArea = area
|
|
||||||
cardLocation.StorageAreaId = area.Id
|
|
||||||
break
|
|
||||||
case "c", "criteria":
|
|
||||||
getSearchCriteria()
|
|
||||||
break
|
|
||||||
case "s", "search":
|
|
||||||
getSearchOptions(db)
|
|
||||||
|
|
||||||
var previousCardPrintingId = cardLocation.CardPrintingId
|
|
||||||
|
|
||||||
cardLocation.CardPrintingId, selectedCardPrintingSearchLine, err = logic.Search(searchOptions)
|
|
||||||
var exitError *exec.ExitError
|
|
||||||
if errors.As(err, &exitError) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
output = ""
|
|
||||||
if cardLocation.CardPrintingId != previousCardPrintingId {
|
|
||||||
copiesInserted = 0
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case "i", "insert":
|
|
||||||
insertSelectedCard(db, selectedStorageArea, cardLocation)
|
|
||||||
break
|
|
||||||
case "l", "locate":
|
|
||||||
cardName := GetStringResponse("Card name:")
|
|
||||||
locations, err := logic.LocateCards(db, cardName)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
for _, location := range locations {
|
|
||||||
fmt.Printf("%s (%s %s) [%s]", location.CardName, location.SetCode, location.CollectorNumber, location.Language)
|
|
||||||
|
|
||||||
if location.IsFoil {
|
|
||||||
fmt.Printf(" FOIL")
|
|
||||||
}
|
|
||||||
|
|
||||||
if location.IsPromo {
|
|
||||||
fmt.Printf(" PROMO")
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf(" in %s \"%s\" at position %d\n", location.StorageAreaType, location.StorageAreaName, location.Position)
|
|
||||||
}
|
|
||||||
fmt.Scanln()
|
|
||||||
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
fmt.Println("Unrecognized command:", command)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetStringResponse(prompt string) string {
|
|
||||||
fmt.Print(prompt + " ")
|
|
||||||
|
|
||||||
var response string
|
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
|
||||||
scanner.Scan()
|
|
||||||
response = scanner.Text()
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetYesNoResponse(prompt string) bool {
|
|
||||||
response := GetStringResponse(prompt)
|
|
||||||
return strings.ToUpper(response) == "Y"
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTriadicResponse(prompt string) logic.Triadic {
|
|
||||||
response := GetStringResponse(prompt)
|
|
||||||
|
|
||||||
switch strings.ToUpper(response) {
|
|
||||||
case "Y":
|
|
||||||
return logic.True
|
|
||||||
case "N":
|
|
||||||
return logic.False
|
|
||||||
default:
|
|
||||||
return logic.Either
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
searchCriteria logic.SearchCriteria = logic.SearchCriteria{
|
|
||||||
SetCode: "",
|
|
||||||
Foil: logic.Either,
|
|
||||||
Promo: logic.Either,
|
|
||||||
Language: "",
|
|
||||||
}
|
|
||||||
shouldRefreshSearch bool = true
|
|
||||||
searchOptions logic.SearchOptions
|
|
||||||
)
|
|
||||||
|
|
||||||
func getSearchCriteria() {
|
|
||||||
searchCriteria.SetCode = GetStringResponse("Set code:")
|
|
||||||
searchCriteria.Foil = GetTriadicResponse("Foil (y/n/E):")
|
|
||||||
searchCriteria.Promo = GetTriadicResponse("Promo (y/n/E):")
|
|
||||||
searchCriteria.Language = GetStringResponse("Language:")
|
|
||||||
shouldRefreshSearch = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTriadicDisplay(triadic logic.Triadic) string {
|
|
||||||
if triadic == logic.True {
|
|
||||||
return "True"
|
|
||||||
}
|
|
||||||
|
|
||||||
if triadic == logic.False {
|
|
||||||
return "False"
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Either"
|
|
||||||
}
|
|
||||||
|
|
||||||
func showSearchCriteria() {
|
|
||||||
fmt.Println("SEARCH CRITERIA")
|
|
||||||
|
|
||||||
setCodeDisplay := getInfoDisplay(searchCriteria.SetCode)
|
|
||||||
foilDisplay := getTriadicDisplay(searchCriteria.Foil)
|
|
||||||
promoDisplay := getTriadicDisplay(searchCriteria.Promo)
|
|
||||||
languageDisplay := getInfoDisplay(searchCriteria.Language)
|
|
||||||
|
|
||||||
fmt.Println("Set code:", setCodeDisplay)
|
|
||||||
fmt.Println("Foil:", foilDisplay)
|
|
||||||
fmt.Println("Promo:", promoDisplay)
|
|
||||||
fmt.Println("Language:", languageDisplay)
|
|
||||||
|
|
||||||
fmt.Print("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func showSelectedCard() {
|
|
||||||
selectedCardDisplay := getInfoDisplay(selectedCardPrintingSearchLine)
|
|
||||||
fmt.Println("Selected card:", selectedCardDisplay)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSearchOptions(db *sql.DB) {
|
|
||||||
if shouldRefreshSearch {
|
|
||||||
fmt.Println("LOADING")
|
|
||||||
options, err := logic.GetAllSearchOptions(db, searchCriteria)
|
|
||||||
logic.Check(err)
|
|
||||||
searchOptions = options
|
|
||||||
shouldRefreshSearch = false
|
|
||||||
fmt.Println("READY")
|
|
||||||
fmt.Println("RUN")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sevenkeys/figlet"
|
|
||||||
|
|
||||||
"github.com/inancgumus/screen"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ClearScreen() {
|
|
||||||
screen.Clear()
|
|
||||||
screen.MoveTopLeft()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ShowSplashScreen() {
|
|
||||||
ClearScreen()
|
|
||||||
|
|
||||||
figlet.PrintMsgSlant("SEVENKEYS", "center")
|
|
||||||
figlet.PrintMsgTerm("the ultimate Magic: the Gathering trading card storage system", "center")
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"sevenkeys/database"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
selectedCardPrintingSearchLine string
|
|
||||||
|
|
||||||
copiesInserted int
|
|
||||||
)
|
|
||||||
|
|
||||||
func getInfoDisplay(info string) string {
|
|
||||||
if info == "" {
|
|
||||||
return "[EMPTY]"
|
|
||||||
}
|
|
||||||
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
func showStorageInfo(w io.Writer, area database.StorageArea) {
|
|
||||||
fmt.Fprint(w, "Selected Storage Area: ")
|
|
||||||
if area.Name == "" { // TODO: Add a struct method to determine whether it is unset?
|
|
||||||
fmt.Fprint(w, "[None]\n")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(w, "%s (%s)\n", area.Name, area.StorageType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func showCopiesInserted() {
|
|
||||||
fmt.Println("Copies inserted:", copiesInserted)
|
|
||||||
}
|
|
||||||
|
|
||||||
func insertSelectedCard(db *sql.DB, area database.StorageArea, location database.CardLocation) {
|
|
||||||
if area.Name == "" {
|
|
||||||
output = "No storage area selected."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if location.CardPrintingId == "" {
|
|
||||||
output = "No card selected, please [search] for a card printing."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err := logic.StoreCard(db, location)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
copiesInserted++
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"sevenkeys/database"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_showStorageInfo_DisplaysNone_IfSelectedStorageAreaIsUnset(t *testing.T) {
|
|
||||||
expected := "Selected Storage Area: [None]\n"
|
|
||||||
|
|
||||||
var output bytes.Buffer
|
|
||||||
|
|
||||||
var area database.StorageArea
|
|
||||||
showStorageInfo(&output, area)
|
|
||||||
|
|
||||||
result := output.String()
|
|
||||||
if result != expected {
|
|
||||||
t.Errorf("expected %s, got %s", expected, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_showStorageInfo_DisplaysStorageAreaNameAndType_IfSelectedStorageAreaIsSet(t *testing.T) {
|
|
||||||
expected := "Selected Storage Area: Test A (Box)\n"
|
|
||||||
|
|
||||||
var output bytes.Buffer
|
|
||||||
|
|
||||||
area := database.StorageArea{
|
|
||||||
Id: 1,
|
|
||||||
Name: "Test A",
|
|
||||||
Type: "Box",
|
|
||||||
}
|
|
||||||
showStorageInfo(&output, area)
|
|
||||||
|
|
||||||
result := output.String()
|
|
||||||
if result != expected {
|
|
||||||
t.Errorf("expected %s, got %s", expected, result)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package cli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
"sevenkeys/logic/scryfall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RunUpdateCheck(db *sql.DB) {
|
|
||||||
fmt.Println("Checking for updates...")
|
|
||||||
bulkData, err := scryfall.GetBulkDataByType(scryfall.BulkDataTypeAllCards)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
needsUpdate, err := logic.CheckForUpdates(db, bulkData)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
if !needsUpdate {
|
|
||||||
fmt.Println("No update required.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Update required.")
|
|
||||||
if GetYesNoResponse("Run update? (y/N)") {
|
|
||||||
fmt.Println("Running update...")
|
|
||||||
|
|
||||||
logic.CreateCacheDirectories()
|
|
||||||
|
|
||||||
err = logic.UpdateSets(db)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
err = logic.UpdateCards(db, bulkData)
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
fmt.Println("Update finished.")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package constants
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Program *tea.Program
|
|
||||||
Database *sql.DB
|
|
||||||
)
|
|
|
@ -5,27 +5,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type CardPrinting struct {
|
type CardPrinting struct {
|
||||||
Id string
|
Id int
|
||||||
Name string
|
Name string
|
||||||
SetCode string
|
SetCode string
|
||||||
IsFoil bool
|
IsFoil bool
|
||||||
IsPromo bool
|
IsPromo bool
|
||||||
CollectorNumber string
|
CollectorNumber string
|
||||||
ImageUrl string
|
|
||||||
Language string
|
Language string
|
||||||
}
|
}
|
||||||
|
|
||||||
func InsertCardPrinting(db *sql.DB, cardPrinting CardPrinting) error {
|
func InsertCardPrinting(db *sql.DB, cardPrinting CardPrinting) error {
|
||||||
query := `INSERT INTO CardPrinting (
|
query := `INSERT INTO CardPrinting (
|
||||||
Id,
|
|
||||||
Name,
|
Name,
|
||||||
SetCode,
|
SetCode,
|
||||||
IsFoil,
|
IsFoil,
|
||||||
IsPromo,
|
IsPromo,
|
||||||
CollectorNumber,
|
CollectorNumber,
|
||||||
ImageUrl,
|
|
||||||
Language)
|
Language)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?);`
|
VALUES (?, ?, ?, ?, ?, ?);`
|
||||||
|
|
||||||
insert, err := db.Prepare(query)
|
insert, err := db.Prepare(query)
|
||||||
defer insert.Close()
|
defer insert.Close()
|
||||||
|
@ -33,7 +30,7 @@ func InsertCardPrinting(db *sql.DB, cardPrinting CardPrinting) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = insert.Exec(cardPrinting.Id, cardPrinting.Name, cardPrinting.SetCode, cardPrinting.IsFoil, cardPrinting.IsPromo, cardPrinting.CollectorNumber, cardPrinting.ImageUrl, cardPrinting.Language)
|
_, err = insert.Exec(cardPrinting.Name, cardPrinting.SetCode, cardPrinting.IsFoil, cardPrinting.IsPromo, cardPrinting.CollectorNumber, cardPrinting.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,41 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import "database/sql"
|
||||||
"database/sql"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CardLocation struct {
|
type CardStorageLocation struct {
|
||||||
Id int
|
Id int
|
||||||
CardPrintingId string
|
CardPrintingId int
|
||||||
StorageAreaId int
|
StorageBox string
|
||||||
Position int
|
Position int
|
||||||
|
Source string
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLastPositionInStorageArea(db *sql.DB, storageAreaId int) (int, error) {
|
func GetLastPositionInBox(db *sql.DB, storageBox string) (int, error) {
|
||||||
query := "SELECT Position FROM CardLocation WHERE StorageAreaId = ? ORDER BY Position DESC LIMIT 1;"
|
query := "SELECT Position FROM CardStorageLocation WHERE StorageBox = ? ORDER BY Position DESC LIMIT 1"
|
||||||
|
|
||||||
var lastPosition int
|
var lastPosition int
|
||||||
err := db.QueryRow(query, storageAreaId).Scan(&lastPosition)
|
err := db.QueryRow(query, storageBox).Scan(&lastPosition)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
} else if err != nil {
|
} else {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastPosition, nil
|
return lastPosition, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InsertCardLocation(db *sql.DB, storageLocation CardLocation) error {
|
func InsertCardStorageLocation(db *sql.DB, storageLocation CardStorageLocation) error {
|
||||||
query := `INSERT INTO CardLocation
|
query := `INSERT INTO CardStorageLocation
|
||||||
(CardPrintingId, StorageAreaId, Position)
|
(CardPrintingId, StorageBox, Position, Source)
|
||||||
VALUES (?, ?, ?);`
|
VALUES (?, ?, ?, ?);`
|
||||||
|
|
||||||
insert, err := db.Prepare(query)
|
insert, err := db.Prepare(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = insert.Exec(storageLocation.CardPrintingId, storageLocation.StorageAreaId, storageLocation.Position)
|
_, err = insert.Exec(storageLocation.CardPrintingId, storageLocation.StorageBox, storageLocation.Position, storageLocation.Source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import "database/sql"
|
|
||||||
|
|
||||||
type LocateCardResult struct {
|
|
||||||
CardName string
|
|
||||||
SetCode string
|
|
||||||
IsFoil bool
|
|
||||||
IsPromo bool
|
|
||||||
CollectorNumber string
|
|
||||||
Language string
|
|
||||||
StorageAreaType string
|
|
||||||
StorageAreaName string
|
|
||||||
Position int
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetLocateCardResultsByCardName(db *sql.DB, cardName string) ([]LocateCardResult, error) {
|
|
||||||
var results []LocateCardResult
|
|
||||||
|
|
||||||
query := "SELECT CardPrinting.Name, CardPrinting.SetCode, CardPrinting.IsFoil, CardPrinting.IsPromo, CardPrinting.CollectorNumber, CardPrinting.Language, StorageArea.StorageType, StorageArea.Name, CardLocation.Position FROM CardLocation JOIN CardPrinting ON CardLocation.CardPrintingId = CardPrinting.Id JOIN StorageArea ON CardLocation.StorageAreaId = StorageArea.Id WHERE CardPrinting.Name = ?;"
|
|
||||||
rows, err := db.Query(query, cardName)
|
|
||||||
defer rows.Close()
|
|
||||||
if err != nil {
|
|
||||||
return results, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var result LocateCardResult
|
|
||||||
for rows.Next() {
|
|
||||||
err := rows.Scan(&result.CardName, &result.SetCode, &result.IsFoil, &result.IsPromo, &result.CollectorNumber, &result.Language, &result.StorageAreaType, &result.StorageAreaName, &result.Position)
|
|
||||||
if err != nil {
|
|
||||||
return results, err
|
|
||||||
}
|
|
||||||
|
|
||||||
results = append(results, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
return results, nil
|
|
||||||
}
|
|
|
@ -15,28 +15,21 @@ CREATE TABLE IF NOT EXISTS ExpansionSet (
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS CardPrinting (
|
CREATE TABLE IF NOT EXISTS CardPrinting (
|
||||||
Id VARCHAR(37) PRIMARY KEY, -- GUID, plus one character for foil/nonfoil
|
Id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
Name VARCHAR(150) NOT NULL,
|
Name VARCHAR(150) NOT NULL,
|
||||||
SetCode VARCHAR(6) NOT NULL,
|
SetCode VARCHAR(6) NOT NULL,
|
||||||
FOREIGN KEY (SetCode) REFERENCES ExpansionSet(SetCode),
|
FOREIGN KEY (SetCode) REFERENCES ExpansionSet(SetCode),
|
||||||
IsFoil BOOLEAN NOT NULL,
|
IsFoil BOOLEAN NOT NULL,
|
||||||
IsPromo BOOLEAN NOT NULL,
|
IsPromo BOOLEAN NOT NULL,
|
||||||
CollectorNumber VARCHAR(10) NOT NULL,
|
CollectorNumber VARCHAR(10) NOT NULL,
|
||||||
ImageUrl VARCHAR(100) NOT NULL,
|
|
||||||
Language VARCHAR(3) NOT NULL
|
Language VARCHAR(3) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS StorageArea (
|
CREATE TABLE IF NOT EXISTS CardStorageLocation (
|
||||||
Id INT AUTO_INCREMENT PRIMARY KEY,
|
Id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
Name VARCHAR(100) NOT NULL,
|
CardPrintingId INT NOT NULL,
|
||||||
StorageType ENUM('Binder', 'Box')
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS CardLocation (
|
|
||||||
Id INT AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
CardPrintingId VARCHAR(37) NULL,
|
|
||||||
FOREIGN KEY (CardPrintingId) REFERENCES CardPrinting(Id),
|
FOREIGN KEY (CardPrintingId) REFERENCES CardPrinting(Id),
|
||||||
StorageAreaId INT NOT NULL,
|
StorageBox VARCHAR(20) NOT NULL,
|
||||||
FOREIGN KEY (StorageAreaId) REFERENCES StorageArea(Id),
|
Position INT NOT NULL,
|
||||||
Position INT NULL
|
Source VARCHAR(100) NULL
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
package database
|
|
||||||
|
|
||||||
import "database/sql"
|
|
||||||
|
|
||||||
type StorageArea struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
StorageType string
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAllStorageAreas(db *sql.DB) ([]StorageArea, error) {
|
|
||||||
var storageAreas []StorageArea
|
|
||||||
|
|
||||||
query := `SELECT * FROM StorageArea;`
|
|
||||||
rows, err := db.Query(query)
|
|
||||||
defer rows.Close()
|
|
||||||
if err != nil {
|
|
||||||
return storageAreas, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var area StorageArea
|
|
||||||
for rows.Next() {
|
|
||||||
err := rows.Scan(&area.Id, &area.Name, &area.StorageType)
|
|
||||||
if err != nil {
|
|
||||||
return storageAreas, err
|
|
||||||
}
|
|
||||||
|
|
||||||
storageAreas = append(storageAreas, area)
|
|
||||||
}
|
|
||||||
|
|
||||||
return storageAreas, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func InsertStorageArea(db *sql.DB, storageArea StorageArea) error {
|
|
||||||
query := `INSERT INTO StorageArea (Name, StorageType) VALUES (?, ?);`
|
|
||||||
|
|
||||||
insert, err := db.Prepare(query)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = insert.Exec(storageArea.Name, storageArea.StorageType)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package figlet
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
|
|
||||||
"github.com/lukesampson/figlet/figletlib"
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
FigletFontSlant *figletlib.Font
|
|
||||||
FigletFontTerm *figletlib.Font
|
|
||||||
)
|
|
||||||
|
|
||||||
func ReadFigletFonts() {
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
fontsdir := filepath.Join(cwd, "fonts")
|
|
||||||
|
|
||||||
FigletFontSlant, err = figletlib.GetFontByName(fontsdir, "slant")
|
|
||||||
logic.Check(err)
|
|
||||||
|
|
||||||
FigletFontTerm, err = figletlib.GetFontByName(fontsdir, "term")
|
|
||||||
logic.Check(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTerminalWidth() int {
|
|
||||||
width, _, err := terminal.GetSize(0)
|
|
||||||
if err != nil {
|
|
||||||
return 80
|
|
||||||
}
|
|
||||||
return width
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintMsgSlant(msg, alignment string) {
|
|
||||||
figletlib.PrintMsg(msg,
|
|
||||||
FigletFontSlant,
|
|
||||||
getTerminalWidth(),
|
|
||||||
FigletFontSlant.Settings(),
|
|
||||||
alignment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintMsgTerm(msg, alignment string) {
|
|
||||||
figletlib.PrintMsg(msg,
|
|
||||||
FigletFontTerm,
|
|
||||||
getTerminalWidth(),
|
|
||||||
FigletFontTerm.Settings(),
|
|
||||||
alignment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SprintMsgSlant(msg, alignment string) string {
|
|
||||||
return figletlib.SprintMsg(msg,
|
|
||||||
FigletFontSlant,
|
|
||||||
getTerminalWidth(),
|
|
||||||
FigletFontSlant.Settings(),
|
|
||||||
alignment)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SprintMsgTerm(msg, alignment string) string {
|
|
||||||
return figletlib.SprintMsg(msg,
|
|
||||||
FigletFontTerm,
|
|
||||||
getTerminalWidth(),
|
|
||||||
FigletFontTerm.Settings(),
|
|
||||||
alignment)
|
|
||||||
}
|
|
|
@ -1,900 +0,0 @@
|
||||||
flf2a$ 6 5 76 15 14 1 16271 39
|
|
||||||
Ivrit (Hebrew) Unicode font assembled by John Cowan <cowan@ccil.org>
|
|
||||||
Latin chars from Standard by G. Chappell & Ian Chai
|
|
||||||
Hebrew chars from Jerusalem by Gedaliah Friedenberg <gfrieden@nyx.cs.du.edu>
|
|
||||||
Use "ilhebrew.flc" for Hebrew keyboard mapping
|
|
||||||
Use "ushebrew.flc" for U.S.-style keyboard mapping ("febrew" script)
|
|
||||||
Use "8859-8.flc" for ISO 8859-8 text
|
|
||||||
Or use UTF-8
|
|
||||||
WARNING! FIGfonts aren't bidirectional; this is strictly right-to-left
|
|
||||||
(by default) even for the Latin characters.
|
|
||||||
figlet release 2.2 -- November 1996
|
|
||||||
|
|
||||||
Modified by Paul Burton <solution@earthlink.net> 12/96 to include new parameter
|
|
||||||
supported by FIGlet and FIGWin. May also be slightly modified for better use
|
|
||||||
of new full-width/kern/smush alternatives, but default output is NOT changed.
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@@
|
|
||||||
_ @
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@
|
|
||||||
(_)@
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
( | )@
|
|
||||||
V V @
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
_| || |_ @
|
|
||||||
|_ .. _|@
|
|
||||||
|_ _|@
|
|
||||||
|_||_| @
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
| | @
|
|
||||||
/ __)@
|
|
||||||
\__ \@
|
|
||||||
( /@
|
|
||||||
|_| @@
|
|
||||||
_ __@
|
|
||||||
(_)/ /@
|
|
||||||
/ / @
|
|
||||||
/ /_ @
|
|
||||||
/_/(_)@
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
( _ ) @
|
|
||||||
/ _ \/\@
|
|
||||||
| (_> <@
|
|
||||||
\___/\/@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
( )@
|
|
||||||
|/ @
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
__@
|
|
||||||
/ /@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
\_\@@
|
|
||||||
__ @
|
|
||||||
\ \ @
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
/_/ @@
|
|
||||||
@
|
|
||||||
__/\__@
|
|
||||||
\ /@
|
|
||||||
/_ _\@
|
|
||||||
\/ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ @
|
|
||||||
_| |_ @
|
|
||||||
|_ _|@
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_ @
|
|
||||||
( )@
|
|
||||||
|/ @@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_____ @
|
|
||||||
|_____|@
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_ @
|
|
||||||
(_)@
|
|
||||||
@@
|
|
||||||
__@
|
|
||||||
/ /@
|
|
||||||
/ / @
|
|
||||||
/ / @
|
|
||||||
/_/ @
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
/ _ \ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
/ |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
|___ \ @
|
|
||||||
__) |@
|
|
||||||
/ __/ @
|
|
||||||
|_____|@
|
|
||||||
@@
|
|
||||||
_____ @
|
|
||||||
|___ / @
|
|
||||||
|_ \ @
|
|
||||||
___) |@
|
|
||||||
|____/ @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
| || | @
|
|
||||||
| || |_ @
|
|
||||||
|__ _|@
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
| ___| @
|
|
||||||
|___ \ @
|
|
||||||
___) |@
|
|
||||||
|____/ @
|
|
||||||
@@
|
|
||||||
__ @
|
|
||||||
/ /_ @
|
|
||||||
| '_ \ @
|
|
||||||
| (_) |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
_____ @
|
|
||||||
|___ |@
|
|
||||||
/ / @
|
|
||||||
/ / @
|
|
||||||
/_/ @
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
( _ ) @
|
|
||||||
/ _ \ @
|
|
||||||
| (_) |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
/ _ \ @
|
|
||||||
| (_) |@
|
|
||||||
\__, |@
|
|
||||||
/_/ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ @
|
|
||||||
(_)@
|
|
||||||
_ @
|
|
||||||
(_)@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ @
|
|
||||||
(_)@
|
|
||||||
_ @
|
|
||||||
( )@
|
|
||||||
|/ @@
|
|
||||||
__@
|
|
||||||
/ /@
|
|
||||||
/ / @
|
|
||||||
\ \ @
|
|
||||||
\_\@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_____ @
|
|
||||||
|_____|@
|
|
||||||
|_____|@
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
__ @
|
|
||||||
\ \ @
|
|
||||||
\ \@
|
|
||||||
/ /@
|
|
||||||
/_/ @
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
|__ \@
|
|
||||||
/ /@
|
|
||||||
|_| @
|
|
||||||
(_) @
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
/ __ \ @
|
|
||||||
/ / _` |@
|
|
||||||
| | (_| |@
|
|
||||||
\ \__,_|@
|
|
||||||
\____/ @@
|
|
||||||
_ @
|
|
||||||
/ \ @
|
|
||||||
/ _ \ @
|
|
||||||
/ ___ \ @
|
|
||||||
/_/ \_\@
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
| __ ) @
|
|
||||||
| _ \ @
|
|
||||||
| |_) |@
|
|
||||||
|____/ @
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
/ ___|@
|
|
||||||
| | @
|
|
||||||
| |___ @
|
|
||||||
\____|@
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
| _ \ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
|____/ @
|
|
||||||
@@
|
|
||||||
_____ @
|
|
||||||
| ____|@
|
|
||||||
| _| @
|
|
||||||
| |___ @
|
|
||||||
|_____|@
|
|
||||||
@@
|
|
||||||
_____ @
|
|
||||||
| ___|@
|
|
||||||
| |_ @
|
|
||||||
| _| @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
/ ___|@
|
|
||||||
| | _ @
|
|
||||||
| |_| |@
|
|
||||||
\____|@
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
| _ |@
|
|
||||||
|_| |_|@
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
|_ _|@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
|___|@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
| |@
|
|
||||||
_ | |@
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
_ __@
|
|
||||||
| |/ /@
|
|
||||||
| ' / @
|
|
||||||
| . \ @
|
|
||||||
|_|\_\@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
| |___ @
|
|
||||||
|_____|@
|
|
||||||
@@
|
|
||||||
__ __ @
|
|
||||||
| \/ |@
|
|
||||||
| |\/| |@
|
|
||||||
| | | |@
|
|
||||||
|_| |_|@
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
| \ | |@
|
|
||||||
| \| |@
|
|
||||||
| |\ |@
|
|
||||||
|_| \_|@
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
/ _ \ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
| _ \ @
|
|
||||||
| |_) |@
|
|
||||||
| __/ @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
/ _ \ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\__\_\@
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
| _ \ @
|
|
||||||
| |_) |@
|
|
||||||
| _ < @
|
|
||||||
|_| \_\@
|
|
||||||
@@
|
|
||||||
____ @
|
|
||||||
/ ___| @
|
|
||||||
\___ \ @
|
|
||||||
___) |@
|
|
||||||
|____/ @
|
|
||||||
@@
|
|
||||||
_____ @
|
|
||||||
|_ _|@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
| | | |@
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
__ __@
|
|
||||||
\ \ / /@
|
|
||||||
\ \ / / @
|
|
||||||
\ V / @
|
|
||||||
\_/ @
|
|
||||||
@@
|
|
||||||
__ __@
|
|
||||||
\ \ / /@
|
|
||||||
\ \ /\ / / @
|
|
||||||
\ V V / @
|
|
||||||
\_/\_/ @
|
|
||||||
@@
|
|
||||||
__ __@
|
|
||||||
\ \/ /@
|
|
||||||
\ / @
|
|
||||||
/ \ @
|
|
||||||
/_/\_\@
|
|
||||||
@@
|
|
||||||
__ __@
|
|
||||||
\ \ / /@
|
|
||||||
\ V / @
|
|
||||||
| | @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
_____@
|
|
||||||
|__ /@
|
|
||||||
/ / @
|
|
||||||
/ /_ @
|
|
||||||
/____|@
|
|
||||||
@@
|
|
||||||
__ @
|
|
||||||
| _|@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
|__|@@
|
|
||||||
__ @
|
|
||||||
\ \ @
|
|
||||||
\ \ @
|
|
||||||
\ \ @
|
|
||||||
\_\@
|
|
||||||
@@
|
|
||||||
__ @
|
|
||||||
|_ |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|__|@@
|
|
||||||
/\ @
|
|
||||||
|/\|@
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_____ @
|
|
||||||
|_____|@@
|
|
||||||
_ @
|
|
||||||
( )@
|
|
||||||
\|@
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
__ _ @
|
|
||||||
/ _` |@
|
|
||||||
| (_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
| |__ @
|
|
||||||
| '_ \ @
|
|
||||||
| |_) |@
|
|
||||||
|_.__/ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
___ @
|
|
||||||
/ __|@
|
|
||||||
| (__ @
|
|
||||||
\___|@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
__| |@
|
|
||||||
/ _` |@
|
|
||||||
| (_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
___ @
|
|
||||||
/ _ \@
|
|
||||||
| __/@
|
|
||||||
\___|@
|
|
||||||
@@
|
|
||||||
__ @
|
|
||||||
/ _|@
|
|
||||||
| |_ @
|
|
||||||
| _|@
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
__ _ @
|
|
||||||
/ _` |@
|
|
||||||
| (_| |@
|
|
||||||
\__, |@
|
|
||||||
|___/ @@
|
|
||||||
_ @
|
|
||||||
| |__ @
|
|
||||||
| '_ \ @
|
|
||||||
| | | |@
|
|
||||||
|_| |_|@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
(_)@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
(_)@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
_/ |@
|
|
||||||
|__/ @@
|
|
||||||
_ @
|
|
||||||
| | __@
|
|
||||||
| |/ /@
|
|
||||||
| < @
|
|
||||||
|_|\_\@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ __ ___ @
|
|
||||||
| '_ ` _ \ @
|
|
||||||
| | | | | |@
|
|
||||||
|_| |_| |_|@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ __ @
|
|
||||||
| '_ \ @
|
|
||||||
| | | |@
|
|
||||||
|_| |_|@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
___ @
|
|
||||||
/ _ \ @
|
|
||||||
| (_) |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ __ @
|
|
||||||
| '_ \ @
|
|
||||||
| |_) |@
|
|
||||||
| .__/ @
|
|
||||||
|_| @@
|
|
||||||
@
|
|
||||||
__ _ @
|
|
||||||
/ _` |@
|
|
||||||
| (_| |@
|
|
||||||
\__, |@
|
|
||||||
|_|@@
|
|
||||||
@
|
|
||||||
_ __ @
|
|
||||||
| '__|@
|
|
||||||
| | @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
___ @
|
|
||||||
/ __|@
|
|
||||||
\__ \@
|
|
||||||
|___/@
|
|
||||||
@@
|
|
||||||
_ @
|
|
||||||
| |_ @
|
|
||||||
| __|@
|
|
||||||
| |_ @
|
|
||||||
\__|@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ _ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
__ __@
|
|
||||||
\ \ / /@
|
|
||||||
\ V / @
|
|
||||||
\_/ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
__ __@
|
|
||||||
\ \ /\ / /@
|
|
||||||
\ V V / @
|
|
||||||
\_/\_/ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
__ __@
|
|
||||||
\ \/ /@
|
|
||||||
> < @
|
|
||||||
/_/\_\@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ _ @
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\__, |@
|
|
||||||
|___/ @@
|
|
||||||
@
|
|
||||||
____@
|
|
||||||
|_ /@
|
|
||||||
/ / @
|
|
||||||
/___|@
|
|
||||||
@@
|
|
||||||
__@
|
|
||||||
/ /@
|
|
||||||
| | @
|
|
||||||
< < @
|
|
||||||
| | @
|
|
||||||
\_\@@
|
|
||||||
_ @
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@@
|
|
||||||
__ @
|
|
||||||
\ \ @
|
|
||||||
| | @
|
|
||||||
> >@
|
|
||||||
| | @
|
|
||||||
/_/ @@
|
|
||||||
/\/|@
|
|
||||||
|/\/ @
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/_\ @
|
|
||||||
/ _ \ @
|
|
||||||
/_/ \_\@
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/ _ \ @
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
(_) (_)@
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/ _` |@
|
|
||||||
| (_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/ _ \ @
|
|
||||||
| (_) |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
_ _ @
|
|
||||||
(_) (_)@
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
___ @
|
|
||||||
/ _ \@
|
|
||||||
| |/ /@
|
|
||||||
| |\ \@
|
|
||||||
| ||_/@
|
|
||||||
|_| @@
|
|
||||||
160 NO-BREAK SPACE
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@
|
|
||||||
$@@
|
|
||||||
173 SOFT HYPHEN
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_____ @
|
|
||||||
|_____|@
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
196 LATIN CAPITAL LETTER A WITH DIAERESIS
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/_\ @
|
|
||||||
/ _ \ @
|
|
||||||
/_/ \_\@
|
|
||||||
@@
|
|
||||||
214 LATIN CAPITAL LETTER O WITH DIAERESIS
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/ _ \ @
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
220 LATIN CAPITAL LETTER U WITH DIAERESIS
|
|
||||||
_ _ @
|
|
||||||
(_) (_)@
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
223 LATIN SMALL LETTER SHARP S
|
|
||||||
___ @
|
|
||||||
/ _ \@
|
|
||||||
| |/ /@
|
|
||||||
| |\ \@
|
|
||||||
| ||_/@
|
|
||||||
|_| @@
|
|
||||||
228 LATIN SMALL LETTER A WITH DIAERESIS
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/ _` |@
|
|
||||||
| (_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
246 LATIN SMALL LETTER O WITH DIAERESIS
|
|
||||||
_ _ @
|
|
||||||
(_)_(_)@
|
|
||||||
/ _ \ @
|
|
||||||
| (_) |@
|
|
||||||
\___/ @
|
|
||||||
@@
|
|
||||||
252 LATIN SMALL LETTER U WITH DIAERESIS
|
|
||||||
_ _ @
|
|
||||||
(_) (_)@
|
|
||||||
| | | |@
|
|
||||||
| |_| |@
|
|
||||||
\__,_|@
|
|
||||||
@@
|
|
||||||
0x05D0 HEBREW LETTER ALEF
|
|
||||||
__ __@
|
|
||||||
\ \ / /@
|
|
||||||
| V / @
|
|
||||||
| |\ \ @
|
|
||||||
|_| \_\@
|
|
||||||
@@
|
|
||||||
0x05D1 HEBREW LETTER BET
|
|
||||||
______ @
|
|
||||||
|____ | @
|
|
||||||
| | @
|
|
||||||
_____| |_@
|
|
||||||
/________/@
|
|
||||||
@@
|
|
||||||
0x05D2 HEBREW LETTER GIMEL
|
|
||||||
____ @
|
|
||||||
|__ | @
|
|
||||||
| | @
|
|
||||||
____| | @
|
|
||||||
/____/\_\@
|
|
||||||
@@
|
|
||||||
0x05D3 HEBREW LETTER DALET
|
|
||||||
_______ @
|
|
||||||
|____ |@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
0x05D4 HEBREW LETTER HE
|
|
||||||
_______ @
|
|
||||||
|_____ |@
|
|
||||||
_ | |@
|
|
||||||
| | | |@
|
|
||||||
|_| |_|@
|
|
||||||
@@
|
|
||||||
0x05D5 HEBREW LETTER VAV
|
|
||||||
___ @
|
|
||||||
|_ |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@
|
|
||||||
@@
|
|
||||||
0x05D6 HEBREW LETTER ZAYIN
|
|
||||||
________ @
|
|
||||||
\__ __\@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
|_| @
|
|
||||||
@@
|
|
||||||
0x05D7 HEBREW LETTER HET
|
|
||||||
_______ @
|
|
||||||
|. __ |@
|
|
||||||
| | | |@
|
|
||||||
| | | |@
|
|
||||||
|_| |_|@
|
|
||||||
@@
|
|
||||||
0x05D8 HEBREW LETTER TET
|
|
||||||
__ ___ @
|
|
||||||
|. | /_ |@
|
|
||||||
| | | |@
|
|
||||||
| |___| |@
|
|
||||||
|_______|@
|
|
||||||
@@
|
|
||||||
0x05D9 HEBREW LETTER YOD
|
|
||||||
___ @
|
|
||||||
|_ |@
|
|
||||||
|_|@
|
|
||||||
$ @
|
|
||||||
$ @
|
|
||||||
@@
|
|
||||||
0x05DA HEBREW LETTER FINAL KAF
|
|
||||||
_______ @
|
|
||||||
|____ .|@
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
| | @
|
|
||||||
|_| @@
|
|
||||||
0x05DB HEBREW LETTER KAF
|
|
||||||
_____ @
|
|
||||||
|____ \ @
|
|
||||||
| |@
|
|
||||||
____| |@
|
|
||||||
|_____/ @
|
|
||||||
@@
|
|
||||||
0x05DC HEBREW LETTER LAMED
|
|
||||||
|=|____ @
|
|
||||||
|____ |@
|
|
||||||
/ / @
|
|
||||||
/ / @
|
|
||||||
/_/ @
|
|
||||||
@@
|
|
||||||
0x05DD HEBREW LETTER FINAL MEM
|
|
||||||
________ @
|
|
||||||
|. ___ |@
|
|
||||||
| | | |@
|
|
||||||
| |___| |@
|
|
||||||
|_______|@
|
|
||||||
@@
|
|
||||||
0x05DE HEBREW LETTER MEM
|
|
||||||
_______ @
|
|
||||||
|. __ |@
|
|
||||||
| | | |@
|
|
||||||
| | _| |@
|
|
||||||
|_||___|@
|
|
||||||
@@
|
|
||||||
0x05DF HEBREW LETTER FINAL NUN
|
|
||||||
___ @
|
|
||||||
|_ |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@@
|
|
||||||
0x05E0 HEBREW LETTER NUN
|
|
||||||
___ @
|
|
||||||
|_ |@
|
|
||||||
| |@
|
|
||||||
__| |@
|
|
||||||
|____|@
|
|
||||||
@@
|
|
||||||
0x05E1 HEBREW LETTER SAMEKH
|
|
||||||
_______ @
|
|
||||||
|. __ |@
|
|
||||||
| | | |@
|
|
||||||
| |__/ |@
|
|
||||||
|_____/ @
|
|
||||||
@@
|
|
||||||
0x05E2 HEBREW LETTER AYIN
|
|
||||||
__ _ @
|
|
||||||
\ \ | |@
|
|
||||||
\ \| |@
|
|
||||||
__\ ` |@
|
|
||||||
|______|@
|
|
||||||
@@
|
|
||||||
0x05E3 HEBREW LETTER FINAL PE
|
|
||||||
______ @
|
|
||||||
| __ |@
|
|
||||||
| |_ | |@
|
|
||||||
|___|| |@
|
|
||||||
| |@
|
|
||||||
|_|@@
|
|
||||||
0x05E4 HEBREW LETTER PE
|
|
||||||
_______ @
|
|
||||||
| ___ |@
|
|
||||||
\_\ | |@
|
|
||||||
_____| |@
|
|
||||||
|_______|@
|
|
||||||
@@
|
|
||||||
0x05E5 HEBREW LETTER FINAL TSADI
|
|
||||||
__ _ @
|
|
||||||
|. | | |@
|
|
||||||
| | // @
|
|
||||||
| |// @
|
|
||||||
| | @
|
|
||||||
|_| @@
|
|
||||||
0x05E6 HEBREW LETTER TSADI
|
|
||||||
__ __.@
|
|
||||||
\ \ / / @
|
|
||||||
\ V / @
|
|
||||||
___\ \ @
|
|
||||||
|______| @
|
|
||||||
@@
|
|
||||||
0x05E7 HEBREW LETTER QOF
|
|
||||||
______ @
|
|
||||||
|____ |@
|
|
||||||
_ | |@
|
|
||||||
| | |_|@
|
|
||||||
| | @
|
|
||||||
|_| @@
|
|
||||||
0x05E8 HEBREW LETTER RESH
|
|
||||||
______ @
|
|
||||||
|____ |@
|
|
||||||
| |@
|
|
||||||
| |@
|
|
||||||
|_|@
|
|
||||||
@@
|
|
||||||
0x05E9 HEBREW LETTER SHIN
|
|
||||||
_ _ _ @
|
|
||||||
| | | | | |@
|
|
||||||
| | | | | |@
|
|
||||||
| |/ /_/ / @
|
|
||||||
|_______/ @
|
|
||||||
@@
|
|
||||||
0x05EA HEBREW LETTER TAV
|
|
||||||
______ @
|
|
||||||
| __ |@
|
|
||||||
| | | |@
|
|
||||||
_| | | |@
|
|
||||||
|___| |_|@
|
|
||||||
@@
|
|
||||||
0x2721 STAR OF DAVID
|
|
||||||
@
|
|
||||||
__/\__@
|
|
||||||
\ /@
|
|
||||||
/_ _\@
|
|
||||||
\/ @
|
|
||||||
@@
|
|
||||||
-0x0002
|
|
||||||
aleph = t, bet/vet = c, gimel = d, dalet = s, he = v, vav = u, zayin = z @
|
|
||||||
het = j, tet = y, yod = h, kaf/chaf = f, final kaf = l, lamed = k, mem = n@
|
|
||||||
final mem = o, nun = b, final nun = i, samekh = x, ayin = g, pe/fe = p, @
|
|
||||||
final pe = ;, tsadi = m, final tsadi = ., qof = e, resh = r, shin/sin = a @
|
|
||||||
tav = , comma = ', period = /, semicolon = `, slash = q, apostrophe = w @
|
|
||||||
Star of David = * @@
|
|
||||||
-0x0003
|
|
||||||
aleph = a, bet/vet = b, gimel = g, dalet = d, he = h, vav = v, zayin = z @
|
|
||||||
het = c, tet = t, yod = y, kaf/chaf = k, final kaf = f, lamed = l, mem = m@
|
|
||||||
final mem = o, nun = n, final nun = i, samekh = e, ayin = _, pe/fe = p, @
|
|
||||||
final pe = u, tsadi = j, final tsadi = w, qof = q, resh = r, shin/sin = s @
|
|
||||||
tav = x @
|
|
||||||
Star of David = * @@
|
|
|
@ -1,899 +0,0 @@
|
||||||
flf2a$ 4 3 10 0 10 0 1920 96
|
|
||||||
Mini by Glenn Chappell 4/93
|
|
||||||
Includes ISO Latin-1
|
|
||||||
figlet release 2.1 -- 12 Aug 1994
|
|
||||||
Permission is hereby given to modify this font, as long as the
|
|
||||||
modifier's name is placed on a comment line.
|
|
||||||
|
|
||||||
Modified by Paul Burton <solution@earthlink.net> 12/96 to include new parameter
|
|
||||||
supported by FIGlet and FIGWin. May also be slightly modified for better use
|
|
||||||
of new full-width/kern/smush alternatives, but default output is NOT changed.
|
|
||||||
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@@
|
|
||||||
@
|
|
||||||
|$@
|
|
||||||
o$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
||$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
-|-|-$@
|
|
||||||
-|-|-$@
|
|
||||||
@@
|
|
||||||
_$@
|
|
||||||
(|$ @
|
|
||||||
_|)$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
O/$@
|
|
||||||
/O$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
()$ @
|
|
||||||
(_X$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
/$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
/$@
|
|
||||||
|$ @
|
|
||||||
\$@@
|
|
||||||
@
|
|
||||||
\$ @
|
|
||||||
|$@
|
|
||||||
/$ @@
|
|
||||||
@
|
|
||||||
\|/$@
|
|
||||||
/|\$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_|_$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
/$@@
|
|
||||||
@
|
|
||||||
__$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
/$@
|
|
||||||
/$ @
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
/|$@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
)$@
|
|
||||||
/_$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
_)$@
|
|
||||||
_)$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|_|_$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
|_$ @
|
|
||||||
_)$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
|_$ @
|
|
||||||
|_)$@
|
|
||||||
@@
|
|
||||||
__$@
|
|
||||||
/$@
|
|
||||||
/$ @
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
(_|$@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
o$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
o$@
|
|
||||||
/$@@
|
|
||||||
@
|
|
||||||
/$@
|
|
||||||
\$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
--$@
|
|
||||||
--$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\$@
|
|
||||||
/$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
)$@
|
|
||||||
o$ @
|
|
||||||
@@
|
|
||||||
__$ @
|
|
||||||
/ \$@
|
|
||||||
| (|/$@
|
|
||||||
\__$ @@
|
|
||||||
@
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
|_)$@
|
|
||||||
|_)$@
|
|
||||||
@@
|
|
||||||
_$@
|
|
||||||
/$ @
|
|
||||||
\_$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
| \$@
|
|
||||||
|_/$@
|
|
||||||
@@
|
|
||||||
_$@
|
|
||||||
|_$@
|
|
||||||
|_$@
|
|
||||||
@@
|
|
||||||
_$@
|
|
||||||
|_$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
__$@
|
|
||||||
/__$@
|
|
||||||
\_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
| |$@
|
|
||||||
@@
|
|
||||||
___$@
|
|
||||||
|$ @
|
|
||||||
_|_$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|$@
|
|
||||||
\_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|/$@
|
|
||||||
|\$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|$ @
|
|
||||||
|_$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|\/|$@
|
|
||||||
| |$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|\ |$@
|
|
||||||
| \|$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
|_)$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
/ \$@
|
|
||||||
\_X$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
|_)$@
|
|
||||||
| \$@
|
|
||||||
@@
|
|
||||||
__$@
|
|
||||||
(_$ @
|
|
||||||
__)$@
|
|
||||||
@@
|
|
||||||
___$@
|
|
||||||
|$ @
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
| |$@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\ /$@
|
|
||||||
\/$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\ /$@
|
|
||||||
\/\/$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\/$@
|
|
||||||
/\$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\_/$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
__$@
|
|
||||||
/$@
|
|
||||||
/_$@
|
|
||||||
@@
|
|
||||||
_$@
|
|
||||||
|$ @
|
|
||||||
|_$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\$ @
|
|
||||||
\$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
/\$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
__$@@
|
|
||||||
@
|
|
||||||
\$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|_$ @
|
|
||||||
|_)$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_$@
|
|
||||||
(_$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_|$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_$ @
|
|
||||||
(/_$@
|
|
||||||
@@
|
|
||||||
_$@
|
|
||||||
_|_$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_$ @
|
|
||||||
(_|$@
|
|
||||||
_|$@@
|
|
||||||
@
|
|
||||||
|_$ @
|
|
||||||
| |$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
|$@
|
|
||||||
_|$@@
|
|
||||||
@
|
|
||||||
|$ @
|
|
||||||
|<$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
._ _$ @
|
|
||||||
| | |$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
._$ @
|
|
||||||
| |$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
._$ @
|
|
||||||
|_)$@
|
|
||||||
|$ @@
|
|
||||||
@
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
|$@@
|
|
||||||
@
|
|
||||||
._$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_$@
|
|
||||||
_>$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_|_$@
|
|
||||||
|_$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
\/$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
\/\/$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
><$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
\/$@
|
|
||||||
/$ @@
|
|
||||||
@
|
|
||||||
_$ @
|
|
||||||
/_$@
|
|
||||||
@@
|
|
||||||
,-$@
|
|
||||||
_|$ @
|
|
||||||
|$ @
|
|
||||||
`-$@@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
|$@@
|
|
||||||
-.$ @
|
|
||||||
|_$@
|
|
||||||
|$ @
|
|
||||||
-'$ @@
|
|
||||||
/\/$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
o o$@
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
o_o$@
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
o o$@
|
|
||||||
| |$@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
o o$@
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
o o$@
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
o o$@
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
_$ @
|
|
||||||
| )$@
|
|
||||||
| )$@
|
|
||||||
|$ @@
|
|
||||||
160 NO-BREAK SPACE
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@@
|
|
||||||
161 INVERTED EXCLAMATION MARK
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
162 CENT SIGN
|
|
||||||
@
|
|
||||||
|_$@
|
|
||||||
(__$@
|
|
||||||
|$ @@
|
|
||||||
163 POUND SIGN
|
|
||||||
_$ @
|
|
||||||
_/_`$ @
|
|
||||||
|___$@
|
|
||||||
@@
|
|
||||||
164 CURRENCY SIGN
|
|
||||||
@
|
|
||||||
`o'$@
|
|
||||||
' `$@
|
|
||||||
@@
|
|
||||||
165 YEN SIGN
|
|
||||||
@
|
|
||||||
_\_/_$@
|
|
||||||
--|--$@
|
|
||||||
@@
|
|
||||||
166 BROKEN BAR
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
|$@@
|
|
||||||
167 SECTION SIGN
|
|
||||||
_$@
|
|
||||||
($ @
|
|
||||||
()$@
|
|
||||||
_)$@@
|
|
||||||
168 DIAERESIS
|
|
||||||
o o$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
169 COPYRIGHT SIGN
|
|
||||||
_$ @
|
|
||||||
|C|$@
|
|
||||||
`-'$@
|
|
||||||
@@
|
|
||||||
170 FEMININE ORDINAL INDICATOR
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
---$@
|
|
||||||
@@
|
|
||||||
171 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
||||||
@
|
|
||||||
//$@
|
|
||||||
\\$@
|
|
||||||
@@
|
|
||||||
172 NOT SIGN
|
|
||||||
@
|
|
||||||
__$ @
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
173 SOFT HYPHEN
|
|
||||||
@
|
|
||||||
_$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
174 REGISTERED SIGN
|
|
||||||
_$ @
|
|
||||||
|R|$@
|
|
||||||
`-'$@
|
|
||||||
@@
|
|
||||||
175 MACRON
|
|
||||||
__$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
176 DEGREE SIGN
|
|
||||||
O$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
177 PLUS-MINUS SIGN
|
|
||||||
@
|
|
||||||
_|_$@
|
|
||||||
_|_$@
|
|
||||||
@@
|
|
||||||
178 SUPERSCRIPT TWO
|
|
||||||
2$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
179 SUPERSCRIPT THREE
|
|
||||||
3$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
180 ACUTE ACCENT
|
|
||||||
/$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
181 MICRO SIGN
|
|
||||||
@
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
|$ @@
|
|
||||||
182 PILCROW SIGN
|
|
||||||
__$ @
|
|
||||||
(| |$@
|
|
||||||
| |$@
|
|
||||||
@@
|
|
||||||
183 MIDDLE DOT
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
184 CEDILLA
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
S$@@
|
|
||||||
185 SUPERSCRIPT ONE
|
|
||||||
1$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
186 MASCULINE ORDINAL INDICATOR
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
---$@
|
|
||||||
@@
|
|
||||||
187 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
||||||
@
|
|
||||||
\\$@
|
|
||||||
//$@
|
|
||||||
@@
|
|
||||||
188 VULGAR FRACTION ONE QUARTER
|
|
||||||
@
|
|
||||||
1/$@
|
|
||||||
/4$@
|
|
||||||
@@
|
|
||||||
189 VULGAR FRACTION ONE HALF
|
|
||||||
@
|
|
||||||
1/$@
|
|
||||||
/2$@
|
|
||||||
@@
|
|
||||||
190 VULGAR FRACTION THREE QUARTERS
|
|
||||||
@
|
|
||||||
3/$@
|
|
||||||
/4$@
|
|
||||||
@@
|
|
||||||
191 INVERTED QUESTION MARK
|
|
||||||
@
|
|
||||||
o$@
|
|
||||||
(_$@
|
|
||||||
@@
|
|
||||||
192 LATIN CAPITAL LETTER A WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
193 LATIN CAPITAL LETTER A WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
194 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
|
||||||
/\$ @
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
195 LATIN CAPITAL LETTER A WITH TILDE
|
|
||||||
/\/$@
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
196 LATIN CAPITAL LETTER A WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
/\$ @
|
|
||||||
/--\$@
|
|
||||||
@@
|
|
||||||
197 LATIN CAPITAL LETTER A WITH RING ABOVE
|
|
||||||
O$ @
|
|
||||||
/ \$ @
|
|
||||||
/---\$@
|
|
||||||
@@
|
|
||||||
198 LATIN CAPITAL LETTER AE
|
|
||||||
_$@
|
|
||||||
/|_$@
|
|
||||||
/-|_$@
|
|
||||||
@@
|
|
||||||
199 LATIN CAPITAL LETTER C WITH CEDILLA
|
|
||||||
_$@
|
|
||||||
/$ @
|
|
||||||
\_$@
|
|
||||||
S$@@
|
|
||||||
200 LATIN CAPITAL LETTER E WITH GRAVE
|
|
||||||
\_$@
|
|
||||||
|_$@
|
|
||||||
|_$@
|
|
||||||
@@
|
|
||||||
201 LATIN CAPITAL LETTER E WITH ACUTE
|
|
||||||
_/$@
|
|
||||||
|_$ @
|
|
||||||
|_$ @
|
|
||||||
@@
|
|
||||||
202 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
|_$ @
|
|
||||||
|_$ @
|
|
||||||
@@
|
|
||||||
203 LATIN CAPITAL LETTER E WITH DIAERESIS
|
|
||||||
o_o$@
|
|
||||||
|_$ @
|
|
||||||
|_$ @
|
|
||||||
@@
|
|
||||||
204 LATIN CAPITAL LETTER I WITH GRAVE
|
|
||||||
\__$@
|
|
||||||
|$ @
|
|
||||||
_|_$@
|
|
||||||
@@
|
|
||||||
205 LATIN CAPITAL LETTER I WITH ACUTE
|
|
||||||
__/$@
|
|
||||||
|$ @
|
|
||||||
_|_$@
|
|
||||||
@@
|
|
||||||
206 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
___$@
|
|
||||||
_|_$@
|
|
||||||
@@
|
|
||||||
207 LATIN CAPITAL LETTER I WITH DIAERESIS
|
|
||||||
o_o$@
|
|
||||||
|$ @
|
|
||||||
_|_$@
|
|
||||||
@@
|
|
||||||
208 LATIN CAPITAL LETTER ETH
|
|
||||||
_$ @
|
|
||||||
_|_\$@
|
|
||||||
|_/$@
|
|
||||||
@@
|
|
||||||
209 LATIN CAPITAL LETTER N WITH TILDE
|
|
||||||
/\/$@
|
|
||||||
|\ |$@
|
|
||||||
| \|$@
|
|
||||||
@@
|
|
||||||
210 LATIN CAPITAL LETTER O WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
211 LATIN CAPITAL LETTER O WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
212 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
213 LATIN CAPITAL LETTER O WITH TILDE
|
|
||||||
/\/$@
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
214 LATIN CAPITAL LETTER O WITH DIAERESIS
|
|
||||||
o_o$@
|
|
||||||
/ \$@
|
|
||||||
\_/$@
|
|
||||||
@@
|
|
||||||
215 MULTIPLICATION SIGN
|
|
||||||
@
|
|
||||||
@
|
|
||||||
X$@
|
|
||||||
@@
|
|
||||||
216 LATIN CAPITAL LETTER O WITH STROKE
|
|
||||||
__$ @
|
|
||||||
/ /\$@
|
|
||||||
\/_/$@
|
|
||||||
@@
|
|
||||||
217 LATIN CAPITAL LETTER U WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
| |$@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
218 LATIN CAPITAL LETTER U WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
| |$@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
219 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
| |$@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
220 LATIN CAPITAL LETTER U WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
| |$@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
221 LATIN CAPITAL LETTER Y WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
\_/$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
222 LATIN CAPITAL LETTER THORN
|
|
||||||
|_$ @
|
|
||||||
|_)$@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
223 LATIN SMALL LETTER SHARP S
|
|
||||||
_$ @
|
|
||||||
| )$@
|
|
||||||
| )$@
|
|
||||||
|$ @@
|
|
||||||
224 LATIN SMALL LETTER A WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
225 LATIN SMALL LETTER A WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
226 LATIN SMALL LETTER A WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
227 LATIN SMALL LETTER A WITH TILDE
|
|
||||||
/\/$@
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
228 LATIN SMALL LETTER A WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
229 LATIN SMALL LETTER A WITH RING ABOVE
|
|
||||||
O$ @
|
|
||||||
_.$@
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
230 LATIN SMALL LETTER AE
|
|
||||||
@
|
|
||||||
___$ @
|
|
||||||
(_|/_$@
|
|
||||||
@@
|
|
||||||
231 LATIN SMALL LETTER C WITH CEDILLA
|
|
||||||
@
|
|
||||||
_$@
|
|
||||||
(_$@
|
|
||||||
S$@@
|
|
||||||
232 LATIN SMALL LETTER E WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
_$ @
|
|
||||||
(/_$@
|
|
||||||
@@
|
|
||||||
233 LATIN SMALL LETTER E WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
_$ @
|
|
||||||
(/_$@
|
|
||||||
@@
|
|
||||||
234 LATIN SMALL LETTER E WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
_$ @
|
|
||||||
(/_$@
|
|
||||||
@@
|
|
||||||
235 LATIN SMALL LETTER E WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
_$ @
|
|
||||||
(/_$@
|
|
||||||
@@
|
|
||||||
236 LATIN SMALL LETTER I WITH GRAVE
|
|
||||||
\$@
|
|
||||||
@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
237 LATIN SMALL LETTER I WITH ACUTE
|
|
||||||
/$@
|
|
||||||
@
|
|
||||||
|$@
|
|
||||||
@@
|
|
||||||
238 LATIN SMALL LETTER I WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
239 LATIN SMALL LETTER I WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
@
|
|
||||||
|$ @
|
|
||||||
@@
|
|
||||||
240 LATIN SMALL LETTER ETH
|
|
||||||
X$ @
|
|
||||||
\$ @
|
|
||||||
(_|$@
|
|
||||||
@@
|
|
||||||
241 LATIN SMALL LETTER N WITH TILDE
|
|
||||||
/\/$@
|
|
||||||
._$ @
|
|
||||||
| |$@
|
|
||||||
@@
|
|
||||||
242 LATIN SMALL LETTER O WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
243 LATIN SMALL LETTER O WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
244 LATIN SMALL LETTER O WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
245 LATIN SMALL LETTER O WITH TILDE
|
|
||||||
/\/$@
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
246 LATIN SMALL LETTER O WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
_$ @
|
|
||||||
(_)$@
|
|
||||||
@@
|
|
||||||
247 DIVISION SIGN
|
|
||||||
o$ @
|
|
||||||
---$@
|
|
||||||
o$ @
|
|
||||||
@@
|
|
||||||
248 LATIN SMALL LETTER O WITH STROKE
|
|
||||||
@
|
|
||||||
_$ @
|
|
||||||
(/)$@
|
|
||||||
@@
|
|
||||||
249 LATIN SMALL LETTER U WITH GRAVE
|
|
||||||
\$ @
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
250 LATIN SMALL LETTER U WITH ACUTE
|
|
||||||
/$ @
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
251 LATIN SMALL LETTER U WITH CIRCUMFLEX
|
|
||||||
/\$@
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
252 LATIN SMALL LETTER U WITH DIAERESIS
|
|
||||||
o o$@
|
|
||||||
@
|
|
||||||
|_|$@
|
|
||||||
@@
|
|
||||||
253 LATIN SMALL LETTER Y WITH ACUTE
|
|
||||||
/$@
|
|
||||||
@
|
|
||||||
\/$@
|
|
||||||
/$ @@
|
|
||||||
254 LATIN SMALL LETTER THORN
|
|
||||||
@
|
|
||||||
|_$ @
|
|
||||||
|_)$@
|
|
||||||
|$ @@
|
|
||||||
255 LATIN SMALL LETTER Y WITH DIAERESIS
|
|
||||||
oo$@
|
|
||||||
@
|
|
||||||
\/$@
|
|
||||||
/$ @@
|
|
|
@ -1,899 +0,0 @@
|
||||||
flf2a$ 4 3 14 0 10 0 1920 96
|
|
||||||
SmShadow by Glenn Chappell 4/93 -- based on Small
|
|
||||||
Includes ISO Latin-1
|
|
||||||
figlet release 2.1 -- 12 Aug 1994
|
|
||||||
Permission is hereby given to modify this font, as long as the
|
|
||||||
modifier's name is placed on a comment line.
|
|
||||||
|
|
||||||
Modified by Paul Burton <solution@earthlink.net> 12/96 to include new parameter
|
|
||||||
supported by FIGlet and FIGWin. May also be slightly modified for better use
|
|
||||||
of new full-width/kern/smush alternatives, but default output is NOT changed.
|
|
||||||
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
_)$@
|
|
||||||
@@
|
|
||||||
| )$@
|
|
||||||
V V$ @
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
| |$ @
|
|
||||||
_ |_ |_|$@
|
|
||||||
_ |_ |_|$@
|
|
||||||
_| _|$ @@
|
|
||||||
|$ @
|
|
||||||
(_-<$@
|
|
||||||
_ _/$@
|
|
||||||
_|$ @@
|
|
||||||
_) /$ @
|
|
||||||
/$ @
|
|
||||||
_/ _)$@
|
|
||||||
@@
|
|
||||||
_|$ @
|
|
||||||
_| _|$@
|
|
||||||
\____|$ @
|
|
||||||
@@
|
|
||||||
)$@
|
|
||||||
/$ @
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
/$@
|
|
||||||
|$ @
|
|
||||||
|$ @
|
|
||||||
\_\$@@
|
|
||||||
\ \$ @
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
_/$ @@
|
|
||||||
\ \ /$ @
|
|
||||||
_ _|$@
|
|
||||||
_/ _\$ @
|
|
||||||
@@
|
|
||||||
|$ @
|
|
||||||
__ __|$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
)$@
|
|
||||||
/$ @@
|
|
||||||
@
|
|
||||||
____|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_)$@
|
|
||||||
@@
|
|
||||||
/$@
|
|
||||||
/$ @
|
|
||||||
_/$ @
|
|
||||||
@@
|
|
||||||
\$ @
|
|
||||||
( |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
_ |$@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
_ )$@
|
|
||||||
/$ @
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
__ /$@
|
|
||||||
_ \$@
|
|
||||||
___/$@
|
|
||||||
@@
|
|
||||||
| |$ @
|
|
||||||
__ _|$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
__|$@
|
|
||||||
__ \$@
|
|
||||||
___/$@
|
|
||||||
@@
|
|
||||||
/$ @
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
__ /$@
|
|
||||||
/$ @
|
|
||||||
_/$ @
|
|
||||||
@@
|
|
||||||
_ )$@
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
_ \$@
|
|
||||||
\_ /$@
|
|
||||||
_/$ @
|
|
||||||
@@
|
|
||||||
_)$@
|
|
||||||
@
|
|
||||||
_)$@
|
|
||||||
@@
|
|
||||||
_)$@
|
|
||||||
@
|
|
||||||
)$@
|
|
||||||
/$ @@
|
|
||||||
/$@
|
|
||||||
< <$ @
|
|
||||||
\_\$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
____|$@
|
|
||||||
____|$@
|
|
||||||
@@
|
|
||||||
\ \$ @
|
|
||||||
> >$@
|
|
||||||
_/$ @
|
|
||||||
@@
|
|
||||||
__ \$@
|
|
||||||
_/$@
|
|
||||||
_)$ @
|
|
||||||
@@
|
|
||||||
__ \$ @
|
|
||||||
/ _` |$@
|
|
||||||
\__,_|$@
|
|
||||||
\____/$ @@
|
|
||||||
\$ @
|
|
||||||
_ \$ @
|
|
||||||
_/ _\$@
|
|
||||||
@@
|
|
||||||
_ )$@
|
|
||||||
_ \$@
|
|
||||||
___/$@
|
|
||||||
@@
|
|
||||||
__|$@
|
|
||||||
($ @
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
_ \$ @
|
|
||||||
| |$@
|
|
||||||
___/$ @
|
|
||||||
@@
|
|
||||||
__|$@
|
|
||||||
_|$ @
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
__|$@
|
|
||||||
_|$ @
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
__|$@
|
|
||||||
(_ |$@
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
| |$@
|
|
||||||
__ |$@
|
|
||||||
_| _|$@
|
|
||||||
@@
|
|
||||||
_ _|$@
|
|
||||||
|$ @
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
|$@
|
|
||||||
\ |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
| /$@
|
|
||||||
. <$ @
|
|
||||||
_|\_\$@
|
|
||||||
@@
|
|
||||||
|$ @
|
|
||||||
|$ @
|
|
||||||
____|$@
|
|
||||||
@@
|
|
||||||
\ |$@
|
|
||||||
|\/ |$@
|
|
||||||
_| _|$@
|
|
||||||
@@
|
|
||||||
\ |$@
|
|
||||||
. |$@
|
|
||||||
_|\_|$@
|
|
||||||
@@
|
|
||||||
_ \$ @
|
|
||||||
( |$@
|
|
||||||
\___/$ @
|
|
||||||
@@
|
|
||||||
_ \$@
|
|
||||||
__/$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
_ \$ @
|
|
||||||
( |$@
|
|
||||||
\__\_\$@
|
|
||||||
@@
|
|
||||||
_ \$@
|
|
||||||
/$@
|
|
||||||
_|_\$@
|
|
||||||
@@
|
|
||||||
__|$@
|
|
||||||
\__ \$@
|
|
||||||
____/$@
|
|
||||||
@@
|
|
||||||
__ __|$@
|
|
||||||
|$ @
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
| |$@
|
|
||||||
| |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
\ \ /$@
|
|
||||||
\ \ /$ @
|
|
||||||
\_/$ @
|
|
||||||
@@
|
|
||||||
\ \ /$@
|
|
||||||
\ \ \ /$ @
|
|
||||||
\_/\_/$ @
|
|
||||||
@@
|
|
||||||
\ \ /$@
|
|
||||||
> <$ @
|
|
||||||
_/\_\$@
|
|
||||||
@@
|
|
||||||
\ \ /$@
|
|
||||||
\ /$ @
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
__ /$@
|
|
||||||
/$ @
|
|
||||||
____|$@
|
|
||||||
@@
|
|
||||||
_|$@
|
|
||||||
|$ @
|
|
||||||
|$ @
|
|
||||||
__|$@@
|
|
||||||
\ \$ @
|
|
||||||
\ \$ @
|
|
||||||
\_\$@
|
|
||||||
@@
|
|
||||||
_ |$@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
__|$@@
|
|
||||||
\$ @
|
|
||||||
/\|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
____|$@@
|
|
||||||
)$@
|
|
||||||
\|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
|$ @
|
|
||||||
_ \$@
|
|
||||||
_.__/$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_|$@
|
|
||||||
\__|$@
|
|
||||||
@@
|
|
||||||
|$@
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
-_)$@
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
_|$@
|
|
||||||
_|$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_` |$@
|
|
||||||
\__, |$@
|
|
||||||
____/$ @@
|
|
||||||
|$ @
|
|
||||||
\$ @
|
|
||||||
_| _|$@
|
|
||||||
@@
|
|
||||||
_)$@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
_)$@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
__/$ @@
|
|
||||||
|$ @
|
|
||||||
| /$@
|
|
||||||
_\_\$@
|
|
||||||
@@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
` \$ @
|
|
||||||
_|_|_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\$ @
|
|
||||||
_| _|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
_ \$@
|
|
||||||
.__/$@
|
|
||||||
_|$ @@
|
|
||||||
@
|
|
||||||
_` |$@
|
|
||||||
\__, |$@
|
|
||||||
_|$@@
|
|
||||||
@
|
|
||||||
_|$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
(_-<$@
|
|
||||||
___/$@
|
|
||||||
@@
|
|
||||||
|$ @
|
|
||||||
_|$@
|
|
||||||
\__|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
| |$@
|
|
||||||
\_,_|$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\ \ /$@
|
|
||||||
\_/$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\ \ \ /$@
|
|
||||||
\_/\_/$ @
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
\ \ /$@
|
|
||||||
_\_\$@
|
|
||||||
@@
|
|
||||||
@
|
|
||||||
| |$@
|
|
||||||
\_, |$@
|
|
||||||
___/$ @@
|
|
||||||
@
|
|
||||||
_ /$@
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
/$@
|
|
||||||
_ |$ @
|
|
||||||
|$ @
|
|
||||||
\_\$@@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
|$@
|
|
||||||
_|$@@
|
|
||||||
\ \$ @
|
|
||||||
|_$@
|
|
||||||
|$ @
|
|
||||||
_/$ @@
|
|
||||||
\ |$@
|
|
||||||
/\/$ @
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
_) \_)$@
|
|
||||||
_ \$ @
|
|
||||||
/ _\$@
|
|
||||||
@@
|
|
||||||
_) _)$@
|
|
||||||
__ \$@
|
|
||||||
\____/$@
|
|
||||||
@@
|
|
||||||
_) _)$@
|
|
||||||
| |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
_) _)$@
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
_) _)$@
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
_) _)$@
|
|
||||||
| |$@
|
|
||||||
\_,_|$@
|
|
||||||
@@
|
|
||||||
_ \$@
|
|
||||||
|< <$@
|
|
||||||
|__/$@
|
|
||||||
_|$ @@
|
|
||||||
160 NO-BREAK SPACE
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@
|
|
||||||
$$@@
|
|
||||||
161 INVERTED EXCLAMATION MARK
|
|
||||||
_)$@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
162 CENT SIGN
|
|
||||||
|$ @
|
|
||||||
_)$@
|
|
||||||
\ _)$@
|
|
||||||
|$ @@
|
|
||||||
163 POUND SIGN
|
|
||||||
_\$ @
|
|
||||||
_ _|$ @
|
|
||||||
_,___|$@
|
|
||||||
@@
|
|
||||||
164 CURRENCY SIGN
|
|
||||||
\ . /$@
|
|
||||||
_ \$@
|
|
||||||
\/ /$@
|
|
||||||
@@
|
|
||||||
165 YEN SIGN
|
|
||||||
\ \ /$ @
|
|
||||||
__ __|$@
|
|
||||||
__ __|$@
|
|
||||||
_|$ @@
|
|
||||||
166 BROKEN BAR
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
|$@
|
|
||||||
_|$@@
|
|
||||||
167 SECTION SIGN
|
|
||||||
_)$@
|
|
||||||
\ \$ @
|
|
||||||
\ \/$ @
|
|
||||||
__/$ @@
|
|
||||||
168 DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
169 COPYRIGHT SIGN
|
|
||||||
\$ @
|
|
||||||
_| \$@
|
|
||||||
\ \__| /$@
|
|
||||||
\____/$ @@
|
|
||||||
170 FEMININE ORDINAL INDICATOR
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
_____|$@
|
|
||||||
@@
|
|
||||||
171 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
||||||
/ /$@
|
|
||||||
< < <$ @
|
|
||||||
\_\_\$@
|
|
||||||
@@
|
|
||||||
172 NOT SIGN
|
|
||||||
____ |$@
|
|
||||||
_|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
173 SOFT HYPHEN
|
|
||||||
@
|
|
||||||
___|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
174 REGISTERED SIGN
|
|
||||||
\$ @
|
|
||||||
-) \$@
|
|
||||||
\ |\\ /$@
|
|
||||||
\____/$ @@
|
|
||||||
175 MACRON
|
|
||||||
___|$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
176 DEGREE SIGN
|
|
||||||
.\$@
|
|
||||||
\_/$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
177 PLUS-MINUS SIGN
|
|
||||||
|$ @
|
|
||||||
_ _|$@
|
|
||||||
_|$ @
|
|
||||||
_____|$@@
|
|
||||||
178 SUPERSCRIPT TWO
|
|
||||||
_ )$@
|
|
||||||
__|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
179 SUPERSCRIPT THREE
|
|
||||||
_ /$@
|
|
||||||
__)$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
180 ACUTE ACCENT
|
|
||||||
_/$@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
181 MICRO SIGN
|
|
||||||
@
|
|
||||||
| |$@
|
|
||||||
.,_|$@
|
|
||||||
_|$ @@
|
|
||||||
182 PILCROW SIGN
|
|
||||||
|$@
|
|
||||||
\_ | |$@
|
|
||||||
_|_|$@
|
|
||||||
@@
|
|
||||||
183 MIDDLE DOT
|
|
||||||
@
|
|
||||||
_)$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
184 CEDILLA
|
|
||||||
@
|
|
||||||
@
|
|
||||||
@
|
|
||||||
_)$@@
|
|
||||||
185 SUPERSCRIPT ONE
|
|
||||||
_ |$@
|
|
||||||
_|$@
|
|
||||||
@
|
|
||||||
@@
|
|
||||||
186 MASCULINE ORDINAL INDICATOR
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
____|$@
|
|
||||||
@@
|
|
||||||
187 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
||||||
\ \ \$ @
|
|
||||||
> > >$@
|
|
||||||
_/_/$ @
|
|
||||||
@@
|
|
||||||
188 VULGAR FRACTION ONE QUARTER
|
|
||||||
_ | /$ @
|
|
||||||
_| /_' |$@
|
|
||||||
_/ _|$@
|
|
||||||
@@
|
|
||||||
189 VULGAR FRACTION ONE HALF
|
|
||||||
_ | /$ @
|
|
||||||
_| /_ )$@
|
|
||||||
_/ __|$@
|
|
||||||
@@
|
|
||||||
190 VULGAR FRACTION THREE QUARTERS
|
|
||||||
_ / /$ @
|
|
||||||
__) /_' |$@
|
|
||||||
_/ _|$@
|
|
||||||
@@
|
|
||||||
191 INVERTED QUESTION MARK
|
|
||||||
_)$ @
|
|
||||||
/$ @
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
192 LATIN CAPITAL LETTER A WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
--\$ @
|
|
||||||
_/\_\$@
|
|
||||||
@@
|
|
||||||
193 LATIN CAPITAL LETTER A WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
--\$ @
|
|
||||||
_/\_\$@
|
|
||||||
@@
|
|
||||||
194 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
--\$ @
|
|
||||||
_/\_\$@
|
|
||||||
@@
|
|
||||||
195 LATIN CAPITAL LETTER A WITH TILDE
|
|
||||||
/ _/$ @
|
|
||||||
--\$ @
|
|
||||||
_/\_\$@
|
|
||||||
@@
|
|
||||||
196 LATIN CAPITAL LETTER A WITH DIAERESIS
|
|
||||||
_) \_)$@
|
|
||||||
_ \$ @
|
|
||||||
/ _\$@
|
|
||||||
@@
|
|
||||||
197 LATIN CAPITAL LETTER A WITH RING ABOVE
|
|
||||||
( )$ @
|
|
||||||
_ \$ @
|
|
||||||
_/ _\$@
|
|
||||||
@@
|
|
||||||
198 LATIN CAPITAL LETTER AE
|
|
||||||
, __|$@
|
|
||||||
_ _|$ @
|
|
||||||
_/ ___|$@
|
|
||||||
@@
|
|
||||||
199 LATIN CAPITAL LETTER C WITH CEDILLA
|
|
||||||
|$@
|
|
||||||
($ @
|
|
||||||
\___|$@
|
|
||||||
_)$ @@
|
|
||||||
200 LATIN CAPITAL LETTER E WITH GRAVE
|
|
||||||
\_\$@
|
|
||||||
-<$@
|
|
||||||
__<$@
|
|
||||||
@@
|
|
||||||
201 LATIN CAPITAL LETTER E WITH ACUTE
|
|
||||||
_/$@
|
|
||||||
-<$@
|
|
||||||
__<$@
|
|
||||||
@@
|
|
||||||
202 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
|
||||||
/\\$@
|
|
||||||
-<$@
|
|
||||||
__<$@
|
|
||||||
@@
|
|
||||||
203 LATIN CAPITAL LETTER E WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
-<$ @
|
|
||||||
__<$ @
|
|
||||||
@@
|
|
||||||
204 LATIN CAPITAL LETTER I WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
_ _|$@
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
205 LATIN CAPITAL LETTER I WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
_ _|$@
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
206 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
_ _|$@
|
|
||||||
___|$@
|
|
||||||
@@
|
|
||||||
207 LATIN CAPITAL LETTER I WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
_ _|$ @
|
|
||||||
___|$ @
|
|
||||||
@@
|
|
||||||
208 LATIN CAPITAL LETTER ETH
|
|
||||||
_ \$ @
|
|
||||||
_ _| |$@
|
|
||||||
___/$ @
|
|
||||||
@@
|
|
||||||
209 LATIN CAPITAL LETTER N WITH TILDE
|
|
||||||
/ _/$@
|
|
||||||
\ |$@
|
|
||||||
_|\_|$@
|
|
||||||
@@
|
|
||||||
210 LATIN CAPITAL LETTER O WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
__ \$@
|
|
||||||
\____/$@
|
|
||||||
@@
|
|
||||||
211 LATIN CAPITAL LETTER O WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
__ \$@
|
|
||||||
\____/$@
|
|
||||||
@@
|
|
||||||
212 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
__ \$@
|
|
||||||
\____/$@
|
|
||||||
@@
|
|
||||||
213 LATIN CAPITAL LETTER O WITH TILDE
|
|
||||||
/ _/$ @
|
|
||||||
__ \$@
|
|
||||||
\____/$@
|
|
||||||
@@
|
|
||||||
214 LATIN CAPITAL LETTER O WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
__ \$@
|
|
||||||
\____/$@
|
|
||||||
@@
|
|
||||||
215 MULTIPLICATION SIGN
|
|
||||||
\ \$@
|
|
||||||
, '$@
|
|
||||||
\/\/$@
|
|
||||||
@@
|
|
||||||
216 LATIN CAPITAL LETTER O WITH STROKE
|
|
||||||
_ /\$ @
|
|
||||||
( / |$@
|
|
||||||
\_/__/$ @
|
|
||||||
@@
|
|
||||||
217 LATIN CAPITAL LETTER U WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
| |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
218 LATIN CAPITAL LETTER U WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
| |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
219 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
| |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
220 LATIN CAPITAL LETTER U WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
| |$@
|
|
||||||
\__/$ @
|
|
||||||
@@
|
|
||||||
221 LATIN CAPITAL LETTER Y WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
\ \ /$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
222 LATIN CAPITAL LETTER THORN
|
|
||||||
|$ @
|
|
||||||
-_)$@
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
223 LATIN SMALL LETTER SHARP S
|
|
||||||
_ \$@
|
|
||||||
|< <$@
|
|
||||||
|__/$@
|
|
||||||
_|$ @@
|
|
||||||
224 LATIN SMALL LETTER A WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
225 LATIN SMALL LETTER A WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
226 LATIN SMALL LETTER A WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
227 LATIN SMALL LETTER A WITH TILDE
|
|
||||||
/ _/$ @
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
228 LATIN SMALL LETTER A WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
229 LATIN SMALL LETTER A WITH RING ABOVE
|
|
||||||
( )$ @
|
|
||||||
_` |$@
|
|
||||||
\__,_|$@
|
|
||||||
@@
|
|
||||||
230 LATIN SMALL LETTER AE
|
|
||||||
@
|
|
||||||
_` -_)$@
|
|
||||||
\__,___|$@
|
|
||||||
@@
|
|
||||||
231 LATIN SMALL LETTER C WITH CEDILLA
|
|
||||||
@
|
|
||||||
_|$@
|
|
||||||
\__|$@
|
|
||||||
_)$@@
|
|
||||||
232 LATIN SMALL LETTER E WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
-_)$@
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
233 LATIN SMALL LETTER E WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
-_)$@
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
234 LATIN SMALL LETTER E WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
-_)$@
|
|
||||||
\___|$@
|
|
||||||
@@
|
|
||||||
235 LATIN SMALL LETTER E WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
-_)$ @
|
|
||||||
\___|$ @
|
|
||||||
@@
|
|
||||||
236 LATIN SMALL LETTER I WITH GRAVE
|
|
||||||
\_\$@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
237 LATIN SMALL LETTER I WITH ACUTE
|
|
||||||
_/$@
|
|
||||||
|$@
|
|
||||||
_|$@
|
|
||||||
@@
|
|
||||||
238 LATIN SMALL LETTER I WITH CIRCUMFLEX
|
|
||||||
/\\$@
|
|
||||||
|$ @
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
239 LATIN SMALL LETTER I WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
|$ @
|
|
||||||
_|$ @
|
|
||||||
@@
|
|
||||||
240 LATIN SMALL LETTER ETH
|
|
||||||
, \'$@
|
|
||||||
_` |$@
|
|
||||||
\___/$ @
|
|
||||||
@@
|
|
||||||
241 LATIN SMALL LETTER N WITH TILDE
|
|
||||||
/ _/$ @
|
|
||||||
' \$ @
|
|
||||||
_| _|$@
|
|
||||||
@@
|
|
||||||
242 LATIN SMALL LETTER O WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
243 LATIN SMALL LETTER O WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
244 LATIN SMALL LETTER O WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
245 LATIN SMALL LETTER O WITH TILDE
|
|
||||||
/ _/$@
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
246 LATIN SMALL LETTER O WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
_ \$@
|
|
||||||
\___/$@
|
|
||||||
@@
|
|
||||||
247 DIVISION SIGN
|
|
||||||
_)$ @
|
|
||||||
___|$@
|
|
||||||
_)$ @
|
|
||||||
@@
|
|
||||||
248 LATIN SMALL LETTER O WITH STROKE
|
|
||||||
@
|
|
||||||
/\$@
|
|
||||||
\_/_/$@
|
|
||||||
@@
|
|
||||||
249 LATIN SMALL LETTER U WITH GRAVE
|
|
||||||
\_\$ @
|
|
||||||
| |$@
|
|
||||||
\_,_|$@
|
|
||||||
@@
|
|
||||||
250 LATIN SMALL LETTER U WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
| |$@
|
|
||||||
\_,_|$@
|
|
||||||
@@
|
|
||||||
251 LATIN SMALL LETTER U WITH CIRCUMFLEX
|
|
||||||
/\\$ @
|
|
||||||
| |$@
|
|
||||||
\_,_|$@
|
|
||||||
@@
|
|
||||||
252 LATIN SMALL LETTER U WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
| |$@
|
|
||||||
\_,_|$@
|
|
||||||
@@
|
|
||||||
253 LATIN SMALL LETTER Y WITH ACUTE
|
|
||||||
_/$ @
|
|
||||||
| |$@
|
|
||||||
\_, |$@
|
|
||||||
___/$ @@
|
|
||||||
254 LATIN SMALL LETTER THORN
|
|
||||||
|$ @
|
|
||||||
'_ \$@
|
|
||||||
.__/$@
|
|
||||||
_|$ @@
|
|
||||||
255 LATIN SMALL LETTER Y WITH DIAERESIS
|
|
||||||
_) _)$@
|
|
||||||
| |$@
|
|
||||||
\_, |$@
|
|
||||||
___/$ @@
|
|
|
@ -1,600 +0,0 @@
|
||||||
flf2a 1 1 2 -1 13 0 0 242
|
|
||||||
Terminal by Glenn Chappell 4/93
|
|
||||||
Includes characters 128-255
|
|
||||||
Enhanced for Latin-2,3,4 by John Cowan <cowan@ccil.org>
|
|
||||||
Latin character sets supported only if your screen font does
|
|
||||||
figlet release 2.2 -- November 1996
|
|
||||||
Permission is hereby given to modify this font, as long as the
|
|
||||||
modifier's name is placed on a comment line.
|
|
||||||
|
|
||||||
Double-checked by Paul Burton <solution@earthlink.net> 12/96. Added the new
|
|
||||||
parameter supported by FIGlet and FIGWin. Unlike all other FIGfonts, this one
|
|
||||||
is intended to produce output exactly the same as the input unless a control
|
|
||||||
file is used. Therefore it produces the SAME output for smush, kern or fit.
|
|
||||||
|
|
||||||
@
|
|
||||||
!@
|
|
||||||
"@
|
|
||||||
#@
|
|
||||||
$@
|
|
||||||
%@
|
|
||||||
&@
|
|
||||||
'@
|
|
||||||
(@
|
|
||||||
)@
|
|
||||||
*@
|
|
||||||
+@
|
|
||||||
,@
|
|
||||||
-@
|
|
||||||
.@
|
|
||||||
/@
|
|
||||||
0@
|
|
||||||
1@
|
|
||||||
2@
|
|
||||||
3@
|
|
||||||
4@
|
|
||||||
5@
|
|
||||||
6@
|
|
||||||
7@
|
|
||||||
8@
|
|
||||||
9@
|
|
||||||
:@
|
|
||||||
;@
|
|
||||||
<@
|
|
||||||
=@
|
|
||||||
>@
|
|
||||||
?@
|
|
||||||
@#
|
|
||||||
A@
|
|
||||||
B@
|
|
||||||
C@
|
|
||||||
D@
|
|
||||||
E@
|
|
||||||
F@
|
|
||||||
G@
|
|
||||||
H@
|
|
||||||
I@
|
|
||||||
J@
|
|
||||||
K@
|
|
||||||
L@
|
|
||||||
M@
|
|
||||||
N@
|
|
||||||
O@
|
|
||||||
P@
|
|
||||||
Q@
|
|
||||||
R@
|
|
||||||
S@
|
|
||||||
T@
|
|
||||||
U@
|
|
||||||
V@
|
|
||||||
W@
|
|
||||||
X@
|
|
||||||
Y@
|
|
||||||
Z@
|
|
||||||
[@
|
|
||||||
\@
|
|
||||||
]@
|
|
||||||
^@
|
|
||||||
_@
|
|
||||||
`@
|
|
||||||
a@
|
|
||||||
b@
|
|
||||||
c@
|
|
||||||
d@
|
|
||||||
e@
|
|
||||||
f@
|
|
||||||
g@
|
|
||||||
h@
|
|
||||||
i@
|
|
||||||
j@
|
|
||||||
k@
|
|
||||||
l@
|
|
||||||
m@
|
|
||||||
n@
|
|
||||||
o@
|
|
||||||
p@
|
|
||||||
q@
|
|
||||||
r@
|
|
||||||
s@
|
|
||||||
t@
|
|
||||||
u@
|
|
||||||
v@
|
|
||||||
w@
|
|
||||||
x@
|
|
||||||
y@
|
|
||||||
z@
|
|
||||||
{@
|
|
||||||
|@
|
|
||||||
}@
|
|
||||||
~@
|
|
||||||
願
|
|
||||||
淐
|
|
||||||
軹
|
|
||||||
裰
|
|
||||||
蠩
|
|
||||||
廹
|
|
||||||
稛
|
|
||||||
128
|
|
||||||
<EFBFBD>@
|
|
||||||
129
|
|
||||||
<EFBFBD>
|
|
||||||
130
|
|
||||||
<EFBFBD>
|
|
||||||
131
|
|
||||||
<EFBFBD>
|
|
||||||
132
|
|
||||||
<EFBFBD>
|
|
||||||
133
|
|
||||||
<EFBFBD>
|
|
||||||
134
|
|
||||||
<EFBFBD>
|
|
||||||
135
|
|
||||||
䏰
|
|
||||||
136
|
|
||||||
㇀
|
|
||||||
137
|
|
||||||
𪎩
|
|
||||||
138
|
|
||||||
𧶄
|
|
||||||
139
|
|
||||||
𣏴
|
|
||||||
140
|
|
||||||
倻
|
|
||||||
141
|
|
||||||
𠮟
|
|
||||||
142
|
|
||||||
𣻗
|
|
||||||
143
|
|
||||||
蕋
|
|
||||||
144
|
|
||||||
趩
|
|
||||||
145
|
|
||||||
𥜆
|
|
||||||
146
|
|
||||||
𡏆
|
|
||||||
147
|
|
||||||
媁
|
|
||||||
148
|
|
||||||
銉
|
|
||||||
149
|
|
||||||
𦅜
|
|
||||||
150
|
|
||||||
桇
|
|
||||||
151
|
|
||||||
愌
|
|
||||||
152
|
|
||||||
𦴦
|
|
||||||
153
|
|
||||||
䄉
|
|
||||||
154
|
|
||||||
鋣
|
|
||||||
155
|
|
||||||
𡨭
|
|
||||||
156
|
|
||||||
嵛
|
|
||||||
157
|
|
||||||
𨆉
|
|
||||||
158
|
|
||||||
𠺢
|
|
||||||
159
|
|
||||||
籖
|
|
||||||
160 NO-BREAK SPACE
|
|
||||||
𨩚
|
|
||||||
161 INVERTED EXCLAMATION MARK
|
|
||||||
|
|
||||||
162 CENT SIGN
|
|
||||||
\
|
|
||||||
163 POUND SIGN
|
|
||||||
w
|
|
||||||
164 CURRENCY SIGN
|
|
||||||
一
|
|
||||||
165 YEN SIGN
|
|
||||||
世
|
|
||||||
166 BROKEN BAR
|
|
||||||
共
|
|
||||||
167 SECTION SIGN
|
|
||||||
作
|
|
||||||
168 DIAERESIS
|
|
||||||
杓
|
|
||||||
169 COPYRIGHT SIGN
|
|
||||||
咖
|
|
||||||
170 FEMININE ORDINAL INDICATOR
|
|
||||||
昇
|
|
||||||
171 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
||||||
陂
|
|
||||||
172 NOT SIGN
|
|
||||||
拯
|
|
||||||
173 SOFT HYPHEN
|
|
||||||
耐
|
|
||||||
174 REGISTERED SIGN
|
|
||||||
哦
|
|
||||||
175 MACRON
|
|
||||||
浬
|
|
||||||
176 DEGREE SIGN
|
|
||||||
虔
|
|
||||||
177 PLUS-MINUS SIGN
|
|
||||||
娼
|
|
||||||
178 SUPERSCRIPT TWO
|
|
||||||
毫
|
|
||||||
179 SUPERSCRIPT THREE
|
|
||||||
莆
|
|
||||||
180 ACUTE ACCENT
|
|
||||||
婷
|
|
||||||
181 MICRO SIGN
|
|
||||||
溉
|
|
||||||
182 PILCROW SIGN
|
|
||||||
詔
|
|
||||||
183 MIDDLE DOT
|
|
||||||
媳
|
|
||||||
184 CEDILLA
|
|
||||||
睹
|
|
||||||
185 SUPERSCRIPT ONE
|
|
||||||
辟
|
|
||||||
186 MASCULINE ORDINAL INDICATOR
|
|
||||||
愿
|
|
||||||
187 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
|
||||||
罰
|
|
||||||
188 VULGAR FRACTION ONE QUARTER
|
|
||||||
劇
|
|
||||||
189 VULGAR FRACTION ONE HALF
|
|
||||||
瑾
|
|
||||||
190 VULGAR FRACTION THREE QUARTERS
|
|
||||||
輥
|
|
||||||
191 INVERTED QUESTION MARK
|
|
||||||
濃
|
|
||||||
192 LATIN CAPITAL LETTER A WITH GRAVE
|
|
||||||
錐
|
|
||||||
193 LATIN CAPITAL LETTER A WITH ACUTE
|
|
||||||
瞧
|
|
||||||
194 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
|
||||||
駿
|
|
||||||
195 LATIN CAPITAL LETTER A WITH TILDE
|
|
||||||
鞭
|
|
||||||
196 LATIN CAPITAL LETTER A WITH DIAERESIS
|
|
||||||
願
|
|
||||||
197 LATIN CAPITAL LETTER A WITH RING ABOVE
|
|
||||||
護
|
|
||||||
198 LATIN CAPITAL LETTER AE
|
|
||||||
讖
|
|
||||||
199 LATIN CAPITAL LETTER C WITH CEDILLA
|
|
||||||
す
|
|
||||||
200 LATIN CAPITAL LETTER E WITH GRAVE
|
|
||||||
Л
|
|
||||||
201 LATIN CAPITAL LETTER E WITH ACUTE
|
|
||||||
乂
|
|
||||||
202 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
|
||||||
汌
|
|
||||||
203 LATIN CAPITAL LETTER E WITH DIAERESIS
|
|
||||||
杙
|
|
||||||
204 LATIN CAPITAL LETTER I WITH GRAVE
|
|
||||||
坨
|
|
||||||
205 LATIN CAPITAL LETTER I WITH ACUTE
|
|
||||||
泒
|
|
||||||
206 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
|
||||||
哃
|
|
||||||
207 LATIN CAPITAL LETTER I WITH DIAERESIS
|
|
||||||
柜
|
|
||||||
208 LATIN CAPITAL LETTER ETH
|
|
||||||
穾
|
|
||||||
209 LATIN CAPITAL LETTER N WITH TILDE
|
|
||||||
唊
|
|
||||||
210 LATIN CAPITAL LETTER O WITH GRAVE
|
|
||||||
毨
|
|
||||||
211 LATIN CAPITAL LETTER O WITH ACUTE
|
|
||||||
笄
|
|
||||||
212 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
|
||||||
酎
|
|
||||||
213 LATIN CAPITAL LETTER O WITH TILDE
|
|
||||||
崰
|
|
||||||
214 LATIN CAPITAL LETTER O WITH DIAERESIS
|
|
||||||
淐
|
|
||||||
215 MULTIPLICATION SIGN
|
|
||||||
耞
|
|
||||||
216 LATIN CAPITAL LETTER O WITH STROKE
|
|
||||||
釫
|
|
||||||
217 LATIN CAPITAL LETTER U WITH GRAVE
|
|
||||||
惲
|
|
||||||
218 LATIN CAPITAL LETTER U WITH ACUTE
|
|
||||||
湨
|
|
||||||
219 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
|
||||||
罦
|
|
||||||
220 LATIN CAPITAL LETTER U WITH DIAERESIS
|
|
||||||
軹
|
|
||||||
221 LATIN CAPITAL LETTER Y WITH ACUTE
|
|
||||||
媷
|
|
||||||
222 LATIN CAPITAL LETTER THORN
|
|
||||||
毹
|
|
||||||
223 LATIN SMALL LETTER SHARP S
|
|
||||||
稛
|
|
||||||
224 LATIN SMALL LETTER A WITH GRAVE
|
|
||||||
觡
|
|
||||||
225 LATIN SMALL LETTER A WITH ACUTE
|
|
||||||
凘
|
|
||||||
226 LATIN SMALL LETTER A WITH CIRCUMFLEX
|
|
||||||
榠
|
|
||||||
227 LATIN SMALL LETTER A WITH TILDE
|
|
||||||
禗
|
|
||||||
228 LATIN SMALL LETTER A WITH DIAERESIS
|
|
||||||
裰
|
|
||||||
229 LATIN SMALL LETTER A WITH RING ABOVE
|
|
||||||
噚
|
|
||||||
230 LATIN SMALL LETTER AE
|
|
||||||
澍
|
|
||||||
231 LATIN SMALL LETTER C WITH CEDILLA
|
|
||||||
膞
|
|
||||||
232 LATIN SMALL LETTER E WITH GRAVE
|
|
||||||
踔
|
|
||||||
233 LATIN SMALL LETTER E WITH ACUTE
|
|
||||||
噳
|
|
||||||
234 LATIN SMALL LETTER E WITH CIRCUMFLEX
|
|
||||||
澢
|
|
||||||
235 LATIN SMALL LETTER E WITH DIAERESIS
|
|
||||||
蕀
|
|
||||||
236 LATIN SMALL LETTER I WITH GRAVE
|
|
||||||
錋
|
|
||||||
237 LATIN SMALL LETTER I WITH ACUTE
|
|
||||||
檕
|
|
||||||
238 LATIN SMALL LETTER I WITH CIRCUMFLEX
|
|
||||||
蕷
|
|
||||||
239 LATIN SMALL LETTER I WITH DIAERESIS
|
|
||||||
鞞
|
|
||||||
240 LATIN SMALL LETTER ETH
|
|
||||||
璸
|
|
||||||
241 LATIN SMALL LETTER N WITH TILDE
|
|
||||||
蹛
|
|
||||||
242 LATIN SMALL LETTER O WITH GRAVE
|
|
||||||
徿
|
|
||||||
243 LATIN SMALL LETTER O WITH ACUTE
|
|
||||||
譑
|
|
||||||
244 LATIN SMALL LETTER O WITH CIRCUMFLEX
|
|
||||||
嚵
|
|
||||||
245 LATIN SMALL LETTER O WITH TILDE
|
|
||||||
鏼
|
|
||||||
246 LATIN SMALL LETTER O WITH DIAERESIS
|
|
||||||
蠩
|
|
||||||
247 DIVISION SIGN
|
|
||||||
糴
|
|
||||||
248 LATIN SMALL LETTER O WITH STROKE
|
|
||||||
讌
|
|
||||||
249 LATIN SMALL LETTER U WITH GRAVE
|
|
||||||
纘
|
|
||||||
250 LATIN SMALL LETTER U WITH ACUTE
|
|
||||||
𠕇
|
|
||||||
251 LATIN SMALL LETTER U WITH CIRCUMFLEX
|
|
||||||
𨦼
|
|
||||||
252 LATIN SMALL LETTER U WITH DIAERESIS
|
|
||||||
廹
|
|
||||||
253 LATIN SMALL LETTER Y WITH ACUTE
|
|
||||||
𣑯
|
|
||||||
254 LATIN SMALL LETTER THORN
|
|
||||||
鑂
|
|
||||||
255 LATIN SMALL LETTER Y WITH DIAERESIS
|
|
||||||
<EFBFBD>@
|
|
||||||
0x0100 LATIN CAPITAL LETTER A WITH MACRON
|
|
||||||
錐
|
|
||||||
0x0101 LATIN SMALL LETTER A WITH MACRON
|
|
||||||
觡
|
|
||||||
0x0102 LATIN CAPITAL LETTER A WITH BREVE
|
|
||||||
鞭
|
|
||||||
0x0103 LATIN SMALL LETTER A WITH BREVE
|
|
||||||
禗
|
|
||||||
0x0104 LATIN CAPITAL LETTER A WITH OGONEK
|
|
||||||
|
|
||||||
0x0105 LATIN SMALL LETTER A WITH OGONEK
|
|
||||||
娼
|
|
||||||
0x0106 LATIN CAPITAL LETTER C WITH ACUTE
|
|
||||||
讖
|
|
||||||
0x0107 LATIN SMALL LETTER C WITH ACUTE
|
|
||||||
澍
|
|
||||||
0x0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX
|
|
||||||
讖
|
|
||||||
0x0109 LATIN SMALL LETTER C WITH CIRCUMFLEX
|
|
||||||
澍
|
|
||||||
0x010A LATIN CAPITAL LETTER C WITH DOT ABOVE
|
|
||||||
護
|
|
||||||
0x010B LATIN SMALL LETTER C WITH DOT ABOVE
|
|
||||||
噚
|
|
||||||
0x010C LATIN CAPITAL LETTER C WITH CARON
|
|
||||||
Л
|
|
||||||
0x010D LATIN SMALL LETTER C WITH CARON
|
|
||||||
踔
|
|
||||||
0x010E LATIN CAPITAL LETTER D WITH CARON
|
|
||||||
柜
|
|
||||||
0x010F LATIN SMALL LETTER D WITH CARON
|
|
||||||
鞞
|
|
||||||
0x0110 LATIN CAPITAL LETTER D WITH STROKE
|
|
||||||
穾
|
|
||||||
0x0111 LATIN SMALL LETTER D WITH STROKE
|
|
||||||
璸
|
|
||||||
0x0112 LATIN CAPITAL LETTER E WITH MACRON
|
|
||||||
昇
|
|
||||||
0x0113 LATIN SMALL LETTER E WITH MACRON
|
|
||||||
愿
|
|
||||||
0x0116 LATIN CAPITAL LETTER E WITH DOT ABOVE
|
|
||||||
坨
|
|
||||||
0x0117 LATIN SMALL LETTER E WITH DOT ABOVE
|
|
||||||
錋
|
|
||||||
0x0118 LATIN CAPITAL LETTER E WITH OGONEK
|
|
||||||
汌
|
|
||||||
0x0119 LATIN SMALL LETTER E WITH OGONEK
|
|
||||||
澢
|
|
||||||
0x011A LATIN CAPITAL LETTER E WITH CARON
|
|
||||||
坨
|
|
||||||
0x011B LATIN SMALL LETTER E WITH CARON
|
|
||||||
錋
|
|
||||||
0x011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX
|
|
||||||
釫
|
|
||||||
0x011D LATIN SMALL LETTER G WITH CIRCUMFLEX
|
|
||||||
讌
|
|
||||||
0x011E LATIN CAPITAL LETTER G WITH BREVE
|
|
||||||
陂
|
|
||||||
0x011F LATIN SMALL LETTER G WITH BREVE
|
|
||||||
罰
|
|
||||||
0x0120 LATIN CAPITAL LETTER G WITH DOT ABOVE
|
|
||||||
崰
|
|
||||||
0x0121 LATIN SMALL LETTER G WITH DOT ABOVE
|
|
||||||
鏼
|
|
||||||
0x0122 LATIN CAPITAL LETTER G WITH CEDILLA
|
|
||||||
陂
|
|
||||||
0x0123 LATIN SMALL LETTER G WITH CEDILLA
|
|
||||||
罰
|
|
||||||
0x0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX
|
|
||||||
共
|
|
||||||
0x0125 LATIN SMALL LETTER H WITH CIRCUMFLEX
|
|
||||||
詔
|
|
||||||
0x0126 LATIN CAPITAL LETTER H WITH STROKE
|
|
||||||
|
|
||||||
0x0127 LATIN SMALL LETTER H WITH STROKE
|
|
||||||
娼
|
|
||||||
0x0128 LATIN CAPITAL LETTER I WITH TILDE
|
|
||||||
世
|
|
||||||
0x0129 LATIN SMALL LETTER I WITH TILDE
|
|
||||||
溉
|
|
||||||
0x012A LATIN CAPITAL LETTER I WITH MACRON
|
|
||||||
柜
|
|
||||||
0x012B LATIN SMALL LETTER I WITH MACRON
|
|
||||||
鞞
|
|
||||||
0x012E LATIN CAPITAL LETTER I WITH OGONEK
|
|
||||||
す
|
|
||||||
0x012F LATIN SMALL LETTER I WITH OGONEK
|
|
||||||
膞
|
|
||||||
0x0130 LATIN CAPITAL LETTER I WITH DOT ABOVE
|
|
||||||
咖
|
|
||||||
0x0131 LATIN SMALL LETTER DOTLESS I
|
|
||||||
辟
|
|
||||||
0x0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX
|
|
||||||
拯
|
|
||||||
0x0135 LATIN SMALL LETTER J WITH CIRCUMFLEX
|
|
||||||
劇
|
|
||||||
0x0136 LATIN CAPITAL LETTER K WITH CEDILLA
|
|
||||||
笄
|
|
||||||
0x0137 LATIN SMALL LETTER K WITH CEDILLA
|
|
||||||
譑
|
|
||||||
0x0138 LATIN SMALL LETTER KRA
|
|
||||||
\
|
|
||||||
0x0139 LATIN CAPITAL LETTER L WITH ACUTE
|
|
||||||
護
|
|
||||||
0x013A LATIN SMALL LETTER L WITH ACUTE
|
|
||||||
噚
|
|
||||||
0x013B LATIN CAPITAL LETTER L WITH CEDILLA
|
|
||||||
共
|
|
||||||
0x013C LATIN SMALL LETTER L WITH CEDILLA
|
|
||||||
詔
|
|
||||||
0x013D LATIN CAPITAL LETTER L WITH CARON
|
|
||||||
世
|
|
||||||
0x013E LATIN SMALL LETTER L WITH CARON
|
|
||||||
溉
|
|
||||||
0x0141 LATIN CAPITAL LETTER L WITH STROKE
|
|
||||||
w
|
|
||||||
0x0142 LATIN SMALL LETTER L WITH STROKE
|
|
||||||
莆
|
|
||||||
0x0143 LATIN CAPITAL LETTER N WITH ACUTE
|
|
||||||
唊
|
|
||||||
0x0144 LATIN SMALL LETTER N WITH ACUTE
|
|
||||||
蹛
|
|
||||||
0x0145 LATIN CAPITAL LETTER N WITH CEDILLA
|
|
||||||
唊
|
|
||||||
0x0146 LATIN SMALL LETTER N WITH CEDILLA
|
|
||||||
蹛
|
|
||||||
0x0147 LATIN CAPITAL LETTER N WITH CARON
|
|
||||||
毨
|
|
||||||
0x0148 LATIN SMALL LETTER N WITH CARON
|
|
||||||
徿
|
|
||||||
0x014A LATIN CAPITAL LETTER ENG
|
|
||||||
瑾
|
|
||||||
0x014B LATIN SMALL LETTER ENG
|
|
||||||
濃
|
|
||||||
0x014C LATIN CAPITAL LETTER O WITH MACRON
|
|
||||||
毨
|
|
||||||
0x014D LATIN SMALL LETTER O WITH MACRON
|
|
||||||
徿
|
|
||||||
0x0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
|
|
||||||
崰
|
|
||||||
0x0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE
|
|
||||||
鏼
|
|
||||||
0x0154 LATIN CAPITAL LETTER R WITH ACUTE
|
|
||||||
錐
|
|
||||||
0x0155 LATIN SMALL LETTER R WITH ACUTE
|
|
||||||
觡
|
|
||||||
0x0156 LATIN CAPITAL LETTER R WITH CEDILLA
|
|
||||||
w
|
|
||||||
0x0157 LATIN SMALL LETTER R WITH CEDILLA
|
|
||||||
莆
|
|
||||||
0x0158 LATIN CAPITAL LETTER R WITH CARON
|
|
||||||
釫
|
|
||||||
0x0159 LATIN SMALL LETTER R WITH CARON
|
|
||||||
讌
|
|
||||||
0x015A LATIN CAPITAL LETTER S WITH ACUTE
|
|
||||||
共
|
|
||||||
0x015B LATIN SMALL LETTER S WITH ACUTE
|
|
||||||
詔
|
|
||||||
0x015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX
|
|
||||||
毹
|
|
||||||
0x015D LATIN SMALL LETTER S WITH CIRCUMFLEX
|
|
||||||
鑂
|
|
||||||
0x015E LATIN CAPITAL LETTER S WITH CEDILLA
|
|
||||||
昇
|
|
||||||
0x015F LATIN SMALL LETTER S WITH CEDILLA
|
|
||||||
愿
|
|
||||||
0x0160 LATIN CAPITAL LETTER S WITH CARON
|
|
||||||
咖
|
|
||||||
0x0161 LATIN SMALL LETTER S WITH CARON
|
|
||||||
辟
|
|
||||||
0x0162 LATIN CAPITAL LETTER T WITH CEDILLA
|
|
||||||
毹
|
|
||||||
0x0163 LATIN SMALL LETTER T WITH CEDILLA
|
|
||||||
鑂
|
|
||||||
0x0164 LATIN CAPITAL LETTER T WITH CARON
|
|
||||||
陂
|
|
||||||
0x0165 LATIN SMALL LETTER T WITH CARON
|
|
||||||
罰
|
|
||||||
0x0166 LATIN CAPITAL LETTER T WITH STROKE
|
|
||||||
拯
|
|
||||||
0x0167 LATIN SMALL LETTER T WITH STROKE
|
|
||||||
劇
|
|
||||||
0x0168 LATIN CAPITAL LETTER U WITH TILDE
|
|
||||||
媷
|
|
||||||
0x0169 LATIN SMALL LETTER U WITH TILDE
|
|
||||||
𣑯
|
|
||||||
0x016A LATIN CAPITAL LETTER U WITH MACRON
|
|
||||||
毹
|
|
||||||
0x016B LATIN SMALL LETTER U WITH MACRON
|
|
||||||
鑂
|
|
||||||
0x016C LATIN CAPITAL LETTER U WITH BREVE
|
|
||||||
媷
|
|
||||||
0x016D LATIN SMALL LETTER U WITH BREVE
|
|
||||||
𣑯
|
|
||||||
0x016E LATIN CAPITAL LETTER U WITH RING ABOVE
|
|
||||||
惲
|
|
||||||
0x016F LATIN SMALL LETTER U WITH RING ABOVE
|
|
||||||
纘
|
|
||||||
0x0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
|
|
||||||
罦
|
|
||||||
0x0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE
|
|
||||||
𨦼
|
|
||||||
0x0172 LATIN CAPITAL LETTER U WITH OGONEK
|
|
||||||
惲
|
|
||||||
0x0173 LATIN SMALL LETTER U WITH OGONEK
|
|
||||||
纘
|
|
||||||
0x0179 LATIN CAPITAL LETTER Z WITH ACUTE
|
|
||||||
拯
|
|
||||||
0x017A LATIN SMALL LETTER Z WITH ACUTE
|
|
||||||
劇
|
|
||||||
0x017B LATIN CAPITAL LETTER Z WITH DOT ABOVE
|
|
||||||
浬
|
|
||||||
0x017C LATIN SMALL LETTER Z WITH DOT ABOVE
|
|
||||||
濃
|
|
||||||
0x017D LATIN CAPITAL LETTER Z WITH CARON
|
|
||||||
哦
|
|
||||||
0x017E LATIN SMALL LETTER Z WITH CARON
|
|
||||||
輥
|
|
||||||
0x02C7 CARON
|
|
||||||
媳
|
|
||||||
0x02D8 BREVE
|
|
||||||
\
|
|
||||||
0x02D9 DOT ABOVE
|
|
||||||
<EFBFBD>@
|
|
||||||
0x02DB OGONEK
|
|
||||||
毫
|
|
||||||
0x02DD DOUBLE ACUTE ACCENT
|
|
||||||
瑾
|
|
|
@ -2,34 +2,15 @@ module sevenkeys
|
||||||
|
|
||||||
go 1.22.1
|
go 1.22.1
|
||||||
|
|
||||||
require (
|
require github.com/go-sql-driver/mysql v1.8.1
|
||||||
github.com/charmbracelet/bubbles v0.18.0
|
|
||||||
github.com/charmbracelet/bubbletea v0.25.0
|
|
||||||
github.com/go-mysql/errors v0.0.0-20180603193453-03314bea68e0
|
|
||||||
github.com/go-sql-driver/mysql v1.8.1
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
github.com/atotto/clipboard v0.1.4 // indirect
|
github.com/go-mysql/errors v0.0.0-20180603193453-03314bea68e0 // indirect
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/charmbracelet/lipgloss v0.9.1 // indirect
|
|
||||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 // indirect
|
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
golang.org/x/crypto v0.23.0 // indirect
|
||||||
github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 // indirect
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
golang.org/x/term v0.20.0 // indirect
|
||||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
gotest.tools/v3 v3.5.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
|
||||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
|
|
||||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
|
||||||
github.com/muesli/reflow v0.3.0 // indirect
|
|
||||||
github.com/muesli/termenv v0.15.2 // indirect
|
|
||||||
github.com/rivo/uniseg v0.4.6 // indirect
|
|
||||||
golang.org/x/crypto v0.24.0 // indirect
|
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
|
||||||
golang.org/x/term v0.21.0 // indirect
|
|
||||||
golang.org/x/text v0.16.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,65 +1,18 @@
|
||||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
|
||||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
|
||||||
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
|
|
||||||
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
|
|
||||||
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
|
|
||||||
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
|
|
||||||
github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg=
|
|
||||||
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
|
|
||||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
|
||||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/go-mysql/errors v0.0.0-20180603193453-03314bea68e0 h1:meiLwrW6ukHHehydhoDxVHdQKQe7TFgEpH0A0hHBAWs=
|
github.com/go-mysql/errors v0.0.0-20180603193453-03314bea68e0 h1:meiLwrW6ukHHehydhoDxVHdQKQe7TFgEpH0A0hHBAWs=
|
||||||
github.com/go-mysql/errors v0.0.0-20180603193453-03314bea68e0/go.mod h1:ZH8V0509n2OSZLMYTMHzcy4hqUB+rG8ghK1zsP4i5gE=
|
github.com/go-mysql/errors v0.0.0-20180603193453-03314bea68e0/go.mod h1:ZH8V0509n2OSZLMYTMHzcy4hqUB+rG8ghK1zsP4i5gE=
|
||||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 h1:fO9A67/izFYFYky7l1pDP5Dr0BTCRkaQJUG6Jm5ehsk=
|
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 h1:fO9A67/izFYFYky7l1pDP5Dr0BTCRkaQJUG6Jm5ehsk=
|
||||||
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3/go.mod h1:Ey4uAp+LvIl+s5jRbOHLcZpUDnkjLBROl15fZLwPlTM=
|
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3/go.mod h1:Ey4uAp+LvIl+s5jRbOHLcZpUDnkjLBROl15fZLwPlTM=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 h1:UtyD+eBVdLYSj5/pjfSR6mtnzMgIiOVcFT024G2l4CY=
|
|
||||||
github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42/go.mod h1:/peI0OaxVYh7fzA72CD7rUsyGVdF7sCiFw7GcYqOcCw=
|
|
||||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
|
||||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
|
||||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
|
||||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
|
||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
|
||||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
|
||||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
|
|
||||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
|
||||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
|
||||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
|
||||||
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
|
||||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
|
||||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
|
||||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
||||||
github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg=
|
|
||||||
github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
|
||||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
|
||||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
|
||||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"sevenkeys/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
func LocateCards(db *sql.DB, cardName string) ([]database.LocateCardResult, error) {
|
|
||||||
results, err := database.GetLocateCardResultsByCardName(db, cardName)
|
|
||||||
return results, err
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
package scryfall
|
package scryfall
|
||||||
|
|
||||||
type Card struct {
|
type Card struct {
|
||||||
Id string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Set string `json:"set"`
|
Set string `json:"set"`
|
||||||
Games []string `json:"games"`
|
Games []string `json:"games"`
|
||||||
|
@ -9,6 +8,5 @@ type Card struct {
|
||||||
NonFoil bool `json:"nonfoil"`
|
NonFoil bool `json:"nonfoil"`
|
||||||
Promo bool `json:"promo"`
|
Promo bool `json:"promo"`
|
||||||
CollectorNumber string `json:"collector_number"`
|
CollectorNumber string `json:"collector_number"`
|
||||||
ImageUris map[string]string `json:"image_uris"`
|
|
||||||
Language string `json:"lang"`
|
Language string `json:"lang"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,53 +10,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Triadic int
|
// The SearchOptions type is a map of `string`s (which can be searched using fzf)
|
||||||
|
// to `int`s (which represent a primary key in the CardPrintings table)
|
||||||
|
type SearchOptions map[string]int
|
||||||
|
|
||||||
const (
|
func GetAllSearchOptions(db *sql.DB) (SearchOptions, error) {
|
||||||
True Triadic = iota
|
var searchOptions SearchOptions = make(map[string]int)
|
||||||
False
|
|
||||||
Either
|
|
||||||
)
|
|
||||||
|
|
||||||
type SearchCriteria struct {
|
|
||||||
SetCode string
|
|
||||||
Foil Triadic
|
|
||||||
Promo Triadic
|
|
||||||
Language string
|
|
||||||
}
|
|
||||||
|
|
||||||
// The SearchOptions type is a map of `string` keys (which can be searched using fzf)
|
|
||||||
// to `string` values (which represent a primary key in the CardPrintings table)
|
|
||||||
type SearchOptions map[string]string
|
|
||||||
|
|
||||||
func filterPrinting(printing database.CardPrinting, searchCriteria SearchCriteria) bool {
|
|
||||||
if searchCriteria.SetCode != "" && printing.SetCode != searchCriteria.SetCode {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if searchCriteria.Foil == False && printing.IsFoil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if searchCriteria.Foil == True && !printing.IsFoil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if searchCriteria.Promo == False && printing.IsPromo {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if searchCriteria.Promo == True && !printing.IsPromo {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if searchCriteria.Language != "" && printing.Language != searchCriteria.Language {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (SearchOptions, error) {
|
|
||||||
var searchOptions SearchOptions = make(map[string]string)
|
|
||||||
|
|
||||||
cardPrintings, err := database.GetAllCardPrintings(db)
|
cardPrintings, err := database.GetAllCardPrintings(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -64,13 +23,6 @@ func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (SearchOptio
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, printing := range cardPrintings {
|
for _, printing := range cardPrintings {
|
||||||
// Filter based on search criteria
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
if filter {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct search option string
|
|
||||||
searchString := fmt.Sprintf("%s (%s %s) [%s]", printing.Name, printing.SetCode, printing.CollectorNumber, printing.Language)
|
searchString := fmt.Sprintf("%s (%s %s) [%s]", printing.Name, printing.SetCode, printing.CollectorNumber, printing.Language)
|
||||||
|
|
||||||
if printing.IsFoil {
|
if printing.IsFoil {
|
||||||
|
@ -87,13 +39,13 @@ func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (SearchOptio
|
||||||
return searchOptions, err
|
return searchOptions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Search(searchOptions SearchOptions) (string, string, error) {
|
func Search(searchOptions SearchOptions) (int, string, error) {
|
||||||
cmd := exec.Command("fzf")
|
cmd := exec.Command("fzf")
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
fzfStdin, err := cmd.StdinPipe()
|
fzfStdin, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return -1, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -105,7 +57,7 @@ func Search(searchOptions SearchOptions) (string, string, error) {
|
||||||
|
|
||||||
fzfOutput, err := cmd.Output()
|
fzfOutput, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return -1, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := strings.TrimSuffix(string(fzfOutput), "\n")
|
key := strings.TrimSuffix(string(fzfOutput), "\n")
|
||||||
|
|
|
@ -1,402 +0,0 @@
|
||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sevenkeys/database"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsTrue_IfSetCodeDoesNotMatch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "otj",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != true {
|
|
||||||
t.Errorf("filter was false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfSetCodeDoesMatch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfSetCodeNotSet(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsTrue_IfFoilCardInNonFoilSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: true,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != true {
|
|
||||||
t.Errorf("filter was false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsTrue_IfNonFoilCardInFoilSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: True,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != true {
|
|
||||||
t.Errorf("filter was false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfNonFoilCardInNonFoilSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfFoilCardInFoilSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: true,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: True,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfFoilCardInEitherFoilSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: true,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: Either,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfNonFoilCardInEitherFoilSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: Either,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsTrue_IfPromoCardInNonPromoSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: true,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != true {
|
|
||||||
t.Errorf("filter was false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsTrue_IfNonPromoCardInPromoSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: True,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != true {
|
|
||||||
t.Errorf("filter was false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfNonPromoCardInNonPromoSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfPromoCardInPromoSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: true,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: True,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfPromoCardInEitherPromoSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: true,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: Either,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfNonPromoCardInEitherPromoSearch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: Either,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsTrue_IfLanguageDoesNotMatch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "de",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != true {
|
|
||||||
t.Errorf("filter was false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfLanguageDoesMatch(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "de",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "de",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFilterPrinting_ReturnsFalse_IfLanguageNotSet(t *testing.T) {
|
|
||||||
printing := database.CardPrinting{
|
|
||||||
SetCode: "rtr",
|
|
||||||
IsFoil: false,
|
|
||||||
IsPromo: false,
|
|
||||||
Language: "en",
|
|
||||||
}
|
|
||||||
|
|
||||||
searchCriteria := SearchCriteria{
|
|
||||||
SetCode: "rtr",
|
|
||||||
Foil: False,
|
|
||||||
Promo: False,
|
|
||||||
Language: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filterPrinting(printing, searchCriteria)
|
|
||||||
|
|
||||||
if filter != false {
|
|
||||||
t.Errorf("filter was true")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,72 +2,18 @@ package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"sevenkeys/database"
|
"sevenkeys/database"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error {
|
func StoreCard(db *sql.DB, storageLocation database.CardStorageLocation) error {
|
||||||
// TODO: Check if there's already a storage are with the same name
|
lastPosition, err := database.GetLastPositionInBox(db, storageLocation.StorageBox)
|
||||||
// TODO: Check if the type entered is valid
|
if err != nil {
|
||||||
err := database.InsertStorageArea(db, storageArea)
|
return err
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
storageLocation.Position = lastPosition + 1
|
||||||
|
|
||||||
return nil
|
err = database.InsertCardStorageLocation(db, storageLocation)
|
||||||
}
|
|
||||||
|
|
||||||
func SelectStorageArea(db *sql.DB) (database.StorageArea, error) {
|
|
||||||
var selectedStorageArea database.StorageArea
|
|
||||||
|
|
||||||
storageAreas, err := database.GetAllStorageAreas(db)
|
|
||||||
if err != nil {
|
|
||||||
return selectedStorageArea, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command("fzf")
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
|
|
||||||
fzfStdin, err := cmd.StdinPipe()
|
|
||||||
if err != nil {
|
|
||||||
return selectedStorageArea, err
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer fzfStdin.Close()
|
|
||||||
for _, area := range storageAreas {
|
|
||||||
io.WriteString(fzfStdin, area.Name+"\n")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fzfOutput, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return selectedStorageArea, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := strings.TrimSuffix(string(fzfOutput), "\n")
|
|
||||||
for _, area := range storageAreas {
|
|
||||||
if area.Name == key {
|
|
||||||
selectedStorageArea = area
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return selectedStorageArea, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func StoreCard(db *sql.DB, cardLocation database.CardLocation) error {
|
|
||||||
lastPosition, err := database.GetLastPositionInStorageArea(db, cardLocation.StorageAreaId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cardLocation.Position = lastPosition + 1
|
|
||||||
|
|
||||||
err = database.InsertCardLocation(db, cardLocation)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"sevenkeys/database"
|
"sevenkeys/database"
|
||||||
"sevenkeys/logic/scryfall"
|
"sevenkeys/logic/scryfall"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sqlerr "github.com/go-mysql/errors"
|
sqlerr "github.com/go-mysql/errors"
|
||||||
|
@ -34,6 +35,14 @@ func CheckForUpdates(db *sql.DB, bulkData scryfall.BulkData) (bool, error) {
|
||||||
return bulkData.UpdatedAtTime.After(cachedFileTimestamp), nil
|
return bulkData.UpdatedAtTime.After(cachedFileTimestamp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConfirmUpdate() bool {
|
||||||
|
fmt.Print("Run update? (y/N) ")
|
||||||
|
var response string
|
||||||
|
fmt.Scan(&response)
|
||||||
|
|
||||||
|
return strings.ToUpper(response) == "Y"
|
||||||
|
}
|
||||||
|
|
||||||
func UpdateSets(db *sql.DB) error {
|
func UpdateSets(db *sql.DB) error {
|
||||||
sets, err := scryfall.GetAllSets()
|
sets, err := scryfall.GetAllSets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -118,20 +127,17 @@ func getCardPrintings(card scryfall.Card) []database.CardPrinting {
|
||||||
|
|
||||||
if card.Foil {
|
if card.Foil {
|
||||||
printings = append(printings, database.CardPrinting{
|
printings = append(printings, database.CardPrinting{
|
||||||
Id: card.Id + "f",
|
|
||||||
Name: card.Name,
|
Name: card.Name,
|
||||||
SetCode: card.Set,
|
SetCode: card.Set,
|
||||||
IsFoil: true,
|
IsFoil: true,
|
||||||
IsPromo: card.Promo,
|
IsPromo: card.Promo,
|
||||||
CollectorNumber: card.CollectorNumber,
|
CollectorNumber: card.CollectorNumber,
|
||||||
ImageUrl: card.ImageUris["png"],
|
|
||||||
Language: card.Language,
|
Language: card.Language,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if card.NonFoil {
|
if card.NonFoil {
|
||||||
printings = append(printings, database.CardPrinting{
|
printings = append(printings, database.CardPrinting{
|
||||||
Id: card.Id + "n",
|
|
||||||
Name: card.Name,
|
Name: card.Name,
|
||||||
SetCode: card.Set,
|
SetCode: card.Set,
|
||||||
IsFoil: false,
|
IsFoil: false,
|
||||||
|
|
|
@ -1,18 +1,76 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sevenkeys/cli"
|
"fmt"
|
||||||
"sevenkeys/database"
|
"sevenkeys/database"
|
||||||
"sevenkeys/figlet"
|
"sevenkeys/logic"
|
||||||
|
"sevenkeys/logic/scryfall"
|
||||||
|
|
||||||
|
"github.com/inancgumus/screen"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
db := database.GetDatabaseFromConfig("config.json")
|
db := database.GetDatabaseFromConfig("config.json")
|
||||||
figlet.ReadFigletFonts()
|
|
||||||
|
|
||||||
cli.ShowSplashScreen()
|
fmt.Println("Checking for updates...")
|
||||||
|
bulkData, err := scryfall.GetBulkDataByType(scryfall.BulkDataTypeAllCards)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
cli.RunUpdateCheck(db)
|
needsUpdate, err := logic.CheckForUpdates(db, bulkData)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
cli.MainCliLoop(db)
|
if needsUpdate {
|
||||||
|
fmt.Println("Update required.")
|
||||||
|
|
||||||
|
if logic.ConfirmUpdate() {
|
||||||
|
fmt.Println("Running update...")
|
||||||
|
|
||||||
|
logic.CreateCacheDirectories()
|
||||||
|
|
||||||
|
err = logic.UpdateSets(db)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
|
err = logic.UpdateCards(db, bulkData)
|
||||||
|
logic.Check(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Update finished.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("No update required.")
|
||||||
|
}
|
||||||
|
|
||||||
|
storageBox := logic.GetResponse("Enter storage box label:")
|
||||||
|
source := logic.GetResponse("Enter source:")
|
||||||
|
searchOptions, err := logic.GetAllSearchOptions(db)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
|
for {
|
||||||
|
screen.Clear()
|
||||||
|
screen.MoveTopLeft()
|
||||||
|
fmt.Println("Storage location:", storageBox)
|
||||||
|
fmt.Println("Source:", source)
|
||||||
|
|
||||||
|
selectedCardPrintingId, selectedSearchOption, err := logic.Search(searchOptions)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
|
fmt.Println("Inserted card:", selectedSearchOption)
|
||||||
|
storageLocation := database.CardStorageLocation{
|
||||||
|
CardPrintingId: selectedCardPrintingId,
|
||||||
|
StorageBox: storageBox,
|
||||||
|
Source: source,
|
||||||
|
}
|
||||||
|
err = logic.StoreCard(db, storageLocation)
|
||||||
|
logic.Check(err)
|
||||||
|
|
||||||
|
nextAction := logic.GetResponse("[s]earch again/[r]epeat last insert/[q]uit:")
|
||||||
|
switch nextAction {
|
||||||
|
case "s":
|
||||||
|
continue
|
||||||
|
case "r":
|
||||||
|
err = logic.StoreCard(db, storageLocation)
|
||||||
|
logic.Check(err)
|
||||||
|
case "q":
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,188 +0,0 @@
|
||||||
package tui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sevenkeys/constants"
|
|
||||||
"sevenkeys/figlet"
|
|
||||||
"sevenkeys/tui/searchui"
|
|
||||||
"sevenkeys/tui/updateui"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/help"
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sessionState int
|
|
||||||
|
|
||||||
const (
|
|
||||||
homeView sessionState = iota
|
|
||||||
updateView
|
|
||||||
searchView
|
|
||||||
)
|
|
||||||
|
|
||||||
type homeKeyMappings struct {
|
|
||||||
Update key.Binding
|
|
||||||
SearchCriteria key.Binding
|
|
||||||
Search key.Binding
|
|
||||||
StorageOptions key.Binding
|
|
||||||
Find key.Binding
|
|
||||||
Quit key.Binding
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k homeKeyMappings) ShortHelp() []key.Binding {
|
|
||||||
return []key.Binding{k.Update, k.SearchCriteria, k.Search, k.StorageOptions, k.Find, k.Quit}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k homeKeyMappings) FullHelp() [][]key.Binding {
|
|
||||||
return [][]key.Binding{
|
|
||||||
{k.Update, k.SearchCriteria, k.Search},
|
|
||||||
{k.StorageOptions, k.Find, k.Quit},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type MainModel struct {
|
|
||||||
state sessionState
|
|
||||||
updateModel tea.Model
|
|
||||||
searchModel tea.Model
|
|
||||||
|
|
||||||
help help.Model
|
|
||||||
keyMappings homeKeyMappings
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMainModel() MainModel {
|
|
||||||
help := help.New()
|
|
||||||
help.ShortSeparator = help.FullSeparator
|
|
||||||
|
|
||||||
updateModel := updateui.NewUpdateModel()
|
|
||||||
searchModel := searchui.NewSearchModel()
|
|
||||||
|
|
||||||
keyMappings := homeKeyMappings{
|
|
||||||
Update: key.NewBinding(
|
|
||||||
key.WithKeys("u"),
|
|
||||||
key.WithHelp("u", "update database"),
|
|
||||||
),
|
|
||||||
SearchCriteria: key.NewBinding(
|
|
||||||
key.WithKeys("c"),
|
|
||||||
key.WithHelp("c", "card printing search criteria"),
|
|
||||||
),
|
|
||||||
Search: key.NewBinding(
|
|
||||||
key.WithKeys("s"),
|
|
||||||
key.WithHelp("s", "card printing search"),
|
|
||||||
),
|
|
||||||
StorageOptions: key.NewBinding(
|
|
||||||
key.WithKeys("o"),
|
|
||||||
key.WithHelp("o", "card storage options"),
|
|
||||||
),
|
|
||||||
Find: key.NewBinding(
|
|
||||||
key.WithKeys("f"),
|
|
||||||
key.WithHelp("f", "find in storage"),
|
|
||||||
),
|
|
||||||
Quit: key.NewBinding(
|
|
||||||
key.WithKeys("ctrl+c", "q"),
|
|
||||||
key.WithHelp("q", "quit program"),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
return MainModel{
|
|
||||||
state: homeView,
|
|
||||||
updateModel: updateModel,
|
|
||||||
searchModel: searchModel,
|
|
||||||
|
|
||||||
help: help,
|
|
||||||
keyMappings: keyMappings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m MainModel) Init() tea.Cmd {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderHomeScreen(m MainModel) string {
|
|
||||||
var ui string
|
|
||||||
|
|
||||||
// Display splash screen
|
|
||||||
ui += figlet.SprintMsgSlant("SEVENKEYS", "center")
|
|
||||||
ui += figlet.SprintMsgTerm("the ultimate Magic: the Gathering trading card storage system", "center")
|
|
||||||
|
|
||||||
// Display help
|
|
||||||
ui += strings.Repeat("\n", constants.WindowHeight-8) // TODO: Avoid hardcoding height somehow
|
|
||||||
ui += m.help.View(m.keyMappings)
|
|
||||||
|
|
||||||
return ui
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m MainModel) View() string {
|
|
||||||
var ui string
|
|
||||||
|
|
||||||
if constants.WindowWidth <= 0 {
|
|
||||||
return ui
|
|
||||||
}
|
|
||||||
|
|
||||||
switch m.state {
|
|
||||||
case homeView:
|
|
||||||
ui += renderHomeScreen(m)
|
|
||||||
break
|
|
||||||
case updateView:
|
|
||||||
ui += m.updateModel.View()
|
|
||||||
break
|
|
||||||
case searchView:
|
|
||||||
ui += m.searchModel.View()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return ui
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
||||||
var cmd tea.Cmd
|
|
||||||
var cmds []tea.Cmd
|
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case tea.WindowSizeMsg:
|
|
||||||
constants.WindowHeight = msg.Height
|
|
||||||
constants.WindowWidth = msg.Width
|
|
||||||
m.help.Width = msg.Width
|
|
||||||
case tea.KeyMsg:
|
|
||||||
switch {
|
|
||||||
case key.Matches(msg, m.keyMappings.Quit):
|
|
||||||
return m, tea.Quit
|
|
||||||
}
|
|
||||||
case updateui.BackMsg:
|
|
||||||
m.state = homeView
|
|
||||||
}
|
|
||||||
|
|
||||||
switch m.state {
|
|
||||||
case homeView:
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case tea.KeyMsg:
|
|
||||||
switch {
|
|
||||||
case key.Matches(msg, m.keyMappings.Update):
|
|
||||||
m.state = updateView
|
|
||||||
case key.Matches(msg, m.keyMappings.Search):
|
|
||||||
m.state = searchView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case updateView:
|
|
||||||
newUpdate, newCmd := m.updateModel.Update(msg)
|
|
||||||
|
|
||||||
newUpdateModel, ok := newUpdate.(updateui.Model)
|
|
||||||
if !ok {
|
|
||||||
panic("Could not perform assertion on updateui.Model")
|
|
||||||
}
|
|
||||||
|
|
||||||
m.updateModel = newUpdateModel
|
|
||||||
cmd = newCmd
|
|
||||||
case searchView:
|
|
||||||
newSearch, newCmd := m.searchModel.Update(msg)
|
|
||||||
newSearchModel, ok := newSearch.(searchui.Model)
|
|
||||||
if !ok {
|
|
||||||
panic("Could not perform assertion on searchui.Model")
|
|
||||||
}
|
|
||||||
|
|
||||||
m.searchModel = newSearchModel
|
|
||||||
cmd = newCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds = append(cmds, cmd)
|
|
||||||
return m, tea.Batch(cmds...)
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package searchui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sevenkeys/figlet"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Model struct {
|
|
||||||
searchOptions logic.SearchOptions
|
|
||||||
selectedCardPrintingId int
|
|
||||||
selectedCardPrintingSearch string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSearchModel() Model {
|
|
||||||
return Model{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) Init() tea.Cmd {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
||||||
/*
|
|
||||||
var cmd tea.Cmd
|
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case cardPrintingsLoadedMsg:
|
|
||||||
m.cardPrintingsLoaded = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return m, tea.Quit
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) View() string {
|
|
||||||
var ui string
|
|
||||||
|
|
||||||
ui += figlet.SprintMsgSlant("Insert Cards")
|
|
||||||
|
|
||||||
return ui
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
package updateui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"log"
|
|
||||||
"sevenkeys/constants"
|
|
||||||
"sevenkeys/logic"
|
|
||||||
"sevenkeys/logic/scryfall"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/help"
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
|
||||||
"github.com/lukesampson/figlet/figletlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BackMsg int
|
|
||||||
|
|
||||||
type updateRequiredMsg bool
|
|
||||||
type errorMsg error
|
|
||||||
|
|
||||||
type updateKeyMappings struct {
|
|
||||||
back key.Binding
|
|
||||||
quit key.Binding
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k updateKeyMappings) ShortHelp() []key.Binding {
|
|
||||||
return []key.Binding{k.back, k.quit}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k updateKeyMappings) FullHelp() [][]key.Binding {
|
|
||||||
return [][]key.Binding{{k.back, k.quit}}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Model struct {
|
|
||||||
updateRequired bool
|
|
||||||
updateFinished bool
|
|
||||||
|
|
||||||
canLeave bool
|
|
||||||
|
|
||||||
help help.Model
|
|
||||||
keyMappings updateKeyMappings
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUpdateModel() Model {
|
|
||||||
help := help.New()
|
|
||||||
help.ShortSeparator = help.FullSeparator
|
|
||||||
|
|
||||||
keyMappings := updateKeyMappings{
|
|
||||||
back: key.NewBinding(
|
|
||||||
key.WithKeys("esc"),
|
|
||||||
key.WithHelp("esc", "back"),
|
|
||||||
),
|
|
||||||
quit: key.NewBinding(
|
|
||||||
key.WithKeys("q"),
|
|
||||||
key.WithHelp("q", "quit"),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
return Model{
|
|
||||||
canLeave: true,
|
|
||||||
help: help,
|
|
||||||
keyMappings: keyMappings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) Init() tea.Cmd {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
||||||
var cmd tea.Cmd
|
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
|
||||||
case tea.KeyMsg:
|
|
||||||
if m.canLeave {
|
|
||||||
switch {
|
|
||||||
case key.Matches(msg, m.keyMappings.back):
|
|
||||||
return m, backCmd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case errorMsg:
|
|
||||||
log.Fatal(msg.Error())
|
|
||||||
break
|
|
||||||
case updateRequiredMsg:
|
|
||||||
m.updateRequired = bool(msg)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return m, cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) View() string {
|
|
||||||
var ui string
|
|
||||||
|
|
||||||
ui += figletlib.SprintMsg("Update", constants.FigletFontSlant, constants.WindowWidth, constants.FigletFontSlant.Settings(), "left")
|
|
||||||
ui += strings.Repeat("-", constants.WindowWidth)
|
|
||||||
ui += "\n"
|
|
||||||
|
|
||||||
if m.updateRequired {
|
|
||||||
ui += "Database is out of date. Running update."
|
|
||||||
} else {
|
|
||||||
ui += "No update required."
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.canLeave {
|
|
||||||
ui += strings.Repeat("\n", constants.WindowHeight-8) // TODO: Hardcoded height (again)
|
|
||||||
ui += m.help.View(m.keyMappings)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ui
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkUpdateRequiredCmd(db *sql.DB) tea.Cmd {
|
|
||||||
return func() tea.Msg {
|
|
||||||
bulkData, err := scryfall.GetBulkDataByType(scryfall.BulkDataTypeAllCards)
|
|
||||||
if err != nil {
|
|
||||||
return errorMsg(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
needsUpdate, err := logic.CheckForUpdates(db, bulkData)
|
|
||||||
if err != nil {
|
|
||||||
return errorMsg(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateRequiredMsg(needsUpdate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func backCmd() tea.Cmd {
|
|
||||||
return func() tea.Msg {
|
|
||||||
return BackMsg(1)
|
|
||||||
}
|
|
||||||
}
|
|