feat: port Hatena server to Python 3
* Update server-side database and dynamic resource code for Python 3 * Preserve existing Flipnote, UGO, NTFT, CSS, localization, and Hatena assets * Port Flipnote upload and movie endpoints * Update front page UGO menu generators * Preserve existing database and sample Flipnote data * Add regression tests for database operations and binary formats * Add server resource loading tests * Maintain compatibility with the original DSi Flipnote Studio protocol
This commit is contained in:
1 parent
687a2bcb43
commit
e4bb0b00ba
48 files changed
+3463
No files matched your search
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
74CC1F_0D3AA40F2B3A0_000 2 0 0 0 0 0 0
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import atexit
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
from twisted.internet import reactor
|
||||||
|
except ImportError: # Allows the database module to be used/tested without Twisted installed.
|
||||||
|
reactor = None
|
||||||
|
|
||||||
|
from Hatenatools import TMB
|
||||||
|
|
||||||
|
|
||||||
|
class Database:
|
||||||
|
"""Plain-text Flipnote database used by the original server.
|
||||||
|
|
||||||
|
This backend is intentionally single-process, matching the original design.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
newest_path = "database/new_flipnotes.dat"
|
||||||
|
if os.path.exists(newest_path):
|
||||||
|
with open(newest_path, "r", encoding="utf-8", newline="") as f:
|
||||||
|
raw = f.read()
|
||||||
|
else:
|
||||||
|
raw = ""
|
||||||
|
|
||||||
|
self.Newest = [tuple(line.split("\t")) for line in raw.splitlines() if line] if raw else []
|
||||||
|
self.Creator = {}
|
||||||
|
|
||||||
|
self.new = False
|
||||||
|
self.Views = 0
|
||||||
|
self.Stars = 0
|
||||||
|
self.Downloads = 0
|
||||||
|
|
||||||
|
if reactor is not None:
|
||||||
|
reactor.callLater(60 * 3, self.flusher)
|
||||||
|
atexit.register(self.write)
|
||||||
|
|
||||||
|
def flusher(self):
|
||||||
|
if reactor is not None:
|
||||||
|
reactor.callLater(60 * 3, self.flusher)
|
||||||
|
self.write()
|
||||||
|
|
||||||
|
def write(self):
|
||||||
|
if self.new:
|
||||||
|
if len(self.Newest) > 5000:
|
||||||
|
self.Newest = self.Newest[:5000]
|
||||||
|
with open("database/new_flipnotes.dat", "w", encoding="utf-8", newline="") as f:
|
||||||
|
f.write("\n".join("\t".join(map(str, row)) for row in self.Newest))
|
||||||
|
self.new = False
|
||||||
|
|
||||||
|
for creator_id in list(self.Creator.keys()):
|
||||||
|
creator_dir = os.path.join("database", "Creators", creator_id)
|
||||||
|
os.makedirs(creator_dir, exist_ok=True)
|
||||||
|
with open(os.path.join(creator_dir, "flipnotes.dat"), "w", encoding="utf-8", newline="") as f:
|
||||||
|
f.write("\n".join("\t".join(map(str, row)) for row in self.Creator[creator_id]))
|
||||||
|
del self.Creator[creator_id]
|
||||||
|
|
||||||
|
def CreatorExists(self, CreatorID):
|
||||||
|
return os.path.exists(os.path.join("database", "Creators", CreatorID)) or CreatorID in self.Creator
|
||||||
|
|
||||||
|
def FlipnoteExists(self, CreatorID, filename):
|
||||||
|
return os.path.exists(self.FlipnotePath(CreatorID, filename))
|
||||||
|
|
||||||
|
def GetCreator(self, CreatorID, Store=False):
|
||||||
|
if CreatorID in self.Creator:
|
||||||
|
return self.Creator[CreatorID]
|
||||||
|
|
||||||
|
creator_dir = os.path.join("database", "Creators", CreatorID)
|
||||||
|
if not os.path.exists(creator_dir):
|
||||||
|
return None
|
||||||
|
|
||||||
|
with open(os.path.join(creator_dir, "flipnotes.dat"), "r", encoding="utf-8", newline="") as f:
|
||||||
|
raw = f.read()
|
||||||
|
ret = [line.split("\t") for line in raw.splitlines() if line]
|
||||||
|
|
||||||
|
# Current format:
|
||||||
|
# filename, views, stars, green, red, blue, purple, channel, downloads
|
||||||
|
for row in ret:
|
||||||
|
filename = row[0]
|
||||||
|
defaults = (filename, 0, 0, 0, 0, 0, 0, "", 0)
|
||||||
|
while len(row) < len(defaults):
|
||||||
|
row.append(defaults[len(row)])
|
||||||
|
|
||||||
|
if Store:
|
||||||
|
self.Creator[CreatorID] = ret
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def GetFlipnote(self, CreatorID, filename, Store=False):
|
||||||
|
for row in self.GetCreator(CreatorID, Store) or []:
|
||||||
|
if row[0] == filename:
|
||||||
|
return row
|
||||||
|
return False
|
||||||
|
|
||||||
|
def GetFlipnotePPM(self, CreatorID, filename):
|
||||||
|
with open(self.FlipnotePath(CreatorID, filename), "rb") as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
def GetFlipnoteTMB(self, CreatorID, filename):
|
||||||
|
with open(self.FlipnotePath(CreatorID, filename), "rb") as f:
|
||||||
|
return f.read(0x6A0)
|
||||||
|
|
||||||
|
def AddFlipnote(self, content, Channel=""):
|
||||||
|
content = bytes(content)
|
||||||
|
tmb = TMB().Read(content)
|
||||||
|
if not tmb:
|
||||||
|
return False
|
||||||
|
|
||||||
|
CreatorID = tmb.EditorAuthorID
|
||||||
|
filename = tmb.CurrentFilename[:-4]
|
||||||
|
if self.FlipnoteExists(CreatorID, filename):
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.new = True
|
||||||
|
self.Newest.insert(0, (CreatorID, filename))
|
||||||
|
|
||||||
|
if not self.GetCreator(CreatorID, True):
|
||||||
|
self.Creator[CreatorID] = [[filename, 0, 0, 0, 0, 0, 0, Channel, 0]]
|
||||||
|
else:
|
||||||
|
self.Creator[CreatorID].append([filename, 0, 0, 0, 0, 0, 0, Channel, 0])
|
||||||
|
|
||||||
|
creator_dir = os.path.join("database", "Creators", CreatorID)
|
||||||
|
os.makedirs(creator_dir, exist_ok=True)
|
||||||
|
with open(self.FlipnotePath(CreatorID, filename), "wb") as f:
|
||||||
|
f.write(content)
|
||||||
|
return CreatorID, filename
|
||||||
|
|
||||||
|
def AddView(self, CreatorID, filename):
|
||||||
|
for i, flipnote in enumerate(self.GetCreator(CreatorID, True) or []):
|
||||||
|
if flipnote[0] == filename:
|
||||||
|
self.Creator[CreatorID][i][1] = int(flipnote[1]) + 1
|
||||||
|
self.Views += 1
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def AddStar(self, CreatorID, filename, amount=1, color="yellow"):
|
||||||
|
starindices = {"yellow": 2, "green": 3, "red": 4, "blue": 5, "purple": 6}
|
||||||
|
if color not in starindices:
|
||||||
|
return False
|
||||||
|
for i, flipnote in enumerate(self.GetCreator(CreatorID, True) or []):
|
||||||
|
if flipnote[0] == filename:
|
||||||
|
idx = starindices[color]
|
||||||
|
self.Creator[CreatorID][i][idx] = int(flipnote[idx]) + amount
|
||||||
|
self.Stars += 1
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def AddDownload(self, CreatorID, filename):
|
||||||
|
for i, flipnote in enumerate(self.GetCreator(CreatorID, True) or []):
|
||||||
|
if flipnote[0] == filename:
|
||||||
|
self.Creator[CreatorID][i][8] = int(flipnote[8]) + 1
|
||||||
|
self.Downloads += 1
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def FlipnotePath(self, CreatorID, filename):
|
||||||
|
return os.path.join("database", "Creators", CreatorID, filename + ".ppm")
|
||||||
|
|
||||||
|
|
||||||
|
Database = Database()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
913304C0CC74CC1F 74CC1F_0D3AA40F2B3A0_000
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
table.profbox {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.prof_out {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color: #82c300;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 0 1px;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
span.more-f{
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.notice2 {
|
||||||
|
margin:0 11px 5px 11px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#fbfbfb;
|
||||||
|
}
|
||||||
|
span.url{
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
span.comptxt {
|
||||||
|
color:#ff8a00;
|
||||||
|
}
|
||||||
|
span.star0 {
|
||||||
|
color:#fdc556;
|
||||||
|
}
|
||||||
|
span.star1 {
|
||||||
|
color:#138200;
|
||||||
|
}
|
||||||
|
span.star2 {
|
||||||
|
color:#ff455c;
|
||||||
|
}
|
||||||
|
span.star3 {
|
||||||
|
color:#00b0f9;
|
||||||
|
}
|
||||||
|
span.star4 {
|
||||||
|
color:#a411b9;
|
||||||
|
}
|
||||||
|
span.star0c {
|
||||||
|
color:#fdc556;
|
||||||
|
}
|
||||||
|
span.star1c {
|
||||||
|
color:#138200;
|
||||||
|
}
|
||||||
|
span.star2c {
|
||||||
|
color:#ff455c;
|
||||||
|
}
|
||||||
|
span.star3c {
|
||||||
|
color:#00b0f9;
|
||||||
|
}
|
||||||
|
span.star4c {
|
||||||
|
color:#a411b9;
|
||||||
|
}
|
||||||
|
span.orange{
|
||||||
|
color: #ff8d45;
|
||||||
|
}
|
||||||
|
span.green {
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
span.gray{
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
span.white {
|
||||||
|
color:#FFFFFF;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color:#333333;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
div.title {
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px 5px 7px 5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.description {
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px 5px 7px 5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.hr {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.hr-tab {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
span.timestamp {
|
||||||
|
color:#999999;
|
||||||
|
}
|
||||||
|
a.timestamp {
|
||||||
|
color:#999999;
|
||||||
|
}
|
||||||
|
a.violation {
|
||||||
|
color:#333333;
|
||||||
|
}
|
||||||
|
div.box {
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.more {
|
||||||
|
margin:7px 0 0 0;
|
||||||
|
}
|
||||||
|
div.pager {
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
div.num {
|
||||||
|
margin:5px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
span.new {
|
||||||
|
color: #cc0000;
|
||||||
|
}
|
||||||
|
span.price {
|
||||||
|
color: #92cb22;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
table.detail{
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
}
|
||||||
|
table.fullsize {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
div.item-term {
|
||||||
|
padding:3px 0 3px 5px;
|
||||||
|
}
|
||||||
|
div.item-value {
|
||||||
|
padding:3px 5px 3px 0;
|
||||||
|
}
|
||||||
|
div.item-text {
|
||||||
|
padding:3px 5px 3px 15px;
|
||||||
|
}
|
||||||
|
div.item-tcom {
|
||||||
|
padding: 3px 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.item-com {
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.td-body {
|
||||||
|
padding:3px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
div.comlist {
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.comment-text {
|
||||||
|
padding:3px 5px 5px 15px;
|
||||||
|
}
|
||||||
|
div.comment-memo {
|
||||||
|
padding:0 0 0 15px;
|
||||||
|
}
|
||||||
|
div.staff {
|
||||||
|
color:#FFFFFF;
|
||||||
|
background-color:#1a1a1a;
|
||||||
|
}
|
||||||
|
a.staffnam {
|
||||||
|
color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.notice {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 3px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.colorstar {
|
||||||
|
margin:7px 0 7px 0;
|
||||||
|
}
|
||||||
|
div.code-box{
|
||||||
|
width:226px;
|
||||||
|
margin:7px 0 0 0;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.code-data{
|
||||||
|
margin:7px 0 7px 0;
|
||||||
|
}
|
||||||
|
div.mail-reply {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.lett_txt {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0 2px;
|
||||||
|
border-color:#92d300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.lett_to {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#92d300;
|
||||||
|
color:#ffffff;
|
||||||
|
padding: 1px 0 6px 5px;
|
||||||
|
}
|
||||||
|
div.pad0{
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
}
|
||||||
|
div.pad5t{
|
||||||
|
padding: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
div.pad5b{
|
||||||
|
padding: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
div.pad1b{
|
||||||
|
padding: 0 0 1px 0;
|
||||||
|
}
|
||||||
|
div.pad2b{
|
||||||
|
padding: 0 0 2px 0;
|
||||||
|
}
|
||||||
|
div.pad2{
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
div.pad5{
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
div.pad0-5{
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
td.pad2{
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
div.pad3-5{
|
||||||
|
padding: 3px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
div.lett_from{
|
||||||
|
padding: 3px 11px 3px 0;
|
||||||
|
}
|
||||||
|
div.pad11{
|
||||||
|
padding: 11px 11px 11px 11px;
|
||||||
|
}
|
||||||
|
div.pad5-11{
|
||||||
|
padding: 5px 11px 5px 11px;
|
||||||
|
}
|
||||||
|
div.pad10b{
|
||||||
|
padding: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
div.pad20b{
|
||||||
|
padding: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
div.mar0-7{
|
||||||
|
margin: 0px 7px 0px 7px;
|
||||||
|
}
|
||||||
|
div.mar0-11{
|
||||||
|
margin: 0px 11px 0px 11px;
|
||||||
|
}
|
||||||
|
div.mar0{
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
div.mar5 {
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
div.yaritori{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#ffffff;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0 2px;
|
||||||
|
border-color:#92d300;
|
||||||
|
}
|
||||||
|
div.gr-tit{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#92d300;
|
||||||
|
color:#ffffff;
|
||||||
|
}
|
||||||
|
div.kadomaru{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
}
|
||||||
|
div.lett-note{
|
||||||
|
margin: 5px 11px 5px 11px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92d300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.pk{
|
||||||
|
background-color:#ff3ab7;
|
||||||
|
}
|
||||||
|
div.blue{
|
||||||
|
background-color:#3acfff;
|
||||||
|
}
|
||||||
|
div.gray{
|
||||||
|
background-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.gray_box{
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.vio-intro {
|
||||||
|
width:240px;
|
||||||
|
padding:7px 0 7px 7px;
|
||||||
|
}
|
||||||
|
div.vio-memo {
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-text {
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-note {
|
||||||
|
color:#999999;
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-submit {
|
||||||
|
padding:10px 0 10px 0;
|
||||||
|
}
|
||||||
|
div.info-head {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.noborder{
|
||||||
|
border-style:solid;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
border-width:0 0 0 0;
|
||||||
|
}
|
||||||
|
div.info-body {
|
||||||
|
padding:7px;
|
||||||
|
}
|
||||||
|
div.info-msg {
|
||||||
|
margin:0 0 7px 0;
|
||||||
|
}
|
||||||
|
div.news-head {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.news-body {
|
||||||
|
padding:7px;
|
||||||
|
}
|
||||||
|
div.news-h1 {
|
||||||
|
margin:7px 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:3px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.news-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
img.news-memo {
|
||||||
|
margin:0 10px 5px 0;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.info-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.num-box{
|
||||||
|
background-color:#cccccc;
|
||||||
|
margin:0 30px;
|
||||||
|
}
|
||||||
|
td.tit-star{
|
||||||
|
background-color:#e9f8c3;
|
||||||
|
}
|
||||||
|
img.help{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:2px;
|
||||||
|
border-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.list{
|
||||||
|
padding:0 0 5px 0;
|
||||||
|
}
|
||||||
|
div.star-det{
|
||||||
|
padding:5px 0 5px 0;
|
||||||
|
}
|
||||||
|
img.sc{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
td.border {
|
||||||
|
background-color: #82c300;
|
||||||
|
}
|
||||||
|
div.border {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 5px 0;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
div.border-c {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 2px 0;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
td.space {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
td.tabon {
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
td.taboff {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
td.tabpager {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.on {
|
||||||
|
padding: 1px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
span.border {
|
||||||
|
color: #b2db59;
|
||||||
|
}
|
||||||
|
span.border-gray {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
a.taboff {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.comme {
|
||||||
|
padding: 3px 3px 3px 12px;
|
||||||
|
color: #b2db59;
|
||||||
|
}
|
||||||
|
span.text {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
td.gray {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
div.message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.error-message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#F5C8A7;
|
||||||
|
background-color:#FFEED8;
|
||||||
|
color:#9B2E2E;
|
||||||
|
}
|
||||||
|
div.ok-message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#C5DABA;
|
||||||
|
background-color:#E3F9DB;
|
||||||
|
color:#517B29;
|
||||||
|
}
|
||||||
|
div.guide-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#66ccff;
|
||||||
|
}
|
||||||
|
div.guide-h3 {
|
||||||
|
padding:3px 3px 3px 3px;
|
||||||
|
background-color:#66ccff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.select-t {
|
||||||
|
color: #66ccff;
|
||||||
|
padding: 0 0 3px 0;
|
||||||
|
}
|
||||||
|
div.select-b {
|
||||||
|
padding:5px 3px 5px 3px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #99ccff;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
span.border-s {
|
||||||
|
color: #99ccff;
|
||||||
|
}
|
||||||
|
span.color {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.credit {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.rule-tit {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 3px 3px 3px 3px;
|
||||||
|
}
|
||||||
|
div.rule-ind {
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
}
|
||||||
|
div.hr-prof {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 3px 0;
|
||||||
|
border-color:transparent;
|
||||||
|
}
|
||||||
|
table.send {
|
||||||
|
margin: 5px 0 0 0 ;
|
||||||
|
}
|
||||||
|
div.icon {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #cccccc;
|
||||||
|
}
|
||||||
|
td.username {
|
||||||
|
height:20px;
|
||||||
|
}
|
||||||
|
td.mystatus {
|
||||||
|
}
|
||||||
|
div.prev {
|
||||||
|
padding: 1px 0 5px 0;
|
||||||
|
}
|
||||||
|
div.next {
|
||||||
|
padding: 5px 0 1px 0;
|
||||||
|
}
|
||||||
|
div.prof-det{
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.catch {
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px 2px 2px 2px;
|
||||||
|
border-color: #ffffff;
|
||||||
|
}
|
||||||
|
a.still {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.head {
|
||||||
|
margin: 0px 0 0 0;
|
||||||
|
}
|
||||||
|
div.send {
|
||||||
|
margin: 0px 10px 3px 11px;
|
||||||
|
}
|
||||||
|
div.link {
|
||||||
|
margin: 0px 10px 0 11px;
|
||||||
|
}
|
||||||
|
img.button {
|
||||||
|
margin: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
td.theme {
|
||||||
|
margin: 0 0 0 3px;
|
||||||
|
}
|
||||||
|
div.trial-h1 {
|
||||||
|
margin: 5px 0 5px 0;
|
||||||
|
padding:3px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:3px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.mar-b10{
|
||||||
|
margin:0 0 10px 0;
|
||||||
|
}
|
||||||
|
div.cam1{
|
||||||
|
margin:7px 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
background-color: #ff2828;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.cam2{
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width: 2px 2px 2px 2px;
|
||||||
|
border-color: #ff2828;
|
||||||
|
}
|
||||||
|
table.xmas2009{
|
||||||
|
margin: 0 10px 0 11px;
|
||||||
|
background-color: #c70606;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.yellow {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#ffe800;
|
||||||
|
}
|
||||||
|
div.sttr_mes {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_gacha {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#ea475c;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.compsp {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#ffe800;
|
||||||
|
background-color:#fff9b7;
|
||||||
|
}
|
||||||
|
div.sttr_war {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#F5C8A7;
|
||||||
|
background-color:#FFEED8;
|
||||||
|
color:#9B2E2E;
|
||||||
|
}
|
||||||
|
div.sttr_price {
|
||||||
|
background-color:#FF9933;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_item {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_theme {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 3px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0px 1px 1px 1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_back {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 0px 7px;
|
||||||
|
}
|
||||||
|
div.gift_l {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0px 2px;
|
||||||
|
border-color:#ff5252;
|
||||||
|
}
|
||||||
|
div.gift_h {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0px 2px;
|
||||||
|
border-color:#ffd616;
|
||||||
|
}
|
||||||
|
img.shop_icon {
|
||||||
|
margin:0 1px 1px 0;
|
||||||
|
}
|
||||||
|
div.help_guide {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#ffac3e;
|
||||||
|
}
|
||||||
|
div.guide-head {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5abcea;
|
||||||
|
}
|
||||||
|
div.guide-title {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5abcea;
|
||||||
|
}
|
||||||
|
div.guide-main {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#5abcea;
|
||||||
|
}
|
||||||
|
div.green-title {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #91C900;
|
||||||
|
}
|
||||||
|
div.green-main {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
table.method{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.search {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
td.keyboard {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
table.key-tab{
|
||||||
|
margin: 0 6px 0 6px;
|
||||||
|
}
|
||||||
|
div.keyout {
|
||||||
|
margin: 0 7px 0 7px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.on-ja {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.off-en {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 0;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.off-aa {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 0;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
table.camp-detail {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
table.center {
|
||||||
|
margin: 0 15px 0 16px;
|
||||||
|
}
|
||||||
|
div.codeborder {
|
||||||
|
border-style: solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
div.codeprev {
|
||||||
|
border-style: solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
td.code {
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
table.codetab {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
div.codetab {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.c_tab2 {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.topic {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#fff273;
|
||||||
|
background-color:#fff8b2;
|
||||||
|
}
|
||||||
|
div.icon-green {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
div.p-block {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#000000;
|
||||||
|
color:#000000;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.clstar-help{
|
||||||
|
background-color:#ffffff;
|
||||||
|
color:#82c300;
|
||||||
|
}
|
||||||
|
div.ugo4th{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#c4260f;
|
||||||
|
background-color:#d52515;
|
||||||
|
}
|
||||||
@@ -0,0 +1,863 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
div.head {
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color:#e63333;
|
||||||
|
}
|
||||||
|
table.profbox {
|
||||||
|
background-color: #353535;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.prof_out {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color: #353535;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 0 1px;
|
||||||
|
border-color: #6c8ff2;
|
||||||
|
}
|
||||||
|
span.more-f{
|
||||||
|
color: #e63333;
|
||||||
|
}
|
||||||
|
div.notice2 {
|
||||||
|
margin:0 11px 5px 11px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#139a2f;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
td.border{
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
div.border {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 5px 0;
|
||||||
|
border-color: #000000;
|
||||||
|
}
|
||||||
|
div.border-c {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 2px 0;
|
||||||
|
border-color: #000000;
|
||||||
|
}
|
||||||
|
td.space {
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
td.tabon {
|
||||||
|
color: #ed5151;
|
||||||
|
}
|
||||||
|
td.taboff {
|
||||||
|
background-color: #000000;
|
||||||
|
color: #ed5151;
|
||||||
|
}
|
||||||
|
td.tabpager {
|
||||||
|
background-color: #000000;
|
||||||
|
color: #ed5151;
|
||||||
|
}
|
||||||
|
span.url{
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
span.comptxt {
|
||||||
|
color:#ff8a00;
|
||||||
|
}
|
||||||
|
span.star0 {
|
||||||
|
color:#fdc556;
|
||||||
|
}
|
||||||
|
span.star1 {
|
||||||
|
color:#138200;
|
||||||
|
}
|
||||||
|
span.star2 {
|
||||||
|
color:#ff455c;
|
||||||
|
}
|
||||||
|
span.star3 {
|
||||||
|
color:#00b0f9;
|
||||||
|
}
|
||||||
|
span.star4 {
|
||||||
|
color:#a411b9;
|
||||||
|
}
|
||||||
|
span.star0c {
|
||||||
|
color:#fdc556;
|
||||||
|
}
|
||||||
|
span.star1c {
|
||||||
|
color:#138200;
|
||||||
|
}
|
||||||
|
span.star2c {
|
||||||
|
color:#ff455c;
|
||||||
|
}
|
||||||
|
span.star3c {
|
||||||
|
color:#00b0f9;
|
||||||
|
}
|
||||||
|
span.star4c {
|
||||||
|
color:#a411b9;
|
||||||
|
}
|
||||||
|
span.orange{
|
||||||
|
color: #ff8d45;
|
||||||
|
}
|
||||||
|
span.green {
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
span.gray{
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
span.white {
|
||||||
|
color:#FFFFFF;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color:#333333;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
div.title {
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px 5px 7px 5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.description {
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px 5px 7px 5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.hr {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.hr-tab {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
span.timestamp {
|
||||||
|
color:#999999;
|
||||||
|
}
|
||||||
|
a.timestamp {
|
||||||
|
color:#999999;
|
||||||
|
}
|
||||||
|
a.violation {
|
||||||
|
color:#333333;
|
||||||
|
}
|
||||||
|
div.box {
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.more {
|
||||||
|
margin:7px 0 0 0;
|
||||||
|
}
|
||||||
|
div.pager {
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
div.num {
|
||||||
|
margin:5px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
span.new {
|
||||||
|
color: #cc0000;
|
||||||
|
}
|
||||||
|
span.price {
|
||||||
|
color: #92cb22;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
table.detail{
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
}
|
||||||
|
table.fullsize {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
div.item-term {
|
||||||
|
padding:3px 0 3px 5px;
|
||||||
|
}
|
||||||
|
div.item-value {
|
||||||
|
padding:3px 5px 3px 0;
|
||||||
|
}
|
||||||
|
div.item-text {
|
||||||
|
padding:3px 5px 3px 15px;
|
||||||
|
}
|
||||||
|
div.item-tcom {
|
||||||
|
padding: 3px 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.item-com {
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.td-body {
|
||||||
|
padding:3px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
div.comlist {
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.comment-text {
|
||||||
|
padding:3px 5px 5px 15px;
|
||||||
|
}
|
||||||
|
div.comment-memo {
|
||||||
|
padding:0 0 0 15px;
|
||||||
|
}
|
||||||
|
div.staff {
|
||||||
|
color:#FFFFFF;
|
||||||
|
background-color:#1a1a1a;
|
||||||
|
}
|
||||||
|
a.staffnam {
|
||||||
|
color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.notice {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 3px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.colorstar {
|
||||||
|
margin:7px 0 7px 0;
|
||||||
|
}
|
||||||
|
div.code-box{
|
||||||
|
width:226px;
|
||||||
|
margin:7px 0 0 0;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.code-data{
|
||||||
|
margin:7px 0 7px 0;
|
||||||
|
}
|
||||||
|
div.mail-reply {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.lett_txt {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0 2px;
|
||||||
|
border-color:#92d300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.lett_to {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#92d300;
|
||||||
|
color:#ffffff;
|
||||||
|
padding: 1px 0 6px 5px;
|
||||||
|
}
|
||||||
|
div.pad0{
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
}
|
||||||
|
div.pad5t{
|
||||||
|
padding: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
div.pad5b{
|
||||||
|
padding: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
div.pad1b{
|
||||||
|
padding: 0 0 1px 0;
|
||||||
|
}
|
||||||
|
div.pad2b{
|
||||||
|
padding: 0 0 2px 0;
|
||||||
|
}
|
||||||
|
div.pad2{
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
div.pad5{
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
div.pad0-5{
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
td.pad2{
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
div.pad3-5{
|
||||||
|
padding: 3px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
div.lett_from{
|
||||||
|
padding: 3px 11px 3px 0;
|
||||||
|
}
|
||||||
|
div.pad11{
|
||||||
|
padding: 11px 11px 11px 11px;
|
||||||
|
}
|
||||||
|
div.pad5-11{
|
||||||
|
padding: 5px 11px 5px 11px;
|
||||||
|
}
|
||||||
|
div.pad10b{
|
||||||
|
padding: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
div.pad20b{
|
||||||
|
padding: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
div.mar0-7{
|
||||||
|
margin: 0px 7px 0px 7px;
|
||||||
|
}
|
||||||
|
div.mar0-11{
|
||||||
|
margin: 0px 11px 0px 11px;
|
||||||
|
}
|
||||||
|
div.mar0{
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
div.mar5 {
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
div.yaritori{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#ffffff;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0 2px;
|
||||||
|
border-color:#92d300;
|
||||||
|
}
|
||||||
|
div.gr-tit{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#92d300;
|
||||||
|
color:#ffffff;
|
||||||
|
}
|
||||||
|
div.kadomaru{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
}
|
||||||
|
div.lett-note{
|
||||||
|
margin: 5px 11px 5px 11px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92d300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.pk{
|
||||||
|
background-color:#ff3ab7;
|
||||||
|
}
|
||||||
|
div.blue{
|
||||||
|
background-color:#3acfff;
|
||||||
|
}
|
||||||
|
div.gray{
|
||||||
|
background-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.gray_box{
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.vio-intro {
|
||||||
|
width:240px;
|
||||||
|
padding:7px 0 7px 7px;
|
||||||
|
}
|
||||||
|
div.vio-memo {
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-text {
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-note {
|
||||||
|
color:#999999;
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-submit {
|
||||||
|
padding:10px 0 10px 0;
|
||||||
|
}
|
||||||
|
div.info-head {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.noborder{
|
||||||
|
border-style:solid;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
border-width:0 0 0 0;
|
||||||
|
}
|
||||||
|
div.info-body {
|
||||||
|
padding:7px;
|
||||||
|
}
|
||||||
|
div.info-msg {
|
||||||
|
margin:0 0 7px 0;
|
||||||
|
}
|
||||||
|
div.news-head {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.news-body {
|
||||||
|
padding:7px;
|
||||||
|
}
|
||||||
|
div.news-h1 {
|
||||||
|
margin:7px 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:3px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.news-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
img.news-memo {
|
||||||
|
margin:0 10px 5px 0;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.info-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.num-box{
|
||||||
|
background-color:#cccccc;
|
||||||
|
margin:0 30px;
|
||||||
|
}
|
||||||
|
td.tit-star{
|
||||||
|
background-color:#e9f8c3;
|
||||||
|
}
|
||||||
|
img.help{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:2px;
|
||||||
|
border-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.list{
|
||||||
|
padding:0 0 5px 0;
|
||||||
|
}
|
||||||
|
div.star-det{
|
||||||
|
padding:5px 0 5px 0;
|
||||||
|
}
|
||||||
|
img.sc{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
td.border {
|
||||||
|
background-color: #82c300;
|
||||||
|
}
|
||||||
|
div.border {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 5px 0;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
div.border-c {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 2px 0;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
td.space {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
td.tabon {
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
td.taboff {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
td.tabpager {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.on {
|
||||||
|
padding: 1px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
span.border {
|
||||||
|
color: #b2db59;
|
||||||
|
}
|
||||||
|
span.border-gray {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
a.taboff {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.comme {
|
||||||
|
padding: 3px 3px 3px 12px;
|
||||||
|
color: #b2db59;
|
||||||
|
}
|
||||||
|
span.text {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
td.gray {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
div.message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.error-message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#F5C8A7;
|
||||||
|
background-color:#FFEED8;
|
||||||
|
color:#9B2E2E;
|
||||||
|
}
|
||||||
|
div.ok-message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#C5DABA;
|
||||||
|
background-color:#E3F9DB;
|
||||||
|
color:#517B29;
|
||||||
|
}
|
||||||
|
div.guide-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#66ccff;
|
||||||
|
}
|
||||||
|
div.guide-h3 {
|
||||||
|
padding:3px 3px 3px 3px;
|
||||||
|
background-color:#66ccff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.select-t {
|
||||||
|
color: #66ccff;
|
||||||
|
padding: 0 0 3px 0;
|
||||||
|
}
|
||||||
|
div.select-b {
|
||||||
|
padding:5px 3px 5px 3px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #99ccff;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
span.border-s {
|
||||||
|
color: #99ccff;
|
||||||
|
}
|
||||||
|
span.color {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.credit {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.rule-tit {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 3px 3px 3px 3px;
|
||||||
|
}
|
||||||
|
div.rule-ind {
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
}
|
||||||
|
div.hr-prof {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 3px 0;
|
||||||
|
border-color:transparent;
|
||||||
|
}
|
||||||
|
table.send {
|
||||||
|
margin: 5px 0 0 0 ;
|
||||||
|
}
|
||||||
|
div.icon {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #cccccc;
|
||||||
|
}
|
||||||
|
td.username {
|
||||||
|
height:20px;
|
||||||
|
}
|
||||||
|
td.mystatus {
|
||||||
|
}
|
||||||
|
div.prev {
|
||||||
|
padding: 1px 0 5px 0;
|
||||||
|
}
|
||||||
|
div.next {
|
||||||
|
padding: 5px 0 1px 0;
|
||||||
|
}
|
||||||
|
div.prof-det{
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.catch {
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px 2px 2px 2px;
|
||||||
|
border-color: #ffffff;
|
||||||
|
}
|
||||||
|
a.still {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.head {
|
||||||
|
margin: 0px 0 0 0;
|
||||||
|
}
|
||||||
|
div.send {
|
||||||
|
margin: 0px 10px 3px 11px;
|
||||||
|
}
|
||||||
|
div.link {
|
||||||
|
margin: 0px 10px 0 11px;
|
||||||
|
}
|
||||||
|
img.button {
|
||||||
|
margin: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
td.theme {
|
||||||
|
margin: 0 0 0 3px;
|
||||||
|
}
|
||||||
|
div.trial-h1 {
|
||||||
|
margin: 5px 0 5px 0;
|
||||||
|
padding:3px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:3px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.mar-b10{
|
||||||
|
margin:0 0 10px 0;
|
||||||
|
}
|
||||||
|
div.cam1{
|
||||||
|
margin:7px 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
background-color: #ff2828;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.cam2{
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width: 2px 2px 2px 2px;
|
||||||
|
border-color: #ff2828;
|
||||||
|
}
|
||||||
|
table.xmas2009{
|
||||||
|
margin: 0 10px 0 11px;
|
||||||
|
background-color: #c70606;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.yellow {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#ffe800;
|
||||||
|
}
|
||||||
|
div.sttr_mes {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_gacha {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#ea475c;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.compsp {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#ffe800;
|
||||||
|
background-color:#fff9b7;
|
||||||
|
}
|
||||||
|
div.sttr_war {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#F5C8A7;
|
||||||
|
background-color:#FFEED8;
|
||||||
|
color:#9B2E2E;
|
||||||
|
}
|
||||||
|
div.sttr_price {
|
||||||
|
background-color:#FF9933;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_item {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_theme {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 3px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0px 1px 1px 1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_back {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 0px 7px;
|
||||||
|
}
|
||||||
|
div.gift_l {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0px 2px;
|
||||||
|
border-color:#ff5252;
|
||||||
|
}
|
||||||
|
div.gift_h {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0px 2px;
|
||||||
|
border-color:#ffd616;
|
||||||
|
}
|
||||||
|
img.shop_icon {
|
||||||
|
margin:0 1px 1px 0;
|
||||||
|
}
|
||||||
|
div.help_guide {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#ffac3e;
|
||||||
|
}
|
||||||
|
div.guide-head {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5abcea;
|
||||||
|
}
|
||||||
|
div.guide-title {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5abcea;
|
||||||
|
}
|
||||||
|
div.guide-main {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#5abcea;
|
||||||
|
}
|
||||||
|
div.green-title {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #91C900;
|
||||||
|
}
|
||||||
|
div.green-main {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
table.method{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.search {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
td.keyboard {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
table.key-tab{
|
||||||
|
margin: 0 6px 0 6px;
|
||||||
|
}
|
||||||
|
div.keyout {
|
||||||
|
margin: 0 7px 0 7px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.on-ja {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.off-en {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 0;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.off-aa {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 0;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
table.camp-detail {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
table.center {
|
||||||
|
margin: 0 15px 0 16px;
|
||||||
|
}
|
||||||
|
div.codeborder {
|
||||||
|
border-style: solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
div.codeprev {
|
||||||
|
border-style: solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
td.code {
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
table.codetab {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
div.codetab {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.c_tab2 {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.topic {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#fff273;
|
||||||
|
background-color:#fff8b2;
|
||||||
|
}
|
||||||
|
div.icon-green {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
div.p-block {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#000000;
|
||||||
|
color:#000000;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.clstar-help{
|
||||||
|
background-color:#ffffff;
|
||||||
|
color:#82c300;
|
||||||
|
}
|
||||||
|
div.ugo4th{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#c4260f;
|
||||||
|
background-color:#d52515;
|
||||||
|
}
|
||||||
@@ -0,0 +1,808 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
span.url{
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
span.comptxt {
|
||||||
|
color:#ff8a00;
|
||||||
|
}
|
||||||
|
span.star0 {
|
||||||
|
color:#fdc556;
|
||||||
|
}
|
||||||
|
span.star1 {
|
||||||
|
color:#138200;
|
||||||
|
}
|
||||||
|
span.star2 {
|
||||||
|
color:#ff455c;
|
||||||
|
}
|
||||||
|
span.star3 {
|
||||||
|
color:#00b0f9;
|
||||||
|
}
|
||||||
|
span.star4 {
|
||||||
|
color:#a411b9;
|
||||||
|
}
|
||||||
|
span.star0c {
|
||||||
|
color:#fdc556;
|
||||||
|
}
|
||||||
|
span.star1c {
|
||||||
|
color:#138200;
|
||||||
|
}
|
||||||
|
span.star2c {
|
||||||
|
color:#ff455c;
|
||||||
|
}
|
||||||
|
span.star3c {
|
||||||
|
color:#00b0f9;
|
||||||
|
}
|
||||||
|
span.star4c {
|
||||||
|
color:#a411b9;
|
||||||
|
}
|
||||||
|
span.orange{
|
||||||
|
color: #ff8d45;
|
||||||
|
}
|
||||||
|
span.green {
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
span.gray{
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
span.white {
|
||||||
|
color:#FFFFFF;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color:#333333;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
div.title {
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px 5px 7px 5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.description {
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px 5px 7px 5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.hr {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.hr-tab {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
span.timestamp {
|
||||||
|
color:#999999;
|
||||||
|
}
|
||||||
|
a.timestamp {
|
||||||
|
color:#999999;
|
||||||
|
}
|
||||||
|
a.violation {
|
||||||
|
color:#333333;
|
||||||
|
}
|
||||||
|
div.box {
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.more {
|
||||||
|
margin:7px 0 0 0;
|
||||||
|
}
|
||||||
|
div.pager {
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
div.num {
|
||||||
|
margin:5px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
span.new {
|
||||||
|
color: #cc0000;
|
||||||
|
}
|
||||||
|
span.price {
|
||||||
|
color: #92cb22;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
table.detail{
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
}
|
||||||
|
table.fullsize {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
div.item-term {
|
||||||
|
padding:3px 0 3px 5px;
|
||||||
|
}
|
||||||
|
div.item-value {
|
||||||
|
padding:3px 5px 3px 0;
|
||||||
|
}
|
||||||
|
div.item-text {
|
||||||
|
padding:3px 5px 3px 15px;
|
||||||
|
}
|
||||||
|
div.item-tcom {
|
||||||
|
padding: 3px 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.item-com {
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.td-body {
|
||||||
|
padding:3px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
div.comlist {
|
||||||
|
background-color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.comment-text {
|
||||||
|
padding:3px 5px 5px 15px;
|
||||||
|
}
|
||||||
|
div.comment-memo {
|
||||||
|
padding:0 0 0 15px;
|
||||||
|
}
|
||||||
|
div.staff {
|
||||||
|
color:#FFFFFF;
|
||||||
|
background-color:#1a1a1a;
|
||||||
|
}
|
||||||
|
a.staffnam {
|
||||||
|
color:#FFFFFF;
|
||||||
|
}
|
||||||
|
div.notice {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 3px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.colorstar {
|
||||||
|
margin:7px 0 7px 0;
|
||||||
|
}
|
||||||
|
div.code-box{
|
||||||
|
width:226px;
|
||||||
|
margin:7px 0 0 0;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.code-data{
|
||||||
|
margin:7px 0 7px 0;
|
||||||
|
}
|
||||||
|
div.mail-reply {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.lett_txt {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0 2px;
|
||||||
|
border-color:#92d300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.lett_to {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#92d300;
|
||||||
|
color:#ffffff;
|
||||||
|
padding: 1px 0 6px 5px;
|
||||||
|
}
|
||||||
|
div.pad0{
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
}
|
||||||
|
div.pad5t{
|
||||||
|
padding: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
div.pad5b{
|
||||||
|
padding: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
div.pad1b{
|
||||||
|
padding: 0 0 1px 0;
|
||||||
|
}
|
||||||
|
div.pad2b{
|
||||||
|
padding: 0 0 2px 0;
|
||||||
|
}
|
||||||
|
div.pad2{
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
div.pad5{
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
div.pad0-5{
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
td.pad2{
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
div.pad3-5{
|
||||||
|
padding: 3px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
div.lett_from{
|
||||||
|
padding: 3px 11px 3px 0;
|
||||||
|
}
|
||||||
|
div.pad11{
|
||||||
|
padding: 11px 11px 11px 11px;
|
||||||
|
}
|
||||||
|
div.pad5-11{
|
||||||
|
padding: 5px 11px 5px 11px;
|
||||||
|
}
|
||||||
|
div.pad10b{
|
||||||
|
padding: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
div.pad20b{
|
||||||
|
padding: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
div.mar0-7{
|
||||||
|
margin: 0px 7px 0px 7px;
|
||||||
|
}
|
||||||
|
div.mar0-11{
|
||||||
|
margin: 0px 11px 0px 11px;
|
||||||
|
}
|
||||||
|
div.mar0{
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
div.mar5 {
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
div.yaritori{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#ffffff;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0 2px;
|
||||||
|
border-color:#92d300;
|
||||||
|
}
|
||||||
|
div.gr-tit{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#92d300;
|
||||||
|
color:#ffffff;
|
||||||
|
}
|
||||||
|
div.kadomaru{
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
}
|
||||||
|
div.lett-note{
|
||||||
|
margin: 5px 11px 5px 11px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92d300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.pk{
|
||||||
|
background-color:#ff3ab7;
|
||||||
|
}
|
||||||
|
div.blue{
|
||||||
|
background-color:#3acfff;
|
||||||
|
}
|
||||||
|
div.gray{
|
||||||
|
background-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.gray_box{
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.vio-intro {
|
||||||
|
width:240px;
|
||||||
|
padding:7px 0 7px 7px;
|
||||||
|
}
|
||||||
|
div.vio-memo {
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-text {
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-note {
|
||||||
|
color:#999999;
|
||||||
|
padding:0 0 10px 15px;
|
||||||
|
}
|
||||||
|
div.vio-submit {
|
||||||
|
padding:10px 0 10px 0;
|
||||||
|
}
|
||||||
|
div.info-head {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.noborder{
|
||||||
|
border-style:solid;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
border-width:0 0 0 0;
|
||||||
|
}
|
||||||
|
div.info-body {
|
||||||
|
padding:7px;
|
||||||
|
}
|
||||||
|
div.info-msg {
|
||||||
|
margin:0 0 7px 0;
|
||||||
|
}
|
||||||
|
div.news-head {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.news-body {
|
||||||
|
padding:7px;
|
||||||
|
}
|
||||||
|
div.news-h1 {
|
||||||
|
margin:7px 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:3px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.news-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
img.news-memo {
|
||||||
|
margin:0 10px 5px 0;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
}
|
||||||
|
div.info-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.num-box{
|
||||||
|
background-color:#cccccc;
|
||||||
|
margin:0 30px;
|
||||||
|
}
|
||||||
|
td.tit-star{
|
||||||
|
background-color:#e9f8c3;
|
||||||
|
}
|
||||||
|
img.help{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:2px;
|
||||||
|
border-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.list{
|
||||||
|
padding:0 0 5px 0;
|
||||||
|
}
|
||||||
|
div.star-det{
|
||||||
|
padding:5px 0 5px 0;
|
||||||
|
}
|
||||||
|
img.sc{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
td.border {
|
||||||
|
background-color: #82c300;
|
||||||
|
}
|
||||||
|
div.border {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 5px 0;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
div.border-c {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 2px 0;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
td.space {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
td.tabon {
|
||||||
|
color: #82c300;
|
||||||
|
}
|
||||||
|
td.taboff {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
td.tabpager {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.on {
|
||||||
|
padding: 1px 6px 3px 6px;
|
||||||
|
}
|
||||||
|
span.border {
|
||||||
|
color: #b2db59;
|
||||||
|
}
|
||||||
|
span.border-gray {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
a.taboff {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.comme {
|
||||||
|
padding: 3px 3px 3px 12px;
|
||||||
|
color: #b2db59;
|
||||||
|
}
|
||||||
|
span.text {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
td.gray {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
div.message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#BCCDED;
|
||||||
|
background-color:#E5EEFE;
|
||||||
|
}
|
||||||
|
div.error-message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#F5C8A7;
|
||||||
|
background-color:#FFEED8;
|
||||||
|
color:#9B2E2E;
|
||||||
|
}
|
||||||
|
div.ok-message {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 2px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#C5DABA;
|
||||||
|
background-color:#E3F9DB;
|
||||||
|
color:#517B29;
|
||||||
|
}
|
||||||
|
div.guide-h2 {
|
||||||
|
padding:0 0 3px 7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 1px 4px;
|
||||||
|
border-color:#66ccff;
|
||||||
|
}
|
||||||
|
div.guide-h3 {
|
||||||
|
padding:3px 3px 3px 3px;
|
||||||
|
background-color:#66ccff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.select-t {
|
||||||
|
color: #66ccff;
|
||||||
|
padding: 0 0 3px 0;
|
||||||
|
}
|
||||||
|
div.select-b {
|
||||||
|
padding:5px 3px 5px 3px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #99ccff;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
span.border-s {
|
||||||
|
color: #99ccff;
|
||||||
|
}
|
||||||
|
span.color {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.credit {
|
||||||
|
padding:5px 7px 5px 7px;
|
||||||
|
background-color:#eeeeee;
|
||||||
|
}
|
||||||
|
div.rule-tit {
|
||||||
|
background-color: #82c300;
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 3px 3px 3px 3px;
|
||||||
|
}
|
||||||
|
div.rule-ind {
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
}
|
||||||
|
div.hr-prof {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 0 3px 0;
|
||||||
|
border-color:transparent;
|
||||||
|
}
|
||||||
|
table.send {
|
||||||
|
margin: 5px 0 0 0 ;
|
||||||
|
}
|
||||||
|
div.icon {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #cccccc;
|
||||||
|
}
|
||||||
|
td.username {
|
||||||
|
height:20px;
|
||||||
|
}
|
||||||
|
td.mystatus {
|
||||||
|
}
|
||||||
|
div.prev {
|
||||||
|
padding: 1px 0 5px 0;
|
||||||
|
}
|
||||||
|
div.next {
|
||||||
|
padding: 5px 0 1px 0;
|
||||||
|
}
|
||||||
|
div.prof-det{
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
}
|
||||||
|
div.catch {
|
||||||
|
margin: 5px 5px 5px 5px;
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px 2px 2px 2px;
|
||||||
|
border-color: #ffffff;
|
||||||
|
}
|
||||||
|
a.still {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.head {
|
||||||
|
margin: 0px 0 0 0;
|
||||||
|
}
|
||||||
|
div.send {
|
||||||
|
margin: 0px 10px 3px 11px;
|
||||||
|
}
|
||||||
|
div.link {
|
||||||
|
margin: 0px 10px 0 11px;
|
||||||
|
}
|
||||||
|
img.button {
|
||||||
|
margin: 5px 0 0 0;
|
||||||
|
}
|
||||||
|
td.theme {
|
||||||
|
margin: 0 0 0 3px;
|
||||||
|
}
|
||||||
|
div.trial-h1 {
|
||||||
|
margin: 5px 0 5px 0;
|
||||||
|
padding:3px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:3px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
div.mar-b10{
|
||||||
|
margin:0 0 10px 0;
|
||||||
|
}
|
||||||
|
div.cam1{
|
||||||
|
margin:7px 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
background-color: #ff2828;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.cam2{
|
||||||
|
margin:0 7px 0 7px;
|
||||||
|
padding:7px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width: 2px 2px 2px 2px;
|
||||||
|
border-color: #ff2828;
|
||||||
|
}
|
||||||
|
table.xmas2009{
|
||||||
|
margin: 0 10px 0 11px;
|
||||||
|
background-color: #c70606;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.yellow {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
background-color:#ffe800;
|
||||||
|
}
|
||||||
|
div.sttr_mes {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_gacha {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#ea475c;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.compsp {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#ffe800;
|
||||||
|
background-color:#fff9b7;
|
||||||
|
}
|
||||||
|
div.sttr_war {
|
||||||
|
width:226px;
|
||||||
|
margin:7px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#F5C8A7;
|
||||||
|
background-color:#FFEED8;
|
||||||
|
color:#9B2E2E;
|
||||||
|
}
|
||||||
|
div.sttr_price {
|
||||||
|
background-color:#FF9933;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_item {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 0px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_theme {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 3px 7px;
|
||||||
|
padding:5px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0px 1px 1px 1px;
|
||||||
|
border-color:#92cb22;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.sttr_back {
|
||||||
|
width:226px;
|
||||||
|
margin:0px 7px 0px 7px;
|
||||||
|
}
|
||||||
|
div.gift_l {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0px 2px;
|
||||||
|
border-color:#ff5252;
|
||||||
|
}
|
||||||
|
div.gift_h {
|
||||||
|
margin: 0 11px 0 11px;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 2px 0px 2px;
|
||||||
|
border-color:#ffd616;
|
||||||
|
}
|
||||||
|
img.shop_icon {
|
||||||
|
margin:0 1px 1px 0;
|
||||||
|
}
|
||||||
|
div.help_guide {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#ffac3e;
|
||||||
|
}
|
||||||
|
div.guide-head {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5abcea;
|
||||||
|
}
|
||||||
|
div.guide-title {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5abcea;
|
||||||
|
}
|
||||||
|
div.guide-main {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#5abcea;
|
||||||
|
}
|
||||||
|
div.green-title {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #91C900;
|
||||||
|
}
|
||||||
|
div.green-main {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#91C900;
|
||||||
|
}
|
||||||
|
table.method{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.search {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
td.keyboard {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
table.key-tab{
|
||||||
|
margin: 0 6px 0 6px;
|
||||||
|
}
|
||||||
|
div.keyout {
|
||||||
|
margin: 0 7px 0 7px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.on-ja {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.off-en {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 0;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
div.off-aa {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 0;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
table.camp-detail {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color:#cccccc;
|
||||||
|
}
|
||||||
|
table.center {
|
||||||
|
margin: 0 15px 0 16px;
|
||||||
|
}
|
||||||
|
div.codeborder {
|
||||||
|
border-style: solid;
|
||||||
|
border-width:0 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
div.codeprev {
|
||||||
|
border-style: solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
td.code {
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
table.codetab {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
}
|
||||||
|
div.codetab {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.c_tab2 {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color:#82c300;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.topic {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#fff273;
|
||||||
|
background-color:#fff8b2;
|
||||||
|
}
|
||||||
|
div.icon-green {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px 1px 1px 1px;
|
||||||
|
border-color: #82c300;
|
||||||
|
}
|
||||||
|
div.p-block {
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#000000;
|
||||||
|
color:#000000;
|
||||||
|
background-color:#ffffff;
|
||||||
|
}
|
||||||
|
div.clstar-help{
|
||||||
|
background-color:#ffffff;
|
||||||
|
color:#82c300;
|
||||||
|
}
|
||||||
|
div.ugo4th{
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color:#c4260f;
|
||||||
|
background-color:#d52515;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
����������������������������������������������������������������ςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σςς�Σ�Σςς�Σ�Σ�Σ�Σ�Σ�Σςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σ�ΣΟ‚�Σςςςς�ΣΟ‚�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�ΣΟ‚�Σςςςς�ΣΟ‚�Σ�Σ�Σ�Σ�Σςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σςςςςςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σςςςςςςςςςς�Σ�Σ�Σ�Σςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σςς�Σ�Σ�Σ�Σ�Σ�Σςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σςςς�Σ�Σ�Σ�Σ�Σ�Σςςς�Σ�Σ�Σςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σςςςς�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σςςςς�Σ�Σςςςς�Σ�Σ�Σ�Σςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σςςςςςςςςςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σςςςςςςςςςςςςςςς�Σςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σςςςςςς�Σςςςςςςςςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σςςςςςςςςς�Σςςςςςςςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σςςςςςςςςςςςςςςς�Σςςςςςς�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςς�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σ�Σςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςςς����������������������������������������������������������������
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
���������������サ纎ロワ������������������������ン�モォョ完完完完完諌�5ササ゚������������������ン�ソョ完完完完完完完完完完完寄椢ロ���������������xマョ完完完完完諌儒�潁漬式完完完完岐「ワ������������5キョ完完完�5」垤�ヌ�ヒ�ヒ�ヒ�ヒ�ヒシソxッム聴完完官噛゚����������ッョ完完岐埆サ�ヒ�ヒ�ヒ�ヒ�ヒWォョ岸テ�ヒ�ヒ�ヒyウョ完完完噛゚��������Vテョ完完碍ァ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォョ寄繭キ�ヒ�ヒ�ヒシソミ聴完完款������壙ョ完完蓋ォ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォョ完完官�6ァンテ�ヒンテミ聴完貫������ミ粍完�4」�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォッ式完完完官孜ウ�ヒワソョ完完楽モ����燮ョ完諌釣ヌ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ�シソ5」ョ完完官爵テ�ヒ垤ョ完観�����ョ完噛キ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヌWォョ完棺サ�ヒ�ヒ�ョ完噛ラ��ワ�完諌�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヒ5」ョ岸テ�ヒ�ヒ垤ョ完�ォ��Wテョ完�5」�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヌミ�6ァ�ヒ�ヒ�ヒ�ヌョ完完��ウョ完噛キ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒンテ��ヒ�ヒ�ヒ�ヒ�ヒ�ョ完款��ョ完款ソ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ4洌完鎌ラ�ム坩完岸テ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ5」ョ完岳マ�ム坩完岸テ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ5」ョ完岳マ��ョ完棺サ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ洌完噛ラ�5サョ完岳ッ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォ��ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ョ完含�yモョ完�5」�ヒ�ヒ�ヒ�ヒ�ヒンテxッ漑�6ァササWォ��ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒンテョ完観��ン�完官岸テ�ヒ�ヒ�ヒ6ァョ完完完完完諌梯�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒWォョ完�5キ���4キョ完碍ァ�ヒ�ヒシソョ完完完完完完完岐�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒンテッ完完棺���サ羂完完款ソ�ヒササョ完完完完完完完岐�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒVァョ完岐ヲ�����ウョ完諌釣テ�ヒ�ョ完完完完完官湿ソ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ匍ョ完完棺�����シ�完完�巫テ�ヒyウWォ��6ァyウ�ヌ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒササョ完完�4ウ�������壤ョ完完寄吊ソ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒxッョ完完寄���������xマョ完完完学ォ�ヌ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒ�ヒササ洌完完諌吊����������壅ョ完完完諌�5」垤ンデテ�ヌ゙テササxッ岼完完完岐ヲ�������������シ�ォョ完完完完完完完完完完完完完完蓋ヌ����������������サ゚ッョ完完完完完完完完完官桟ソワ�������������������ワ�マッム墟佃漬梯「5ササ゚�������������������������������������������
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
RQBuAGcAbABpAHMAaAA= en
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,73 @@
|
|||||||
|
from twisted.web import resource
|
||||||
|
from twisted.internet import reactor
|
||||||
|
import time
|
||||||
|
|
||||||
|
from hatena import Log, NotFound, request_args, request_path
|
||||||
|
from DB import Database
|
||||||
|
from Hatenatools import UGO
|
||||||
|
|
||||||
|
|
||||||
|
class PyResource(resource.Resource):
|
||||||
|
isLeaf = True
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.pages = []
|
||||||
|
self.newestflip = None
|
||||||
|
self.newestview = None
|
||||||
|
self.Update()
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
try:
|
||||||
|
page = int(request_args(request).get("page", ["1"])[0])
|
||||||
|
except ValueError:
|
||||||
|
page = 1
|
||||||
|
if 1 <= page <= len(self.pages):
|
||||||
|
path = "/".join(request_path(request).split("/")[3:])
|
||||||
|
Log(request, "%s page %i" % (path, page))
|
||||||
|
request.setHeader(b"content-type", b"text/plain")
|
||||||
|
return self.pages[page - 1]
|
||||||
|
return NotFound.render(request)
|
||||||
|
|
||||||
|
def Update(self):
|
||||||
|
reactor.callLater(600, self.Update)
|
||||||
|
current = Database.Newest[0] if Database.Newest else None
|
||||||
|
if current != self.newestflip or self.newestview != Database.Views:
|
||||||
|
self.newestflip = current
|
||||||
|
self.newestview = Database.Views
|
||||||
|
reactor.callInThread(self.UpdateThreaded, list(Database.Newest))
|
||||||
|
|
||||||
|
def UpdateThreaded(self, flipnotes):
|
||||||
|
def score(item):
|
||||||
|
i, (creator_id, flip) = item
|
||||||
|
views, stars = Database.GetFlipnote(creator_id, flip)[1:3]
|
||||||
|
return int(views) * 60 + int(stars) // 4 - i
|
||||||
|
flipnotes = [x[1] for x in sorted(enumerate(flipnotes), key=score, reverse=True)[:500]]
|
||||||
|
pages = []
|
||||||
|
pagecount = (len(flipnotes) + 49) // 50
|
||||||
|
pagecount = min(pagecount, 10)
|
||||||
|
flipcount = min(len(flipnotes), 500)
|
||||||
|
for i in range(pagecount):
|
||||||
|
pages.append(self.MakePage(flipnotes[i * 50 : i * 50 + 50], i + 1, i < pagecount - 1, flipcount))
|
||||||
|
if self.pages:
|
||||||
|
print(time.strftime("[%H:%M:%S] Updated hotmovies.ugo"))
|
||||||
|
self.pages = pages
|
||||||
|
|
||||||
|
def MakePage(self, flipnotes, page, has_next, count):
|
||||||
|
ugo = UGO()
|
||||||
|
ugo.Loaded = True
|
||||||
|
ugo.Items = []
|
||||||
|
ugo.Items.append(("layout", (2, 1)))
|
||||||
|
ugo.Items.append(("topscreen text", ["Popular Flipnotes", "Flipnotes", str(count), "", "The most popular new Flipnotes."], 0))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls", "Most Popular", True))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/likedmovies.uls", "Most Liked", False))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls", "New Flipnotes", False))
|
||||||
|
ugo.Items.append(("unknown", ("3", "http://flipnote.hatena.com/ds/v2-xx/help/post_howto.htm", "UABvAHMAdAAgAEYAbABpAHAAbgBvAHQAZQA=")))
|
||||||
|
if page > 1:
|
||||||
|
ugo.Items.append(("button", 115, "Previous", "http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls?page=%i" % (page - 1), ("", ""), None))
|
||||||
|
for creatorid, filename in flipnotes:
|
||||||
|
stars = str(Database.GetFlipnote(creatorid, filename)[2])
|
||||||
|
ugo.Items.append(("button", 3, "", "http://flipnote.hatena.com/ds/v2-xx/movie/%s/%s.ppm" % (creatorid, filename), (stars, "765", "573", "0"), (filename + ".ppm", Database.GetFlipnoteTMB(creatorid, filename))))
|
||||||
|
if has_next:
|
||||||
|
ugo.Items.append(("button", 115, "Next", "http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls?page=%i" % (page + 1), ("", ""), None))
|
||||||
|
return ugo.Pack()
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
from twisted.web import resource
|
||||||
|
from twisted.internet import reactor
|
||||||
|
import time
|
||||||
|
|
||||||
|
from hatena import Log, NotFound, request_args, request_path
|
||||||
|
from DB import Database
|
||||||
|
from Hatenatools import UGO
|
||||||
|
|
||||||
|
|
||||||
|
class PyResource(resource.Resource):
|
||||||
|
isLeaf = True
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.pages = []
|
||||||
|
self.newestflip = None
|
||||||
|
self.neweststar = None
|
||||||
|
reactor.callLater(2, self.Update)
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
try:
|
||||||
|
page = int(request_args(request).get("page", ["1"])[0])
|
||||||
|
except ValueError:
|
||||||
|
page = 1
|
||||||
|
if 1 <= page <= len(self.pages):
|
||||||
|
path = "/".join(request_path(request).split("/")[3:])
|
||||||
|
Log(request, "%s page %i" % (path, page))
|
||||||
|
request.setHeader(b"content-type", b"text/plain")
|
||||||
|
return self.pages[page - 1]
|
||||||
|
return NotFound.render(request)
|
||||||
|
|
||||||
|
def Update(self):
|
||||||
|
reactor.callLater(600, self.Update)
|
||||||
|
current = Database.Newest[0] if Database.Newest else None
|
||||||
|
if current != self.newestflip or self.neweststar != Database.Stars:
|
||||||
|
self.newestflip = current
|
||||||
|
self.neweststar = Database.Stars
|
||||||
|
reactor.callInThread(self.UpdateThreaded, list(Database.Newest))
|
||||||
|
|
||||||
|
def UpdateThreaded(self, flipnotes):
|
||||||
|
def score(item):
|
||||||
|
i, (creator_id, flip) = item
|
||||||
|
views, stars = Database.GetFlipnote(creator_id, flip)[1:3]
|
||||||
|
return int(stars) * 110 + int(views) // 10 - i
|
||||||
|
flipnotes = [x[1] for x in sorted(enumerate(flipnotes), key=score, reverse=True)[:500]]
|
||||||
|
pages = []
|
||||||
|
pagecount = (len(flipnotes) + 49) // 50
|
||||||
|
pagecount = min(pagecount, 10)
|
||||||
|
flipcount = min(len(flipnotes), 500)
|
||||||
|
for i in range(pagecount):
|
||||||
|
pages.append(self.MakePage(flipnotes[i * 50 : i * 50 + 50], i + 1, i < pagecount - 1, flipcount))
|
||||||
|
if self.pages:
|
||||||
|
print(time.strftime("[%H:%M:%S] Updated likedmovies.ugo"))
|
||||||
|
self.pages = pages
|
||||||
|
|
||||||
|
def MakePage(self, flipnotes, page, has_next, count):
|
||||||
|
ugo = UGO()
|
||||||
|
ugo.Loaded = True
|
||||||
|
ugo.Items = []
|
||||||
|
ugo.Items.append(("layout", (2, 1)))
|
||||||
|
ugo.Items.append(("topscreen text", ["Liked Flipnotes", "Flipnotes", str(count), "", "The most liked new Flipnotes."], 0))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls", "Most Popular", False))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/likedmovies.uls", "Most Liked", True))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls", "New Flipnotes", False))
|
||||||
|
ugo.Items.append(("unknown", ("3", "http://flipnote.hatena.com/ds/v2-xx/help/post_howto.htm", "UABvAHMAdAAgAEYAbABpAHAAbgBvAHQAZQA=")))
|
||||||
|
if page > 1:
|
||||||
|
ugo.Items.append(("button", 115, "Previous", "http://flipnote.hatena.com/ds/v2-xx/frontpage/likedmovies.uls?page=%i" % (page - 1), ("", ""), None))
|
||||||
|
for creatorid, filename in flipnotes:
|
||||||
|
stars = str(Database.GetFlipnote(creatorid, filename)[2])
|
||||||
|
ugo.Items.append(("button", 3, "", "http://flipnote.hatena.com/ds/v2-xx/movie/%s/%s.ppm" % (creatorid, filename), (stars, "765", "573", "0"), (filename + ".ppm", Database.GetFlipnoteTMB(creatorid, filename))))
|
||||||
|
if has_next:
|
||||||
|
ugo.Items.append(("button", 115, "Next", "http://flipnote.hatena.com/ds/v2-xx/frontpage/likedmovies.uls?page=%i" % (page + 1), ("", ""), None))
|
||||||
|
return ugo.Pack()
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
from twisted.web import resource
|
||||||
|
from twisted.internet import reactor
|
||||||
|
import time
|
||||||
|
|
||||||
|
from hatena import Log, NotFound, request_args, request_path
|
||||||
|
from DB import Database
|
||||||
|
from Hatenatools import UGO
|
||||||
|
|
||||||
|
|
||||||
|
class PyResource(resource.Resource):
|
||||||
|
isLeaf = True
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.pages = []
|
||||||
|
self.newestflip = None
|
||||||
|
reactor.callLater(4, self.Update)
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
try:
|
||||||
|
page = int(request_args(request).get("page", ["1"])[0])
|
||||||
|
except ValueError:
|
||||||
|
page = 1
|
||||||
|
if 1 <= page <= len(self.pages):
|
||||||
|
path = "/".join(request_path(request).split("/")[3:])
|
||||||
|
Log(request, "%s page %i" % (path, page))
|
||||||
|
request.setHeader(b"content-type", b"text/plain")
|
||||||
|
return self.pages[page - 1]
|
||||||
|
return NotFound.render(request)
|
||||||
|
|
||||||
|
def Update(self):
|
||||||
|
reactor.callLater(60, self.Update)
|
||||||
|
current = Database.Newest[0] if Database.Newest else None
|
||||||
|
if current != self.newestflip:
|
||||||
|
self.newestflip = current
|
||||||
|
reactor.callInThread(self.UpdateThreaded, list(Database.Newest))
|
||||||
|
|
||||||
|
def UpdateThreaded(self, flipnotes):
|
||||||
|
flipnotes = list(flipnotes)
|
||||||
|
pages = []
|
||||||
|
pagecount = (len(flipnotes) + 49) // 50
|
||||||
|
pagecount = min(pagecount, 10)
|
||||||
|
flipcount = len(flipnotes)
|
||||||
|
for i in range(pagecount):
|
||||||
|
pages.append(self.MakePage(flipnotes[i * 50 : i * 50 + 50], i + 1, i < pagecount - 1, flipcount))
|
||||||
|
if self.pages:
|
||||||
|
print(time.strftime("[%H:%M:%S] Updated newmovies.ugo"))
|
||||||
|
self.pages = pages
|
||||||
|
|
||||||
|
def MakePage(self, flipnotes, page, has_next, count):
|
||||||
|
ugo = UGO()
|
||||||
|
ugo.Loaded = True
|
||||||
|
ugo.Items = []
|
||||||
|
ugo.Items.append(("layout", (2, 1)))
|
||||||
|
ugo.Items.append(("topscreen text", ["New Flipnotes", "Flipnotes", str(count), "", "The newest Flipnotes submitted."], 0))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls", "Most Popular", False))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/likedmovies.uls", "Most Liked", False))
|
||||||
|
ugo.Items.append(("category", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls", "New Flipnotes", True))
|
||||||
|
ugo.Items.append(("unknown", ("3", "http://flipnote.hatena.com/ds/v2-xx/help/post_howto.htm", "UABvAHMAdAAgAEYAbABpAHAAbgBvAHQAZQA=")))
|
||||||
|
if page > 1:
|
||||||
|
ugo.Items.append(("button", 115, "Previous", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls?page=%i" % (page - 1), ("", ""), None))
|
||||||
|
for creatorid, filename in flipnotes:
|
||||||
|
stars = str(Database.GetFlipnote(creatorid, filename)[2])
|
||||||
|
ugo.Items.append(("button", 3, "", "http://flipnote.hatena.com/ds/v2-xx/movie/%s/%s.ppm" % (creatorid, filename), (stars, "765", "573", "0"), (filename + ".ppm", Database.GetFlipnoteTMB(creatorid, filename))))
|
||||||
|
if has_next:
|
||||||
|
ugo.Items.append(("button", 115, "Next", "http://flipnote.hatena.com/ds/v2-xx/frontpage/newmovies.uls?page=%i" % (page + 1), ("", ""), None))
|
||||||
|
return ugo.Pack()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<html>␍ <head>␍ <title>Info</title>␍ <meta name="uppertitle" content="Info">␍ <link rel="stylesheet" type="text/css" href="http://flipnote.hatena.com/css/ds/common.css">␍ </head>␍ <body>␍ <div class="container">␍ <div class="title" align="center">pbsds's Hatena Server</div>␍ <div class="news-body">␍ <p>This server is a proof of concept server. There's not much functionality yet because it's in early stages. Please enjoy your stay.</p>␍ </div>␍ </div>␍ </body>␍</html>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<html>␍ <head>␍ <title>Post Flipnote</title>␍ <meta name="uppertitle" content="Post Flipnote">␍ <meta name="postchannelbutton" content="http://flipnote.hatena.com/ds/v2-xx/post/flipnote.post">␍ <link rel="stylesheet" type="text/css" href="http://flipnote.hatena.com/css/ds/common.css">␍ </head>␍ <body>␍ <div class="container">␍ <div class="title" align="center">Posting a Flipnote</div>␍ <div class="news-body">␍ <p>Posting a flipnote is as easy as pressing the button down below and selecting the flipnote you want to upload!</p>␍ </div>␍ </div>␍ </body>␍</html>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<ugo_xml>
|
||||||
|
<layout>
|
||||||
|
<value>2</value>
|
||||||
|
<value>1</value>
|
||||||
|
</layout>
|
||||||
|
<title>
|
||||||
|
<label>Inbox</label>
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<num>0</num>
|
||||||
|
</title>
|
||||||
|
<button>
|
||||||
|
<label>Info</label>
|
||||||
|
<address>http://flipnote.hatena.com/ds/v2-xx/help/info.htm</address>
|
||||||
|
<trait>3</trait>
|
||||||
|
</button>
|
||||||
|
</ugo_xml>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<ugo_xml>
|
||||||
|
<layout>
|
||||||
|
<value>0</value>
|
||||||
|
</layout>
|
||||||
|
<title>
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<label />
|
||||||
|
<num>0</num>
|
||||||
|
</title>
|
||||||
|
<button>
|
||||||
|
<label>Browse Flipnotes</label>
|
||||||
|
<address>http://flipnote.hatena.com/ds/v2-xx/frontpage/hotmovies.uls</address>
|
||||||
|
<trait>100</trait>
|
||||||
|
<value />
|
||||||
|
<value>0</value>
|
||||||
|
</button>
|
||||||
|
<button>
|
||||||
|
<label>Info</label>
|
||||||
|
<address>http://flipnote.hatena.com/ds/v2-xx/help/info.htm</address>
|
||||||
|
<trait>0</trait>
|
||||||
|
<value />
|
||||||
|
<value>0</value>
|
||||||
|
<embedded_file>__ntfts/News.ntft</embedded_file>
|
||||||
|
</button>
|
||||||
|
</ugo_xml>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,221 @@
|
|||||||
|
from twisted.web import resource
|
||||||
|
|
||||||
|
from hatena import Log, ServerLog, Silent, NotFound, as_text, request_path, request_args, request_headers, client_ip
|
||||||
|
from DB import Database
|
||||||
|
from Hatenatools import TMB
|
||||||
|
|
||||||
|
|
||||||
|
class PyResource(resource.Resource):
|
||||||
|
isLeaf = False
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.CreatorID = CreatorIDResource()
|
||||||
|
|
||||||
|
def getChild(self, name, request):
|
||||||
|
name = as_text(name)
|
||||||
|
if Database.CreatorExists(name):
|
||||||
|
return self.CreatorID
|
||||||
|
if name == "":
|
||||||
|
return self
|
||||||
|
return NotFound
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
request.setResponseCode(403)
|
||||||
|
return b"403 - Denied access"
|
||||||
|
|
||||||
|
|
||||||
|
class CreatorIDResource(resource.Resource):
|
||||||
|
isLeaf = False
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.CreatorIDFile = CreatorIDFileResource()
|
||||||
|
|
||||||
|
def getChild(self, name, request):
|
||||||
|
creator_id = request_path(request).split("/")[-2]
|
||||||
|
name = as_text(name)
|
||||||
|
filename = ".".join(name.split(".")[:-1])
|
||||||
|
if Database.FlipnoteExists(creator_id, filename):
|
||||||
|
return self.CreatorIDFile
|
||||||
|
if name == "":
|
||||||
|
return self
|
||||||
|
return NotFound
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
request.setResponseCode(403)
|
||||||
|
return b"403 - Denied access"
|
||||||
|
|
||||||
|
|
||||||
|
class CreatorIDFileResource(resource.Resource):
|
||||||
|
isLeaf = True
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
creator, file = request_path(request).split("/")[-2:]
|
||||||
|
filetype = file.rsplit(".", 1)[-1].lower()
|
||||||
|
path = "/".join(request_path(request).split("/")[3:])
|
||||||
|
|
||||||
|
if filetype == "ppm":
|
||||||
|
Log(request, path)
|
||||||
|
Database.AddView(creator, file[:-4])
|
||||||
|
request.setHeader(b"content-type", b"text/plain")
|
||||||
|
return Database.GetFlipnotePPM(creator, file[:-4])
|
||||||
|
|
||||||
|
if filetype == "info":
|
||||||
|
Log(request, path, True)
|
||||||
|
request.setHeader(b"content-type", b"text/plain")
|
||||||
|
return b"0\n0\n"
|
||||||
|
|
||||||
|
if filetype == "htm":
|
||||||
|
request.setHeader(b"content-type", b"text/html; charset=utf-8")
|
||||||
|
return self.GenerateDetailsPage(creator, ".".join(file.split(".")[:-1])).encode("UTF-8")
|
||||||
|
|
||||||
|
if filetype == "star":
|
||||||
|
args = request_args(request)
|
||||||
|
color = args.get("starcolor", ["yellow"])[0].split(",", 1)[0].lower()
|
||||||
|
headers = request_headers(request)
|
||||||
|
if "x-hatena-star-count" not in headers:
|
||||||
|
ServerLog.write(
|
||||||
|
"%s got 403 when requesting %s without a X-Hatena-Star-Count header" % (client_ip(request), path),
|
||||||
|
Silent,
|
||||||
|
)
|
||||||
|
request.setResponseCode(403)
|
||||||
|
return b"403 - Denied access\nRequest lacks a X-Hatena-Star-Count http header"
|
||||||
|
try:
|
||||||
|
amount = int(headers["x-hatena-star-count"])
|
||||||
|
except ValueError:
|
||||||
|
amount = 0
|
||||||
|
if amount < 1 or amount > 65535:
|
||||||
|
ServerLog.write(
|
||||||
|
"%s got 403 when requesting %s with an invalid X-Hatena-Star-Count header" % (client_ip(request), path),
|
||||||
|
Silent,
|
||||||
|
)
|
||||||
|
request.setResponseCode(403)
|
||||||
|
return b"403 - Denied access\nRequest has an invalid X-Hatena-Star-Count http header"
|
||||||
|
if not Database.AddStar(creator, file[:-5], amount, color):
|
||||||
|
ServerLog.write("%s got 500 when requesting %s" % (client_ip(request), path), Silent)
|
||||||
|
request.setResponseCode(500)
|
||||||
|
return b"500 - Internal server error\nAdding the stars seems to have failed."
|
||||||
|
ServerLog.write(
|
||||||
|
"%s added %i %s stars to %s/%s.ppm" % (client_ip(request), amount, color, creator, file[:-5]),
|
||||||
|
Silent,
|
||||||
|
)
|
||||||
|
return b"Success"
|
||||||
|
|
||||||
|
if filetype == "dl":
|
||||||
|
Log(request, path, True)
|
||||||
|
Database.AddDownload(creator, file[:-3])
|
||||||
|
return b"Noted ;)"
|
||||||
|
|
||||||
|
ServerLog.write("%s got 403 when requesting %s" % (client_ip(request), path), Silent)
|
||||||
|
request.setResponseCode(403)
|
||||||
|
return b"403 - Denied access"
|
||||||
|
|
||||||
|
def GenerateDetailsPage(self, CreatorID, filename):
|
||||||
|
flipnote = Database.GetFlipnote(CreatorID, filename)
|
||||||
|
if not flipnote:
|
||||||
|
return "This flipnote doesn't exist!"
|
||||||
|
tmb = TMB().Read(Database.GetFlipnoteTMB(CreatorID, filename))
|
||||||
|
if not tmb:
|
||||||
|
return "This flipnote is corrupt!"
|
||||||
|
|
||||||
|
spinoff = ""
|
||||||
|
if tmb.OriginalAuthorID != tmb.EditorAuthorID or tmb.OriginalFilename != tmb.CurrentFilename:
|
||||||
|
if Database.FlipnoteExists(tmb.OriginalAuthorID, tmb.OriginalFilename[:-4]):
|
||||||
|
spinoff = SpinoffTemplate1.replace("%%CreatorID%%", tmb.OriginalAuthorID).replace("%%Filename%%", tmb.OriginalFilename[:-4])
|
||||||
|
elif tmb.OriginalAuthorID != tmb.EditorAuthorID:
|
||||||
|
spinoff = SpinoffTemplate2
|
||||||
|
|
||||||
|
entries = []
|
||||||
|
content = '<a href="http://flipnote.hatena.com/ds/v2-xx/%s/profile.htm?t=260&pm=80">%s</a>' % (CreatorID, tmb.Username)
|
||||||
|
entries.append(PageEntryTemplate.replace("%%Name%%", "Creator").replace("%%Content%%", content))
|
||||||
|
|
||||||
|
content = '<a href="http://flipnote.hatena.com/ds/v2-xx/movie/%s/%s.htm?mode=stardetail"><span class="star0c">★</span> <span class="star0">%s</span></a>' % (CreatorID, filename, flipnote[2])
|
||||||
|
for css, value in zip(("1", "2", "3", "4"), flipnote[3:7]):
|
||||||
|
content += '<br/><a href="http://flipnote.hatena.com/ds/v2-xx/movie/%s/%s.htm?mode=stardetail"><span class="star%sc">★</span> <span class="star%s">%s</span></a>' % (CreatorID, filename, css, css, value)
|
||||||
|
entries.append(PageEntryTemplate.replace("%%Name%%", "Stars").replace("%%Content%%", content))
|
||||||
|
entries.append(PageEntryTemplate.replace("%%Name%%", "Views").replace("%%Content%%", str(flipnote[1])))
|
||||||
|
entries.append(PageEntryTemplate.replace("%%Name%%", "Downloads").replace("%%Content%%", str(flipnote[8])))
|
||||||
|
|
||||||
|
if flipnote[7]:
|
||||||
|
content = '<a href="http://flipnote.hatena.com/ds/v2-xx/ch/%s.uls">%s</a>' % (flipnote[7], flipnote[7])
|
||||||
|
entries.append(PageEntryTemplate.replace("%%Name%%", "Channel").replace("%%Content%%", content))
|
||||||
|
|
||||||
|
return (
|
||||||
|
DetailsPageTemplate.replace("%%CreatorID%%", CreatorID)
|
||||||
|
.replace("%%Filename%%", filename)
|
||||||
|
.replace("%%Username%%", tmb.Username)
|
||||||
|
.replace("%%CommentCount%%", "0")
|
||||||
|
.replace("%%Spinoff%%", spinoff)
|
||||||
|
.replace("%%PageEntries%%", PageEntrySeparator.join(entries))
|
||||||
|
)
|
||||||
|
|
||||||
|
#templates:
|
||||||
|
DetailsPageTemplate = """<html>
|
||||||
|
<head>
|
||||||
|
<title>Flipnote by %%Username%%</title>
|
||||||
|
<meta name="upperlink" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.ppm">
|
||||||
|
<meta name="starbutton" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star">
|
||||||
|
<meta name="starbutton1" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star?starcolor=green,9001">
|
||||||
|
<meta name="starbutton2" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star?starcolor=red,9001">
|
||||||
|
<meta name="starbutton3" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star?starcolor=blue,9001">
|
||||||
|
<meta name="starbutton4" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star?starcolor=purple,9001">
|
||||||
|
<meta name="savebutton" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.ppm">
|
||||||
|
<meta name="playcontrolbutton" content="">
|
||||||
|
<link rel="stylesheet" href="http://flipnote.hatena.com/css/ds/basic.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table width="240" border="0" cellspacing="0" cellpadding="0" class="tab">
|
||||||
|
<tr>
|
||||||
|
<td class="border" width="5" align="center">
|
||||||
|
<div class="border"></div>
|
||||||
|
</td>
|
||||||
|
<td class="border" width="70" align="center">
|
||||||
|
<div class="border"></div>
|
||||||
|
</td>
|
||||||
|
<td class="border" width="95" align="center">
|
||||||
|
<div class="border"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="space"> </td>
|
||||||
|
<td class="tabon" align="center">
|
||||||
|
<div class="on" align="center">Description</div>
|
||||||
|
</td>
|
||||||
|
<td class="taboff" align="center">
|
||||||
|
<a class="taboff" href="http://flipnote.hatena.com/ds/v2-eu/movie/%%CreatorID%%/%%Filename%%.htm?mode=commentshalfsize">Comments(%%CommentCount%%)</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="pad5b"></div>%%Spinoff%%
|
||||||
|
<table width="226" border="0" cellspacing="0" cellpadding="0" class="detail">%%PageEntries%%
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>"""
|
||||||
|
SpinoffTemplate1 = """
|
||||||
|
<div class="notice2" align="center">
|
||||||
|
This Flipnote is a spin-off.<br>
|
||||||
|
<a href="http://flipnote.hatena.com/ds/v2-eu/movie/%%CreatorID%%/%%Filename%%.htm">Original Flipnote</a>
|
||||||
|
</div>"""
|
||||||
|
SpinoffTemplate2 = """
|
||||||
|
<div class="notice2" align="center">
|
||||||
|
This Flipnote is a spin-off.
|
||||||
|
</div>"""
|
||||||
|
PageEntryTemplate = """
|
||||||
|
<tr>
|
||||||
|
<th width="90">
|
||||||
|
<div class="item-term" align="left">%%Name%%</div>
|
||||||
|
</th>
|
||||||
|
<td width="136">
|
||||||
|
<div class="item-value" align="right">
|
||||||
|
%%Content%%
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>"""
|
||||||
|
PageEntrySeparator="""
|
||||||
|
<tr> </tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="hr"></div>
|
||||||
|
</td>
|
||||||
|
</tr>"""
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
from twisted.web import resource
|
||||||
|
|
||||||
|
from hatena import ServerLog, Silent, request_args, client_ip
|
||||||
|
from DB import Database
|
||||||
|
|
||||||
|
|
||||||
|
class PyResource(resource.Resource):
|
||||||
|
isLeaf = True
|
||||||
|
|
||||||
|
def render_GET(self, request):
|
||||||
|
ServerLog.write("%s got 403 when requesting post/flipnote.post with GET" % client_ip(request), Silent)
|
||||||
|
request.setResponseCode(405)
|
||||||
|
return b"405 - Method Not Allowed"
|
||||||
|
|
||||||
|
def render_POST(self, request):
|
||||||
|
data = request.content.read()
|
||||||
|
channel = request_args(request).get("channel", [""])[0]
|
||||||
|
add = Database.AddFlipnote(data, channel)
|
||||||
|
if add:
|
||||||
|
ServerLog.write('%s successfully uploaded "%s.ppm"' % (client_ip(request), add[1]), Silent)
|
||||||
|
request.setResponseCode(200)
|
||||||
|
else:
|
||||||
|
ServerLog.write("%s tried to upload a flipnote, but failed..." % client_ip(request), Silent)
|
||||||
|
request.setResponseCode(500)
|
||||||
|
return b""
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
���������3욎욎�3�������3욎욎�3�����������������������������������������������3욎욎�3�������3욎욎�3�����������������������������������������������3욎욎�3�������3욎욎�3��������������������������������������������3욎����3욎욎욎욎욎�3����3욎�����������������������������������������3욎����3욎욎욎욎욎�3����3욎�����������������������������������������3욎����3욎욎욎욎욎�3����3욎�����������������������������������������3욎����3욎욎욎욎욎�3����3욎�����������������������������������������3욎����3욎욎욎욎욎�3����3욎�����������������������������������������3욎����3욎욎욎욎욎�3����3욎�����������������������������������������3욎욎욎욎욎욎욎욎욎욎욎�3�����������������������������������������3욎욎욎욎욎욎욎욎욎욎욎�3�����������������������������������������3욎욎욎욎욎욎욎욎욎욎욎�3��������������������������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�����������������������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�����������������������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�����������������������������������3욎욎�3�������������������3욎욎�3�����������������������������������3욎욎�3�������������������3욎욎�3�����������������������������������3욎욎�3�������������������3욎욎�3��������������������������������3욎욎욎욎�������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3����3욎욎욎욎욎�3�������3욎욎욎욎욎�3�����������������������������������3욎욎욎욎욎�3�������3욎욎욎욎욎�3�����������������������������������3욎욎욎욎욎�3�������3욎욎욎욎욎�3��������������������������������3욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎욎�3�
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
������������������2�2�2�2����2�2�2�2�2�2��2�2�2���2�2�2�2�2�����2�2�2�2�����2�2�2�2�2���2�2�2��2�2�2�2�2�2����2�2�2�2�����2�2�2�2�����2�2�2�2�����2�2�2�2�����2�2�2�2�����2�2�2�2�����2�2�2�2���
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Line truncated
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
���™�5�5�5�5�5�5�5�5�������™��γ?Οό�ό�?Ο?Ο?Ο?Ο?Ο5�5�����™��γ?Ο?Ο?Οό�?Ο�γ�γ?Ο?Ο?Ο5����ό�ό�ό�ό�ό�?Ο?Ο�γ�γ�γ�γ�γ?Ο5���™��γ?Ο?Ο?Οό�?Ο?Ο?Ο?Ο?Ο�γ�γ5���ό�ό�ό�ό�ό�?Ο?Οό�ό�ό�?Ο�γ�γ™���™��γ?Ο?Ο?Οό�ό�?Ο?Ο?Ο?Ο�γ�γ™���ό�ό�ό�ό�ό�?Ο?Ο?Ο�γ�γ�γ?Ο?Ο5���™��γ�γ�γ�γό�?Ο�γ�γ�γ?Ο?Ο5�����™�™�™�™�5�?Ο?Ο?Ο?Ο5�5����������5�?Ο?Ο?Ο5�����������™�?Ο?Ο?Ο5�����������™��γ?Ο?Ο5������������™��γ?Ο?Ο5������������™��γ�γ�γ™�������������™�™�™��������
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import database as database_module
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SAMPLE_CREATOR = "913304C0CC74CC1F"
|
||||||
|
SAMPLE_NAME = "74CC1F_0D3AA40F2B3A0_000"
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.tmp = tempfile.TemporaryDirectory()
|
||||||
|
self.old_cwd = os.getcwd()
|
||||||
|
temp_root = Path(self.tmp.name)
|
||||||
|
shutil.copytree(ROOT / "database", temp_root / "database")
|
||||||
|
os.chdir(temp_root)
|
||||||
|
self.db = database_module.Database.__class__()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Prevent the per-test instance from having anything left to flush at interpreter exit.
|
||||||
|
self.db.Creator.clear()
|
||||||
|
self.db.new = False
|
||||||
|
os.chdir(self.old_cwd)
|
||||||
|
self.tmp.cleanup()
|
||||||
|
|
||||||
|
def test_read_sample(self):
|
||||||
|
self.assertTrue(self.db.CreatorExists(SAMPLE_CREATOR))
|
||||||
|
row = self.db.GetFlipnote(SAMPLE_CREATOR, SAMPLE_NAME)
|
||||||
|
self.assertTrue(row)
|
||||||
|
self.assertEqual(row[0], SAMPLE_NAME)
|
||||||
|
self.assertEqual(len(row), 9)
|
||||||
|
self.assertTrue(self.db.GetFlipnotePPM(SAMPLE_CREATOR, SAMPLE_NAME).startswith(b"PARA"))
|
||||||
|
self.assertEqual(len(self.db.GetFlipnoteTMB(SAMPLE_CREATOR, SAMPLE_NAME)), 0x6A0)
|
||||||
|
|
||||||
|
def test_counters_and_write(self):
|
||||||
|
self.assertTrue(self.db.AddView(SAMPLE_CREATOR, SAMPLE_NAME))
|
||||||
|
self.assertTrue(self.db.AddStar(SAMPLE_CREATOR, SAMPLE_NAME, 5, "green"))
|
||||||
|
self.assertTrue(self.db.AddDownload(SAMPLE_CREATOR, SAMPLE_NAME))
|
||||||
|
self.assertEqual(self.db.Views, 1)
|
||||||
|
self.assertEqual(self.db.Stars, 1)
|
||||||
|
self.assertEqual(self.db.Downloads, 1)
|
||||||
|
row = self.db.GetFlipnote(SAMPLE_CREATOR, SAMPLE_NAME, True)
|
||||||
|
self.assertEqual(int(row[1]), 3)
|
||||||
|
self.assertEqual(int(row[3]), 5)
|
||||||
|
self.assertEqual(int(row[8]), 1)
|
||||||
|
self.db.write()
|
||||||
|
text = Path("database/Creators") / SAMPLE_CREATOR / "flipnotes.dat"
|
||||||
|
self.assertIn("\t3\t", text.read_text(encoding="utf-8"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from Hatenatools import NTFT, PPM, TMB, UGO
|
||||||
|
from Hatenatools.PPM import WriteImage, get_metadata
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SAMPLE_PPM = ROOT / "database" / "Creators" / "913304C0CC74CC1F" / "74CC1F_0D3AA40F2B3A0_000.ppm"
|
||||||
|
NEWS_NTFT = ROOT / "hatenadir" / "ds" / "v2-xx" / "__ntfts" / "News.ntft"
|
||||||
|
KAERU_NTFT = ROOT / "hatenadir" / "images" / "ds" / "kaeru.ntft"
|
||||||
|
INDEX_UGOXML = ROOT / "hatenadir" / "ds" / "v2-xx" / "index.ugoxml"
|
||||||
|
INBOX_UGOXML = ROOT / "hatenadir" / "ds" / "v2-xx" / "inbox.ugoxml"
|
||||||
|
|
||||||
|
|
||||||
|
class PPMTests(unittest.TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.data = SAMPLE_PPM.read_bytes()
|
||||||
|
|
||||||
|
def test_tmb_metadata_and_exact_pack(self):
|
||||||
|
tmb = TMB().Read(self.data[:0x6A0], DecodeThumbnail=True)
|
||||||
|
self.assertTrue(tmb)
|
||||||
|
self.assertEqual(tmb.EditorAuthorID, "913304C0CC74CC1F")
|
||||||
|
self.assertEqual(tmb.CurrentFilename, "74CC1F_0D3AA40F2B3A0_000.tmb")
|
||||||
|
self.assertEqual(tmb.FrameCount, 3)
|
||||||
|
self.assertEqual(tmb.GetThumbnail().shape, (64, 48))
|
||||||
|
self.assertEqual(tmb.Pack(), self.data[:0x6A0])
|
||||||
|
|
||||||
|
def test_ppm_full_parse_and_frame(self):
|
||||||
|
ppm = PPM().Read(self.data, DecodeThumbnail=True, ReadFrames=True, ReadSound=True)
|
||||||
|
self.assertTrue(ppm)
|
||||||
|
self.assertEqual(ppm.EditorAuthorID, "913304C0CC74CC1F")
|
||||||
|
self.assertEqual(ppm.CurrentFilename, "74CC1F_0D3AA40F2B3A0_000.ppm")
|
||||||
|
self.assertEqual(ppm.FrameCount, 3)
|
||||||
|
self.assertEqual(ppm.GetThumbnail().shape, (64, 48))
|
||||||
|
frame = ppm.GetFrame(0)
|
||||||
|
self.assertIsInstance(frame, np.ndarray)
|
||||||
|
self.assertEqual(frame.shape, (256, 192))
|
||||||
|
self.assertEqual(len(ppm.SoundData), 4)
|
||||||
|
|
||||||
|
def test_metadata_helper_infers_filetype(self):
|
||||||
|
ppm = PPM().Read(self.data, ReadFrames=False)
|
||||||
|
metadata = get_metadata(ppm)
|
||||||
|
self.assertEqual(metadata["Current filename"], "74CC1F_0D3AA40F2B3A0_000.ppm")
|
||||||
|
self.assertEqual(metadata["Number of frames"], 3)
|
||||||
|
self.assertIn("Frame speed", metadata)
|
||||||
|
|
||||||
|
def test_image_export(self):
|
||||||
|
ppm = PPM().Read(self.data, DecodeThumbnail=True, ReadFrames=False)
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
output = Path(tmp) / "thumb.png"
|
||||||
|
self.assertTrue(WriteImage(ppm.GetThumbnail(), str(output)))
|
||||||
|
self.assertGreater(output.stat().st_size, 0)
|
||||||
|
|
||||||
|
|
||||||
|
class NTFTTests(unittest.TestCase):
|
||||||
|
def test_exact_roundtrip_news(self):
|
||||||
|
raw = NEWS_NTFT.read_bytes()
|
||||||
|
image = NTFT().Read(raw, (32, 32))
|
||||||
|
self.assertTrue(image)
|
||||||
|
self.assertEqual(image.Pack(), raw)
|
||||||
|
|
||||||
|
def test_exact_roundtrip_kaeru(self):
|
||||||
|
raw = KAERU_NTFT.read_bytes()
|
||||||
|
image = NTFT().Read(raw, (36, 30))
|
||||||
|
self.assertTrue(image)
|
||||||
|
self.assertEqual(image.Pack(), raw)
|
||||||
|
|
||||||
|
|
||||||
|
class UGOTests(unittest.TestCase):
|
||||||
|
def _roundtrip_xml(self, path: Path):
|
||||||
|
ugo = UGO().ReadXML(str(path), False)
|
||||||
|
self.assertTrue(ugo)
|
||||||
|
packed = ugo.Pack()
|
||||||
|
self.assertIsInstance(packed, bytes)
|
||||||
|
self.assertEqual(packed[:4], b"UGAR")
|
||||||
|
decoded = UGO().Read(packed)
|
||||||
|
self.assertTrue(decoded)
|
||||||
|
# Embedded-file names are XML-side metadata and are not stored in the
|
||||||
|
# binary UGO format. The meaningful binary round-trip is idempotence.
|
||||||
|
self.assertEqual(decoded.Pack(), packed)
|
||||||
|
|
||||||
|
def test_index_xml(self):
|
||||||
|
self._roundtrip_xml(INDEX_UGOXML)
|
||||||
|
|
||||||
|
def test_inbox_xml(self):
|
||||||
|
self._roundtrip_xml(INBOX_UGOXML)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import sys
|
||||||
|
import types
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
|
||||||
|
def install_twisted_stub():
|
||||||
|
"""Install only the Twisted surface needed to smoke-test this project."""
|
||||||
|
if importlib.util.find_spec("twisted") is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
twisted = types.ModuleType("twisted")
|
||||||
|
web = types.ModuleType("twisted.web")
|
||||||
|
resource_mod = types.ModuleType("twisted.web.resource")
|
||||||
|
static_mod = types.ModuleType("twisted.web.static")
|
||||||
|
internet_mod = types.ModuleType("twisted.internet")
|
||||||
|
|
||||||
|
class Resource:
|
||||||
|
isLeaf = False
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.children = {}
|
||||||
|
|
||||||
|
def putChild(self, name, child):
|
||||||
|
if not isinstance(name, bytes):
|
||||||
|
raise TypeError("Twisted child names must be bytes")
|
||||||
|
self.children[name] = child
|
||||||
|
|
||||||
|
def getChild(self, name, request):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def getChildWithDefault(self, name, request):
|
||||||
|
return self.children.get(name, self.getChild(name, request))
|
||||||
|
|
||||||
|
class File(Resource):
|
||||||
|
def __init__(self, path):
|
||||||
|
super().__init__()
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
def render(self, request):
|
||||||
|
p = Path(self.path)
|
||||||
|
return p.read_bytes() if p.is_file() else b""
|
||||||
|
|
||||||
|
class Reactor:
|
||||||
|
def __init__(self):
|
||||||
|
self.calls = []
|
||||||
|
|
||||||
|
def callLater(self, delay, func, *args, **kwargs):
|
||||||
|
self.calls.append((delay, func, args, kwargs))
|
||||||
|
return object()
|
||||||
|
|
||||||
|
def callInThread(self, func, *args, **kwargs):
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
resource_mod.Resource = Resource
|
||||||
|
static_mod.File = File
|
||||||
|
web.resource = resource_mod
|
||||||
|
web.static = static_mod
|
||||||
|
internet_mod.reactor = Reactor()
|
||||||
|
twisted.web = web
|
||||||
|
twisted.internet = internet_mod
|
||||||
|
|
||||||
|
sys.modules.update(
|
||||||
|
{
|
||||||
|
"twisted": twisted,
|
||||||
|
"twisted.web": web,
|
||||||
|
"twisted.web.resource": resource_mod,
|
||||||
|
"twisted.web.static": static_mod,
|
||||||
|
"twisted.internet": internet_mod,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceTreeTests(unittest.TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
install_twisted_stub()
|
||||||
|
cls.old_cwd = Path.cwd()
|
||||||
|
import os
|
||||||
|
os.chdir(ROOT)
|
||||||
|
import hatena
|
||||||
|
cls.hatena = hatena
|
||||||
|
cls.root = hatena.Setup()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
import os
|
||||||
|
os.chdir(cls.old_cwd)
|
||||||
|
|
||||||
|
def test_core_resource_tree_loads(self):
|
||||||
|
region = self.root.dsResource.region
|
||||||
|
expected = {
|
||||||
|
b"index.ugo",
|
||||||
|
b"inbox.ugo",
|
||||||
|
b"movie",
|
||||||
|
b"post",
|
||||||
|
b"frontpage",
|
||||||
|
b"help",
|
||||||
|
b"eula_list.tsv",
|
||||||
|
}
|
||||||
|
self.assertTrue(expected.issubset(region.children))
|
||||||
|
self.assertIn(b"flipnote.post", region.children[b"post"].children)
|
||||||
|
self.assertIn(b"hotmovies.ugo", region.children[b"frontpage"].children)
|
||||||
|
self.assertIn(b"likedmovies.ugo", region.children[b"frontpage"].children)
|
||||||
|
self.assertIn(b"newmovies.ugo", region.children[b"frontpage"].children)
|
||||||
|
|
||||||
|
def test_prepacked_ugo_resources_are_binary(self):
|
||||||
|
region = self.root.dsResource.region
|
||||||
|
self.assertTrue(region.children[b"index.ugo"].ugofile.startswith(b"UGAR"))
|
||||||
|
self.assertTrue(region.children[b"inbox.ugo"].ugofile.startswith(b"UGAR"))
|
||||||
|
|
||||||
|
def test_hot_page_builds_from_database(self):
|
||||||
|
hot = self.root.dsResource.region.children[b"frontpage"].children[b"hotmovies.ugo"]
|
||||||
|
self.assertGreaterEqual(len(hot.pages), 1)
|
||||||
|
self.assertTrue(hot.pages[0].startswith(b"UGAR"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in new issue
Block a user
