Compare commits
No commits in common. "c2ca6d284d1d56daa5f6998bc878f904b2097413" and "4018f26998c8ca9b4217ac9201af5012a722318f" have entirely different histories.
c2ca6d284d
...
4018f26998
|
@ -1,6 +1,3 @@
|
|||
penny_dreadful_downloader/legality_data/
|
||||
a_scanner_dorkly/.venv/
|
||||
scantap/images/
|
||||
sevenkeys/sevenkeys
|
||||
MTG-Card-Identifier_v5.pdf
|
||||
info.txt
|
||||
|
|
|
@ -4,4 +4,3 @@ find_package( OpenCV REQUIRED )
|
|||
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||
add_executable( AScannerDarkly main.cpp )
|
||||
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 <tesseract/baseapi.h>
|
||||
#include <leptonica/allheaders.h>
|
||||
#include <string>
|
||||
|
||||
const std::string SCANNER_WINDOW_NAME = "A Scanner Darkly";
|
||||
const std::string CARD_WINDOW_NAME = "Detected Card";
|
||||
const std::string WINDOW_NAME = "A Scanner Darkly";
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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 ) {
|
||||
cv::VideoCapture cap;
|
||||
cap.open(0);
|
||||
|
@ -128,34 +22,71 @@ int main(int argc, char** argv ) {
|
|||
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::createTrackbar(ASPECT_RATIO_TOLERANCE_TRACKBAR_NAME, SCANNER_WINDOW_NAME, &g_aspect_ratio_tolerance, MAX_ASPECT_RATIO_TOLERANCE, NULL);
|
||||
cv::namedWindow(WINDOW_NAME);
|
||||
|
||||
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) {
|
||||
cap >> frame;
|
||||
//cardFrame = detectCardInFrame(frame);
|
||||
cv::imshow(SCANNER_WINDOW_NAME, frame);
|
||||
|
||||
/*
|
||||
if (cardFrame.size().width > 0) {
|
||||
printf("Card detected\n");
|
||||
while (true) {
|
||||
cv::imshow(CARD_WINDOW_NAME, cardFrame);
|
||||
char c = (char)cv::waitKey(33);
|
||||
if (c == 27) {
|
||||
cv::destroyWindow(CARD_WINDOW_NAME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
std::vector<std::vector<cv::Point> > contours;
|
||||
std::vector<cv::Vec4i> hierarchy;
|
||||
cv::findContours(cannyFrame, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
|
||||
|
||||
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);
|
||||
if (c == 27) {
|
||||
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/
|
||||
cmd/database/config.json
|
||||
sevenkeys.sql
|
||||
|
|
|
@ -3,5 +3,3 @@ createdb:
|
|||
removedb:
|
||||
rm -rf cache/
|
||||
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 {
|
||||
Id string
|
||||
Id int
|
||||
Name string
|
||||
SetCode string
|
||||
IsFoil bool
|
||||
IsPromo bool
|
||||
CollectorNumber string
|
||||
ImageUrl string
|
||||
Language string
|
||||
}
|
||||
|
||||
func InsertCardPrinting(db *sql.DB, cardPrinting CardPrinting) error {
|
||||
query := `INSERT INTO CardPrinting (
|
||||
Id,
|
||||
Name,
|
||||
SetCode,
|
||||
IsFoil,
|
||||
IsPromo,
|
||||
CollectorNumber,
|
||||
ImageUrl,
|
||||
Language)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?);`
|
||||
VALUES (?, ?, ?, ?, ?, ?);`
|
||||
|
||||
insert, err := db.Prepare(query)
|
||||
defer insert.Close()
|
||||
|
@ -33,7 +30,7 @@ func InsertCardPrinting(db *sql.DB, cardPrinting CardPrinting) error {
|
|||
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 {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,42 +1,41 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
)
|
||||
import "database/sql"
|
||||
|
||||
type CardLocation struct {
|
||||
type CardStorageLocation struct {
|
||||
Id int
|
||||
CardPrintingId string
|
||||
StorageAreaId int
|
||||
CardPrintingId int
|
||||
StorageBox string
|
||||
Position int
|
||||
Source string
|
||||
}
|
||||
|
||||
func GetLastPositionInStorageArea(db *sql.DB, storageAreaId int) (int, error) {
|
||||
query := "SELECT Position FROM CardLocation WHERE StorageAreaId = ? ORDER BY Position DESC LIMIT 1;"
|
||||
func GetLastPositionInBox(db *sql.DB, storageBox string) (int, error) {
|
||||
query := "SELECT Position FROM CardStorageLocation WHERE StorageBox = ? ORDER BY Position DESC LIMIT 1"
|
||||
|
||||
var lastPosition int
|
||||
err := db.QueryRow(query, storageAreaId).Scan(&lastPosition)
|
||||
err := db.QueryRow(query, storageBox).Scan(&lastPosition)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
} else {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return lastPosition, nil
|
||||
}
|
||||
|
||||
func InsertCardLocation(db *sql.DB, storageLocation CardLocation) error {
|
||||
query := `INSERT INTO CardLocation
|
||||
(CardPrintingId, StorageAreaId, Position)
|
||||
VALUES (?, ?, ?);`
|
||||
func InsertCardStorageLocation(db *sql.DB, storageLocation CardStorageLocation) error {
|
||||
query := `INSERT INTO CardStorageLocation
|
||||
(CardPrintingId, StorageBox, Position, Source)
|
||||
VALUES (?, ?, ?, ?);`
|
||||
|
||||
insert, err := db.Prepare(query)
|
||||
if err != nil {
|
||||
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 {
|
||||
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 (
|
||||
Id VARCHAR(37) PRIMARY KEY, -- GUID, plus one character for foil/nonfoil
|
||||
Id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
Name VARCHAR(150) NOT NULL,
|
||||
SetCode VARCHAR(6) NOT NULL,
|
||||
FOREIGN KEY (SetCode) REFERENCES ExpansionSet(SetCode),
|
||||
IsFoil BOOLEAN NOT NULL,
|
||||
IsPromo BOOLEAN NOT NULL,
|
||||
CollectorNumber VARCHAR(10) NOT NULL,
|
||||
ImageUrl VARCHAR(100) 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,
|
||||
Name VARCHAR(100) NOT NULL,
|
||||
StorageType ENUM('Binder', 'Box')
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS CardLocation (
|
||||
Id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
CardPrintingId VARCHAR(37) NULL,
|
||||
CardPrintingId INT NOT NULL,
|
||||
FOREIGN KEY (CardPrintingId) REFERENCES CardPrinting(Id),
|
||||
StorageAreaId INT NOT NULL,
|
||||
FOREIGN KEY (StorageAreaId) REFERENCES StorageArea(Id),
|
||||
Position INT NULL
|
||||
StorageBox VARCHAR(20) NOT NULL,
|
||||
Position INT NOT 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
|
||||
|
||||
require (
|
||||
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 github.com/go-sql-driver/mysql v1.8.1
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // 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/go-mysql/errors v0.0.0-20180603193453-03314bea68e0 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-localereader v0.0.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
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/term v0.20.0 // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
)
|
||||
|
|
|
@ -1,65 +1,18 @@
|
|||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
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/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/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/go.mod h1:Ey4uAp+LvIl+s5jRbOHLcZpUDnkjLBROl15fZLwPlTM=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
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/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
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.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/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
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=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
|
|
|
@ -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,14 +1,12 @@
|
|||
package scryfall
|
||||
|
||||
type Card struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Set string `json:"set"`
|
||||
Games []string `json:"games"`
|
||||
Foil bool `json:"foil"`
|
||||
NonFoil bool `json:"nonfoil"`
|
||||
Promo bool `json:"promo"`
|
||||
CollectorNumber string `json:"collector_number"`
|
||||
ImageUris map[string]string `json:"image_uris"`
|
||||
Language string `json:"lang"`
|
||||
Name string `json:"name"`
|
||||
Set string `json:"set"`
|
||||
Games []string `json:"games"`
|
||||
Foil bool `json:"foil"`
|
||||
NonFoil bool `json:"nonfoil"`
|
||||
Promo bool `json:"promo"`
|
||||
CollectorNumber string `json:"collector_number"`
|
||||
Language string `json:"lang"`
|
||||
}
|
||||
|
|
|
@ -10,53 +10,12 @@ import (
|
|||
"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 (
|
||||
True Triadic = iota
|
||||
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)
|
||||
func GetAllSearchOptions(db *sql.DB) (SearchOptions, error) {
|
||||
var searchOptions SearchOptions = make(map[string]int)
|
||||
|
||||
cardPrintings, err := database.GetAllCardPrintings(db)
|
||||
if err != nil {
|
||||
|
@ -64,13 +23,6 @@ func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (SearchOptio
|
|||
}
|
||||
|
||||
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)
|
||||
|
||||
if printing.IsFoil {
|
||||
|
@ -87,13 +39,13 @@ func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (SearchOptio
|
|||
return searchOptions, err
|
||||
}
|
||||
|
||||
func Search(searchOptions SearchOptions) (string, string, error) {
|
||||
func Search(searchOptions SearchOptions) (int, string, error) {
|
||||
cmd := exec.Command("fzf")
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
fzfStdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
return -1, "", err
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@ -105,7 +57,7 @@ func Search(searchOptions SearchOptions) (string, string, error) {
|
|||
|
||||
fzfOutput, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
return -1, "", err
|
||||
}
|
||||
|
||||
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 (
|
||||
"database/sql"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sevenkeys/database"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CreateStorageArea(db *sql.DB, storageArea database.StorageArea) error {
|
||||
// TODO: Check if there's already a storage are with the same name
|
||||
// TODO: Check if the type entered is valid
|
||||
err := database.InsertStorageArea(db, storageArea)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
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)
|
||||
func StoreCard(db *sql.DB, storageLocation database.CardStorageLocation) error {
|
||||
lastPosition, err := database.GetLastPositionInBox(db, storageLocation.StorageBox)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
storageLocation.Position = lastPosition + 1
|
||||
|
||||
err = database.InsertCardStorageLocation(db, storageLocation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"os"
|
||||
"sevenkeys/database"
|
||||
"sevenkeys/logic/scryfall"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
sets, err := scryfall.GetAllSets()
|
||||
if err != nil {
|
||||
|
@ -118,20 +127,17 @@ func getCardPrintings(card scryfall.Card) []database.CardPrinting {
|
|||
|
||||
if card.Foil {
|
||||
printings = append(printings, database.CardPrinting{
|
||||
Id: card.Id + "f",
|
||||
Name: card.Name,
|
||||
SetCode: card.Set,
|
||||
IsFoil: true,
|
||||
IsPromo: card.Promo,
|
||||
CollectorNumber: card.CollectorNumber,
|
||||
ImageUrl: card.ImageUris["png"],
|
||||
Language: card.Language,
|
||||
})
|
||||
}
|
||||
|
||||
if card.NonFoil {
|
||||
printings = append(printings, database.CardPrinting{
|
||||
Id: card.Id + "n",
|
||||
Name: card.Name,
|
||||
SetCode: card.Set,
|
||||
IsFoil: false,
|
||||
|
|
|
@ -1,18 +1,76 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"sevenkeys/cli"
|
||||
"fmt"
|
||||
"sevenkeys/database"
|
||||
"sevenkeys/figlet"
|
||||
"sevenkeys/logic"
|
||||
"sevenkeys/logic/scryfall"
|
||||
|
||||
"github.com/inancgumus/screen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
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)
|
||||
}
|
||||
}
|