From: Maxious
Date: Wed, 28 Mar 2012 23:13:02 +0000
Subject: Add start of metadata extract
X-Git-Url: https://maxious.lambdacomplex.org/git/?p=disclosr.git&a=commitdiff&h=f7e996f7d620a6eb4f3ee6f45d98dc403e75d5fd
---
Add start of metadata extract
Former-commit-id: 51210e2d4385a4942d9d7a380a4c16c16811f98b
---
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,9 +4,6 @@
[submodule "couchdb/settee"]
path = couchdb/settee
url = https://github.com/inadarei/settee.git
-[submodule "lib/springy"]
- path = lib/springy
- url = https://github.com/dhotson/springy.git
[submodule "lib/php-diff"]
path = lib/php-diff
url = https://github.com/chrisboulton/php-diff.git
@@ -16,4 +13,13 @@
[submodule "javascripts/flotr2"]
path = javascripts/flotr2
url = https://github.com/HumbleSoftware/Flotr2.git
+[submodule "lib/phpquery"]
+ path = lib/phpquery
+ url = https://github.com/TobiaszCudnik/phpquery.git
+[submodule "javascripts/sigma"]
+ path = javascripts/sigma
+ url = https://github.com/jacomyal/sigma.js.git
+[submodule "javascripts/bubbletree"]
+ path = javascripts/bubbletree
+ url = https://github.com/okfn/bubbletree.git
--- a/admin/exportEmployees.csv.php
+++ b/admin/exportEmployees.csv.php
@@ -22,6 +22,7 @@
if (isset($row->value->statistics->employees)) {
$headers = array_unique(array_merge($headers, array_keys(object_to_array($row->value->statistics->employees))));
+
}
}
} catch (SetteeRestClientException $e) {
--- /dev/null
+++ b/admin/exportScore.csv.php
@@ -1,1 +1,73 @@
+get_db('disclosr-agencies');
+$format = "csv";
+//$format = "json";
+if (isset($_REQUEST['format'])) $format = $_REQUEST['format'];
+
+setlocale(LC_CTYPE, 'C');
+
+ $headers = Array();
+
+$fp = fopen('php://output', 'w');
+if ($fp && $db) {
+ if ($format == "csv") {
+ header('Content-Type: text/csv; charset=utf-8');
+ header('Content-Disposition: attachment; filename="export.score.' . date("c") . '.csv"');
+ }
+ header('Pragma: no-cache');
+ header('Expires: 0');
+
+ try {
+ $agencies = $db->get_view("score", "score", null, true)->rows;
+ //print_r($agencies);
+ $first = true;
+ if ($format == "json") {
+ echo '"data" : ['.PHP_EOL;
+
+ }
+ foreach ($agencies as $agency) {
+ $agencyArray = object_to_array($agency->value);
+ if ($first) {
+ $headers = array_keys($agencyArray);
+if ($format == "csv") {
+ fputcsv($fp, $headers);
+ } else if ($format == "json") {
+ echo '{
+ "labels" : ["' . implode('","', $headers) . '"],'.PHP_EOL;
+ }
+ }
+ $row = Array();
+
+ foreach ($headers as $i => $fieldName) {
+ if (isset($agencyArray[$fieldName])) {
+ $row[] = $agencyArray[$fieldName];
+ } else {
+ $row[] = '';
+ }
+ }
+ if ($format == "csv") {
+ fputcsv($fp, array_values($row));
+ } else if ($format == "json") {
+ if (!$first) echo ",";
+ echo '{"data" : [' . implode(",", array_values($row)) . '], "label": "'.$agency->value->name.'", "lines" : { "show" : true }, "points" : { "show" : true }}'.PHP_EOL;
+
+ }
+ $first = false;
+ }
+
+ if ($format == "json") {
+ echo ']
+ }'.PHP_EOL;
+
+ }
+ } catch (SetteeRestClientException $e) {
+ setteErrorHandler($e);
+ }
+
+ die;
+}
+?>
+
--- /dev/null
+++ b/admin/importAustraliaGovAuGov2.php
@@ -1,1 +1,61 @@
+get_db('disclosr-agencies');
+$rows = $db->get_view("app", "byName")->rows;
+$nametoid = Array();
+$accounts = Array();
+foreach ($rows as $row) {
+ $nametoid[trim($row->key)] = $row->value;
+}
+
+function extractCSVAccounts($url, $nameField, $accountField, $filter) {
+ global $accounts, $nametoid;
+ $request = Requests::get($url);
+ $Data = str_getcsv($request->body, "\n"); //parse the rows
+ $headers = Array();
+ foreach ($Data as $num => $line) {
+ $Row = str_getcsv($line, ",");
+ if ($num == 0) {
+
+ } else if ($num == 1) {
+ $headers = $Row;
+ //print_r($headers);
+ } else {
+ if (isset($Row[array_search($nameField, $headers)])) {
+ $agencyName = $Row[array_search($nameField, $headers)];
+ if (!$filter || $Row[array_search("State", $headers)] == "NAT") {
+ if (!in_array(trim($agencyName), array_keys($nametoid))) {
+ echo "$agencyName missing" . PHP_EOL;
+ } else {
+ // echo $Row[array_search($nameField, $headers)] . PHP_EOL;
+ }
+ }
+ } else {
+ //echo "error finding agency" . $line . PHP_EOL;
+ }
+ }
+ }
+}
+
+// http://agimo.govspace.gov.au/page/gov2register/
+// twitter
+//extractCSVAccounts("https://docs.google.com/spreadsheet/pub?key=0Ap1exl80wB8OdHNKVmQ5RVlvQWpibDAxNHkzcU1nV2c&single=true&gid=0&output=csv", "Agency/Body/Event", "", true);
+// RSS
+// https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0Ah41IAK0HzSTdGJxandJREhLSGlWWUZfZ2xKOTNHZ0E&output=csv
+// facebook
+extractCSVAccounts("https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0Ah41IAK0HzSTdGtjcW9vOXdyZ3pOV21vQU51VmhzQnc&single=true&gid=0&output=csv","Agency","Name");
+
+/*
+ * http://australia.gov.au/news-and-media/media-release-rss-feeds
+ * http://australia.gov.au/news-and-media/social-media/blogs
+ * http://australia.gov.au/news-and-media/social-media/twitter
+ * http://australia.gov.au/news-and-media/social-media/facebook
+ * http://australia.gov.au/news-and-media/social-media/youtube
+ * http://australia.gov.au/news-and-media/social-media/flickr
+ * http://australia.gov.au/news-and-media/social-media/apps http://www.harmony.gov.au/get-involved/app-downloads.htm http://www.em.gov.au/Resources/Pages/Before-the-Storm-phone-game.aspx
+ * http://australia.gov.au/news-and-media/social-media/podcasts
+ */
+?>
+
--- a/admin/importGov2RegisterRSSFacebookTwitter.php
+++ b/admin/importGov2RegisterRSSFacebookTwitter.php
@@ -1,6 +1,7 @@
get_db('disclosr-agencies');
$rows = $db->get_view("app", "byName")->rows;
@@ -10,13 +11,48 @@
$nametoid[trim($row->key)] = $row->value;
}
-function extractCSVAccounts($url, $nameField, $accountField, $filter) {
+function extractHTMLAccounts($url, $accountType) {
+ global $accounts, $nametoid;
+ $request = Requests::get($url);
+ $doc = phpQuery::newDocumentHTML($request->body);
+ phpQuery::selectDocument($doc);
+ foreach (pq('tr')->elements as $tr) {
+ //echo $tr->nodeValue.PHP_EOL;
+ $agency = "";
+ $url = "";
+ foreach ($tr->childNodes as $td) {
+ $class = $td->getAttribute("class");
+ //echo "cccc $class ".$td->nodeValue.PHP_EOL;
+ if ($class == "s11" || $class == "s10" || $class == "s7") {
+ $agency = $td->nodeValue;
+ } else if ($class == "s6" || $class == "s9") {
+ $url = $td->nodeValue;
+ foreach ($td->childNodes as $a) {
+ $href = $a->getAttribute("href");
+ if ($href != "") {
+ $url = $href;
+ }
+ }
+ }
+ }
+ if ($agency != "" && $url != "") {
+ if (!in_array(trim($agency), array_keys($nametoid))) {
+ echo trim($agency) . " missing" . PHP_EOL;
+ } else {
+ // echo $agency." = ".$url.PHP_EOL;
+ $accounts[$nametoid[trim($agency)]][$accountType][] = $url;
+ }
+ }
+ }
+}
+
+function extractCSVAccounts($url, $accountType, $nameField, $accountField, $filter) {
global $accounts, $nametoid;
$request = Requests::get($url);
$Data = str_getcsv($request->body, "\n"); //parse the rows
$headers = Array();
foreach ($Data as $num => $line) {
- $Row = str_getcsv($line, ",");
+ $Row = str_getcsv($line, ",", '"');
if ($num == 0) {
} else if ($num == 1) {
@@ -27,9 +63,10 @@
$agencyName = $Row[array_search($nameField, $headers)];
if (!$filter || $Row[array_search("State", $headers)] == "NAT") {
if (!in_array(trim($agencyName), array_keys($nametoid))) {
- echo "$agencyName missing" . PHP_EOL;
+ echo trim($agencyName) . " missing" . PHP_EOL;
} else {
// echo $Row[array_search($nameField, $headers)] . PHP_EOL;
+ $accounts[$nametoid[trim($agencyName)]][$accountType][] = $Row[array_search($accountField, $headers)];
}
}
} else {
@@ -41,21 +78,23 @@
// http://agimo.govspace.gov.au/page/gov2register/
// twitter
-//extractCSVAccounts("https://docs.google.com/spreadsheet/pub?key=0Ap1exl80wB8OdHNKVmQ5RVlvQWpibDAxNHkzcU1nV2c&single=true&gid=0&output=csv", "Agency/Body/Event", "", true);
+extractCSVAccounts("https://docs.google.com/spreadsheet/pub?key=0Ap1exl80wB8OdHNKVmQ5RVlvQWpibDAxNHkzcU1nV2c&single=true&gid=0&output=csv", "Twitter", "Agency/Body/Event", "", true);
// RSS
-// https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0Ah41IAK0HzSTdGJxandJREhLSGlWWUZfZ2xKOTNHZ0E&output=csv
+extractHTMLAccounts("https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0Ah41IAK0HzSTdGJxandJREhLSGlWWUZfZ2xKOTNHZ0E&output=html", "RSS");
// facebook
-extractCSVAccounts("https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0Ah41IAK0HzSTdGtjcW9vOXdyZ3pOV21vQU51VmhzQnc&single=true&gid=0&output=csv","Agency","Name");
+extractHTMLAccounts("https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0Ah41IAK0HzSTdGtjcW9vOXdyZ3pOV21vQU51VmhzQnc&single=true&gid=0&output=html", "Facebook");
+foreach ($accounts as $id => $accountTypes) {
+ echo $id . "
" . PHP_EOL;
+ $doc = object_to_array($db->get($id));
+ // print_r($doc);
-/*
- * http://australia.gov.au/news-and-media/media-release-rss-feeds
- * http://australia.gov.au/news-and-media/social-media/blogs
- * http://australia.gov.au/news-and-media/social-media/twitter
- * http://australia.gov.au/news-and-media/social-media/facebook
- * http://australia.gov.au/news-and-media/social-media/youtube
- * http://australia.gov.au/news-and-media/social-media/flickr
- * http://australia.gov.au/news-and-media/social-media/apps http://www.harmony.gov.au/get-involved/app-downloads.htm http://www.em.gov.au/Resources/Pages/Before-the-Storm-phone-game.aspx
- * http://australia.gov.au/news-and-media/social-media/podcasts
- */
+ foreach ($accountTypes as $accountType => $accounts) {
+ if (!isset($doc["has" . $accountType]) || !is_array($doc["has" . $accountType])) {
+ $doc["has" . $accountType] = Array();
+ }
+ $doc["has" . $accountType] = array_unique(array_merge($doc["has" . $accountType], $accounts));
+ }
+ $db->save($doc);
+}
?>
--- /dev/null
+++ b/admin/metadata.py
@@ -1,1 +1,22 @@
+#http://packages.python.org/CouchDB/client.html
+import couchdb
+from BeautifulSoup import BeautifulSoup
+couch = couchdb.Server('http://127.0.0.1:5984/')
+
+# select database
+docsdb = couch['disclosr-documents']
+
+for row in docsdb.view('app/getMetadataExtractRequired'):
+ print row.id
+ html = docsdb.get_attachment(row.id,row.value.iterkeys().next()).read()
+ metadata = []
+ # http://www.crummy.com/software/BeautifulSoup/documentation.html
+ soup = BeautifulSoup(html)
+metatags = soup.meta
+ for metatag in metatags:
+ print metatag['name']
+ doc = docsdb.get(row.id)
+ //doc['metadata'] = metadata
+ //docsdb.save(doc)
+
--- /dev/null
+++ b/admin/validation.py
@@ -1,1 +1,30 @@
+#http://packages.python.org/CouchDB/client.html
+import couchdb
+import json
+import pprint
+import re
+from tidylib import tidy_document
+couch = couchdb.Server('http://127.0.0.1:5984/')
+
+# select database
+docsdb = couch['disclosr-documents']
+
+def f(x):
+ invalid = re.compile(r"ensure|testing|flicker|updating|longdesc|Accessibility Checks|not recognized")
+ valid = re.compile(r"line")
+ return (not invalid.search(x)) and valid.search(x) and x != ''
+
+for row in docsdb.view('app/getValidationRequired'):
+ print row.id
+ html = docsdb.get_attachment(row.id,row.value.iterkeys().next()).read()
+ #print html
+ document, errors = tidy_document(html,options={'accessibility-check':1,'show-warnings':0,'markup':0},keep_doc=True)
+ #http://www.aprompt.ca/Tidy/accessibilitychecks.html
+ #print document
+ errors = '\n'.join(filter(f,errors.split('\n')))
+ #print errors
+ doc = docsdb.get(row.id)
+ doc['validation'] = errors
+ docsdb.save(doc)
+
--- /dev/null
+++ b/bubbletree.php
@@ -1,1 +1,108 @@
+
+
+
+
+ Minimal BubbleTree Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- a/getAgency.php
+++ b/getAgency.php
@@ -86,9 +86,14 @@
} else if ($schemas['agency']['properties'][$defaultField]['type'] == "array") {
if (is_array($row[$defaultField])) {
$row[$defaultField][] = "";
+ $row[$defaultField][] = "";
+ $row[$defaultField][] = "";
} else {
$value = $row[$defaultField];
$row[$defaultField] = Array($value);
+ $row[$defaultField][] = "";
+ $row[$defaultField][] = "";
+
}
}
}
@@ -102,7 +107,7 @@
// by name = startkey="Ham"&endkey="Ham\ufff0"
// edit?
- $row = $db->get($_REQUEST['id']);
+ $obj = $db->get($_REQUEST['id']);
//print_r($row);
if (sizeof($_POST) > 0) {
//print_r($_POST);
@@ -126,17 +131,19 @@
echo "Edited version was latest version, continue saving";
$newdoc = $_POST;
$newdoc['metadata']['lastModified'] = time();
- $row = $db->save($newdoc);
+ $obj = $db->save($newdoc);
} else {
echo "ALERT doc revised by someone else while editing. Document not saved.";
}
}
$mode = "edit";
+ $rowArray = object_to_array($obj);
+ksort($rowArray);
if ($mode == "edit") {
- $row = addDefaultFields(object_to_array($row));
+ $row = addDefaultFields($rowArray);
} else {
- $row = object_to_array($row);
+ $row = $rowArray;
}
if ($mode == "view") {
@@ -188,14 +195,14 @@
(isset($row->value->name) && $row->value->name != "" ? $row->value->name : "NO NAME " . $row->value->abn)
. '';
} */
- $rows = $db->get_view("app", "byName")->rows;
+ $rows = $db->get_view("app", "byCanonicalName")->rows;
//print_r($rows);
echo '";
--- a/graph.php
+++ b/graph.php
@@ -6,36 +6,46 @@
$format = $_REQUEST['format'];
}
-function add_node($id, $label) {
+function add_node($id, $label, $parent="") {
global $format;
if ($format == "html") {
- echo "nodes[\"$id\"] = graph.newNode({label: \"$label\"});" . PHP_EOL;
+ // echo "nodes[\"$id\"] = graph.newNode({label: \"$label\"});" . PHP_EOL;
}
if ($format == "dot" && $label != "") {
echo "$id [label=\"$label\"];". PHP_EOL;
}
+ if ($format == "gexf") {
+ echo "":">")
+ .""
+ ."". PHP_EOL;
+ }
}
function add_edge($from, $to, $color) {
global $format;
if ($format == "html") {
- echo "graph.newEdge(nodes[\"$from\"], nodes['$to'], {color: '$color'});" . PHP_EOL;
+ // echo "graph.newEdge(nodes[\"$from\"], nodes['$to'], {color: '$color'});" . PHP_EOL;
}
if ($format == "dot") {
echo "$from -> $to ".($color != ""? "[color=$color]":"").";". PHP_EOL;
}
+ if ($format == "gexf") {
+ echo "". PHP_EOL;
+ }
+}
+if ($format == "gexf") {
+ //header('Content-Type: text/xml');
+ header('Content-Type: application/gexf+xml');
+echo '
+
+
+ Gexf.net
+ A hello world! file
+
+
+ '. PHP_EOL;
}
-if ($format == "html") {
- ?>
-
-
-
-
+
+
+
+
+
+
+
+'. PHP_EOL;
+}
//include_footer();
?>
--- a/include/couchdb.inc.php
+++ b/include/couchdb.inc.php
@@ -22,7 +22,10 @@
},
"byWebServer": {
"map": "function(doc) {\n emit(doc.web_server, doc);\n}"
- }
+ },
+ "getValidationRequired": {
+ "map": "function(doc) {\nif (doc.mime_type == \"text/html\" \n&& typeof(doc.validation) == \"undefined\") {\n emit(doc._id, doc._attachments);\n}\n}"
+ }
}*/
}
@@ -92,25 +95,29 @@
}
}";
// http://stackoverflow.com/questions/646628/javascript-startswith
- $obj->views->scoreHas->map = 'if(!String.prototype.startsWith){
+$obj->views->score->map = 'if(!String.prototype.startsWith){
String.prototype.startsWith = function (str) {
return !this.indexOf(str);
}
}
-if(!String.prototype.endsWith){
- String.prototype.endsWith = function(suffix) {
- return this.indexOf(suffix, this.length - suffix.length) !== -1;
- };
-}
+
function(doc) {
-if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") {
-for(var propName in doc) {
- if(typeof(doc[propName]) != "undefined" && (propName.startsWith("has") || propName.endsWith("URL"))) {
- emit(propName, 1);
- }
-}
- emit("total", 1);
- }
+ count = 0;
+ if (doc["status"] != "suspended") {
+ for(var propName in doc) {
+ if(typeof(doc[propName]) != "undefined" && doc[propName] != "") {
+ count++;
+ }
+ }
+ portfolio = doc.parentOrg;
+ if (doc.orgType == "FMA-DepartmentOfState") {
+ portfolio = doc._id;
+ }
+ if (doc.orgType == "Court-Commonwealth" || doc.orgType == "FMA-DepartmentOfParliament") {
+ portfolio = doc.orgType;
+ }
+ emit(count+doc._id, {id:doc._id, name: doc.name, score:count, orgType: doc.orgType, portfolio:portfolio});
+ }
}';
$obj->views->scoreHas->map = 'if(!String.prototype.startsWith){
String.prototype.startsWith = function (str) {
@@ -163,3 +170,4 @@
function setteErrorHandler($e) {
echo $e->getMessage() . "
" . PHP_EOL;
}
+
--- /dev/null
+++ b/javascripts/bubbletree
--- /dev/null
+++ b/javascripts/sigma
--- /dev/null
+++ b/javascripts/sigma.min.js
@@ -1,1 +1,63 @@
+/* sigmajs.org - an open-source light-weight JavaScript graph drawing library - Version: 0.1 - Author: Alexis Jacomy - License: MIT */
+var sigma={tools:{},classes:{},instances:{}};
+(function(){if(!Array.prototype.some)Array.prototype.some=function(i,n){var g=this.length;if("function"!=typeof i)throw new TypeError;for(var j=0;jGLOBAL :
";for(var b in d.p.globalProbes)a+=""+b+" : "+d.p.globalProbes[b]()+"
";a+="
LOCAL :
";for(b in d.p.localProbes)a+=""+b+" : "+d.p.localProbes[b]()+"
";d.p.dom.innerHTML=
+a;return d}sigma.classes.Cascade.call(this);var d=this;this.instance=b;this.monitoring=!1;this.p={fps:40,dom:h,globalProbes:{"Time (ms)":sigma.chronos.getExecutionTime,Queue:sigma.chronos.getQueuedTasksCount,Tasks:sigma.chronos.getTasksCount,FPS:sigma.chronos.getFPS},localProbes:{"Nodes count":function(){return d.instance.graph.nodes.length},"Edges count":function(){return d.instance.graph.edges.length}}};this.activate=function(){if(!d.monitoring)d.monitoring=window.setInterval(e,1E3/d.p.fps);return d};
+this.desactivate=function(){if(d.monitoring)window.clearInterval(d.monitoring),d.monitoring=null,d.p.dom.innerHTML="";return d}}function j(b){function h(b){if(a.p.mouseEnabled&&(e(a.mouseX,a.mouseY,a.ratio*(0<(void 0!=b.wheelDelta&&b.wheelDelta||void 0!=b.detail&&-b.detail)?a.p.zoomMultiply:1/a.p.zoomMultiply)),a.p.blockScroll))b.preventDefault?b.preventDefault():b.returnValue=!1}function e(b,c,e){if(!a.isMouseDown&&(window.clearInterval(a.interpolationID),n=void 0!=e,i=a.stageX,j=b,k=a.stageY,l=
+c,f=e||a.ratio,f=Math.min(Math.max(f,a.p.minRatio),a.p.maxRatio),u=a.p.directZooming?1-(n?a.p.zoomDelta:a.p.dragDelta):0,a.ratio!=f||a.stageX!=j||a.stageY!=l))d(),a.interpolationID=window.setInterval(d,50),a.dispatch("startinterpolate")}function d(){u+=n?a.p.zoomDelta:a.p.dragDelta;u=Math.min(u,1);var b=sigma.easing.quadratic.easeout(u),c=a.ratio;a.ratio=c*(1-b)+f*b;n?(a.stageX=j+(a.stageX-j)*a.ratio/c,a.stageY=l+(a.stageY-l)*a.ratio/c):(a.stageX=i*(1-b)+j*b,a.stageY=k*(1-b)+l*b);a.dispatch("interpolate");
+if(1<=u)window.clearInterval(a.interpolationID),b=a.ratio,n?(a.ratio=f,a.stageX=j+(a.stageX-j)*a.ratio/b,a.stageY=l+(a.stageY-l)*a.ratio/b):(a.stageX=j,a.stageY=l),a.dispatch("stopinterpolate")}sigma.classes.Cascade.call(this);sigma.classes.EventDispatcher.call(this);var a=this;this.p={minRatio:1,maxRatio:32,marginRatio:1,zoomDelta:0.1,dragDelta:0.3,zoomMultiply:2,directZooming:!1,blockScroll:!0,inertia:1.1,mouseEnabled:!0};var g=0,c=0,i=0,k=0,f=1,j=0,l=0,s=0,q=0,z=0,m=0,u=0,n=!1;this.stageY=this.stageX=
+0;this.ratio=1;this.mouseY=this.mouseX=0;this.isMouseDown=!1;b.addEventListener("DOMMouseScroll",h,!0);b.addEventListener("mousewheel",h,!0);b.addEventListener("mousemove",function(b){a.mouseX=void 0!=b.offsetX&&b.offsetX||void 0!=b.layerX&&b.layerX||void 0!=b.clientX&&b.clientX;a.mouseY=void 0!=b.offsetY&&b.offsetY||void 0!=b.layerY&&b.layerY||void 0!=b.clientY&&b.clientY;if(a.isMouseDown){var d=a.mouseX-g+i,f=a.mouseY-c+k;if(d!=a.stageX||f!=a.stageY)q=s,m=z,s=d,z=f,a.stageX=d,a.stageY=f,a.dispatch("drag")}a.dispatch("move");
+b.preventDefault?b.preventDefault():b.returnValue=!1},!0);b.addEventListener("mousedown",function(b){if(a.p.mouseEnabled)a.isMouseDown=!0,a.dispatch("mousedown"),i=a.stageX,k=a.stageY,g=a.mouseX,c=a.mouseY,q=s=a.stageX,m=z=a.stageY,a.dispatch("startdrag"),b.preventDefault?b.preventDefault():b.returnValue=!1},!0);document.addEventListener("mouseup",function(b){if(a.p.mouseEnabled&&a.isMouseDown)a.isMouseDown=!1,a.dispatch("mouseup"),(i!=a.stageX||k!=a.stageY)&&e(a.stageX+a.p.inertia*(a.stageX-q),a.stageY+
+a.p.inertia*(a.stageY-m)),b.preventDefault?b.preventDefault():b.returnValue=!1},!0);this.checkBorders=function(){return a};this.interpolate=e}function m(b,h,e,d,a,g,c){function i(a){var b=d,c="fixed"==f.p.labelSize?f.p.defaultLabelSize:f.p.labelSizeRatio*a.displaySize;b.font=(f.p.hoverFontStyle||f.p.fontStyle||"")+" "+c+"px "+(f.p.hoverFont||f.p.font||"");b.fillStyle="node"==f.p.labelHoverBGColor?a.color||f.p.defaultNodeColor:f.p.defaultHoverLabelBGColor;b.beginPath();if(f.p.labelHoverShadow)b.shadowOffsetX=
+0,b.shadowOffsetY=0,b.shadowBlur=4,b.shadowColor=f.p.labelHoverShadowColor;sigma.tools.drawRoundRect(b,Math.round(a.displayX-c/2-2),Math.round(a.displayY-c/2-2),Math.round(b.measureText(a.label).width+1.5*a.displaySize+c/2+4),Math.round(c+4),Math.round(c/2+2),"left");b.closePath();b.fill();b.shadowOffsetX=0;b.shadowOffsetY=0;b.shadowBlur=0;b.beginPath();b.fillStyle="node"==f.p.nodeBorderColor?a.color||f.p.defaultNodeColor:f.p.defaultNodeBorderColor;b.arc(Math.round(a.displayX),Math.round(a.displayY),
+a.displaySize+f.p.borderSize,0,2*Math.PI,!0);b.closePath();b.fill();b.beginPath();b.fillStyle="node"==f.p.nodeHoverColor?a.color||f.p.defaultNodeColor:f.p.defaultNodeHoverColor;b.arc(Math.round(a.displayX),Math.round(a.displayY),a.displaySize,0,2*Math.PI,!0);b.closePath();b.fill();b.fillStyle="node"==f.p.labelHoverColor?a.color||f.p.defaultNodeColor:f.p.defaultLabelHoverColor;b.fillText(a.label,Math.round(a.displayX+1.5*a.displaySize),Math.round(a.displayY+c/2-3));return f}function k(a){if(isNaN(a.x)||
+isNaN(a.y))throw Error("A node's coordinate is not a number (id: "+a.id+")");return!a.hidden&&a.displayX+a.displaySize>-j/3&&a.displayX-a.displaySize<4*j/3&&a.displayY+a.displaySize>-l/3&&a.displayY-a.displaySize<4*l/3}sigma.classes.Cascade.call(this);var f=this;this.p={labelColor:"default",defaultLabelColor:"#000",labelHoverBGColor:"default",defaultHoverLabelBGColor:"#fff",labelHoverShadow:!0,labelHoverShadowColor:"#000",labelHoverColor:"default",defaultLabelHoverColor:"#000",labelActiveBGColor:"default",
+defaultActiveLabelBGColor:"#fff",labelActiveShadow:!0,labelActiveShadowColor:"#000",labelActiveColor:"default",defaultLabelActiveColor:"#000",labelSize:"fixed",defaultLabelSize:12,labelSizeRatio:2,labelThreshold:6,font:"Arial",hoverFont:"",activeFont:"",fontStyle:"",hoverFontStyle:"",activeFontStyle:"",edgeColor:"source",defaultEdgeColor:"#aaa",defaultEdgeType:"line",defaultNodeColor:"#aaa",nodeHoverColor:"node",defaultNodeHoverColor:"#fff",nodeActiveColor:"node",defaultNodeActiveColor:"#fff",borderSize:0,
+nodeBorderColor:"node",defaultNodeBorderColor:"#fff",edgesSpeed:200,nodesSpeed:200,labelsSpeed:200};var j=g,l=c;this.currentLabelIndex=this.currentNodeIndex=this.currentEdgeIndex=0;this.task_drawLabel=function(){for(var b=a.nodes.length,c=0;c++=f.p.labelThreshold){var k="fixed"==f.p.labelSize?f.p.defaultLabelSize:f.p.labelSizeRatio*d.displaySize;h.font=
+f.p.fontStyle+k+"px "+f.p.font;h.fillStyle="node"==f.p.labelColor?d.color||f.p.defaultNodeColor:f.p.defaultLabelColor;h.fillText(d.label,Math.round(d.displayX+1.5*d.displaySize),Math.round(d.displayY+k/2-3))}}else f.currentLabelIndex++;return f.currentLabelIndex(b*=2)?0.5*b*b:-0.5*(--b*(b-2)-1)};sigma.tools.drawRoundRect=function(b,h,e,d,a,g,c){var g=g?g:0,i=c?c:[],i="string"==typeof i?i.split(" "):i,c=g&&(0<=i.indexOf("topleft")||0<=i.indexOf("top")||0<=i.indexOf("left")),j=g&&(0<=i.indexOf("topright")||0<=i.indexOf("top")||0<=i.indexOf("right")),f=g&&(0<=i.indexOf("bottomleft")||0<=i.indexOf("bottom")||0<=i.indexOf("left")),i=g&&(0<=i.indexOf("bottomright")||
+0<=i.indexOf("bottom")||0<=i.indexOf("right"));b.moveTo(h,e+g);c?b.arcTo(h,e,h+g,e,g):b.lineTo(h,e);j?(b.lineTo(h+d-g,e),b.arcTo(h+d,e,h+d,e+g,g)):b.lineTo(h+d,e);i?(b.lineTo(h+d,e+a-g),b.arcTo(h+d,e+a,h+d-g,e+a,g)):b.lineTo(h+d,e+a);f?(b.lineTo(h+g,e+a),b.arcTo(h,e+a,h,e+a-g,g)):b.lineTo(h,e+a);b.lineTo(h,e+g)};sigma.tools.getRGB=function(b,g){var b=b.toString(),e={r:0,g:0,b:0};if(3<=b.length&&"#"==b.charAt(0)){var d=b.length-1;6==d?e={r:parseInt(b.charAt(1)+b.charAt(2),16),g:parseInt(b.charAt(3)+
+b.charAt(4),16),b:parseInt(b.charAt(5)+b.charAt(5),16)}:3==d&&(e={r:parseInt(b.charAt(1)+b.charAt(1),16),g:parseInt(b.charAt(2)+b.charAt(2),16),b:parseInt(b.charAt(3)+b.charAt(3),16)})}g&&(e=[e.r,e.g,e.b]);return e};sigma.tools.rgbToHex=function(b,g,e){return sigma.tools.toHex(b)+sigma.tools.toHex(g)+sigma.tools.toHex(e)};sigma.tools.toHex=function(b){b=parseInt(b,10);if(isNaN(b))return"00";b=Math.max(0,Math.min(b,255));return"0123456789ABCDEF".charAt((b-b%16)/16)+"0123456789ABCDEF".charAt(b%16)};
+sigma.publicPrototype=p.prototype})();
--- /dev/null
+++ b/lib/Color.php
@@ -1,1 +1,502 @@
-
+
+ *
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ *
+ * @version $Id$
+ *
+ */
+class Lux_Color
+{
+ /**
+ *
+ * Converts hexadecimal colors to RGB.
+ *
+ * @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers,
+ * with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC.
+ *
+ * @return array RGB values: 0 => R, 1 => G, 2 => B
+ *
+ */
+ public function hex2rgb($hex)
+ {
+ // Remove #.
+ if (strpos($hex, '#') === 0) {
+ $hex = substr($hex, 1);
+ }
+
+ if (strlen($hex) == 3) {
+ $hex .= $hex;
+ }
+
+ if (strlen($hex) != 6) {
+ return false;
+ }
+
+ // Convert each tuple to decimal.
+ $r = hexdec(substr($hex, 0, 2));
+ $g = hexdec(substr($hex, 2, 2));
+ $b = hexdec(substr($hex, 4, 2));
+
+ return array($r, $g, $b);
+ }
+
+ /**
+ *
+ * Converts hexadecimal colors to HSV.
+ *
+ * @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers,
+ * with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC.
+ *
+ * @return array HSV values: 0 => H, 1 => S, 2 => V
+ *
+ */
+ public function hex2hsv($hex)
+ {
+ return $this->rgb2hsv($this->hex2rgb($hex));
+ }
+
+ /**
+ *
+ * Converts hexadecimal colors to HSL.
+ *
+ * @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers,
+ * with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC.
+ *
+ * @return array HSL values: 0 => H, 1 => S, 2 => L
+ *
+ */
+ public function hex2hsl($hex)
+ {
+ return $this->rgb2hsl($this->hex2rgb($hex));
+ }
+
+ /**
+ *
+ * Converts RGB colors to hexadecimal.
+ *
+ * @param array $rgb RGB values: 0 => R, 1 => G, 2 => B
+ *
+ * @return string Hexadecimal value with six digits, e.g., CCCCCC.
+ *
+ */
+ public function rgb2hex($rgb)
+ {
+ if(count($rgb) < 3) {
+ return false;
+ }
+
+ list($r, $g, $b) = $rgb;
+
+ // From php.net.
+ $r = 0x10000 * max(0, min(255, $r));
+ $g = 0x100 * max(0, min(255, $g));
+ $b = max(0, min(255, $b));
+
+ return strtoupper(str_pad(dechex($r + $g + $b), 6, 0, STR_PAD_LEFT));
+ }
+
+ /**
+ *
+ * Converts RGB to HSV.
+ *
+ * @param array $rgb RGB values: 0 => R, 1 => G, 2 => B
+ *
+ * @return array HSV values: 0 => H, 1 => S, 2 => V
+ *
+ */
+ public function rgb2hsv($rgb)
+ {
+ // RGB values = 0 ÷ 255
+ $var_R = ($rgb[0] / 255);
+ $var_G = ($rgb[1] / 255);
+ $var_B = ($rgb[2] / 255);
+
+ // Min. value of RGB
+ $var_Min = min($var_R, $var_G, $var_B);
+
+ // Max. value of RGB
+ $var_Max = max($var_R, $var_G, $var_B);
+
+ // Delta RGB value
+ $del_Max = $var_Max - $var_Min;
+
+ $V = $var_Max;
+
+ // This is a gray, no chroma...
+ if ( $del_Max == 0 ) {
+ // HSV results = 0 ÷ 1
+ $H = 0;
+ $S = 0;
+ } else {
+ // Chromatic data...
+ $S = $del_Max / $var_Max;
+
+ $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
+ $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
+ $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
+
+ if ($var_R == $var_Max) {
+ $H = $del_B - $del_G;
+ } else if ($var_G == $var_Max) {
+ $H = (1 / 3) + $del_R - $del_B;
+ } else if ($var_B == $var_Max) {
+ $H = (2 / 3) + $del_G - $del_R;
+ }
+
+ if ($H < 0) {
+ $H += 1;
+ }
+ if ($H > 1) {
+ $H -= 1;
+ }
+ }
+
+ // Returns agnostic values.
+ // Range will depend on the application: e.g. $H*360, $S*100, $V*100.
+ return array($H, $S, $V);
+ }
+
+ /**
+ *
+ * Converts RGB to HSL.
+ *
+ * @param array $rgb RGB values: 0 => R, 1 => G, 2 => B
+ *
+ * @return array HSL values: 0 => H, 1 => S, 2 => L
+ *
+ */
+ public function rgb2hsl($rgb)
+ {
+ // Where RGB values = 0 ÷ 255.
+ $var_R = $rgb[0] / 255;
+ $var_G = $rgb[1] / 255;
+ $var_B = $rgb[2] / 255;
+
+ // Min. value of RGB
+ $var_Min = min($var_R, $var_G, $var_B);
+ // Max. value of RGB
+ $var_Max = max($var_R, $var_G, $var_B);
+ // Delta RGB value
+ $del_Max = $var_Max - $var_Min;
+
+ $L = ($var_Max + $var_Min) / 2;
+
+ if ( $del_Max == 0 ) {
+ // This is a gray, no chroma...
+ // HSL results = 0 ÷ 1
+ $H = 0;
+ $S = 0;
+ } else {
+ // Chromatic data...
+ if ($L < 0.5) {
+ $S = $del_Max / ($var_Max + $var_Min);
+ } else {
+ $S = $del_Max / ( 2 - $var_Max - $var_Min );
+ }
+
+ $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
+ $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
+ $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
+
+ if ($var_R == $var_Max) {
+ $H = $del_B - $del_G;
+ } else if ($var_G == $var_Max) {
+ $H = ( 1 / 3 ) + $del_R - $del_B;
+ } else if ($var_B == $var_Max) {
+ $H = ( 2 / 3 ) + $del_G - $del_R;
+ }
+
+ if ($H < 0) {
+ $H += 1;
+ }
+ if ($H > 1) {
+ $H -= 1;
+ }
+ }
+
+ return array($H, $S, $L);
+ }
+
+ /**
+ *
+ * Converts HSV colors to hexadecimal.
+ *
+ * @param array $hsv HSV values: 0 => H, 1 => S, 2 => V
+ *
+ * @return string Hexadecimal value with six digits, e.g., CCCCCC.
+ *
+ */
+ public function hsv2hex($hsv)
+ {
+ return $this->rgb2hex($this->hsv2rgb($hsv));
+ }
+
+ /**
+ *
+ * Converts HSV to RGB.
+ *
+ * @param array $hsv HSV values: 0 => H, 1 => S, 2 => V
+ *
+ * @return array RGB values: 0 => R, 1 => G, 2 => B
+ *
+ */
+ public function hsv2rgb($hsv)
+ {
+ $H = $hsv[0];
+ $S = $hsv[1];
+ $V = $hsv[2];
+
+ // HSV values = 0 ÷ 1
+ if ($S == 0) {
+ $R = $V * 255;
+ $G = $V * 255;
+ $B = $V * 255;
+ } else {
+ $var_h = $H * 6;
+ // H must be < 1
+ if ( $var_h == 6 ) {
+ $var_h = 0;
+ }
+ // Or ... $var_i = floor( $var_h )
+ $var_i = floor( $var_h );
+ $var_1 = $V * ( 1 - $S );
+ $var_2 = $V * ( 1 - $S * ( $var_h - $var_i ) );
+ $var_3 = $V * ( 1 - $S * ( 1 - ( $var_h - $var_i ) ) );
+
+ switch($var_i) {
+ case 0:
+ $var_r = $V;
+ $var_g = $var_3;
+ $var_b = $var_1;
+ break;
+ case 1:
+ $var_r = $var_2;
+ $var_g = $V;
+ $var_b = $var_1;
+ break;
+ case 2:
+ $var_r = $var_1;
+ $var_g = $V;
+ $var_b = $var_3;
+ break;
+ case 3:
+ $var_r = $var_1;
+ $var_g = $var_2;
+ $var_b = $V;
+ break;
+ case 4:
+ $var_r = $var_3;
+ $var_g = $var_1;
+ $var_b = $V;
+ break;
+ default:
+ $var_r = $V;
+ $var_g = $var_1;
+ $var_b = $var_2;
+ }
+
+ //RGB results = 0 ÷ 255
+ $R = $var_r * 255;
+ $G = $var_g * 255;
+ $B = $var_b * 255;
+ }
+
+ return array($R, $G, $B);
+ }
+
+ /**
+ *
+ * Converts HSV colors to HSL.
+ *
+ * @param array $hsv HSV values: 0 => H, 1 => S, 2 => V
+ *
+