mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Added external crash handler
This commit is contained in:
parent
d7db3f0d0f
commit
3326269e36
1
Jamfile
1
Jamfile
@ -16,6 +16,7 @@ Clean distclean : $(JCACHEFILE) $(HCACHEFILE) ;
|
||||
# SubInclude goes after local rules
|
||||
SubInclude TOP econtrol ;
|
||||
SubInclude TOP ecalc ;
|
||||
SubInclude TOP ecrasher ;
|
||||
SubInclude TOP edewm ;
|
||||
SubInclude TOP eiconman ;
|
||||
SubInclude TOP evoke ;
|
||||
|
286
ecrasher/CrashDialog.cpp
Normal file
286
ecrasher/CrashDialog.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Ecrasher, a crash handler tool
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2008 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "icons/core.xpm"
|
||||
#include "CrashDialog.h"
|
||||
|
||||
#include <FL/Fl.h>
|
||||
#include <FL/Fl_Pixmap.h>
|
||||
#include <FL/Fl_File_Chooser.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <edelib/Nls.h>
|
||||
#include <edelib/File.h>
|
||||
#include <edelib/Directory.h>
|
||||
#include <edelib/MessageBox.h>
|
||||
|
||||
#define DIALOG_W 380
|
||||
#define DIALOG_H 130
|
||||
#define DIALOG_W_EXPANDED 380
|
||||
#define DIALOG_H_EXPANDED 340
|
||||
|
||||
int spawn_backtrace(const char* gdb_path, const char* program, const char* core, const char* output, const char* script) {
|
||||
const char* gdb_script = "bt\nquit\n";
|
||||
const int gdb_script_len = 8;
|
||||
|
||||
// file with gdb commands
|
||||
int sfd = open(script, O_WRONLY | O_TRUNC | O_CREAT, 0770);
|
||||
if(sfd == -1)
|
||||
return -1;
|
||||
write(sfd, gdb_script, gdb_script_len);
|
||||
close(sfd);
|
||||
|
||||
// output file with gdb backtrace
|
||||
int ofd = open(output, O_WRONLY | O_TRUNC | O_CREAT, 0770);
|
||||
if(ofd == -1)
|
||||
return -1;
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if(pid == -1) {
|
||||
close(ofd);
|
||||
return -1;
|
||||
} else if(pid == 0) {
|
||||
dup2(ofd, 1);
|
||||
close(ofd);
|
||||
|
||||
char* argv[8];
|
||||
argv[0] = (char*)gdb_path;
|
||||
argv[1] = "--quiet";
|
||||
argv[2] = "--batch";
|
||||
argv[3] = "-x";
|
||||
argv[4] = (char*)script;
|
||||
argv[5] = (char*)program;
|
||||
argv[6] = (char*)core;
|
||||
argv[7] = 0;
|
||||
|
||||
execvp(argv[0], argv);
|
||||
return -1;
|
||||
} else {
|
||||
int status;
|
||||
if(waitpid(pid, &status, 0) != pid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
edelib::String get_uname(void) {
|
||||
struct utsname ut;
|
||||
uname(&ut);
|
||||
|
||||
edelib::String ret;
|
||||
ret.printf("%s %s %s %s %s", ut.sysname, ut.nodename, ut.release, ut.version, ut.machine);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void show_details_cb(Fl_Widget*, void* cd) {
|
||||
CrashDialog* c = (CrashDialog*)cd;
|
||||
c->show_details();
|
||||
}
|
||||
|
||||
void close_cb(Fl_Widget*, void* cd) {
|
||||
CrashDialog* c = (CrashDialog*)cd;
|
||||
c->hide();
|
||||
}
|
||||
|
||||
void save_cb(Fl_Widget*, void* cd) {
|
||||
CrashDialog* c = (CrashDialog*)cd;
|
||||
c->save();
|
||||
}
|
||||
|
||||
CrashDialog::CrashDialog() : Fl_Window(DIALOG_W, DIALOG_H, _("EDE crash handler")),
|
||||
appname(NULL), apppath(NULL), bugaddress(NULL), pid(NULL), signal_num(NULL) {
|
||||
details_shown = false;
|
||||
|
||||
begin();
|
||||
pix = new Fl_Pixmap(core_xpm);
|
||||
|
||||
icon_box = new Fl_Box(10, 10, 70, 75);
|
||||
icon_box->image(pix);
|
||||
|
||||
txt_box = new Fl_Box(85, 10, 285, 75);
|
||||
txt_box->align(FL_ALIGN_WRAP | FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
|
||||
|
||||
close = new Fl_Button(280, 95, 90, 25, _("&Close"));
|
||||
close->callback(close_cb, this);
|
||||
|
||||
details = new Fl_Button(10, 95, 265, 25, _("@> Show details"));
|
||||
details->box(FL_FLAT_BOX);
|
||||
details->align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT);
|
||||
details->callback(show_details_cb, this);
|
||||
|
||||
// widgets for expanded dialog
|
||||
trace_log = new Fl_Text_Display(10, 130, 360, 165);
|
||||
trace_buff = new Fl_Text_Buffer();
|
||||
trace_log->buffer(trace_buff);
|
||||
trace_log->hide();
|
||||
save_as = new Fl_Button(280, 305, 90, 25, _("&Save As..."));
|
||||
save_as->callback(save_cb, this);
|
||||
save_as->hide();
|
||||
end();
|
||||
}
|
||||
|
||||
CrashDialog::~CrashDialog() {
|
||||
// looks like fltk does not clean image() assigned data
|
||||
delete pix;
|
||||
}
|
||||
|
||||
void CrashDialog::show_details(void) {
|
||||
if(trace_log->visible()) {
|
||||
trace_log->hide();
|
||||
save_as->hide();
|
||||
details->label(_("@> Show details"));
|
||||
size(DIALOG_W, DIALOG_H);
|
||||
} else {
|
||||
trace_log->show();
|
||||
save_as->show();
|
||||
details->label(_("@< Hide details"));
|
||||
size(DIALOG_W_EXPANDED, DIALOG_H_EXPANDED);
|
||||
|
||||
if(!details_shown) {
|
||||
trace_buff->remove(0, trace_buff->length());
|
||||
|
||||
edelib::String address = _("\nPlease report this at: ");
|
||||
if(bugaddress)
|
||||
address += bugaddress;
|
||||
else
|
||||
address += "bugs@equinox-project.org";
|
||||
|
||||
trace_buff->append(address.c_str());
|
||||
trace_buff->append("\n\n");
|
||||
|
||||
trace_buff->append("---------- short summary ----------\n");
|
||||
trace_buff->append("\nEDE version: 2.0");
|
||||
trace_buff->append("\nSystem info: ");
|
||||
trace_buff->append(get_uname().c_str());
|
||||
|
||||
trace_buff->append("\nProgram name: ");
|
||||
if(appname)
|
||||
trace_buff->append(appname);
|
||||
else
|
||||
trace_buff->append("(unknown)");
|
||||
|
||||
trace_buff->append("\nExecutable path: ");
|
||||
if(apppath)
|
||||
trace_buff->append(apppath);
|
||||
else
|
||||
trace_buff->append("(unknown)");
|
||||
|
||||
trace_buff->append("\nRunning PID: ");
|
||||
if(pid)
|
||||
trace_buff->append(pid);
|
||||
else
|
||||
trace_buff->append("(unknown)");
|
||||
|
||||
trace_buff->append("\nSignal received: ");
|
||||
if(signal_num)
|
||||
trace_buff->append(signal_num);
|
||||
else
|
||||
trace_buff->append("(unknown)");
|
||||
|
||||
// try backtrace via gdb
|
||||
trace_buff->append("\n\n---------- backtrace ----------\n");
|
||||
const char* core_file = "core";
|
||||
|
||||
if(!edelib::file_exists(core_file)) {
|
||||
trace_buff->append("\nUnable to find 'core' file. Backtrace will not be done.");
|
||||
details_shown = false;
|
||||
return;
|
||||
}
|
||||
|
||||
edelib::String gdb_path = edelib::file_path("gdb");
|
||||
if(gdb_path.empty()) {
|
||||
trace_buff->append("\nUnable to find gdb. Is it installed ?");
|
||||
// set to false so next 'Show Details' click can try again with the debugger
|
||||
details_shown = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// check if we can write in /tmp; if not, try with $HOME
|
||||
edelib::String dir = "/tmp";
|
||||
if(!edelib::dir_writeable(dir.c_str())) {
|
||||
dir = edelib::dir_home();
|
||||
|
||||
if(!edelib::dir_writeable(dir.c_str())) {
|
||||
trace_buff->append("\nDon't have permissions to write either to /tmp or $HOME");
|
||||
details_shown = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
edelib::String gdb_output, gdb_script;
|
||||
gdb_output = gdb_script = dir;
|
||||
// TODO: these files should be unique per session
|
||||
gdb_output += "/.gdb_output";
|
||||
gdb_script += "/.gdb_script";
|
||||
|
||||
if(spawn_backtrace(gdb_path.c_str(), cmd.c_str(), core_file, gdb_output.c_str(), gdb_script.c_str()) == -1) {
|
||||
trace_buff->append("\nUnable to properly execute gdb");
|
||||
details_shown = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!edelib::file_exists(gdb_output.c_str())) {
|
||||
trace_buff->append("\nStrange, can't find gdb output that I was just wrote to");
|
||||
details_shown = false;
|
||||
return;
|
||||
}
|
||||
|
||||
trace_buff->appendfile(gdb_output.c_str());
|
||||
|
||||
edelib::file_remove(gdb_output.c_str());
|
||||
edelib::file_remove(gdb_script.c_str());
|
||||
edelib::file_remove(core_file);
|
||||
|
||||
|
||||
details_shown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrashDialog::save(void) {
|
||||
const char* p = fl_file_chooser(_("Save details to..."), "Text Files (*.txt)\tAll Files(*)", "dump.txt");
|
||||
if(!p)
|
||||
return;
|
||||
|
||||
// so we can have EOL in file
|
||||
trace_buff->append("\n");
|
||||
|
||||
if(trace_buff->savefile(p) != 0)
|
||||
edelib::alert(_("Unable to save to %s. Please check permissions to write in this directory or file"), p);
|
||||
}
|
||||
|
||||
void CrashDialog::run(void) {
|
||||
edelib::String l;
|
||||
|
||||
if(appname || apppath) {
|
||||
const char* p = (appname ? appname : apppath);
|
||||
l.printf(_("Program '%s' just crashed !"), p);
|
||||
} else
|
||||
l += _("Program just crashed !");
|
||||
l += _("\n\nYou can inspect details about this crash by clicking on 'Show details' below");
|
||||
|
||||
txt_box->copy_label(l.c_str());
|
||||
|
||||
if(!shown())
|
||||
show();
|
||||
|
||||
while(shown())
|
||||
Fl::wait();
|
||||
}
|
62
ecrasher/CrashDialog.h
Normal file
62
ecrasher/CrashDialog.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Ecrasher, a crash handler tool
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2008 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#ifndef __CRASHDIALOG_H__
|
||||
#define __CRASHDIALOG_H__
|
||||
|
||||
#include <FL/Fl_Window.h>
|
||||
#include <FL/Fl_Box.h>
|
||||
#include <FL/Fl_Button.h>
|
||||
#include <FL/Fl_Pixmap.h>
|
||||
#include <FL/Fl_Text_Display.h>
|
||||
#include <FL/Fl_Text_Buffer.h>
|
||||
|
||||
#include <edelib/String.h>
|
||||
|
||||
class CrashDialog : public Fl_Window {
|
||||
private:
|
||||
const char* appname;
|
||||
const char* apppath;
|
||||
const char* bugaddress;
|
||||
const char* pid;
|
||||
const char* signal_num;
|
||||
|
||||
Fl_Pixmap* pix;
|
||||
Fl_Box* txt_box;
|
||||
Fl_Box* icon_box;
|
||||
Fl_Button* close;
|
||||
Fl_Button* details;
|
||||
|
||||
Fl_Text_Display* trace_log;
|
||||
Fl_Text_Buffer* trace_buff;
|
||||
Fl_Button* save_as;
|
||||
|
||||
edelib::String cmd;
|
||||
bool details_shown;
|
||||
|
||||
public:
|
||||
CrashDialog();
|
||||
~CrashDialog();
|
||||
void show_details(void);
|
||||
|
||||
void set_appname(const char* a) { appname = a; }
|
||||
void set_apppath(const char* p) { apppath = p; }
|
||||
void set_bugaddress(const char* a) { bugaddress = a; }
|
||||
void set_pid(const char* p) { pid = p; }
|
||||
void set_signal(const char* s) { signal_num = s; }
|
||||
|
||||
void save(void);
|
||||
|
||||
void run(void);
|
||||
};
|
||||
|
||||
#endif
|
15
ecrasher/Jamfile
Normal file
15
ecrasher/Jamfile
Normal file
@ -0,0 +1,15 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Part of Equinox Desktop Environment (EDE).
|
||||
# Copyright (c) 2008 EDE Authors.
|
||||
#
|
||||
# This program is licensed under terms of the
|
||||
# GNU General Public License version 2 or newer.
|
||||
# See COPYING for details.
|
||||
|
||||
SubDir TOP ecrasher ;
|
||||
|
||||
SOURCE = ecrasher.cpp CrashDialog.cpp ;
|
||||
|
||||
EdeProgram ecrasher : $(SOURCE) ;
|
109
ecrasher/ecrasher.cpp
Normal file
109
ecrasher/ecrasher.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Ecrasher, a crash handler tool
|
||||
* Part of Equinox Desktop Environment (EDE).
|
||||
* Copyright (c) 2008 EDE Authors.
|
||||
*
|
||||
* This program is licensed under terms of the
|
||||
* GNU General Public License version 2 or newer.
|
||||
* See COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "CrashDialog.h"
|
||||
|
||||
#define CHECK_ARGV(argv, pshort, plong) ((strcmp(argv, pshort) == 0) || (strcmp(argv, plong) == 0))
|
||||
|
||||
const char* next_param(int curr, char** argv, int argc) {
|
||||
int j = curr + 1;
|
||||
if(j >= argc)
|
||||
return NULL;
|
||||
if(argv[j][0] == '-')
|
||||
return NULL;
|
||||
return argv[j];
|
||||
}
|
||||
|
||||
void help(void) {
|
||||
puts("Usage: ecrasher [OPTIONS]");
|
||||
puts("EDE crash handler\n");
|
||||
puts("Options:");
|
||||
puts(" -h, --help this help");
|
||||
puts(" -b, --bugaddress [ADDRESS] bug address to use");
|
||||
puts(" -p, --pid [PID] the PID of the program");
|
||||
puts(" -a, --appname [NAME] name of the program");
|
||||
puts(" -e, --apppath [PATH] path to the executable");
|
||||
puts(" -s, --signal [SIGNAL] the signal number that was caught");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc <= 1) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* a;
|
||||
const char* bugaddress = NULL;
|
||||
const char* appname = NULL;
|
||||
const char* apppath = NULL;
|
||||
const char* pid = 0;
|
||||
const char* signal_num = 0;
|
||||
|
||||
for(int i = 1; i < argc; i++) {
|
||||
a = argv[i];
|
||||
if(CHECK_ARGV(a, "-h", "--help")) {
|
||||
help();
|
||||
return 0;
|
||||
} else if(CHECK_ARGV(a, "-b", "--bugaddress")) {
|
||||
bugaddress = next_param(i, argv, argc);
|
||||
if(!bugaddress) {
|
||||
puts("Missing bug address parameter");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
} else if(CHECK_ARGV(a, "-p", "--pid")) {
|
||||
pid = next_param(i, argv, argc);
|
||||
if(!pid) {
|
||||
puts("Missing pid parameter");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
} else if(CHECK_ARGV(a, "-a", "--appname")) {
|
||||
appname = next_param(i, argv, argc);
|
||||
if(!appname) {
|
||||
puts("Missing application name");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
} else if(CHECK_ARGV(a, "-e", "--apppath")) {
|
||||
apppath = next_param(i, argv, argc);
|
||||
if(!apppath) {
|
||||
puts("Missing application path");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
} else if(CHECK_ARGV(a, "-s", "--signal")) {
|
||||
signal_num = next_param(i, argv, argc);
|
||||
if(!signal_num) {
|
||||
puts("Missing signal number");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
printf("Unknown '%s' parameter. Run ecrasher -h for options\n", a);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
CrashDialog cd;
|
||||
cd.set_appname(appname);
|
||||
cd.set_apppath(apppath);
|
||||
cd.set_bugaddress(bugaddress);
|
||||
cd.set_pid(pid);
|
||||
cd.set_signal(signal_num);
|
||||
|
||||
cd.run();
|
||||
|
||||
return 0;
|
||||
}
|
28
ecrasher/fl/crash.fl
Normal file
28
ecrasher/fl/crash.fl
Normal file
@ -0,0 +1,28 @@
|
||||
# data file for the Fltk User Interface Designer (fluid)
|
||||
version 1.0108
|
||||
header_name {.h}
|
||||
code_name {.cxx}
|
||||
Function {} {open
|
||||
} {
|
||||
Fl_Window {} {open
|
||||
xywh {354 160 380 130} type Double visible
|
||||
} {
|
||||
Fl_Box {} {
|
||||
image {../icons/core.xpm} xywh {10 10 70 75} labelsize 14
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Program foo just crashed !!!
|
||||
|
||||
You can inspect details about this crash by clicking on 'Show details' below} selected
|
||||
xywh {85 10 285 75} align 148
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {&Close}
|
||||
xywh {280 95 90 25}
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {@> Show details}
|
||||
xywh {10 95 265 25} box FLAT_BOX align 20
|
||||
}
|
||||
}
|
||||
}
|
35
ecrasher/fl/crash_expanded.fl
Normal file
35
ecrasher/fl/crash_expanded.fl
Normal file
@ -0,0 +1,35 @@
|
||||
# data file for the Fltk User Interface Designer (fluid)
|
||||
version 1.0108
|
||||
header_name {.h}
|
||||
code_name {.cxx}
|
||||
Function {} {open selected
|
||||
} {
|
||||
Fl_Window {} {open
|
||||
xywh {354 160 380 340} type Double visible
|
||||
} {
|
||||
Fl_Box {} {
|
||||
image {../icons/core.xpm} xywh {10 10 70 75} labelsize 14
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {Program foo just crashed !!!
|
||||
|
||||
You can inspect details about this crash by clicking on 'Show details' below}
|
||||
xywh {85 10 285 75} align 148
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {&Close}
|
||||
xywh {280 95 90 25}
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {@< Hide details}
|
||||
xywh {10 95 265 25} box FLAT_BOX align 20
|
||||
}
|
||||
Fl_Text_Display {} {
|
||||
xywh {10 130 360 165} labelsize 14 textsize 14
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {&Save As...}
|
||||
xywh {280 305 90 25}
|
||||
}
|
||||
}
|
||||
}
|
416
ecrasher/icons/core.xpm
Normal file
416
ecrasher/icons/core.xpm
Normal file
@ -0,0 +1,416 @@
|
||||
/* XPM */
|
||||
static char * core_xpm[] = {
|
||||
"48 48 365 2",
|
||||
" c None",
|
||||
". c #FAE601",
|
||||
"+ c #FCF001",
|
||||
"@ c #FEF800",
|
||||
"# c #F9E202",
|
||||
"$ c #F2BE04",
|
||||
"% c #F2BD04",
|
||||
"& c #F5CC03",
|
||||
"* c #FBE901",
|
||||
"= c #FBEC01",
|
||||
"- c #EB9A06",
|
||||
"; c #EEAA05",
|
||||
"> c #FEFC00",
|
||||
", c #F7D506",
|
||||
"' c #E78808",
|
||||
") c #E88D06",
|
||||
"! c #D1B46D",
|
||||
"~ c #C7AF75",
|
||||
"{ c #C2994A",
|
||||
"] c #F1BB04",
|
||||
"^ c #F5CF03",
|
||||
"/ c #FCEE01",
|
||||
"( c #EDD426",
|
||||
"_ c #DCBC76",
|
||||
": c #E3C06E",
|
||||
"< c #CCAB4F",
|
||||
"[ c #E7C16F",
|
||||
"} c #ECC36B",
|
||||
"| c #CCB34C",
|
||||
"1 c #FCFB04",
|
||||
"2 c #D1C652",
|
||||
"3 c #D0B76B",
|
||||
"4 c #DDBA6C",
|
||||
"5 c #DAB96E",
|
||||
"6 c #CFBB40",
|
||||
"7 c #A7A7A7",
|
||||
"8 c #A8A8A8",
|
||||
"9 c #A9A9A9",
|
||||
"0 c #A4A4A4",
|
||||
"a c #9F9F9F",
|
||||
"b c #999999",
|
||||
"c c #919191",
|
||||
"d c #A5B4BE",
|
||||
"e c #E7E7E1",
|
||||
"f c #C3C2C7",
|
||||
"g c #B3AB9B",
|
||||
"h c #B5A679",
|
||||
"i c #C5AF6A",
|
||||
"j c #D6B86A",
|
||||
"k c #CDB16B",
|
||||
"l c #C9B05B",
|
||||
"m c #B7A27C",
|
||||
"n c #EBDC19",
|
||||
"o c #AFAFAF",
|
||||
"p c #B8B8B8",
|
||||
"q c #BBBBBB",
|
||||
"r c #BCBCBC",
|
||||
"s c #BABABA",
|
||||
"t c #B4B4B4",
|
||||
"u c #888888",
|
||||
"v c #7B7B7B",
|
||||
"w c #102032",
|
||||
"x c #808285",
|
||||
"y c #FBF5F2",
|
||||
"z c #D9D0BF",
|
||||
"A c #C6AD71",
|
||||
"B c #DFBB69",
|
||||
"C c #D9B86B",
|
||||
"D c #C0AC7C",
|
||||
"E c #BBA785",
|
||||
"F c #AAAAAA",
|
||||
"G c #ADADAD",
|
||||
"H c #D6D6D6",
|
||||
"I c #EBEBEB",
|
||||
"J c #FCFCFC",
|
||||
"K c #FEFEFE",
|
||||
"L c #FFFFFF",
|
||||
"M c #FBFBFB",
|
||||
"N c #F5F5F5",
|
||||
"O c #E7E7E7",
|
||||
"P c #D2D2D2",
|
||||
"Q c #868686",
|
||||
"R c #636363",
|
||||
"S c #616161",
|
||||
"T c #6E6E6E",
|
||||
"U c #3E3E3D",
|
||||
"V c #3B3A3A",
|
||||
"W c #161311",
|
||||
"X c #65605D",
|
||||
"Y c #C3BCB7",
|
||||
"Z c #D8CFB0",
|
||||
"` c #D1B873",
|
||||
" . c #DFBD6A",
|
||||
".. c #C8B37E",
|
||||
"+. c #AAAEBF",
|
||||
"@. c #FFFD00",
|
||||
"#. c #B1B1B1",
|
||||
"$. c #CACACA",
|
||||
"%. c #E9E9E9",
|
||||
"&. c #F0F0F0",
|
||||
"*. c #E5E5E5",
|
||||
"=. c #E3E3E3",
|
||||
"-. c #E1E1E1",
|
||||
";. c #DFDFDF",
|
||||
">. c #898989",
|
||||
",. c #3C3C3C",
|
||||
"'. c #393939",
|
||||
"). c #262626",
|
||||
"!. c #1D1D1E",
|
||||
"~. c #0F0F0F",
|
||||
"{. c #5A5857",
|
||||
"]. c #5A5955",
|
||||
"^. c #4D4D45",
|
||||
"/. c #918E7A",
|
||||
"(. c #D3CBA7",
|
||||
"_. c #E5DCB3",
|
||||
":. c #E0DECD",
|
||||
"<. c #AEAEAE",
|
||||
"[. c #D3D3D3",
|
||||
"}. c #FAFAFA",
|
||||
"|. c #FDFDFD",
|
||||
"1. c #EFEFEF",
|
||||
"2. c #EAEAEA",
|
||||
"3. c #DDDDDD",
|
||||
"4. c #D7D7D7",
|
||||
"5. c #D0D0D0",
|
||||
"6. c #C9C9C9",
|
||||
"7. c #C1C1C1",
|
||||
"8. c #BDBDBD",
|
||||
"9. c #7D7D7D",
|
||||
"0. c #333333",
|
||||
"a. c #131313",
|
||||
"b. c #4F4F4F",
|
||||
"c. c #484848",
|
||||
"d. c #5F5F60",
|
||||
"e. c #393C3A",
|
||||
"f. c #080C09",
|
||||
"g. c #1F1F1B",
|
||||
"h. c #817F74",
|
||||
"i. c #D8D6C6",
|
||||
"j. c #F2F2E8",
|
||||
"k. c #DFE7F0",
|
||||
"l. c #F9F9F9",
|
||||
"m. c #F3F3F3",
|
||||
"n. c #EDEDED",
|
||||
"o. c #E8E8E8",
|
||||
"p. c #E4E4E4",
|
||||
"q. c #DEDEDE",
|
||||
"r. c #CCCCCC",
|
||||
"s. c #C3C3C3",
|
||||
"t. c #B9B9B9",
|
||||
"u. c #ABABAB",
|
||||
"v. c #A1A1A1",
|
||||
"w. c #151515",
|
||||
"x. c #4B4B4B",
|
||||
"y. c #6B6B6B",
|
||||
"z. c #3F3F3F",
|
||||
"A. c #1B1B1B",
|
||||
"B. c #121211",
|
||||
"C. c #050604",
|
||||
"D. c #000000",
|
||||
"E. c #0C0707",
|
||||
"F. c #433F37",
|
||||
"G. c #7E7F79",
|
||||
"H. c #F7F7F7",
|
||||
"I. c #ECECEC",
|
||||
"J. c #E2E2E2",
|
||||
"K. c #DCDCDC",
|
||||
"L. c #B0B0B0",
|
||||
"M. c #A5A5A5",
|
||||
"N. c #979797",
|
||||
"O. c #969696",
|
||||
"P. c #434343",
|
||||
"Q. c #191919",
|
||||
"R. c #010101",
|
||||
"S. c #060001",
|
||||
"T. c #0C0203",
|
||||
"U. c #050002",
|
||||
"V. c #0B0D14",
|
||||
"W. c #EEEEEE",
|
||||
"X. c #DADADA",
|
||||
"Y. c #C6C6C6",
|
||||
"Z. c #BEBEBE",
|
||||
"`. c #B6B6B6",
|
||||
" + c #9C9C9C",
|
||||
".+ c #909090",
|
||||
"++ c #848484",
|
||||
"@+ c #6C6C6C",
|
||||
"#+ c #1A1A1A",
|
||||
"$+ c #060606",
|
||||
"%+ c #020101",
|
||||
"&+ c #010403",
|
||||
"*+ c #020405",
|
||||
"=+ c #010202",
|
||||
"-+ c #D8D8D8",
|
||||
";+ c #CFCFCF",
|
||||
">+ c #C2C2C2",
|
||||
",+ c #A2A2A2",
|
||||
"'+ c #878787",
|
||||
")+ c #787878",
|
||||
"!+ c #656565",
|
||||
"~+ c #252525",
|
||||
"{+ c #080C0D",
|
||||
"]+ c #F4F4F4",
|
||||
"^+ c #D9D9D9",
|
||||
"/+ c #D4D4D4",
|
||||
"(+ c #CECECE",
|
||||
"_+ c #C5C5C5",
|
||||
":+ c #BFBFBF",
|
||||
"<+ c #B2B2B2",
|
||||
"[+ c #A0A0A0",
|
||||
"}+ c #989898",
|
||||
"|+ c #8E8E8E",
|
||||
"1+ c #737373",
|
||||
"2+ c #6D6D6D",
|
||||
"3+ c #585858",
|
||||
"4+ c #202020",
|
||||
"5+ c #070707",
|
||||
"6+ c #4B4C4C",
|
||||
"7+ c #767676",
|
||||
"8+ c #D1D1D1",
|
||||
"9+ c #A3A3A3",
|
||||
"0+ c #9B9B9B",
|
||||
"a+ c #949494",
|
||||
"b+ c #8C8C8C",
|
||||
"c+ c #838383",
|
||||
"d+ c #797979",
|
||||
"e+ c #6F6F6F",
|
||||
"f+ c #676767",
|
||||
"g+ c #4A4A4A",
|
||||
"h+ c #030303",
|
||||
"i+ c #181818",
|
||||
"j+ c #040404",
|
||||
"k+ c #565656",
|
||||
"l+ c #D5D5D5",
|
||||
"m+ c #C7C7C7",
|
||||
"n+ c #C4C4C4",
|
||||
"o+ c #ACACAC",
|
||||
"p+ c #9E9E9E",
|
||||
"q+ c #7E7E7E",
|
||||
"r+ c #666666",
|
||||
"s+ c #606060",
|
||||
"t+ c #575757",
|
||||
"u+ c #353535",
|
||||
"v+ c #383738",
|
||||
"w+ c #777677",
|
||||
"x+ c #494949",
|
||||
"y+ c #CBCBCB",
|
||||
"z+ c #B5B5B5",
|
||||
"A+ c #9A9A9A",
|
||||
"B+ c #939393",
|
||||
"C+ c #8B8B8B",
|
||||
"D+ c #7C7C7C",
|
||||
"E+ c #5E5E5E",
|
||||
"F+ c #595959",
|
||||
"G+ c #424242",
|
||||
"H+ c #171717",
|
||||
"I+ c #0C0C0C",
|
||||
"J+ c #5D5D5D",
|
||||
"K+ c #2F2F2F",
|
||||
"L+ c #8F8F8F",
|
||||
"M+ c #8A8A8A",
|
||||
"N+ c #858585",
|
||||
"O+ c #7F7F7F",
|
||||
"P+ c #757575",
|
||||
"Q+ c #686868",
|
||||
"R+ c #5B5B5B",
|
||||
"S+ c #4D4D4D",
|
||||
"T+ c #6F6D6E",
|
||||
"U+ c #3B3B3B",
|
||||
"V+ c #9D9D9D",
|
||||
"W+ c #959595",
|
||||
"X+ c #8D8D8D",
|
||||
"Y+ c #828282",
|
||||
"Z+ c #6A6A6A",
|
||||
"`+ c #646464",
|
||||
" @ c #555555",
|
||||
".@ c #2E2E2E",
|
||||
"+@ c #0B0B0B",
|
||||
"@@ c #020202",
|
||||
"#@ c #222222",
|
||||
"$@ c #1D1D1D",
|
||||
"%@ c #080808",
|
||||
"&@ c #808080",
|
||||
"*@ c #7A7A7A",
|
||||
"=@ c #707070",
|
||||
"-@ c #5F5F5F",
|
||||
";@ c #545454",
|
||||
">@ c #525252",
|
||||
",@ c #2B2B2B",
|
||||
"'@ c #0D0D0D",
|
||||
")@ c #050505",
|
||||
"!@ c #111111",
|
||||
"~@ c #5A5A5A",
|
||||
"{@ c #929292",
|
||||
"]@ c #717171",
|
||||
"^@ c #515151",
|
||||
"/@ c #3D3D3D",
|
||||
"(@ c #272727",
|
||||
"_@ c #323232",
|
||||
":@ c #6D6C6C",
|
||||
"<@ c #1C1C1C",
|
||||
"[@ c #535353",
|
||||
"}@ c #414141",
|
||||
"|@ c #0A0A0A",
|
||||
"1@ c #646363",
|
||||
"2@ c #161616",
|
||||
"3@ c #696969",
|
||||
"4@ c #313131",
|
||||
"5@ c #1F1F1F",
|
||||
"6@ c #0E0E0E",
|
||||
"7@ c #090909",
|
||||
"8@ c #121212",
|
||||
"9@ c #444444",
|
||||
"0@ c #464646",
|
||||
"a@ c #282828",
|
||||
"b@ c #5C5C5C",
|
||||
"c@ c #141414",
|
||||
"d@ c #212121",
|
||||
"e@ c #101010",
|
||||
"f@ c #616061",
|
||||
"g@ c #626262",
|
||||
"h@ c #232323",
|
||||
"i@ c #373737",
|
||||
"j@ c #5B5959",
|
||||
"k@ c #1E1E1E",
|
||||
"l@ c #2C2C2C",
|
||||
"m@ c #505050",
|
||||
"n@ c #494646",
|
||||
"o@ c #303030",
|
||||
"p@ c #626162",
|
||||
"q@ c #292929",
|
||||
"r@ c #2A2A2A",
|
||||
"s@ c #616060",
|
||||
"t@ c #2D2D2D",
|
||||
"u@ c #575656",
|
||||
"v@ c #363636",
|
||||
"w@ c #3E3E3E",
|
||||
"x@ c #5F5E5E",
|
||||
"y@ c #3A3A3A",
|
||||
"z@ c #242424",
|
||||
"A@ c #343434",
|
||||
"B@ c #383838",
|
||||
"C@ c #474747",
|
||||
"D@ c #4F4D4D",
|
||||
"E@ c #737272",
|
||||
"F@ c #404040",
|
||||
"G@ c #5B5A5A",
|
||||
"H@ c #696869",
|
||||
"I@ c #4E4E4E",
|
||||
"J@ c #3D3C3C",
|
||||
"K@ c #5D5B5C",
|
||||
"L@ c #6A696A",
|
||||
"M@ c #454545",
|
||||
"N@ c #5B595A",
|
||||
"O@ c #6A6969",
|
||||
"P@ c #515050",
|
||||
"Q@ c #595859",
|
||||
"R@ c #656464",
|
||||
"S@ c #413F3F",
|
||||
"T@ c #747373",
|
||||
"U@ c #5F5E5F",
|
||||
"V@ c #605F5F",
|
||||
"W@ c #595858",
|
||||
"X@ c #545252",
|
||||
" . + ",
|
||||
" @ # $ % & * ",
|
||||
" = - ; $ ",
|
||||
" > , ' ) ",
|
||||
" > ! ~ { ] ^ ",
|
||||
" / ( _ : < . ",
|
||||
" [ } | ",
|
||||
" 1 2 3 4 5 6 ",
|
||||
" 7 8 9 0 a b c d e f g h i j k l m n ",
|
||||
" 8 o p q r s t 8 b u v w x y z A B C D E ",
|
||||
" F G s H I J K L M N O P t Q R S T U V W X Y Z ` ...+. @. ",
|
||||
" 7 #.$.%.L L L M N &.%.*.=.-.;.$.>.,.'.).!.~.{.].^./.(._.:. ",
|
||||
" <.[.}.L L |.N 1.2.=.3.4.5.6.7.8.7.s 9.0.a.b.c.d.e.f.g.h.i.j.k. ",
|
||||
" #.I L L l.m.n.I o.p.q.4.[.r.s.t.u.v.G u w.x.y.z.A.B.C.D.E.F.G. ",
|
||||
" #.m.L H.1.I.I.o.*.J.K.H 5.6.7.t.L.M.N.O.u P.S P.Q.R.D.S.T.U.D.V. ",
|
||||
" 8 W.L &.%.o.O *.J.3.X.[.r.Y.Z.`.G 0 +.+Q ++@+0.#+$+D.R.%+&+*+=+ ",
|
||||
" c q.L I.-.=.-.;.3.-+[.;+$.>+r t u.,+b c '+9.)+!+~+R.D.R.R.D.D.{+ ",
|
||||
" )+L.]+o.^+X.^+H /+P (+6._+:+t.<+8 [+}+|+++v 1+2+3+4+D.D.D.D.D.5+6+ ",
|
||||
" 7+8+%.4.8+8+5.(+$.Y.s.Z.p <+u.9+0+a+b+c+d+e+f+R g+w.D.D.D.h+i+j+k+ ",
|
||||
" y.>.l+H 6.m+m+n+7.Z.q `.L.o+M.p+O..+u q+7+e+r+s+t+u+5+D.D.D.D.D.D.v+w+ ",
|
||||
" x+a+y+_+q r q p z+<+<.9 0 a A+B+C+c+D+1+2+!+E+F+G+H+R.D.D.D.D.D.D.I+r+ ",
|
||||
" J+K+L+Z.z+<.o G F 7 M.[+ +N.c M+N+O+P+e+Q+S R+F+S+~+h+D.D.D.D.D.D.D.D.c.T+ ",
|
||||
" U+i+2+t 9 a [+V+A+}+W+c X+>.Y+v )+1+Z+`+J+t+ @x..@+@@@h+@@@@D.D.D.D.D.#@P+ ",
|
||||
" $@%@U+O.0 B+X+|+b+M+'+c+&@*@P+=@@+`+-@F+;@>@c.,@'@j+j+j+j+j+@@D.D.D.D.)@t+ ",
|
||||
"@++@D.!@~@{@.+&@O+O+v d+7+]@@+Q+!+s+3+ @^@g+/@(@'@)@$+$+j+j+$+$+h+R.D.D.D._@:@ ",
|
||||
"J+@@D.D.<@~@D+D+7+1+=@T y.r+S -@R+3+[@x.}@K+#+|@)@$+$+$+)@$+5+%@%@h+D.D.D.$@1@ ",
|
||||
"3+@@D.D.D.2@G+s+3@Q+r+`+S J+F+[@S+g+}@4@5@6@)@$+)@5+5+5+5+%@7@|@+@5+@@D.D.8@E+ ",
|
||||
";@@@D.D.D.D.|@~+U+9@c.g+g+0@P.U+4@a@$@~.5+$+5+5+5+%@%@7@7@|@+@I+'@'@$+D.D.'@b@ ",
|
||||
"b.@@D.D.D.D.R.@@+@c@$@d@#@5@<@H+!@7@$+5+5+5+%@|@+@+@7@+@I+'@6@6@e@a.6@h+D.I+~@ ",
|
||||
"-@)@D.D.D.D.h+h+@@h+j+)@j+$+$+5+$+$+$+5+5+5+7@+@I+I+I+'@~.e@8@a.a.2@2@5+D.e@E+ ",
|
||||
"-@+@D.D.D.D.h+@@h+j+j+)@)@$+$+5+%@%@%@%@7@|@|@+@'@'@6@~.!@!@a.w.w.2@<@7@D.a.f@ ",
|
||||
"g@!@D.D.D.D.h+j+$+$+$+$+$+5+5+%@7@7@7@|@+@I+I+'@~.~.e@!@a.c@2@i+Q.#+h@I+D.#@!+ ",
|
||||
" 5@@@D.D.D.$+$+$+$+5+5+5+%@7@7@|@|@|@+@I+'@e@8@8@c@2@2@H+#+A.<@$@4+a@~.D.i@j@ ",
|
||||
" P.h+D.D.D.5+%@5+%@|@|@+@|@I+I+'@6@~.~.~.e@8@8@c@H+i+Q.#+<@k@4+d@).l@a.@@m@n@ ",
|
||||
" Q+I+D.D.D.$+%@7@|@|@+@I+I+'@'@~.e@e@e@e@8@c@2@H+Q.A.$@k@4+h@~+).l@o@c@6@p@ ",
|
||||
" ++q@@@D.D.%@|@+@I+I++@I+6@e@!@!@8@c@c@c@w.i+A.A.$@5@#@h@~+a@r@l@u+4@a._@s@ ",
|
||||
" k+5+D.D.%@I+~.6@6@6@~.8@8@a.c@w.H+i+H+Q.<@5@5@d@h@).a@l@t@o@0.,.t@6@u@ ",
|
||||
" =@).D.D.)@+@8@!@!@a.c@c@w.2@H+i+#+A.<@k@4+#@h@).q@,@.@_@0.v@z.w@<@4@x@ ",
|
||||
" 3+6@D.R.$+8@2@w.2@H+i+Q.#+#+A.$@5@d@h@~+).a@,@.@o@0.v@y@P.x+K+2@x@ ",
|
||||
" 9@j+D.@@6@Q.A.Q.Q.A.k@5@k@4+#@h@z@(@r@l@K+_@A@v@B@U+C@S+U+w.x.D@ ",
|
||||
" E@i@R.D.)@8@k@#@d@5@d@h@z@~+(@q@a@l@K+4@A@B@'.,.P.x.b./@Q.F@G@ ",
|
||||
" H@4@D.D.$+c@h@r@r@q@(@(@q@,@.@K+_@A@v@y@w@P.g+^@I@B@<@J@K@ ",
|
||||
" L@0.)@D.)@8@#@o@0.0._@_@_@A@v@i@y@F@M@g+m@^@M@l@k@P.N@ ",
|
||||
" O@z.6@D.@@|@A.r@i@w@/@w@F@}@P.0@x+x.x.P..@4+).P@Q@ ",
|
||||
" F+(@+@j+j++@c@#@t@'.}@9@0@G+'..@#@H+z@^@R@S@ ",
|
||||
" R@k+0.|@5+j+)@@@R.D.D.R.R.j+c@u+F+T@ ",
|
||||
" U@s@;@,.z@|@'@)@5+i+d@,.E@ ",
|
||||
" E+V@W@R+W@X@ "};
|
Loading…
Reference in New Issue
Block a user