Not found :(
22 |Sorry, but the page you were trying to view does not exist.
24 |It looks like this was the result of either:
25 |-
26 |
- a mistyped address 27 |
- an out-of-date link 28 |
├── app ├── .htaccess ├── templates │ ├── error.html │ └── sql_table.html ├── data │ ├── base.sqlite3 │ ├── session.sqlite3 │ └── base.dump.sql ├── config.json ├── INSTALL ├── session.php ├── user_data.php └── common.php ├── session └── .htaccess ├── dev ├── img │ ├── .gitignore │ ├── sqmight.png │ ├── sqmight.pxm │ ├── throbber_big.gif │ ├── throbber_small.gif │ ├── dark_linen_brown1.png │ ├── dark_stripes_red1.png │ └── dark_leather_brown1.gif ├── js │ ├── mylibs │ │ └── .gitignore │ ├── libs │ │ └── prettify.min │ │ │ ├── lang-sql.js │ │ │ └── prettify.js │ ├── plugins.js │ └── script.js ├── dump.php ├── schema.pdf ├── favicon.ico ├── css │ ├── style.css │ ├── prettify.css │ ├── sqmight.css │ └── base.css ├── robots.txt ├── create_db.php ├── .htaccess ├── test │ ├── tests.js │ ├── index.html │ └── qunit │ │ ├── qunit.css │ │ └── qunit.js ├── crossdomain.xml ├── 404.html ├── humans.txt ├── query.php ├── about.md ├── index.html └── about.html ├── .htaccess ├── .gitignore ├── LICENSE ├── TODO └── Rakefile /app/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /session/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /dev/img/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | 3 | -------------------------------------------------------------------------------- /dev/js/mylibs/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | 3 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | #TODO: deny from all 2 | php_value open_basedir "/" -------------------------------------------------------------------------------- /dev/dump.php: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /dev/schema.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/schema.pdf -------------------------------------------------------------------------------- /dev/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/favicon.ico -------------------------------------------------------------------------------- /dev/img/sqmight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/sqmight.png -------------------------------------------------------------------------------- /dev/img/sqmight.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/sqmight.pxm -------------------------------------------------------------------------------- /app/data/base.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/app/data/base.sqlite3 -------------------------------------------------------------------------------- /app/data/session.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/app/data/session.sqlite3 -------------------------------------------------------------------------------- /dev/img/throbber_big.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/throbber_big.gif -------------------------------------------------------------------------------- /dev/img/throbber_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/throbber_small.gif -------------------------------------------------------------------------------- /dev/img/dark_linen_brown1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/dark_linen_brown1.png -------------------------------------------------------------------------------- /dev/img/dark_stripes_red1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/dark_stripes_red1.png -------------------------------------------------------------------------------- /dev/css/style.css: -------------------------------------------------------------------------------- 1 | @import url("base.css"); 2 | @import url("sqmight.css"); 3 | @import url("prettify.css"); 4 | -------------------------------------------------------------------------------- /dev/img/dark_leather_brown1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/img/dark_leather_brown1.gif -------------------------------------------------------------------------------- /dev/js/libs/prettify.min/lang-sql.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tag/sqmight/master/dev/js/libs/prettify.min/lang-sql.js -------------------------------------------------------------------------------- /dev/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 3 | 4 | User-agent: * 5 | 6 | -------------------------------------------------------------------------------- /app/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": "development", 3 | "debug": true, 4 | 5 | "user_data_path": "./session/", 6 | "php": { 7 | "date.timezone":"America/New_York", 8 | "display_errors": "On" 9 | } 10 | } -------------------------------------------------------------------------------- /app/INSTALL: -------------------------------------------------------------------------------- 1 | 2 | The following folders must be writeable by the server: 3 | + /app/log 4 | + /app/session 5 | 6 | The following files must be writable by the server: 7 | + /app/data/sessions.sqlite3 8 | 9 | All other files/folders should NOT be writeable by the server 10 | 11 | Some hosts don' allow PHP directives in .htaccess. If this is the case, use the php.ini; if not, delete php.ini. -------------------------------------------------------------------------------- /app/templates/sql_table.html: -------------------------------------------------------------------------------- 1 || '.H($row[$key]).' | '; 14 | } 15 | echo "\n"; 16 | } 17 | ?> 18 | 19 |
Sorry, but the page you were trying to view does not exist.
24 |It looks like this was the result of either:
25 |Query too long (1024 character limit).
'); 9 | return; 10 | }**/ 11 | 12 | $('user_sql').request({ 13 | onComplete: function(response){ 14 | $(qid+'-response').update(response.responseText); 15 | } 16 | }); 17 | 18 | var ppQuery = prettyPrintOne(query.escapeHTML(), 'sql', false); 19 | 20 | var li = new Element('li'); 21 | li.id = qid; 22 | li.update(''
23 | + ppQuery + '');
24 | // style="display:none"
25 | //X
26 |
27 | //TODO slide down new inertion
28 | $('history').insert({top:li});
29 |
30 | // TODO: pop if a size limit is reached? Mask?
31 | },
32 |
33 | delete_history: function () {
34 | if (!confirm("really?")) {return;}
35 | alert(this);
36 | }
37 | };
38 |
39 | document.observe("dom:loaded", function() {
40 | $('user_sql').observe('submit', function(evt) {
41 | evt.stop();
42 |
43 | if (!$('results').visible()) {
44 | Effect.SlideDown('results', { duration: 0.5});
45 | }
46 |
47 | $('sql').value = $F('sql').strip();
48 |
49 | //push sql statement to history and execute
50 | SQM.push($F('sql'), 'output-' +new Date().getTime());
51 | });
52 |
53 | $('user_create_db').show();
54 | $('user_create_db').observe('submit', function(evt) {
55 | evt.stop();
56 |
57 | // Show throbber.
58 | $('create').hide();
59 | $('throbber_create').show();
60 |
61 | //TODO: Should check to see if db is valid, first
62 | $('user_create_db').request({
63 | onSuccess: function(response){
64 | $('entry').remove();
65 | Effect.SlideDown('user_sql', { duration: 0.5});
66 | },
67 | onFailure: function(response){
68 | $('user_create_db').replace( response.responseText
69 | || 'An unknown error occurred.
'); 70 | } 71 | }); 72 | }); 73 | 74 | }); -------------------------------------------------------------------------------- /dev/css/prettify.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Derived from einaros's Sons of Obsidian theme at 3 | * http://studiostyl.es/schemes/son-of-obsidian by 4 | * Alex Ford of CodeTunnel: 5 | * http://CodeTunnel.com/blog/post/71/google-code-prettify-obsidian-theme 6 | * Further tweaks by Tom Gregory, http://alt-tag.com 7 | */ 8 | 9 | .str 10 | { 11 | color: #EC7600; 12 | } 13 | .kwd 14 | { 15 | color: #93C763; 16 | font-weight: bold; 17 | } 18 | .com 19 | { 20 | color: #66747B; 21 | } 22 | .typ 23 | { 24 | color: #678CB1; 25 | } 26 | .lit 27 | { 28 | color: #FACD22; 29 | } 30 | .pun 31 | { 32 | color: #ccc; 33 | } 34 | .pln 35 | { 36 | color: #F1F2F3; 37 | } 38 | .tag 39 | { 40 | color: #8AC763; 41 | } 42 | .atn 43 | { 44 | color: #E0E2E4; 45 | } 46 | .atv 47 | { 48 | color: #EC7600; 49 | } 50 | .dec 51 | { 52 | color: purple; 53 | } 54 | pre.prettyprint 55 | { 56 | border: 0px solid #888; 57 | } 58 | ol.linenums 59 | { 60 | margin-top: 0; 61 | margin-bottom: 0; 62 | } 63 | .prettyprint { 64 | background: #111; 65 | } 66 | li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 67 | { 68 | color: #555; 69 | } 70 | li.L1, li.L3, li.L5, li.L7, li.L9 { 71 | background: #111; 72 | } 73 | @media print 74 | { 75 | .str 76 | { 77 | color: #060; 78 | } 79 | .kwd 80 | { 81 | color: #006; 82 | font-weight: bold; 83 | } 84 | .com 85 | { 86 | color: #600; 87 | font-style: italic; 88 | } 89 | .typ 90 | { 91 | color: #404; 92 | font-weight: bold; 93 | } 94 | .lit 95 | { 96 | color: #044; 97 | } 98 | .pun 99 | { 100 | color: #440; 101 | } 102 | .pln 103 | { 104 | color: #000; 105 | } 106 | .tag 107 | { 108 | color: #006; 109 | font-weight: bold; 110 | } 111 | .atn 112 | { 113 | color: #404; 114 | } 115 | .atv 116 | { 117 | color: #060; 118 | } 119 | } -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | + get it working on Bluehost 2 | + Remove error reporting code from common.php (on Bluehost) 3 | + db create more dummy data! 4 | + sha1 db password 5 | + lower case db email 6 | 7 | + Build automation: Markdown, About page 8 | + About page 9 | + Schema printing 10 | + Remove index's js from md template file 11 | + Create index.html off of md template 12 | + Update Redcloth (instead of PHP-markdown) in about 13 | + update md template to include main, text align left, fix links to amazon, etc. 14 | + Make header a link home (if not index!) 15 | 16 | + remove associated db on session destroy (the whole point of a custom session handler!) 17 | 18 | + Install optipng to enable png optimization in build process. For instructions see 'Dependencies' at: http://html5boilerplate.com/docs/#Build-script#dependencies 19 | 20 | + db reset 21 | 22 | + Add behavior to delete history queries from DOM 23 | + Build automation (rake): minify & concat prettify/lang-sql; include developer-readable js in project 24 | + Trim preffity (e.g., so unused onload event doesn't fire) 25 | + SQL parsing/verification 26 | + sql dump export 27 | + Include query run time in output 28 | + Include character count below query box 29 | 30 | + Add LIMIT to keywords in pretify sql-lang (temporarily added; test/submit ticket/pull request) 31 | + Handle printing of multiline queries; e.g. "SELECT * FROM users -- foo \n LIMIT 5;" 32 | + When packaging: create dummy config.js.example 33 | 34 | + Add html, css, .htaccess comments TODOs to rakefile :todo 35 | + favicon 36 | 37 | AUTO-GENERATED 38 | -------------- 39 | + slide down new inertion (./dev/js/script.js:27) 40 | + pop if a size limit is reached? Mask? (./dev/js/script.js:30) 41 | + Should check to see if db is valid, first (./dev/js/script.js:61) 42 | + implement dump.php (./dev/dump.php:2) 43 | + Validate query — Input checking (./dev/query.php:20) 44 | + better error handling (./dev/query.php:40) 45 | + if not XHR, show full page. (./app/common.php:135) 46 | + fix HTTP status code (./app/common.php:170) 47 | + Verify key, remove associated user db (./app/session.php:112) 48 | + Verify key, remove associated user db (./app/session.php:126) 49 | + Add error logging (./app/user_data.php:17) 50 | + exportUserDb not yet completed (./app/user_data.php:72) 51 | -------------------------------------------------------------------------------- /dev/about.md: -------------------------------------------------------------------------------- 1 | About **sqMight** 2 | ================= 3 | 4 | *sqMight* uses [sqLite](http://www.sqlite.org/) as a backend, and offers each user a unique, temporary database instance. So, yes, go ahead and write those INSERT and UPDATE queries. CREATE or DROP tables. No one will know but you. Your personal database instance will stick around for a couple of hours, then it's kaput. 5 | 6 | *sqMight* is intended for use in learning SQL, and is available under an MIT-style license. 7 | 8 | Items listed in the 'products' table are real items found online. Many are listed at [hackerthings.com](http://hackerthings.com), [thinkgeek.com](http://thinkgeek.com), or [amazon.com](http://amazon.com). None of these shopping sites have any affiliation with this site. 9 | 10 | If you wish to incorporate *sqMight* into your classroom curriculum or research, or otherwise use it commercially, please contact Tom Gregory at tom@alt-tag.com. 11 | 12 | *sqMight* was conceived and built by [Tom Gregory](http://alt-tag.com), based on an idea from [Gove Allen](http://gove.net/home/page1.html) in 2009. 13 | 14 | *sqMight* uses code, ideas, images, or inspiration from the following publicly avaible sources: 15 | 16 | + [Prototype](http://prototypejs.org), by Sam Stephenson 17 | Copyright © 2005–2010; [MIT-style license](https://raw.github.com/sstephenson/prototype/master/LICENSE) 18 | + [Scriptaculous](http://script.aculo.us/), by Thomas Fuchs 19 | Copyright © 2005-2008; [MIT-style license](http://madrobby.github.com/scriptaculous/license/) 20 | + [php-markdown](https://github.com/wolfie/php-markdown), by [Michel Fortin](http://www.michelf.com/) 21 | Copyright © 2004, All rights reserved; BSD-style open license. 22 | + [Markdown](http://daringfireball.net/projects/markdown/), by [John Gruber](http://daringfireball.net/ "Daring Fireball") 23 | Copyright © 2004, All rights reserved; BSD-style open license. 24 | + [Google Code Pretify](http://code.google.com/p/google-code-prettify/), Google 25 | Copyright © 2006; [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0) 26 | + [HTML5 Boilerplate](http://html5boilerplate.com/), Public Domain 27 | + [Modernizr](http://www.modernizr.com/license/), MIT/BSD license 28 | + [Respond.js](https://github.com/scottjehl/Respond/blob/master/README.md), MIT/GPL license 29 | + [Normalize.css](https://github.com/necolas/normalize.css/blob/master/README.md), Public Domain 30 | + Background textures adapted from [subtlepatterns.com](http://subtlepatterns.com) 31 | + Throbbers from [ajaxloader.info](http://ajaxloader.info). 32 | -------------------------------------------------------------------------------- /app/session.php: -------------------------------------------------------------------------------- 1 | , © 2012 5 | * 6 | * Custom session handler; creates/destroys user db instances and session data. 7 | * Implemented as a Singlton. 8 | */ 9 | class SQM_SessionHandler 10 | { 11 | private static $instance; // Singleton 12 | static private $dbPath = './app/data/session.sqlite3'; 13 | private $db; 14 | 15 | private function __construct() { 16 | session_set_save_handler( 17 | array($this, "open"), 18 | array($this, "close"), 19 | array($this, "read"), 20 | array($this, "write"), 21 | array($this, "destroy"), 22 | array($this, "clean")); 23 | 24 | register_shutdown_function('session_write_close'); // Triggers session shutdown before objects are unloaded 25 | session_start(); 26 | } 27 | 28 | public static function singleton() 29 | { 30 | if (!isset(self::$instance)) { 31 | $className = __CLASS__; 32 | self::$instance = new $className; 33 | } 34 | return self::$instance; 35 | } 36 | 37 | public function __clone() { 38 | trigger_error('Clone is not allowed.', E_USER_ERROR); 39 | } 40 | 41 | public function __wakeup() { 42 | trigger_error('Unserializing is not allowed.', E_USER_ERROR); 43 | } 44 | 45 | /*** 46 | * Opens session database for reading. Params not used, but provided per spec. 47 | * See e.g., http://us2.php.net/manual/en/function.session-set-save-handler.php 48 | * 49 | * @param string $save_path 50 | * @param string $session_name 51 | * @return bool success 52 | */ 53 | function open($save_path, $session_name) { 54 | $this->db = new PDO('sqlite:'.self::$dbPath); 55 | 56 | assert($this->db); 57 | 58 | return TRUE; 59 | } 60 | 61 | /*** 62 | * Closes db connection by nulling PDO object 63 | * 64 | * @return bool success 65 | */ 66 | function close() { 67 | $this->db = null; 68 | return TRUE; 69 | } 70 | 71 | /** 72 | * Reads session data. Parsed automatically by PHP 73 | * 74 | * @return string encoded session data; empty string if no data 75 | */ 76 | public function read($id) { 77 | assert($this->db); 78 | 79 | $sql = $this->db->prepare('SELECT data FROM sessions WHERE id = ?'); 80 | $sql->execute(array($id)); 81 | 82 | $data = $sql->fetch(PDO::FETCH_ASSOC); 83 | 84 | return $data === FALSE ? '' : $data['data']; 85 | } 86 | 87 | /** 88 | * Writes session data, which is already encoded by PHP 89 | * 90 | * @param string session id 91 | * @return bool success 92 | */ 93 | 94 | public function write($id, $data) { 95 | assert($this->db); 96 | 97 | $sql = $this->db->prepare('REPLACE INTO sessions (id, access_time, data) VALUES (?, ?, ?)'); 98 | return $sql->execute(array($id, time(), $data)); 99 | } 100 | 101 | /** 102 | * Destroys session data 103 | * 104 | * 105 | * @return bool success; no return value specificed by PHP docs 106 | */ 107 | 108 | public function destroy($id) { 109 | assert($this->db); 110 | 111 | $sql = $this->db->prepare('DELETE FROM sessions WHERE id = ?'); 112 | #TODO: Verify key, remove associated user db 113 | return $sql->execute(array($id)); 114 | } 115 | 116 | /** 117 | * @param int max session lifetime (seconds) 118 | */ 119 | public function clean($max) { 120 | assert($this->db); 121 | 122 | $old = time() - $max; 123 | 124 | $getData = $this->db->prepare('DELETE FROM sessions WHERE access_time < ?'); 125 | 126 | #TODO: Verify key, remove associated user db 127 | 128 | return $getData->execute(array($old)); 129 | } 130 | } 131 | 132 | /*** 133 | 134 | CREATE TABLE sessions 135 | ( 136 | id text NOT NULL, 137 | access_time int DEFAULT 0, 138 | data text DEFAULT '', 139 | PRIMARY KEY (id) 140 | ); 141 | 142 | ***/ 143 | 144 | $GLOBALS['session_handler'] = SQM_SessionHandler::singleton(); 145 | 146 | 147 | -------------------------------------------------------------------------------- /dev/test/qunit/qunit.css: -------------------------------------------------------------------------------- 1 | /** Font Family and Sizes */ 2 | 3 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 4 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial; 5 | } 6 | 7 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 8 | #qunit-tests { font-size: smaller; } 9 | 10 | 11 | /** Resets */ 12 | 13 | #qunit-tests, #qunit-tests li ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | 19 | /** Header */ 20 | 21 | #qunit-header { 22 | padding: 0.5em 0 0.5em 1em; 23 | 24 | color: #fff; 25 | text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px; 26 | background-color: #0d3349; 27 | 28 | border-radius: 15px 15px 0 0; 29 | -moz-border-radius: 15px 15px 0 0; 30 | -webkit-border-top-right-radius: 15px; 31 | -webkit-border-top-left-radius: 15px; 32 | } 33 | 34 | #qunit-banner { 35 | height: 5px; 36 | } 37 | 38 | #qunit-testrunner-toolbar { 39 | padding: 0em 0 0.5em 2em; 40 | } 41 | 42 | #qunit-userAgent { 43 | padding: 0.5em 0 0.5em 2.5em; 44 | background-color: #2b81af; 45 | color: #fff; 46 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 47 | } 48 | 49 | 50 | /** Tests: Pass/Fail */ 51 | 52 | #qunit-tests { 53 | list-style-position: inside; 54 | } 55 | 56 | #qunit-tests li { 57 | padding: 0.4em 0.5em 0.4em 2.5em; 58 | border-bottom: 1px solid #fff; 59 | list-style-position: inside; 60 | } 61 | 62 | #qunit-tests li strong { 63 | cursor: pointer; 64 | } 65 | 66 | #qunit-tests li ol { 67 | margin-top: 0.5em; 68 | padding: 0.5em; 69 | 70 | background-color: #fff; 71 | 72 | border-radius: 15px; 73 | -moz-border-radius: 15px; 74 | -webkit-border-radius: 15px; 75 | 76 | box-shadow: inset 0px 2px 13px #999; 77 | -moz-box-shadow: inset 0px 2px 13px #999; 78 | -webkit-box-shadow: inset 0px 2px 13px #999; 79 | } 80 | 81 | #qunit-tests li li { 82 | margin: 0.5em; 83 | padding: 0.4em 0.5em 0.4em 0.5em; 84 | background-color: #fff; 85 | border-bottom: none; 86 | list-style-position: inside; 87 | } 88 | 89 | /*** Passing Styles */ 90 | 91 | #qunit-tests li li.pass { 92 | color: #5E740B; 93 | background-color: #fff; 94 | border-left: 26px solid #C6E746; 95 | } 96 | 97 | #qunit-tests li.pass { color: #528CE0; background-color: #D2E0E6; } 98 | #qunit-tests li.pass span.test-name { color: #366097; } 99 | 100 | #qunit-tests li li.pass span.test-actual, 101 | #qunit-tests li li.pass span.test-expected { color: #999999; } 102 | 103 | strong b.pass { color: #5E740B; } 104 | 105 | #qunit-banner.qunit-pass { background-color: #C6E746; } 106 | 107 | /*** Failing Styles */ 108 | 109 | #qunit-tests li li.fail { 110 | color: #710909; 111 | background-color: #fff; 112 | border-left: 26px solid #EE5757; 113 | } 114 | 115 | #qunit-tests li.fail { color: #000000; background-color: #EE5757; } 116 | #qunit-tests li.fail span.test-name, 117 | #qunit-tests li.fail span.module-name { color: #000000; } 118 | 119 | #qunit-tests li li.fail span.test-actual { color: #EE5757; } 120 | #qunit-tests li li.fail span.test-expected { color: green; } 121 | 122 | strong b.fail { color: #710909; } 123 | 124 | #qunit-banner.qunit-fail, 125 | #qunit-testrunner-toolbar { background-color: #EE5757; } 126 | 127 | 128 | /** Footer */ 129 | 130 | #qunit-testresult { 131 | padding: 0.5em 0.5em 0.5em 2.5em; 132 | 133 | color: #2b81af; 134 | background-color: #D2E0E6; 135 | 136 | border-radius: 0 0 15px 15px; 137 | -moz-border-radius: 0 0 15px 15px; 138 | -webkit-border-bottom-right-radius: 15px; 139 | -webkit-border-bottom-left-radius: 15px; 140 | } 141 | 142 | /** Fixture */ 143 | 144 | #qunit-fixture { 145 | position: absolute; 146 | top: -10000px; 147 | left: -10000px; 148 | } 149 | -------------------------------------------------------------------------------- /app/user_data.php: -------------------------------------------------------------------------------- 1 | authUserDb() 12 | * 13 | * @return objec|bool PDOConnection on success, else FALSE 14 | **/ 15 | 16 | public function getDbConnection() { 17 | if (!$this->authUserDb()) {return FALSE;} #TODO: Add error logging 18 | 19 | if (!$this->db) { 20 | // Confirm dbName is alphanumeric. (It shouldn't ever change.) 21 | assert(ctype_alnum($_SESSION['dbName'])); 22 | error_log(USER_DATA_PATH.'/'.$_SESSION['dbName'].'.sqlite3'); 23 | try { 24 | $this->db = new PDO( 25 | 'sqlite:'.USER_DATA_PATH.'/'.$_SESSION['dbName'].'.sqlite3'); 26 | } catch (Exception $e) { 27 | error_log('ERROR OPENING USER DB:' . USER_DATA_PATH . 28 | '/'.$_SESSION['dbName'].'.sqlite3'); 29 | throw $e; 30 | } 31 | } 32 | return $this->db; 33 | } 34 | 35 | public function createUserDb() { 36 | // Remove old DB, if exists 37 | $this->destroyUserDb(); 38 | 39 | $_SESSION['dbName'] = $this->generateToken(); 40 | $key = hash_hmac('sha256', $this->generateToken(32) . 41 | (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? 42 | $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']) 43 | , time()); 44 | 45 | setcookie('key', $key, time()+ini_get('session.gc_maxlifetime'), '/'); 46 | 47 | # hash MUST match sha512(key, $dbName) or DB no worky 48 | $_SESSION['auth'] = $this->userHash($key); 49 | 50 | error_log('sqlite3 '.USER_DATA_PATH.'/'.$_SESSION['dbName'] 51 | .'.sqlite3 < ./app/data/base.dump.sql'); 52 | $tmp = exec('sqlite3 '.USER_DATA_PATH.'/'.$_SESSION['dbName'] 53 | .'.sqlite3 < ./app/data/base.dump.sql'); 54 | error_log('Exec output:' . $tmp); 55 | } 56 | 57 | public function destroyUserDb() { 58 | if (!$this->authUserDb()) {return FALSE;} 59 | error_log('SESSION DESTROY: destroyUserDb'); 60 | unlink(USER_DATA_PATH.'/'.$_SESSION['dbName'].'.sqlite3'); 61 | 62 | setcookie('key', '', time() - 3600, '/'); // Negative time deletes cookie 63 | 64 | $_SESSION = array(); // Clean out session variables 65 | if (session_id() != '') { 66 | session_destroy(); 67 | session_start(); 68 | } 69 | } 70 | 71 | public function exportUserDb() { 72 | assert(FALSE); //TODO: exportUserDb not yet completed 73 | if (!$this->authUserDb()) {return FALSE;} 74 | 75 | $tmp = exec('sqlite3 '.USER_DATA_PATH.'/'.$_SESSION['dbName'].'.sqlite3 .dump'); 76 | 77 | echo $tmp; 78 | } 79 | 80 | 81 | /** 82 | * Relies on $_SESSION['dbName'], session auth token, and user's 'key' cookie 83 | * @return bool success 84 | */ 85 | public function authUserDb() { 86 | if (!isset($_SESSION['dbName']) 87 | || ! isset($_SESSION['auth']) 88 | || ! isset($_COOKIE['key'])) {return FALSE;} 89 | 90 | // Update timestamp on hash cookie 91 | setcookie('key', $_COOKIE['key'], time()+ini_get('session.gc_maxlifetime'), '/'); 92 | 93 | // hash MUST match sha512(key . IP_addr, $dbName) or DB doesn't authenticate 94 | $hash = $this->userHash($_COOKIE['key']); 95 | 96 | return $hash === $_SESSION['auth']; 97 | } 98 | 99 | /** 100 | * @param string has of user supplied key + IP address using dbName 101 | * @return bool success 102 | */ 103 | protected function userHash($key) { 104 | return hash_hmac('sha512', $key . 105 | (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? 106 | $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']) 107 | , $_SESSION['dbName']); 108 | } 109 | 110 | /** 111 | * @param int token length 112 | * @return string random token 113 | */ 114 | protected function generateToken($len = 20) { 115 | $chars = array(0,1,2,3,4,5,6,7,8,9,0, 116 | 'a','b','c','d','e','f','g','h','i','j','k','m', 117 | 'n','o','p','q','r','s','t','u','v','w','x','y','z'); 118 | shuffle($chars); 119 | return implode('', array_slice($chars, 0, $len)); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
101 |
102 |
103 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | #task :default => [ :clean, :fresh_scriptaculous, :package ]
2 |
3 | # task :clean do
4 | # rm_rf PKG_DESTINATION
5 | # end
6 |
7 | #task :default => [ :jslint ]
8 | task :default => [ :md ]
9 |
10 |
11 | # task :build => [ :basics_production ]
12 | # task :test => [ :basics_test ]
13 | # task :dev => [ :basics_dev
14 |
15 |
16 | dir = { :source => '.',
17 | :publish => 'publish',
18 | :js => 'js',
19 | }
20 | dir[:js_lib] = File.join(dir[:js], 'lib')
21 | dir[:dev] = File.join(dir[:source], 'dev')
22 | dir[:build] = File.join(dir[:source], 'build')
23 | dir[:build_tools] = File.join(dir[:build], 'tools')
24 | dir[:build_templates] = File.join(dir[:build], 'templates')
25 |
26 | #http://www.jslint.com/lint.html
27 | opt = {}
28 | opt[:jslint] = 'maxerr=25,evil=true,browser=true,eqeqeq=true,immed=true,newcap=true,nomen=true,es5=true,rhino=true,undef=true,white=false'
29 |
30 | summary = []
31 |
32 | desc "Run jslint on dev js files"
33 | task :jslint do #=> :summary
34 | fl = FileList.new(File.join( dir[:dev], dir[:js], '**', '*.js'))
35 | fl.exclude('*.min.js.');
36 | fl.exclude(File.join(dir[:dev], dir[:js_lib]))
37 | fl.each {|file|
38 | puts "== jslint on #{file}"
39 | sh "java -jar #{File.join(dir[:build_tools], 'rhino.jar')} #{File.join(dir[:build_tools], 'fulljslint.js')} #{file} #{opt[:jslint]}" do |ok, res|
40 | if !ok
41 | summary.push "jslint: Errors found in #{file}"
42 | end
43 | end
44 | }
45 | end
46 |
47 | # task :summary do
48 | # puts 'SUMMARY'
49 | # summary.each {|s| puts s}
50 | # end
51 |
52 | desc "Searches code files for TODOs, appends to TODO file"
53 | task :todo do
54 | todo = File.join(dir[:source],'TODO')
55 | content = File.read(todo)
56 | content.gsub!(/\nAUTO(-GENERATED)?\n-+\n.*/m, "\n")
57 |
58 | puts content
59 | File.open(todo, 'w') do |f|
60 | f.puts content, "AUTO-GENERATED\n--------------\n"
61 |
62 | fl = FileList.new(File.join( dir[:dev], '**', '*.{js,php,rb,bash}'))
63 | fl.exclude('*.min.js.')
64 | fl.exclude(File.join(dir[:dev], dir[:js_lib]))
65 | fl.include(File.join(dir[:source], '*.{js,php,rb,bash}'))
66 |
67 | fl.include(File.join(dir[:source], 'app','**','*.{js,php,rb,bash}'))
68 |
69 | pattern = /(\/\/|#)\s*TODO:?\s+(.+)$/
70 | fl.each do |file|
71 | File.open(file) do |grep_file|
72 | grep_file.each do |line|
73 | f.puts "+ #{$2} (#{file}:#{grep_file.lineno.to_s})" if pattern.match(line)
74 | end
75 | end
76 | end
77 | end
78 | end
79 |
80 | # jshint
81 | # csslint
82 | # build => -build.production
83 | # -build.production => ["-rev,
84 | # -usemin,
85 | # -js.all.minify,
86 | # -js.main.concat,
87 | # -js.mylibs.concat,
88 | # -js.scripts.concat,
89 | # -css,
90 | # -manifest,
91 | # -htmlclean,
92 | # -imagespng,
93 | # -imagesjpg,
94 | # -copy]
95 |
96 | # minify => -minify.production
97 |
98 | # namespace :js
99 | # task :minify_prototype do
100 | # end
101 | # end
102 |
103 | # namespace :md
104 | # require 'rubygems'
105 | # require 'redcarpet'
106 | # markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
107 | # :autolink => true, :strikethrough => true)
108 | #
109 |
110 | # rule ".html" => [".markdown", ".md"] do |t|
111 | MD = FileList[File.join( dir[:dev], '*.{md,markdown}')]
112 | HTML = MD.ext('html')
113 | #
114 | # #rule File.join(dir[:dev], 'about.html') => [File.join(dir[:dev], 'about.md')] do |t|
115 | #rule HTML => MD do
116 | rule File.join( dir[:dev], 'about.html') => File.join( dir[:dev], 'about.md') do |t|
117 | puts "#{t.source} RULE"
118 | mdfile_to_html t.source, File.join(dir[:build_templates] , "base.html.erb")
119 | # # sh "markdown #{t.source} > #{t.name}"
120 | end
121 |
122 | desc "markdown"
123 | task :md => [File.join( dir[:dev], 'about.html').to_s] do |t|
124 | # puts "#{t.source} to md"
125 | # file_to_html File.join( dir[:dev], 'about.md')
126 | end
127 | #
128 | # task :all do
129 | #
130 | # end
131 | # end
132 |
133 | require "erb"
134 | require "rubygems"
135 | #require "rdiscount"
136 | require 'redcarpet'
137 |
138 | def mdfile_to_html(file, template_file)
139 | basename = File.basename(file, ".md")
140 | # template_file =
141 | output_file = File.join(File.dirname(file), "#{basename}.html")
142 |
143 | begin
144 | @template = nil
145 | pre_body = ERB.new(File.open(file).read).result
146 | # @body = RDiscount.new(pre_body).to_html
147 | markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
148 | :autolink => true, :strikethrough => true)
149 | @body = markdown.render(pre_body)
150 |
151 | if @template # may be defined in .md file.
152 | template_file = @template
153 | end
154 |
155 | if File.exists? template_file
156 | template = File.open(template_file).read
157 | else
158 | template = %q{
159 |
160 |
161 |
162 | <%= @body %>
163 |
164 |
165 | }
166 | puts 'OOPS'
167 | # TODO: ERROR if template not found
168 | end
169 |
170 | File.open(output_file, "w") do |f|
171 | f.write ""
172 | f.write ERB.new(template).result
173 | end
174 | puts "#{file} => #{output_file}"
175 | rescue => e
176 | puts "Error while working with file \"#{file}\":"
177 | puts " - #{e.message}"
178 | end
179 | end
180 |
--------------------------------------------------------------------------------
/app/common.php:
--------------------------------------------------------------------------------
1 | $val) {
22 | ini_set($key, $val);
23 | }
24 |
25 | define ("DEBUG",
26 | isset($GLOBALS['CONFIG']['debug']) && $GLOBALS['CONFIG']['debug']);
27 |
28 | define ("USER_DATA_PATH", isset($GLOBALS['config']['user_data_path']) ?
29 | $GLOBALS['config']['user_data_path'] : './session');
30 |
31 | // --------------------
32 | // Assertions
33 | // --------------------
34 | function _assertCallback($file, $line, $code) {
35 | $trace = print_r(debug_backtrace(), true);
36 | error_log($trace);
37 |
38 | $dt = new DateTime();
39 | $dt_out = $dt->format(DateTime::ISO8601);
40 |
41 | $details = <<sqMight uses sqLite as a backend, and offers each user a unique, temporary database instance. So, yes, go ahead and write those INSERT and UPDATE queries. CREATE or DROP tables. No one will know but you. Your personal database instance will stick around for a couple of hours, then it's kaput.
55 | 56 |sqMight is intended for use in learning SQL, and is available under an MIT-style license.
57 | 58 |Items listed in the 'products' table are real items found online. Many are listed at hackerthings.com, thinkgeek.com, or amazon.com. None of these shopping sites have any affiliation with this site.
59 | 60 |If you wish to incorporate sqMight into your classroom curriculum or research, or otherwise use it commercially, please contact Tom Gregory at tom@alt-tag.com.
61 | 62 |sqMight was conceived and built by Tom Gregory, based on an idea from Gove Allen in 2009.
63 | 64 |sqMight uses code, ideas, images, or inspiration from the following publicly avaible sources:
65 | 66 |
108 |
109 |
110 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/dev/css/sqmight.css:
--------------------------------------------------------------------------------
1 | body {
2 | background:#322F0C url('../img/dark_leather_brown1.gif') top left;
3 | padding: 10px 10px 10px 160px;
4 | min-width:760px;
5 | position: relative;
6 | }
7 |
8 | #main {
9 | width: 100%;
10 | }
11 |
12 | #ribbon {
13 | position: absolute;
14 | left: 15px;
15 | top: 0;
16 | width: 120px;
17 |
18 | color: #E0DDCD;
19 | background:#7A1111 url('../img/dark_stripes_red1.png') top left;
20 |
21 | font-size: 14px;
22 |
23 | text-shadow: 0px 1px 2px #000;
24 |
25 | -moz-box-shadow: 0px 4px 12px #000;
26 | -webkit-box-shadow: 0px 4px 12px #000;
27 | box-shadow: 0px 4px 12px #000;
28 | }
29 |
30 | #ribbon ul#menu {
31 | position:relative;
32 | margin-top: 2px;
33 | border-top: 1px dotted #E0DDCD;
34 | border-bottom: 1px dotted #E0DDCD;
35 | }
36 |
37 | #ribbon ul {
38 | margin: 2px 5px 5px 5px; padding: 4px 0;
39 | list-style-type: none;
40 | text-align:center;
41 | }
42 | #ribbon li {
43 | margin: 2px 0 2px 0; padding:0;
44 | }
45 |
46 | #ribbon a:link, #ribbon a:visited {
47 | display: block;
48 | padding: 2px 0;
49 | width 100%;
50 | font-weight: bold;
51 | color: #E0DDCD;
52 | text-decoration:none;
53 | -webkit-border-radius: 6px;
54 | -moz-border-radius: 6px;
55 | border-radius: 6px;
56 | }
57 |
58 | #ribbon a:hover, #ribbon a:active {
59 | color: rgb(224,218,96);
60 | color: white;
61 | text-decoration: underline;
62 | background-color: rgba(224,221,205, .10);
63 | }
64 |
65 | #ribbon footer {
66 | font-size: 11px;
67 | }
68 |
69 | #banner img {
70 | position:relative;
71 | margin: 0 0 0 15px;
72 | }
73 |
74 | .content {
75 | width: 75%;
76 | background-color: #E0DDCD;
77 | padding: 5px 15px 15px 15px;
78 | font-size: 120%;
79 | margin: 15px auto;
80 | border: 1px solid #111;
81 |
82 | -webkit-border-radius: 10px 10px 10px 10px;
83 | -moz-border-radius: 10px 10px 10px 10px;
84 | border-radius: 10px 10px 10px 10px;
85 |
86 | -moz-box-shadow: inset 2px 2px 6px #111;
87 | -webkit-box-shadow: inset 2px 2px 6px #111;
88 | box-shadow: inset 2px 2px 6px #111;
89 | }
90 |
91 | #entry {
92 | width: 50%;
93 | background-color: #E0DDCD;
94 | padding: 5px 15px 15px 15px;
95 | text-align:center;
96 | font-size: 120%;
97 | margin: 15px auto;
98 | border: 1px solid #111;
99 |
100 | -webkit-border-radius: 10px 10px 10px 10px;
101 | -moz-border-radius: 10px 10px 10px 10px;
102 | border-radius: 10px 10px 10px 10px;
103 |
104 | -moz-box-shadow: inset 2px 2px 6px #111;
105 | -webkit-box-shadow: inset 2px 2px 6px #111;
106 | box-shadow: inset 2px 2px 6px #111;
107 | }
108 | #entry h2{
109 | color: #1F1A07 /** #322F0C **/ ;
110 | font-size: 20pt;
111 | text-shadow: rgba(0,0,0,0.5) -1px 0, rgba(0,0,0,0.3) 0 -1px, rgba(255,255,255,0.5) 0 1px, rgba(0,0,0,0.3) -1px -1px;
112 | }
113 | #create {
114 | padding:20px;
115 | }
116 |
117 |
118 | table.sql-output td, table.sql-output th {
119 | padding: 4px;
120 | border: 1px solid #999;
121 | }
122 |
123 | table.sql-output th {
124 | background-color: #dfdfdf;
125 | }
126 |
127 | #sql {
128 | margin:0 auto;
129 | padding: 4px;
130 | width: 80%;
131 | font-family: Inconsolata, Consolas, Monaco, 'Courier New';
132 | font-size: 12pt;
133 | -webkit-border-radius: 8px;
134 | -moz-border-radius: 8px;
135 | border-radius: 8px;
136 | }
137 |
138 | #history {
139 | margin: 2px 0; padding: 0;
140 | list-style-type: none;
141 | }
142 |
143 | #history a {
144 | float: right;
145 | }
146 | pre {
147 | padding:5px;
148 | font-size: 11pt;
149 | font-family: Inconsolata, Consolas, Monaco, 'Courier New';
150 | }
151 |
152 | #history pre {
153 | margin: 0;
154 | -webkit-border-radius: 6px 6px 0 0;
155 | -moz-border-radius: 6px 6px 0 0;
156 | border-radius: 6px 6px 0 0;
157 |
158 | -moz-box-shadow: 0px 2px 8px #000;
159 | -webkit-box-shadow: 0px 2px 8px #000;
160 | box-shadow: 0px 2px 8px #000;
161 | }
162 | #history li {
163 | margin-bottom: 12px;
164 |
165 | }
166 |
167 | #history li div.response {
168 | padding: 4px;
169 | background-color: #E0DDCD;
170 |
171 | -webkit-border-radius: 0 0 6px 6px;
172 | -moz-border-radius: 0 0 6px 6px;
173 | border-radius: 0 0 6px 6px;
174 |
175 | -moz-box-shadow: 0px 2px 8px #000;
176 | -webkit-box-shadow: 0px 2px 8px #000;
177 | box-shadow: 0px 2px 8px #000;
178 | }
179 |
180 | #history li div.response p {
181 | padding: 0 6px;
182 | }
183 |
184 |
185 | /***
186 | Button
187 | ***/
188 | button, input.button {
189 | display: inline-block;
190 | white-space: nowrap;
191 | background-color: #ccc;
192 | background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#ccc));
193 | background-image: -webkit-linear-gradient(top, #eee, #ccc);
194 | background-image: -moz-linear-gradient(top, #eee, #ccc);
195 | background-image: -ms-linear-gradient(top, #eee, #ccc);
196 | background-image: -o-linear-gradient(top, #eee, #ccc);
197 | background-image: linear-gradient(top, #eee, #ccc);
198 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#cccccc');
199 | border: 1px solid #777;
200 | padding: 0 1.5em;
201 | margin: 0.5em;
202 | font-weight: bold;
203 | font-size: 14pt;
204 | text-decoration: none;
205 | color: #333;
206 | text-shadow: 0 1px 0 rgba(255,255,255,.8);
207 | -moz-border-radius: .2em;
208 | -webkit-border-radius: .2em;
209 | border-radius: .2em;
210 | -moz-box-shadow: 0 0 1px 1px rgba(255,255,255,.8) inset, 0 1px 0 rgba(0,0,0,.3);
211 | -webkit-box-shadow: 0 0 1px 1px rgba(255,255,255,.8) inset, 0 1px 0 rgba(0,0,0,.3);
212 | box-shadow: 0 0 1px 1px rgba(255,255,255,.8) inset, 0 1px 0 rgba(0,0,0,.3);
213 | }
214 |
215 | button:hover, input.button:hover {
216 | background-color: #ddd;
217 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#ddd));
218 | background-image: -webkit-linear-gradient(top, #fafafa, #ddd);
219 | background-image: -moz-linear-gradient(top, #fafafa, #ddd);
220 | background-image: -ms-linear-gradient(top, #fafafa, #ddd);
221 | background-image: -o-linear-gradient(top, #fafafa, #ddd);
222 | background-image: linear-gradient(top, #fafafa, #ddd);
223 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa', EndColorStr='#dddddd');
224 | }
225 |
226 | button:active, input.button:active {
227 | -moz-box-shadow: 0 0 4px 2px rgba(0,0,0,.3) inset;
228 | -webkit-box-shadow: 0 0 4px 2px rgba(0,0,0,.3) inset;
229 | box-shadow: 0 0 4px 2px rgba(0,0,0,.3) inset;
230 | position: relative;
231 | top: 1px;
232 | }
233 |
234 | button:focus, input.button:focus {
235 | outline: 0;
236 | background: #fafafa;
237 | }
238 |
239 | button:before, input.button:before {
240 | background: #ccc;
241 | background: rgba(0,0,0,.1);
242 | float: left;
243 | width: 1em;
244 | text-align: center;
245 | font-size: 1.5em;
246 | margin: 0 1em 0 -1em;
247 | padding: .2em .2em;
248 | -moz-box-shadow: 1px 0 0 rgba(0,0,0,.5), 2px 0 0 rgba(255,255,255,.5);
249 | -webkit-box-shadow: 1px 0 0 rgba(0,0,0,.5), 2px 0 0 rgba(255,255,255,.5);
250 | box-shadow: 1px 0 0 rgba(0,0,0,.5), 2px 0 0 rgba(255,255,255,.5);
251 | -moz-border-radius: .15em 0 0 .15em;
252 | -webkit-border-radius: .15em 0 0 .15em;
253 | border-radius: .15em 0 0 .15em;
254 | pointer-events: none;
255 | }
256 |
257 | /* Hexadecimal entities for the icons */
258 | button:before, input.button:before {
259 | content: "\25B6";
260 | }
261 |
262 | .error {
263 | color:rgb(128,0,0);
264 | }
265 |
266 | noscript {
267 | padding: 6px 10px;
268 | background-color:#BBA192;
269 | background-color: rgba(128,0,0,.15);
270 | color:rgb(128,0,0);
271 | border: 2px solid rgb(128,0,0);
272 | -webkit-border-radius: 8px;
273 | -moz-border-radius: 8px;
274 | border-radius: 8px;
275 | }
--------------------------------------------------------------------------------
/dev/css/base.css:
--------------------------------------------------------------------------------
1 | /*
2 | * HTML5 ✰ Boilerplate
3 | *
4 | * What follows is the result of much research on cross-browser styling.
5 | * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
6 | * Kroc Camen, and the H5BP dev community and team.
7 | *
8 | * Detailed information about this CSS: h5bp.com/css
9 | *
10 | * ==|== normalize ==========================================================
11 | */
12 |
13 |
14 | /* =============================================================================
15 | HTML5 display definitions
16 | ========================================================================== */
17 |
18 | article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
19 | audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
20 | audio:not([controls]) { display: none; }
21 | [hidden] { display: none; }
22 |
23 | /* =============================================================================
24 | Base
25 | ========================================================================== */
26 |
27 | /*
28 | * 1. Correct text resizing oddly in IE6/7 when body font-size is set using em units
29 | * 2. Force vertical scrollbar in non-IE
30 | * 3. Prevent iOS text size adjust on device orientation change, without disabling user zoom: h5bp.com/g
31 | */
32 |
33 | html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
34 |
35 | body { margin: 0; font-size: 13px; line-height: 1.231; }
36 |
37 | body, button, input, select, textarea { font-family: sans-serif; color: #222; }
38 |
39 | /*
40 | * Remove text-shadow in selection highlight: h5bp.com/i
41 | * These selection declarations have to be separate
42 | * Also: hot pink! (or customize the background color to match your design)
43 | */
44 |
45 | /* #TODO: Fix selection color; for now, default to user preference
46 | ::-moz-selection { background: #fe57a1; color: #fff; text-shadow: none; }
47 | ::selection { background: #fe57a1; color: #fff; text-shadow: none; }
48 | */
49 |
50 | /* =============================================================================
51 | Links
52 | ========================================================================== */
53 |
54 | a { color: #00e; }
55 | a:visited { color: #551a8b; }
56 | a:hover { color: #06e; }
57 | a:focus { outline: thin dotted; }
58 |
59 | /* Improve readability when focused and hovered in all browsers: h5bp.com/h */
60 | a:hover, a:active { outline: 0; }
61 |
62 |
63 | /* =============================================================================
64 | Typography
65 | ========================================================================== */
66 |
67 | abbr[title] { border-bottom: 1px dotted; }
68 |
69 | b, strong { font-weight: bold; }
70 |
71 | blockquote { margin: 1em 40px; }
72 |
73 | dfn { font-style: italic; }
74 |
75 | hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
76 |
77 | ins { background: #ff9; color: #000; text-decoration: none; }
78 |
79 | mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
80 |
81 | /* Redeclare monospace font family: h5bp.com/j */
82 | pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 1em; }
83 |
84 | /* Improve readability of pre-formatted text in all browsers */
85 | pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
86 |
87 | q { quotes: none; }
88 | q:before, q:after { content: ""; content: none; }
89 |
90 | small { font-size: 85%; }
91 |
92 | /* Position subscript and superscript content without affecting line-height: h5bp.com/k */
93 | sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
94 | sup { top: -0.5em; }
95 | sub { bottom: -0.25em; }
96 |
97 |
98 | /* =============================================================================
99 | Lists
100 | ========================================================================== */
101 |
102 | ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
103 | dd { margin: 0 0 0 40px; }
104 | nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
105 |
106 |
107 | /* =============================================================================
108 | Embedded content
109 | ========================================================================== */
110 |
111 | /*
112 | * 1. Improve image quality when scaled in IE7: h5bp.com/d
113 | * 2. Remove the gap between images and borders on image containers: h5bp.com/e
114 | */
115 |
116 | img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
117 |
118 | /*
119 | * Correct overflow not hidden in IE9
120 | */
121 |
122 | svg:not(:root) { overflow: hidden; }
123 |
124 |
125 | /* =============================================================================
126 | Figures
127 | ========================================================================== */
128 |
129 | figure { margin: 0; }
130 |
131 |
132 | /* =============================================================================
133 | Forms
134 | ========================================================================== */
135 |
136 | form { margin: 0; }
137 | fieldset { border: 0; margin: 0; padding: 0; }
138 |
139 | /* Indicate that 'label' will shift focus to the associated form element */
140 | label { cursor: pointer; }
141 |
142 | /*
143 | * 1. Correct color not inheriting in IE6/7/8/9
144 | * 2. Correct alignment displayed oddly in IE6/7
145 | */
146 |
147 | legend { border: 0; *margin-left: -7px; padding: 0; }
148 |
149 | /*
150 | * 1. Correct font-size not inheriting in all browsers
151 | * 2. Remove margins in FF3/4 S5 Chrome
152 | * 3. Define consistent vertical alignment display in all browsers
153 | */
154 |
155 | button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
156 |
157 | /*
158 | * 1. Define line-height as normal to match FF3/4 (set using !important in the UA stylesheet)
159 | * 2. Correct inner spacing displayed oddly in IE6/7
160 | */
161 |
162 | button, input { line-height: normal; *overflow: visible; }
163 |
164 | /*
165 | * Reintroduce inner spacing in 'table' to avoid overlap and whitespace issues in IE6/7
166 | */
167 |
168 | table button, table input { *overflow: auto; }
169 |
170 | /*
171 | * 1. Display hand cursor for clickable form elements
172 | * 2. Allow styling of clickable form elements in iOS
173 | */
174 |
175 | button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; }
176 |
177 | /*
178 | * Consistent box sizing and appearance
179 | */
180 |
181 | input[type="checkbox"], input[type="radio"] { box-sizing: border-box; }
182 | input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
183 | input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
184 |
185 | /*
186 | * Remove inner padding and border in FF3/4: h5bp.com/l
187 | */
188 |
189 | button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
190 |
191 | /*
192 | * 1. Remove default vertical scrollbar in IE6/7/8/9
193 | * 2. Allow only vertical resizing
194 | */
195 |
196 | textarea { overflow: auto; vertical-align: top; resize: vertical; }
197 |
198 | /* Colors for form validity */
199 | input:valid, textarea:valid { }
200 | input:invalid, textarea:invalid { background-color: #f0dddd; }
201 |
202 |
203 | /* =============================================================================
204 | Tables
205 | ========================================================================== */
206 |
207 | table { border-collapse: collapse; border-spacing: 0; }
208 | td { vertical-align: top; }
209 |
210 |
211 | /* ==|== primary styles =====================================================
212 | Author:
213 | ========================================================================== */
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 | /* ==|== non-semantic helper classes ========================================
231 | Please define your styles before this section.
232 | ========================================================================== */
233 |
234 | /* For image replacement */
235 | .ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; }
236 | .ir br { display: none; }
237 |
238 | /* Hide from both screenreaders and browsers: h5bp.com/u */
239 | .hidden { display: none !important; visibility: hidden; }
240 |
241 | /* Hide only visually, but have it available for screenreaders: h5bp.com/v */
242 | .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
243 |
244 | /* Extends the .visuallyhidden class to allow the element to be focusable when navigated to via the keyboard: h5bp.com/p */
245 | .visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
246 |
247 | /* Hide visually and from screenreaders, but maintain layout */
248 | .invisible { visibility: hidden; }
249 |
250 | /* Contain floats: h5bp.com/q */
251 | .clearfix:before, .clearfix:after { content: ""; display: table; }
252 | .clearfix:after { clear: both; }
253 | .clearfix { zoom: 1; }
254 |
255 |
256 |
257 | /* ==|== media queries ======================================================
258 | PLACEHOLDER Media Queries for Responsive Design.
259 | These override the primary ('mobile first') styles
260 | Modify as content requires.
261 | ========================================================================== */
262 |
263 | @media only screen and (min-width: 480px) {
264 | /* Style adjustments for viewports 480px and over go here */
265 |
266 | }
267 |
268 | @media only screen and (min-width: 768px) {
269 | /* Style adjustments for viewports 768px and over go here */
270 |
271 | }
272 |
273 |
274 |
275 | /* ==|== print styles =======================================================
276 | Print styles.
277 | Inlined to avoid required HTTP connection: h5bp.com/r
278 | ========================================================================== */
279 |
280 | @media print {
281 | * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */
282 | a, a:visited { text-decoration: underline; }
283 | a[href]:after { content: " (" attr(href) ")"; }
284 | abbr[title]:after { content: " (" attr(title) ")"; }
285 | .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */
286 | pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
287 | thead { display: table-header-group; } /* h5bp.com/t */
288 | tr, img { page-break-inside: avoid; }
289 | img { max-width: 100% !important; }
290 | @page { margin: 0.5cm; }
291 | p, h2, h3 { orphans: 3; widows: 3; }
292 | h2, h3 { page-break-after: avoid; }
293 | }
294 |
--------------------------------------------------------------------------------
/dev/js/libs/prettify.min/prettify.js:
--------------------------------------------------------------------------------
1 | // (c) Google 2006; Apache 2 license
2 | // http://code.google.com/p/google-code-prettify
3 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
4 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
5 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c