Collabtive-2.0/000077500000000000000000000000001237252063700134465ustar00rootroot00000000000000Collabtive-2.0/.gitignore000066400000000000000000000001161237252063700154340ustar00rootroot00000000000000collabtive.sdb Thumbs.db //Eclipse .settings .project .buildpath *.swp *.swo Collabtive-2.0/README.md000066400000000000000000000006211237252063700147240ustar00rootroot00000000000000What is it? =========== Collabtive is a web-based project management software. It provides a free, open source alternative to proprietary tools like Basecamp. Features =========== - Task lists - Milestones - Messaging / Instant messaging - Calendaring - File management - Role-based user permissions - Time tracking - Reporting (Excel, PDF) - Exporting (ZIP, XML, RSS, iCal) - Multilingual interface Collabtive-2.0/admin.php000066400000000000000000000520311237252063700152500ustar00rootroot00000000000000assign("mode", $mode); // get the available languages $languages = getAvailableLanguages(); $template->assign("languages", $languages); $user = new user(); $project = new project(); $companyObj = new company(); $theset = new settings(); $mainclasses = array("desktop" => "", "profil" => "", "admin" => "active" ); $template->assign("mainclasses", $mainclasses); if (!$userpermissions["admin"]["add"] and $action != "addpro") { $errtxt = $langfile["nopermission"]; $noperm = $langfile["accessdenied"]; $template->assign("errortext", "$errtxt
$noperm"); $template->display("error.tpl"); die(); } if ($action == "index") { $classes = array("overview" => "overview_active", "system" => "system", "users" => "users" ); $template->assign("classes", $classes); $title = $langfile['admin']; $template->display("admin.tpl"); } elseif ($action == "users") { // Set the users tab active $classes = array("overview" => "overview", "system" => "system", "users" => "active" ); $template->assign("classes", $classes); $roleobj = (object) new roles(); // Get 25 users $users = $user->getAllUsers(25); // Get All Projects $projects = $project->getProjects(1, 10000); $roles = $roleobj->getAllRoles(); $i2 = 0; if (!empty($users)) { foreach($users as $usr) { $i = 0; // Check if a user is assigned to a project if (!empty($projects)) { foreach ($projects as $pro) { if (chkproject($usr["ID"], $pro["ID"])) { $chk = 1; } else { $chk = 0; } $projects[$i]['assigned'] = $chk; $i = $i + 1; } } $users[$i2]['projects'] = $projects; // Format the lastlogin timestamp to a string for display if (!empty($users[$i2]['lastlogin'])) { $users[$i2]["lastlogin"] = date(CL_DATEFORMAT . " / H:i:s", $users[$i2]['lastlogin']); } $i2 = $i2 + 1; } } $title = $langfile['useradministration']; $template->assign("title", $title); SmartyPaginate::assign($template); $template->assign("users", $users); $template->assign("projects", $projects); $template->assign("roles", $roles); $template->display("adminusers.tpl"); } elseif ($action == "adduser") { $thetag = new tags(); $tags = $thetag->formatInputTags($tags); // Get the system locale and set it as the default locale for the new user $sysloc = $settings["locale"]; // Add the user $newid = $user->add($name, $email, $company, $pass, $sysloc, $tags, $rate); if ($newid) { if (!empty($assignto)) { // Assign the user to all selected projects foreach ($assignto as $proj) { $project->assign($newid, $proj); } } $roleobj = (object) new roles(); $roleobj->assign($role, $newid); if ($settings["mailnotify"]) { if (!empty($email)) { $subject = $langfile["profileaddedsubject"] . ' (' . $langfile['by'] . ' ' . $username . ')'; $mailcontent = $langfile["hello"] . ",

" . $langfile["profileaddedtext"] . "

" . $langfile["profileusername"] . ": " . "$name
" . $langfile["profilepass"] . ": " . "$pass

" . "$url"; // send email $themail = new emailer($settings); $themail->send_mail($email, $subject, $mailcontent); } } header("Location: admin.php?action=users&mode=added"); } else { // There has been an error, go back $goback = $langfile["goback"]; $endafterstart = $langfile["endafterstart"]; $template->assign("errortext", "The email address $email or the username $name already exists in the user database.
$goback"); $template->display("error.tpl"); } } elseif ($action == "editform") { // This is for editing any user as an admin. This provides more options than the normal user edit $roleobj = (object) new roles(); $roles = $roleobj->getAllRoles(); $languages_fin = array(); foreach($languages as $lang) { $lang2 = $langfile[$lang]; $fin = countLanguageStrings($lang); if (!empty($lang2)) { $lang2 .= " (" . $fin . "%)"; $fin = array("val" => $lang, "str" => $lang2); } else { $lang2 = $lang . " (" . $fin . "%)"; $fin = array("val" => $lang, "str" => $lang2); } array_push($languages_fin, $fin); } $template->assign("languages_fin", $languages_fin); $user = $user->getProfile($id); $roleobj = (object) new roles(); $roles = $roleobj->getAllRoles(); $title = $langfile['useradministration']; $template->assign("title", $title); $template->assign("user", $user); $template->assign("roles", $roles); $template->display("edituseradminform.tpl"); } elseif ($action == "edituser") { $thetag = new tags(); $tags = $thetag->formatInputTags($tags); $roleobj = new roles(); $roleobj->assign($role, $id); if ($id == $userid) { $_SESSION['userlocale'] = $locale; $_SESSION['username'] = $name; } if (!isset($isadmin)) { $isadmin = 1; } // Upload of avatar if (!empty($_FILES['userfile']['name'])) { $fname = $_FILES['userfile']['name']; $typ = $_FILES['userfile']['type']; $size = $_FILES['userfile']['size']; $tmp_name = $_FILES['userfile']['tmp_name']; $error = $_FILES['userfile']['error']; $root = "./"; $desc = getArrayVal($_POST,"desc" ); $teilnamen = explode(".", $fname); $teile = count($teilnamen); $workteile = $teile - 1; $erweiterung = $teilnamen[$workteile]; $subname = ""; if ($typ != "image/jpeg" and $typ != "image/png" and $typ != "image/gif") { $loc = $url . "manageuser.php?action=profile&id=$userid"; header("Location: $loc"); die(); } for ($i = 0; $i < $workteile; $i++) { $subname .= $teilnamen[$i]; } list($usec, $sec) = explode(' ', microtime()); $seed = (float) $sec + ((float) $usec * 100000); srand($seed); $randval = rand(1, 999999); $subname = preg_replace("/[^-_0-9a-zA-Z]/", "_", $subname); $subname = preg_replace("/\W/", "", $subname); if (strlen($subname) > 200) { $subname = substr($subname, 0, 200); } $fname = $subname . "_" . $randval . "." . $erweiterung; $datei_final = CL_ROOT . "/files/" . CL_CONFIG . "/avatar/" . $fname; if (move_uploaded_file($tmp_name, $datei_final)) { $avatar = $fname; } if ($user->edit($id, $name, "" , $email, $tel1, $tel2, $company, $zip, $gender, $turl, $address1, $address2, $state, $country, $tags, $locale, $avatar, $rate)) { if (!empty($newpass) and !empty($repeatpass)) { $user->admin_editpass($id, $newpass, $repeatpass); } header("Location: admin.php?action=users&mode=edited"); } } else { if ($user->edit($id, $name, "", $email, $tel1, $tel2, $company, $zip, $gender, $turl, $address1, $address2, $state, $country, $tags, $locale, "", $rate)) { if (!empty($newpass) and !empty($repeatpass)) { $user->admin_editpass($id, $newpass, $repeatpass); } header("Location: admin.php?action=users&mode=edited"); } } } elseif ($action == "deleteuserform") { $usr = $user->getProfile($id); // Get user's projects $proj = new project(); $projects = $proj->getMyProjects($id); // Get members of each project if (!empty($projects)) { for ($i = 0; $i < count($projects); $i++) { $members = $proj->getProjectMembers($projects[$i]["ID"]); $projects[$i]["members"] = $members; } $title = $langfile["deleteuser"]; $template->assign("title", $title); $template->assign("user", $usr); $template->assign("projects", $projects); $template->display("admindeluserform.tpl"); } else { if ($user->del($id)) { header("Location: admin.php?action=users&mode=deleted"); } } } elseif ($action == "deleteuser") { $id = getArrayVal($_POST, "id"); $uprojects = getArrayVal($_POST, "uprojects"); $proarr = array(); foreach($uprojects as $upro) { $dat = explode("#", $upro); $todo = array("project" => $dat[0], "user" => $dat[1]); array_push($proarr, $todo); } if (!empty($proarr)) { $task = new task(); foreach($proarr as $proj) { $tasks = $task->getAllMyProjectTasks($proj["project"], 100, $id); if ($proj["project"] > 0 and $proj["user"] > 0) { if (!empty($tasks)) { foreach($tasks as $mytask) { if ($task->deassign($mytask["ID"], $id)) { $task->assign($mytask["ID"], $proj["user"]); } } } } else { if (!empty($tasks)) { foreach($tasks as $mytask) { $task->del($mytask["ID"]); } } } } } if ($user->del($id)) { header("Location: admin.php?action=users&mode=deleted"); } } elseif ($action == "assignform") { $projects = $project->getProjects(1, 10000); $i = 0; foreach ($projects as $project) { if (chkproject($id, $project[ID])) { $chk = 1; } else { $chk = 0; } $projects[$i]['assigned'] = $chk; $i = $i + 1; } $template->assign("projects", $projects); $user = $user->getProfile($id); $template->assign("user", $user); $template->display("assignform.tpl"); } elseif ($action == "massassign") { $projects = $_POST['projects']; $user = $_POST['id']; $allprojects = $project->getProjects(1, 10000); $allpro = array(); foreach($allprojects as $pro) { array_push($allpro, $pro[ID]); } if (!empty($allpro) and !empty($projects)) { $diff = array_diff($allpro, $projects); } elseif (empty($projects)) { $diff = $allpro; } if (!empty($projects)) { foreach($projects as $pro) { if (!chkproject($user, $pro)) { if ($settings["mailnotify"]) { $usr = (object) new user(); $tuser = $usr->getProfile($user); if (!empty($tuser["email"])) { $userlang = readLangfile($tuser['locale']); $subject = $userlang["projectassignedsubject"] . ' (' . $userlang['by'] . ' ' . $username . ')'; $mailcontent = $userlang["hello"] . ",

" . $userlang["projectassignedtext"] . " " . $url . "manageproject.php?action=showproject&id=$pro"; // send email $themail = new emailer($settings); $themail->send_mail($tuser["email"], $subject , $mailcontent); } } $project->assign($user, $pro); } } } if (!empty($diff)) { foreach($diff as $mydiff) { $project->deassign($user, $mydiff); } } header("Location: admin.php?action=users&mode=de-assigned"); } elseif ($action == "projects") { $classes = array("overview" => "active", "system" => "system", "users" => "users" ); $title = $langfile['projectadministration']; $template->assign("title", $title); $template->assign("classes", $classes); $opros = $project->getProjects(1, 10000); $clopros = $project->getProjects(0, 10000); $i = 0; $users = $user->getAllUsers(1000000); if (!empty($opros)) { foreach($opros as $opro) { $membs = $project->getProjectMembers($opro["ID"], 1000); $opros[$i]['members'] = $membs; $i = $i + 1; } $template->assign("opros", $opros); } $template->assign("users", $users); $template->assign("clopros", $clopros); $template->display("adminprojects.tpl"); } elseif ($action == "addpro") { if (!$userpermissions["projects"]["add"]) { $errtxt = $langfile["nopermission"]; $noperm = $langfile["accessdenied"]; $template->assign("errortext", "$errtxt
$noperm"); $template->display("error.tpl"); die(); } if (!$end) { $end = 0; } $add = $project->add($name, $desc, $end, $budget, 0); if ($add) { foreach ($assignto as $member) { $project->assign($member, $add); if ($settings["mailnotify"]) { $usr = (object) new user(); $user = $usr->getProfile($member); if (!empty($user["email"])) { $userlang = readLangfile($user['locale']); $subject = $userlang["projectassignedsubject"] . ' (' . $userlang['by'] . ' ' . $username . ')'; $mailcontent = $userlang["hello"] . ",

" . $userlang["projectassignedtext"] . " " . $url . "manageproject.php?action=showproject&id=$add"; // send email $themail = new emailer($settings); $themail->send_mail($user["email"], $subject , $mailcontent); } } } if($company > 0) { echo $company . " " . $add; $companyObj->assign($company,$add); } header("Location: manageproject.php?action=showproject&id=$add"); } } elseif ($action == "closepro") { if ($project->close($id)) { echo "ok"; // header("Location: admin.php?action=projects&mode=closed"); } } elseif ($action == "openpro") { if ($project->open($id)) { header("Location: admin.php?action=projects&mode=opened"); } } elseif ($action == "deletepro") { if ($project->del($id)) { // header("Location: admin.php?action=projects&mode=deleted"); echo "ok"; } } elseif ($action == "customers") { $classes = array("overview" => "overview", "customer" => "active", "system" => "system", "users" => "users" ); $title = $langfile['customeradministration']; $template->assign("title", $title); $template->assign("classes", $classes); $allcust = $companyObj->getAllCompanies(); // $clopros = $project->getProjects(0, 10000); /* $i = 0; $users = $user->getAllUsers(1000000); if (!empty($opros)) { foreach($opros as $opro) { $membs = $project->getProjectMembers($opro["ID"], 1000); $opros[$i]['members'] = $membs; $i = $i + 1; } $template->assign("opros", $opros); }*/ $template->assign("allcust", $allcust); $template->display("admincustomers.tpl"); } elseif ($action == "addcust") { if (!$userpermissions["admin"]["add"]) { $errtxt = $langfile["nopermission"]; $noperm = $langfile["accessdenied"]; $template->assign("errortext", "$errtxt
$noperm"); $template->display("error.tpl"); die(); } if (!$end) { $end = 0; } $data = array('company' => getArrayVal($_POST, "company"), 'contact' => getArrayVal($_POST, "contact"), 'email' => getArrayVal($_POST, "email"), 'phone' => getArrayVal($_POST, "tel1"), 'mobile' => getArrayVal($_POST, "tel2"), 'url' => getArrayVal($_POST, "web"), 'address' => getArrayVal($_POST, "address"), 'zip' => getArrayVal($_POST, "zip"), 'city' => getArrayVal($_POST, "city"), 'country' => getArrayVal($_POST, "country"), 'state' => getArrayVal($_POST, "state"), 'desc' => getArrayVal($_POST, "desc") ); $add = $companyObj->add($data); if ($add) header("Location: admin.php?action=customers&mode=added"); } elseif($action == "assigncustomer") { } elseif ($action == "system") { $classes = array("overview" => "overview", "system" => "active", "users" => "users" ); $languages_fin = array(); foreach($languages as $lang) { $fin = countLanguageStrings($lang); if (!empty($langfile[$lang])) { $lang2 = $langfile[$lang]; $lang2 .= " (" . $fin . "%)"; $fin = array("val" => $lang, "str" => $lang2); } else { $lang2 = $lang . " (" . $fin . "%)"; $fin = array("val" => $lang, "str" => $lang2); } array_push($languages_fin, $fin); } $msgcount = getArrayVal($_GET, "msg"); $peoplecount = getArrayVal($_GET, "peop"); $procount = getArrayVal($_GET, "pro"); $taskcount = getArrayVal($_GET, "tsk"); $template->assign("msgcount", $msgcount); $template->assign("peoplecount", $peoplecount); $template->assign("procount", $procount); $template->assign("taskcount", $taskcount); $template->assign("languages_fin", $languages_fin); $title = $langfile["systemadministration"]; $template->assign("title", $title); $template->assign("classes", $classes); $sets = $theset->getSettings(); $templates = $theset->getTemplates(); $themes = $theset->getThemes($settings["template"]); $template->assign("themes", $themes); $template->assign("settings", $sets); $timezones = DateTimeZone::listIdentifiers(); $template->assign("timezones", $timezones); $template->assign("templates", $templates); $template->display("editsettings.tpl"); } elseif ($action == "editsets") { $theme = getArrayVal($_POST, "theme"); if ($theset->editSettings($name, $subtitle, $locale, $timezone, $dateformat, $templ, $theme, $rssuser, $rsspass)) { $handle = opendir($template->compile_dir); while (false !== ($file = readdir($handle))) { if ($file != "." and $file != "..") { unlink(CL_ROOT . "/" . $template->compile_dir . "/" . $file); } } $_SESSION["userlocale"] = $locale; $users = $user->getAllUsers(100000); foreach($users as $theuser) { // set the new locale for all the users $user->edit($theuser["ID"], $theuser["name"], $theuser["realname"], $theuser["email"], $theuser["tel1"], $theuser["tel2"], $theuser["company"], $theuser["zip"], $theuser["gender"], $theuser["url"], $theuser["adress"], $theuser["adress2"], $theuser["state"], $theuser["country"], $theuser["tags"], $locale, "", $theuser["rate"]); } header("Location: admin.php?action=system&mode=edited"); } } elseif ($action == "editmailsets") { $status = getArrayVal($_POST, "mailstatus"); $mailfrom = getArrayVal($_POST, "mailfrommail"); $mailfromname = getArrayVal($_POST, "mailfromname"); $method = getArrayVal($_POST, "mailmethod"); $server = getArrayVal($_POST, "server"); $mailuser = getArrayVal($_POST, "mailuser"); $mailpass = getArrayVal($_POST, "mailpass"); if ($theset->editMailsettings($status, $mailfrom, $mailfromname, $method, $server, $mailuser, $mailpass)) { header("Location: admin.php?action=system&mode=edited"); } } ?> Collabtive-2.0/api.php000066400000000000000000000075621237252063700147420ustar00rootroot00000000000000The API is deactivated. The API does not properly enforce permissions yet. For example every user can request every project / task etc.
To activate the API remove the die() statement in api.php line 38.
DO NOT USE THE API ON PRODUCTION SERVERS !"); $userobj = new user(); $usr = $_GET["username"]; $pass = $_GET["pass"]; $pass = urldecode($pass); $usr = urldecode($usr); if (!$userobj->login($usr, $pass)) { die("not authorized"); } // variables $action = getArrayVal($_GET, "action"); $id = getArrayVal($_GET, "id"); $user = getArrayVal($_GET, "user"); // output in xml or json $mode = getArrayVal($_GET, "mode"); // create new array to xml converter $xml = new toXml(); // Projects if ($action == "project.get") { $obj = (object) new project(); $theData = $obj->getProject($id); $theRootNode = "project"; } elseif ($action == "myprojects.get") { $obj = (object) new project(); $theData = $obj->getMyProjects($id); $theRootNode = "myprojects"; } elseif ($action == "project.members.get") { $obj = (object) new project(); $theData = $obj->getProjectMembers($id); $theRootNode = "members"; } // Users elseif ($action == "user.profile.get") { $obj = (object) new user(); $theData = $obj->getProfile($id); $theRootNode = "user"; } elseif ($action == "user.id.get") { $obj = (object) new user(); $theData = $obj->getId($id); $theRootNode = "user"; } elseif ($action == "user.list.get") { $obj = (object) new user(); $theData = $obj->getAllUsers(100000); $theRootNode = "userlist"; } elseif ($action == "user.tasks.get") { $obj = (object) new task(); $project = new project(); $myprojects = $project->getMyProjects($user); $theData = array(); foreach($myprojects as $proj) { $theArr = $obj->getAllMyProjectTasks($proj["ID"], 10000, $user); if (!empty($theArr)) { foreach($theArr as $task) { array_push($theData, array("ID" => $task["ID"], "name" => $task["title"])); } } } $theRootNode = "tasks"; } // convert to XML or JSON if ($mode == "json") { $theXml = $xml->arrToJSON($theData); } else { $theXml = $xml->arrToXml($theData, $theRootNode); } // output to the user echo $theXml; ?> Collabtive-2.0/changelog.txt000066400000000000000000001361571237252063700161530ustar00rootroot00000000000000Collabtive 2.0 + Fixed notice on desktop that resulted from missing network connection during update check + Fixed deactivation of error reporting during update + Merge existing members and new members when adding project + Error reporting globally set to E_WARNING + Changed redirection after project creation from desktop or project administration to project dashboard + Improved translations: German, Polish, Farsi, Norwegian (Bokmal & Nynorsk), Simplified Chinese + Improved project tree's handling for special characters + Removed file upload from the add reply form. Now only previously uploaded files can be attached to replies. + Lots of code beautification in templates files + Make filemanager behave more like explorer (i.e. no pagination - show all files in each folder at once) + Revert to gridview as the default file view (this was changed in 1.2 b/c of issues) + Added edge case for SSL detection + Removed .htaccess file as it was causing trouble with some servers + Added start date functionality for tasks + Fixed several typos in style_form.css + Fixed typo in paginate-first function + Fixed cancel button for deleting folders in list view + Corrected label for edit button in project members view ("edit file" -> "edit user") + Changed permission for adding users to an existing project from "administration" to "project edit" + Implemented HTML Purifier filter for all user input. This will give us STRONG protection against all kinds of XSS attacks, while preserving rich formating options. It will also enhance well formedness. + Implemented some Content-Security-Protection header options. No framing,only load css from same origin, only load .js files from same origin, only load images from same origin + Remove force-compile option from template engine. This disabled caching and caused performance problems for some users. + Add compileAllConfig() to force a recompile of the config files in certain cases. + Fixed possible sql vulnerability in manageajax.php + Dont expose plain filesystem links to uploaded files. Downloads are routed through download.php + Added AES encryption of uploaded files + Added CSS theme functionality. Now the CSS and image files for each template set reside in a /themes/ subfolder. This way, there can be CSS only variations of templates created more easily. + Change color of tab info string, making it more readable + Set cache directory for HTML purifier definitions to /files/standard/ics/ + Messages can now be edited asyncronously + Messages can now be replied to asyncronously + Implemented a new structure for the desktop. It is now an accordeon where clicking each section slides it open and closes all others. + Implemented a new structure for the project dashboard. It is now an accordeon where clicking each section slides it open and closes all others. + Customer profiles can be added in admin->customer + A customer can be assigned to projects + Remove user pictures from the onlinelist + Added translation of install-readme: Simplified Chinese + Removed unfunctional links from the day numbers in the desktop calendar + Fixed white page when editing of task failed. + Fixed conversion of umlauts when uploading files. + Fixed accordeon in tasklist view + Fixed a bug where the list view in project->files could not be selected if the user's role had file:add deactivated. + Files in subfolders can now also be attached to messages + Fixed filetype detection in message::getAttachedFiles - needs more refactoring to use file::getFile + Fixed a problem with file uploads and visibility string + Fixed cancel button submitting the form in task->edit + Localized project tree labels + Localized label for name in list view for files + Added a new CSS theme: spring + Fixed various display bugs Collabtive 1.2 + Added translations: Vietnamese + Improved translations: Spanish + Added collapsible tree showing the structure of a project (milestones, tasklists, tasks, messages) + Removed Basecamp importer (didn't work in a long time, see https://github.com/philippK-de/Collabtive/issues/2 ) + Milestones can now have a start date set when created. Start date can also be edited. + Removed links to the my-projects/tasks/messages blocks in block titles on the desktop + Milestones can now be deleted asynchronously + Milestones can now be closed asynchronously + Milestones are now grouped into "current" , "late" and "upcoming" milestones in project->milestones + Closed tasklists now receive their own white bg block in projects->tasklists. Better sets the block apart from active tl's + Removed tags from the add message form. Tags will be removed from Collabtive in order to simplify things. + Removed file upload from the add message form. Now only previously uploaded files can be attached to messages. + Implemented tree view for projects + Fixed display problem with Smarty where pages weren't listed as before + Improved notification emails. They are now much more informative / better localized (StephanRichter) + Implemented iCal auth (StephanRichter) + Fixed bug where certain dates (like 1.9.2013) could not be selected in date picker (StephanRichter) + Added htaccess file to deny folder listing in the file folder (StephanRichter) + Switched from a background-color gradient to a solid color + Fixed a bug where the timetracker report would return a server error (http://collabtive.o-dyn.de/forum/viewtopic.php?f=11&t=11505) + Start date for a timetracker entry can now be set manually + Fixed a mssing (int) typecast in managetimetracker.php. + Timetracker start date can now be manually set Collabtive 1.1 + Fixed bug in tasklist editing, which would automatically remove the tasklist's assignment to a given milestone + Fixed notice in user editing form which showed up when an available language's name was not translated in the selected language + Updated the template engine to Smarty3 (mwirtz) + Updated the bundled TCPDF to 6.0 (mwirtz) + Changed class.mylog to show 25 entries per log page instead of 10 + Changed inserting of default values to settings table to a single query (from a foreach loop) in install.php + Fixed an error where any registered user could delete other users' profiles + Fixed an error where other files than pictures (for example PHP scripts) could be uploaded as the user's avatar + Fixed a possible SQL injection in the timetracker reporting + Fixed text in empty project message PDF export + Fixed bug with empty timetracker PDF exports + Improved replying to messages by putting as editable default title "Re: " + Fixed UI bug in project's tasklist view for tasks with multiple users + Changed UI string "Send" to "Save" + Made sure the database uses UTF-8 for the connection + Fixed links in e-mail notifications for new project / message + When editing closed tasks/projects in tables, the edit form is now displayed in the top block, like for open tasks/projects + Fixed UI glitches with "Never due" field in project add/edit forms + Updated image handling to remain compatible with PHP 5.4+ + Removed unused field "folder description" from form for adding folders + Made field "folder name" required in form for adding folders + Made installer more secure by checking for pre-existing installation in each step of installation (not only on 1st) Collabtive 1.0 + Added translations: Hebrew, Norwegian (Nynorsk), Taiwanese + Improved translations: Albanian, Arabic, Bulgarian, Danish, Farsi, French, German, Greek, Hungarian, Italian, Norwegian (Bokmål), Polish, Portuguese (Brazilian), Slovak, Serbian, Turkish + Added translations of install-readme: Hungarian + Improved translations of install-readme: Arabic + Changed name of autoload function to cl_autoload and added it with spl_autoload_register() to autoload list, to not interfere other autoloaders + Implemented automatic update notification. + Completely re-written the PDF export. It now uses a custom subclass of TCPDF to directly draw the tables for the reports from arrays instead of using an HTML intermediate. This greatly speeds up PDF generation (esp when many lines are exported) and generates much smaller PDFs. + Fixed problem with missing "webcolor" variable in TCPDF + Improved the project log PDF report by merging fields, improving shading and adding automatic font stretching. + Added new PDF report to the "my tasks" block on the desktop. Now a user can export all his tasks to PDF. + Re-enabled permissions checking when deleting a timetracker entry. This got disabled for testing purposes and was commited to trunk. Disabling it posed a possible security risk. + Added permissions checking to timetracker:add and timetracker:edit . Permissions set in the useraccount where not properly enforced for the timetracker before. + Rewrote the settings functionality to work with a key/value table as the datastore. This makes extensibility easier. + Ported all database access from mysql_ to PDO. This became necessary because mysql_ will be deprecated in future versions of PHP. It uses stored procedures for all UPDATE and INSERT queries which brings improved security and performance (caching) advantages. Also, PDO supports a plethora of databases which should make supporting other databases than mysql much easier than before. (Contributed by Mwirtz) + Started porting SELECT queries to use stored procedures as well. This brings security and performance (caching) advantages. + Ported install.php and update.php to also use PDO + Replaced the Excel Export by a more robust CSV export. The excel export was based on an outdated library and not fully compatible with newer versions of Excel and OpenOffice. With CSV Collabtive can now export to a widely used serialisation format that can easily be read into Excel, OpenOffice, and many more. + Switched to using a precompiled static CSS file in production instead of dynamically compiling it at runtime. This saves many call to the php interpreter. + Removed the tabs "my tasks", "my projects", "my messages" from the tabs bar on the desktop. Those tabs were redundant for quite some time now. All their information is, in condensed form, also available on the desktop. they can be reinstated by editing tabsmenue-deskt.tpl + Fixed a bug preventing people from uploading avatar images + Changed the truncation of project titles and task titles on the desktop slightly to prevent http://collabtive.o-dyn.de/forum/viewtopic.php?f=11&t=8750#p17251 + Made timetracker show closed tasks in addition to open tasks when editing a task ( http://collabtive.o-dyn.de/forum/viewtopic.php?f=11&t=8749 ) + When clicking on a folder, set the folder in the select menu for "add file" and "add folder" to the clicked folder. This way you can upload into a folder you just clicked straight away. + Removed the "visibility" functionality for folders ...finally + Removed IE7 compatibility + Files: Made listview/gridview switch respect the currently selected folder when switching views + Made the uploader respect the currently selected folder when refreshing. Now after an upload is complete the view will refresh the subfolder to which a file has been uploaded and not always the main folder. + When editing tasks or projects in tables (i.e. on the desktop) the edit form is now displayed in the top block where the add project/task form is also displayed. This eliminates the need for a dedicated "edit" page. + Enabled multi-byte safe truncation for strings (makes PHP extension "mbstring" required) + Properly enforce user permissions for uploading files, moving files (file_edit), deleting folders (file_del), adding folders (file_add) on the controller/script level. Not only on the template/view level. + Added RTL enabled version of the default theme. Contributed by mrawi. + Implemented "view" permission. It enables you to define roles that can only view certain parts of a project. For example a role that can view milestones, tasks and messages, but not files and the timetracker in a project. + Added "Add task" slider to the "my tasks" block on the desktop. This way a user can add tasks to himself straight from the desktop. + Fix shading of the content table. When clicking "add task" or "add project" on the desktop the table with existing tasks / projects is now correctly shaded. + Made the page update.php translatable + Improved the design of the installer/updater + Fixed a notice in system administration / user profile when a language string was not translated + Fixed a bug that asked for the "add" permission instead of the "reply" permission before posting a reply + Fixed a bug where the datepicker would not keep the dateformat set in the systemsettings and would revert to d.m.Y when changing months. + Fixed a notice when displaying messages + Fixed link in the email notifications for message-replies to point to the replied to message instead of the reply + Send email notifications to all assigned users when creating a project, not just when adding users afterwards. + Bulleted lists now displayed correctly... finally. + Added mimetype icon for PNG images uploaded with IE which is image/x-png and not image/png + Fixed a notice when searching + Fixed a bug where clicking cancel in admin->projects->assign user would add an empty user (removed the cancel button). + Fixed minor glitch in the form for adding a timetracker entry + Substituted deprecated PHP function split() used in e-mail handling by PHP function explode() + Made sure to only offer the password reset function (via e-mail) when e-mail notifications are activated + Made the asynchronous refresh after file upload is complete a bit quicker. the uploader used to wait 1s before refreshing - this is now reduced to 500ms. Collabtive 0.7.6 + Added Estonian translation + Fixed timetracker filtering + Fixed a problem in countLanguageStrings() that would throw warnings on the system admin page when there was an empty folder in the /language/ folder + Files can now be moved up in the folder hierarchy by dragging them onto the "folder up" icon / titlebar + Display the complete path of the folder in the add folder ("Parent folder") and add file ("folder") forms, instead of just the foldernames + Display the complete path in the titlebar of the file manager, instead of just the current folder + Filemanager can now be switched between Gridview (default) and listview (new) + Set sensible defaults for time formating in admin->system + Implemented asynchronous file upload, with real progress indicator (for browsers that can support it) + Removed open ID login option. it was based on a terribly outdated library that only supports openID 1.0, which possibly poses a security problem. + Improved file type checking for avatar uploads to prevent non-image files from being uploaded to the avatar directory. This improves security. + Removed some dead code paths from manageproject.php + Added a security check to install.php to prevent it from being used after Collabtive has already been installed. + Fixed a bug where, when clicking "delete" on a folder and answering the "are you sure" prompt with "no", the folder would be faded out as if deleted (though not really deleted) Collabtive 0.7.5 + Improved code comments + Streamlined user interfaces of the forms for adding and editing a milestone + Fixed bug in the project timetracker filter so the filtered list of timetracker entries is now sorted by date as it should be + Timetracker filter in user profiles now allows for selecting multiple projects instead of just a single project + The quickjump menu in the sidebar now has a fixed width at 100% + Fixed a bug where clicking cancel on the add task form would submit the form + Made the sliding parts of the UI a bit snappier + Cleaned up the desktop: only show the calendar if there are projects available + Extended limits for milestones + Fixed bug where the text of a message or task would not display correctly when adding / editing it in the single item view + Improved translations: Chinese, Russian + Refactored method getAllUsers in class.user.php + PHP date() compatibility for the JS calendar / datepicker + Fixed a small display glitch in winter + Disabled browserinternal forms checking to prevent conflicts with the built in forms validator + Added Beta version of a JSON / XML API. + Fixed display bug in the timetracker report + Optimized asynchronous queries to check for new chat messages and onlinelist updates when idle (i.e. when not browsing through collabtive). It uses a decay mechanism now to reduce the number of ajax requests to the server. This should reduce DB utilisation. + Compressed some large JS assets, that were previously served uncompressed, (like prototype.php) with YUIcompressor, reducing the amount of JS code to be loaded by the user + Fixed a broken implementation of Date.parse() in IE by using a JS version of strtotime() for the calendar + Fix a glitch were online users would briefly not show up in the online list + Fixed a bug where the "select file" in the add file dialog could not be clicked + Made the asyncronous deleting of items (tasks, projects) a bit faster + Improved the styling of the colorpicker and imagechoser in tinymce + Removed unwanted margin from textareas Collabtive 0.7 + Changed assign-to field in add task form to multi-select (was missing only when you clicked a date on the calender and chose "add task") + Optimized user profiles to not show the blocks for projects and time tracking when there are no entries + Made the use of the field Company in user profiles more user friendly + Added missing string "hello" to e-mail notification which a new user receives + Optimized the user add form to not show a label for projects, if no projects have been added, yet + Extended sortability of tables on desktop to My tasks: sortable by Task / Project / Days left, show mouse when hovering over column title + New feature: added a quickfinder to the sidebar, allowing the users to quickly switch to any of their other open projects + Optimized table column widths to show more of the entries in the main column + Optimized table alignment (content should align right, if the column only contains digits) + Added truncation to some views where it was missing + Optimized display of time track entries in user profiles + Optimized truncation in several views (e.g. now longer chunks of file names are shown) + Optimized log to show more of the entries' titles, to log actions applied to folders, to display deleted files' names, to not display log entries for actions concerning time tracking (for privacy reasons), and to log user assigned / withdrawn from project + Fixed a warning by correcting some calls to templates from managemilestone.tpl + Fixed the "cancel" button on the add project form to not submit the form. + Optimized task add form: Now in the assign field, the current user is always pre-selected, which often will save a click + Optimized e-mail notification when a task is added, so that the adding person does not get an e-mail + Added (fake) progress bar that replaces the file upload button when upload is in progress + Added link titles for milestone names in the project milestones view + Added permission check for showing the delete button for attached files in My Messages and single message view + Fixed reloading after deleting of attached files in My message view + Added alt text to the button in the project files view which takes you a level higher in the folders hierarchy + Fixed a notice in project messages + Fixed a bug in the project files lists and all message files lists: When a file is deleted, its icon now neatly fades out and is replaced by the other files moving up + Added new "winter" template. It is based on "standard" and provides a lighter alternative. Replaces the unmaintained "frost" template. + Fixed wrong image file path resulting in missing image in system message for folder added + Fixed wrong image file path resulting in missing image in system message for reply added + Added XSS protection for strings input by the user in getArrayVal() + Added function to edit a user's hourly rate if you are an admin + Updated bundled TC_PDF class to 5.9.038 + Updated the bundled tinyMCE to 3.4.2, took alignment option out of toolbar because it seems pretty useless + Removed unused search modal HTML code + Enabled rounded borders in IE9 (CSS) + Corrected hard-coded string "Budget" on project dashboard to translated string + Added function to edit project budget + Optimized strings shown during hovering in several views + Corrected regular expression in timetracker in order to allow for single digit hours and to dismiss things like 10:60 or 25:00 + Corrected color-coding for projects with due date in the future on dashboard + Removed 'Days left' from dashboard for projects without due date + Color-coding for projects without due dates on desktop and project administration now same as for projects with due date in the future + More string sanitizing in class.user.php + Added comments + Improved security in chat component (added typecast to int) + Corrected typo in tables optimization queries and added missing queries in update script + Fixed bug in files table which prevented .docx files from being stored in the database + New function: User is now enabled to reset his/her password when he/she forgot it + Added missing e-mail notification function when replying to a message + Added missing image files for lytebox feature + New translations: Slovenian, Croatian, Farsi + 100% completed translations: Danish, German, Greek, English, Spanish, Finnish, French, Croatian, Italian, Norwegian, Dutch, Polish, Portuguese, Brazilian Portuguese, Romanian, Russian, Serbian + Improved security: open .php files as plaintext only + Improved sorting of projects on desktop, now sorted chronologically by default + Improved message display: Avatar now appears next to body of text thus making better use of the given space + Fixed bug which prevented choosing existing project files as attachments for a reply + Added title for install script + Beautified code of several template files Collabtive 0.6.5 + Fixed bug when assigning tasks while email notification is deactivated / off + Added name of the project to the desktop calendar overlay + Fixed date format in calendar overlay on desktop + Improved translations: French, Portuguese, Czech, Brasilian Portuguese, Polished + Modified max no. of users to show on projects, now 10000 instead of 100 + Remove the option "All" from the task edit form on single task view + Fixed a bug where a folder wouldnt be visible if visible = all was selected + Fixed a bug where every timetracker entry was tracked for "today" regardless of selection + Removed some debug output in managefile.php + Added check for userpermission of file editing, so the edit icon will not show up any longer in case of missing permission + Added missing truncation to project title on the mymessages view + Corrected file->delete link for attached files in the message view + Backported never due for projects to the frost theme Collabtive 0.6.4 + Fixed a path problem with the filesize() function + Fixed a bug preventing Safari Users from creating tasks + Fixed a bug where an empty user could be assigned to a project + Corrected HTML Errors in project->people and project->timetracker views + Fixed a bug when editing a task + Added generic boder-radius to the CSS so all browsers that support it will display rounded borders (previously only Firefox and Webkit) + Removed keyboard shortcuts. they caused confusion and were probably rarely used + Buttons in the mainmenue now stay highlighted when an area is selected + Fixed a bug where users would not get an email notify when a task is assigned + Usernames on multiply asssigned tasks are now properly linked to each users profile + Fixed a problem preventing Safari and Chrome users from creating users. + Fixed a possible security flaw in the chat component + Added missing truncation to the project name in the "my tasks" column on the desktop, and the my tasks view + Added date of day to the timetracker PDF export per user + Fixed bug where no emails would be send when assigning new users to a task. Also refactored code for assigning users. + Fixed a possible problem in the mailer class. + Removed 2 unneeded tinyMCE plugins. This further reduces the amount of code to load for tiny MCE + Show the calendar on the desktop for all users, not just admins. + Updated list of languages in which the install-readme.txt is available + Added Swedish translation of the install-readme.txt + Fixed folder visibility Collabtive 0.6.3 + Cleaned up user profile: company only displayed if available + Added option "all" to visibility selection of a new folder + Fixed bug where display of members in project members area and user administration was restricted to 10 users + Removed mini calendar from sidebar since it served no real purpose + Fixed a bug in tasklist editing where not all active milestones were available to assign the list to. + Added Favicon to standard theme + Added TinyMCE editor options to message edit form, reply form, milestone add form, and milestone edit form + Dropped update support for updating from versions earlier than 0.5 + Removed calls to deprecated function set_magic_quotes_runtime() in class tcpdf (PDF export) + Renamed language file folders for Chinese, Greek, Ukranian, Galician, Japanese, and Czech so they match those used in TinyMCE + Complete translation to English, German, Romanian, and Bulgarian + Added readme in Italian + Added English manual + Added comments + Replaced chat icon in frost theme with a slightly darker one + Fixed file upload bug where file would be uploaded to the server but not to the database + Fixed a bug where asignee would not be set correctly upon adding a task + Fixed a bug where editing of a task could result in the task being assigned to no user + Fixed a bug where editing of a tasklist enforced assigning the list to a milestone + Fixed a bug where project budget would automatically be reset to 0 upon editing the project + Cleaned up project view: budget only displayed if > 0; description only displayed if available. + Cleaned up tasklist view: description only displayed if available. + Cleaned up message view: replies only displayed if available; removed delete icon, which did not work properly anyway. + Fixed a bug in email notification for task assignment + Fixed a bug in user timetracking filter (last day of selection not discarded any more) + Fixed upload paths + Fixed blank page when trying to install from SVN + Fixed problem where user with project-add-permission but without admin-permission added a project would get an error message + Added permission check for closing tasklist + Added page title for tasklist edit form, message edit form, and reply form + Added system message on desktop when creating, deleting, or closing a project + Added optimization queries for database tables 'roles' and 'roles_assigned' in update script + Code cleanup @descartes + Fixed standard template + Fixed version number in the footer + Updated language files to match fixes + Fixed a bug in user management + Fixed typo when viewing tasklists @whisperwind + Fixed minor issue where deleting user + Fixed an autocompletition issue where editing users + Fixed truncating problem where using multibyte characters + Added login by email in addition to login by username + Remove some more calls to session_is_registred in favour of isset($_SESSION) + Made mb_string extension mandatory during installation + Fixed a problem with long project/task names @avychodil + Fixed wrong image path in message replies Collabtive 0.6.2 + Downgraded Prototype to 1.6.0.3 to avoid problems with IE. + Fixed a bug when filtering timetracker + Fixed "milestones tab unvisible for non-admins" + Removed property required = "0" from non-required form fields. This should improve Opera compatibility. + Fixed some wrong image paths. + Fixed a bug when editing a task. + Properly implemented assign task to some/all users of a project + Added complete russian translation + Fixed small display bug in single tasklist view Collabtive 0.6.1 + Fixed some bugs in the frost theme + Fixed a UTF-8 entity bug in the mailer component + Included missing picture for the upload progressbar + Removed some more calls to deprecated session_is_registered() in favor of isset($_SESSION) + Fixed a display Bug in Safari/Webkit + Fixed role editing in frost + Fixed a UI glitch in the login screen where to login-button would disappear onmouseover. + Included missing pictures for pagination arrows + Fixed inserting default roles fails when updating from an old version due to a missing field + Fixed a bug where the calendar view would not be displayed on the project page. + Tasks without an end-date no longer show as a lot of days overdue + Fixed a bug in the formvalidator where it would not accept certain valid e-mail adresses + Improved Catalan translation + Fixed a security bug where any user could delete any file or folder in projects he belonged to. + Fixed editing timetracker data did not show the tinyMCE editor (mloeffen) + Fixed a bug in TinyMCE textfields where newlines were inserted after editing + File manager now stores who uploaded a file in the database. Uploader is displayed in the file list view. + First version of a plugin implementation + Fixed wrong version number in frost theme Collabtive 0.6 + Fixed a bug where file description of files in subfolders could not be edited. + Added "add project" functionality to the projects block on the desktop. + Fixed a bug preventing the attaching of existing files to messages. + Refactoring of class project. Removed a lot of unneeded code. + Refactoring of class tasklist. Removed a lot of unneeded code. + Refactoring of class message. Removed some uneeded code. + Refactoring of class milestone. Removed a lot of unneeded code. + Refactoring of class datei. Removed some unneeded code. + Fixed a bug in class milestone, preventing milestones with end date "today" from showing up when there where no other milestones. + Fixed a bug in the calculation of days left of milestones. + When closing or deleting stuff (tasks, milestones, messages, etc) asynchronously, the alternating background color of the table rows is properly restored. + Date format can now be configured to be d.m.Y or m/d/Y + Updated Prototype library to 1.6, Scriptaculous to 1.8., finally. + Fixed a bug where the filetype icon of a file would not be displayed (instead "?" icon). + Fixed a bug when deleting folders. + Fixed display of filecount when 0 files are present. + Implemented unlimited subfolders for files. + Implemented moving files between folders via drag and drop. + Implemented access control on a per-file basis. + Removed deprecated function session_register() from user::login(), now relying on $_SESSION only. + Implemented E-Mail notify when uploading new files + Tasks can now be assigned to multiple users + Added (fake) progress indicator when uploading files + Fixed a bad string replacement in install.php, preventing some users from installing + Fixed some MySQL queries that caused problems on some configurations (mloeffen) Collabtive 0.5.5 + Roles may now be edited + Added some missing strings (role added, edited, etc) + Fixed display of days left for projects without due date + Fixed more installer problems + Implemented RSS feed for project messages + New theme: "Frost" included. Contributed by Kemie Guaida. + Backported some changes to the frost theme + Improved themeability of some ajax elements + Updated PDF library to TCPDF 4.5.39 + Removed unneeded PDF fonts, reducing the package size + PDF exports of messages now show the postdate of each message + Implemented PDF export of the "my messages" view. + Implemented PDF export for single messages + Fixed a bug where PDF export would insert empty pages between pages with content + More TinyMCE cleanups (unneeded packages removed) + Fixed some small UI glitches + Removed Basecamp import from the installer to reduce confusion + Fixed a bug where tasks could not be re-opened due to improper permissions + Fixed a bug where users could not be de-assigned from a project due to improper permissions + Users can now be assigned to projects on the admin->projects view in the project details (again). + Implemented email notifications when posting messages. + Added userpermissions for chat functionality (i.e. stop clients chatting ;) ) + Made get methods of class milestone consistently return 10 results by default (instead of some 5, some 10) + Implemented simple company field in the userprofile. + Refactor class task to use internal method getTask() in all get methods, instead of inline code to retrieve tasks. + Messages are now asynchronously deleted + Improved Basecamp importer to use the new permissions system + Fixed a bug where project->tasklists would show no closed tasklists if there are no open ones + Added company field to the userprofile + Addec company field to vCard export Collabtive 0.5 + Fixed problem in the installer on IIS + Make most methods return associative arrays only , instead of numeric and associative indexed arrays. This creates less memory overhead, and simplifies the conversion to XML + First version of an XML API included + Improved PDF Export (full UTF8 support for PDF reports) + Implemented PDF export for project->messages + When creating a new user, the user is notified via email + Fixed a bug in admin->users and project->users (missing pagination) + Fixed some UI glitches + Fixed Imagelist in tinyMCE editor not displaying files without a title + Fixed short PHP tags in style_main.php (standard theme) + Fixed wrong breadcrumb link in single message view + Made randon number generator use mt_rand(). Numbers are attached to uploaded files. + Implemented new, role-based, user permissions system + Started porting smarty classes to strict PHP5 + New locales: Arabian, Slovak, Swedish, Ukrainian, Finish, Catalan + Improved Basecamp import: Assign currently logged in user to imported projects (not just the imported users) + Basecamp import now imports replies to messages, as well as the messages themselves. + Basecamp import now properly imports task-titles , not only the textbody + Fixed Basecamp import in standard template (admin->system and installer) + Fixed a bug where userprofiles would get mangled up when changing system settings in admin->system + Edit project on project view now correctly shows wyswyg editor + Show more tasks on "my tasks" view on the desktop + Removed many unneeded TinyMCE Plugins from the package + Implemented properly styled error messages + Implemented Username and Password for access to RSS Feeds + Tasks may now be added by clicking on the day numbers on the project view calendar Collabtive 0.4.9.1 + Fixed display bug in mac/safari (admin->user) + Fixed a bug when changing the picture of users, as admin + Cleaned up problems in the userprofile + fixed bug preventing avatar pictures from being uploaded in Internet Explorer + Improved folder handling + Improved timetracker reporting (normal users can now see their own hours) + Folderexport now possible in the file explorer + Fixed a bug in timetracker report pagination (project view) + Fixed a bug in the JS calender on the desktop in IE + Fixed some wrong links in the new Collabtive 0.4.9 + Clear the template cache when changing themes + Added option Mail from name + Implemented ajaxified close element and delete element + Updated to TinyMCE 3.2 + Fixed a bug when changing the avatar of other users, as admin + Implemented hourly rate setting for Users + Implemented Budget setting for Projects + Pagination now themeable + Implemented imagelist in TinyMCE editor. When inserting a picture, using tinyMCE a list of pictures populated from the uploaded files is presented + Implemented re-written JS based calendar and datepicker + Added chinese (simplified) localisation + Implemented configurable Date format + Fixed some security vulnerabilities + Fixed link to tasks RSS feed + Fixed detection of own URL on MS IIS + Added profile fields for phone and mobile to the userprofile + Added company information + Added Yahoo map to the userprofile showing the user's location using Yahoo geocoding web API + Implemented new calendar for milestones on the desktop + Completely re-designed standard theme. Classic theme added. + Implemented keyboard Shortcuts (Ctrl-D,Ctrl-T,Ctrl-M,Ctrl-P,esc) + Timetracking report is now in ascending chronological order Collabtive 0.4.8 + Updated TinyMCE to 3.1 + Messages can be attached to milestones + Fixed "my messages" view to include tags selection + Fixed "my messages" view to include tags display + Email alerts improved (now completely localised, available for add task and add project) + Support for using custom SMTP servers with Email Alerts + Fixed: bug in form validator -> it now accepts email adresses containing numbers + Improved: display of dependent items in milestones (removed unneeded comma) + Fixed: bug in the installer, that made timetracking unusable + Timezone can now be set independent of the server timezone in Admin -> System configuration + Cleaned up code in init.php + Removed redundant call to getAvailableLanguages() in init.php. -> more efficient + Implemented support for subfolders + When an administrator changes the global system language, all users language settings are updated accordingly. + Made link in the user profile clickable + Made Email in the user profile clickable + Fixed: bulleted lists created from the wyswyg editor (they now actually include bullets ;) ) + Fixed: various UI glitches + Moved the short project report to the "description" area of the project details on projectview + Fixed: Only display tagcloud when there actually are tagged items in the project + Changed the task title to mandatory , and the text as optional + Added spanish readme + Beginngins of an XML / JSON API (class toXml) Collabtive 0.4.7 + Implemented tagcloud on the projectview + Fixed a bug in timetracker:add on windows + Cleaned up pathing in init.php (pointed out by jcorreia) + Fixed a bug in the updater, preventing messages to be posted + Improved installer to check for PHP 5.1 instead of only PHP5 + Implemented OpenID login + Users can now be tagged + When deassigning a user from a project, remaining tasks of that user can be re-assigned to another user, or deleted + Multisite setup now possible + Fixed typo in JS files (character encoding = UTF8 , not :utf8) + Timetracking reports now include the comments + Implemented preliminary email alerts support + Alpha Version of a Google Gadget included + Fixed link to tasklist on My Tasks->Done Tasks + Updated to the latest Smarty release (2.6.19) + Improved Basecamp import + Fixed security flaw in admin.php + Milestones view on project->milestones can now be toggled between list and calendar view Collabtive 0.4.6 + Fixed a bug preventing user from logging in + Added dutch locale + Added lituanian locale + Added measuring of localizing completeness for each locale (translated vs untranslated ratio) + Language selectors now show completely localized language names ("English", "German") instead of the locale codes ("en","de") + Fixed display Bug in IE7 on the timetracking report (project/user) + When deleting a user, all timetracking for that user is deleted, too. + Installer cimpletely localized now + Additional locales supported in the installer (Spanish, Italian, Japanese, Dutch) + Cleaned up language files (removing redundant / unused strings) + Running on an SSL/HTTPS connection now properly supported + Fix bug when Collabtive is installed with an empty DB password + Fixed missing curly brace in chat.js + Improved protection against SQL injections + Implemented tagging for files and messages + Edit user permissions as Admin + Datepicker supports all supported locales now. + Implemented Basecamp import functionality. + Included Basecamp importer in the installer + When deleting a project, all tasks from that project are deleted too (fixed typo). + Fixed display bug in the "My projects" block when logged in as a non-admin user. Collabtive 0.4.5 + Vcard export of userprofiles + Fixed a bug in the milestones timeline + Added profile fields URL, Gender, ZIP + Improved Formvalidator to support regular expressions + Timetracker form now checks for correct time format (hh:mm) + Updated Tiny MCE to latest version (3.0.5) ; Solves Bug in Safari + Removed some unused Tiny MCE plugins from the package. + Improved Task management code + Messages can be edited again + Admins can now edit the passwords of all users. + Timetracking for Tasks now possible. + Project reporting can now be filtered for tasks + Project reporting can now be filtered for users + User reporting can now be filtered for projects + PDF Reports show the name of the project / user they were generated for + PDF and Excel Reports show tasks + Reorganized order of buttons in the projectview menu + Reorganized order of blocks on the desktop + Projectlog can be exported to excel + Added Accordeon in Projects Block on the desktop (shows projects description) + Fixed some page titles + Fixed security bug when uploading avatars (only pictures are accepted, now) + Introduced new Userrole: Client. Clients have read-only access to the system. They can also not see any internal messages. + When deleting a user, it can now be chosen if the tasks of this user shall be deleted or re-assigned to another user. + Polished edges in the installer template + Support for locales with more than 2 characters (like pt_br, es_gl, etc) + Added turkish locale + Added japanese locale Collabtive 0.4 + Closed tasks can now be edited again + RSS feeds are encoded in UTF8 + Implemented search functionality (class.search.php + managesearch.php) + Ontype search added + Closed tasks are visible on the mytasks view even if they have < 1 days "left" under "closed tasks" + Fixed wrong link for ZIP export of projectfiles + Implemented add search to browser-searchbox for FF2/3 and IE7/8 + Implemented searchplugin autodiscovery for FF2/3 and IE7/8 + Project log can be exported to PDF + Progressmeter improved: The smaller part of the pie should be moving always . + Project progress report as PDF implemented + Collapsing the milestones block is now persistent throughout desktop / project view + Fixed "Out of range error" on INSERT queries with MySQL5 on Windows + Tooltips for milestone details + Object (Message, Task, Project, File, etc) descriptions are now properly formatted (added nl2br modifier) + Made state of blocks (open / collapsed) persistent for remaining (project,timetracker,log) blocks on project view + Improved consistency of language settings (when creating a new user, the system default language is used) + Page title of project view now includes Project name + My messages Block on the desktop shows only messages from open projects now + Refactored database code + Added stripslashes() when reading strings from MySQL + Added My Messages RSS Feed + Added RSS Autodiscovery + New messages can now also be added from the My Messages view + New Collabtive icon as favicon + Changed formblock toggle from appear to blind + Fixed notices in iCal export + Ical feed can now be imported to ms outlook to (outlook is a bit "special" when parsing ical) + Removed favicon option + Implemented Systemsounds for Login, Logout and Error + Implemented filter for Timetracker report (only display a certain timeframe). Exported reports are filtered, too. + Improved styling of the onlinelist + Fixed a bug in thumb.php when running on error_reporting(E_ALL) + Unified Export icon, that expands on mouseover and shows available export options (RSS , PDF, XLS , etc) + Implemented 154 Unit tests to test all classes against regressions automatically. We use Simpletest for this. Fixed many small bugs in the process. + My Messages block on the desktop only shown if there actually are messages. + Class documentation translated to english + Improved localisation in the installer, installing with other systemdefault languages than english works properly now. + Made Collabtive run flawless when setting error_reporting(E_STRICT) / Strict mode. + Improve security by making config.php non-writable again after the installer has written to it (CHMOD 0755). + Added confirm() when deleting closed tasklists + Added confirm() when deleting projects from the "my projects" view. + Removed project edit, and del for non-admin users on my projects view(were non-functional anyway) + First page of the installer better localized + HTML Form in installer step2 styled correctly Collabtive 0.3.6 + When closing a project, close any objects belonging to it, too + When closing a tasklist, close all tasks on the list too + When deleting a tasklist, delete all the tasks on the list too + When deleting a project, timetracking for this project is deleted too + ZIP Format export for projectfiles + Fixed uploading/attaching files when replying to a message through the single page form + Fixed existing file selector for attaching files when replying + Fixed closed objects view + Email Address now optional when editing a user + Various fields now only visible when present, in profile view + When uploading multiple files, they can now have multiple titles + Removed duplicated variable declarations in managetasklist.php + Show progressindicator only if there is at least 1 finished task + Make tasklist names on my tasks view clickable + Milestone titles in the overviews are now truncated after 30 characters + Added confirmdel string to french locale + Replying messages is possible without attaching files + New global JS functions delRow() (delete a table row), delEle() (delete any element), systemMsg() (fade in a block and create a timer to fadeout again) + Closed tasks in tasklist view are now sorted DESC (latest task shows up first) + Project deadline / end date can now be entered + Project view shows remaining days until deadline, instead of startdate + Fixed problem with file upload paths (http://www.collabtive.o-dyn.de/forum/viewtopic.php?f=11&t=80) + PHP Scripts are now uploaded as Textfiles. This prevents random script execution and enables easy viewing as text + Duplicate email address / username results in an errorpage (not in a blank page) + Removed a duplicated Constant definition in install.php + Fixed page title in userprofile view to be multilanguage + Pagetitles now finally _completely_ localized + Fixed Default system locale->user locale relation Collabtive 0.3.5 + Add Flash progressmeter on project view + Attach files when replying a message + Show replies only when there are > 0 replies in the message view + All my Messages view + Eventmessages are faded out after 7 seconds + Correctly display lightbox on filelinks in the single message view + Large code cleanup (no more E_NOTICE) + Fixed datepicker when using english locale + Add pagination at the project->files view + Add projects of a user block to the userprofile , for admins + Fixed task title truncating on desktop + Updated update.php to reflect changes in 0.3.5 + Added simple timetracking + Changed Profile link in the main navigation from edit profile , to view profile + Current time can now be auto entered in the timetracker form onclick. + User password can now be changed + Activity log is now paginated + Excel export for timetracker + PDF export for timetracker + Fixed pagination to not always "remember" the last page visited. Caused problems when previously visited page doesn't exist anymore. + Fixed a 4545possible security vulnerability in class.datei.php + Fixed localisation for eventmessages in the filemanager + Added a Javascript confirm popup to all delete actions, to avoid accidential deletes + Added a Timetracking Tab in the projectview + Put all strings from MySQL through stripslashes() to reverse mysql_real_escape_string on add + Installer checks for templates_c to be present and writable at startup + Installer has better errorhandling + Added danish locale �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/config/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�12372520637�0014713�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/config/standard/���������������������������������������������������������������������0000775�0000000�0000000�00000000000�12372520637�0016513�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/config/standard/config.php�����������������������������������������������������������0000664�0000000�0000000�00000000105�12372520637�0020465�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php $db_host = ""; $db_name = ""; $db_user = ""; $db_pass = ""; ?> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/dav.php������������������������������������������������������������������������������0000664�0000000�0000000�00000013766�12372520637�0014746�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php // Files we need require_once 'include/Sabre/autoload.php'; require("init.php"); // class MyDirectory extends Sabre_DAV_Collection { class MyDirectory extends Sabre_DAV_FS_Directory implements Sabre_DAV_ICollection, Sabre_DAV_IQuota { private $myPath; private $proObj; private $user; function __construct($myPath) { $this->myPath = $myPath; $this->proObj = new project(); $this->fileObj = new datei(); } public function createFile($name, $data = null) { $newPath = $this->myPath . '/' . $name; file_put_contents($newPath, $data); $this->fileObj->add_file(basename($newPath), "", 1, 0, "", $newPath, "", ""); } /** * Creates a new subdirectory * * @param string $name * @return void */ public function createDirectory($name) { $newPath = $this->myPath . '/' . $name; mkdir($newPath); } /** * Deletes all files in this directory, and then itself * * @return void */ public function delete() { foreach($this->getChildren() as $child) $child->delete(); rmdir($this->path); } function getChildren() { $children = array(); // Loop through the directory, and create objects for each node foreach(scandir($this->myPath) as $node) { // Ignoring files staring with . if ($node[0] === '.') continue; $children[] = $this->getChild($node); } return $children; } function getChild($name) { if (strstr($name, "-")) { $name = explode("-", $name); $name = $name[1]; } $path = $this->myPath . '/' . $name; // We have to throw a NotFound exception if the file didn't exist if (!file_exists($path)) die('The file with name: ' . $name . ' could not be found'); // Some added security if ($name[0] == '.') throw new Sabre_DAV_Exception_NotFound('Access denied'); if (is_dir($path)) { return new MyDirectory($path); } else { return new MyFile($path); } } function childExists($name) { if (strstr($name, "-")) { $name = explode("-", $name); $name = $name[1]; } return file_exists($this->myPath . '/' . $name); } function getName() { $tmpname = (int) basename($this->myPath); if ($tmpname > 0) { $user = $_SESSION["userid"]; if (chkproject($user, $tmpname)) { $name = $this->proObj->getProject($tmpname); $name = $name["name"]; if ($name and $tmpname) { return $name . "-" . $tmpname; } } } else { return basename($this->myPath); } } /** * Returns available diskspace information * * @return array */ public function getQuotaInfo() { return array( disk_total_space($this->myPath) - disk_free_space($this->myPath), disk_free_space($this->myPath) ); } } class MyFile extends Sabre_DAV_FS_File implements Sabre_DAV_IFile { private $myPath; function __construct($myPath) { $this->myPath = $myPath; } public function put($data) { file_put_contents($this->$myPath, $data); } function getName() { return basename($this->myPath); } function get() { return fopen($this->myPath, 'r'); } function getSize() { return filesize($this->myPath); } function getETag() { return '"' . md5_file($this->myPath) . '"'; } /** * Returns the mime-type for a file * * If null is returned, we'll assume application/octet-stream * * @return mixed */ public function getContentType() { return null; } public function delete() { unlink($this->$myPath); } } $auth = new Sabre_HTTP_BasicAuth(); $result = $auth->getUserPass(); $aUser = $result[0]; $aPass = $result[1]; $userObj = new user(); $profile = $userObj->getProfile($userObj->getId($aUser)); if (!$profile) { $auth->requireLogin(); echo "Username doesn't exist!\n"; die(); } if ($profile["pass"] != sha1(trim($aPass))) { $auth->requireLogin(); echo "Wrong password!\n"; die(); } $userObj->login($aUser, $aPass); /* if (!$result || $result[0]!=$u || $result[1]!=$p) { $auth->requireLogin(); echo "Authentication required\n"; die(); } */ // Now we're creating a whole bunch of objects // Change public to something else, if you are using a different directory for your files // $rootDirectory = new Sabre_DAV_FS_Directory('files/standard'); $rootDirectory = new MyDirectory('files/standard'); // The server object is responsible for making sense out of the WebDAV protocol // Now we create an ObjectTree, which dispatches all requests to your newly created file system $objectTree = new Sabre_DAV_ObjectTree($rootDirectory); // The object tree needs in turn to be passed to the server class $server = new Sabre_DAV_Server($rootDirectory); // If your server is not on your webroot, make sure the following line has the correct information // $server->setBaseUri('/~evert/mydavfolder'); // if its in some kind of home directory $server->setBaseUri('/test/dav.php/'); // if you can't use mod_rewrite, use server.php as a base uri // $server->setBaseUri('/'); // ideally, SabreDAV lives on a root directory with mod_rewrite sending every request to server.php // The lock manager is reponsible for making sure users don't overwrite each others changes. Change 'data' to a different // directory, if you're storing your data somewhere else. $lockBackend = new Sabre_DAV_Locks_Backend_File('files/davdata/'); $lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend); // $server->addPlugin($lockPlugin); $plugin = new Sabre_DAV_Browser_Plugin(); $server->addPlugin($plugin); // All we need to do now, is to fire up the server $server->exec(); ?>����������Collabtive-2.0/include/�����������������������������������������������������������������������������0000775�0000000�0000000�00000000000�12372520637�0015071�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/include/Config_File.class.php��������������������������������������������������������0000664�0000000�0000000�00000030706�12372520637�0021060�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php /** * Config_File class. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://smarty.php.net/ * @version 2.6.19 * @copyright Copyright: 2001-2005 New Digital Group, Inc. * @author Andrei Zmievski <andrei@php.net> * @access public * @package Smarty */ /* $Id: Config_File.class.php 2702 2007-03-08 19:11:22Z mohrt $ */ /** * Config file reading class * @package Smarty */ class Config_File { /**#@+ * Options * @var boolean */ /** * Controls whether variables with the same name overwrite each other. */ var $overwrite = true; /** * Controls whether config values of on/true/yes and off/false/no get * converted to boolean values automatically. */ var $booleanize = true; /** * Controls whether hidden config sections/vars are read from the file. */ var $read_hidden = true; /** * Controls whether or not to fix mac or dos formatted newlines. * If set to true, \r or \r\n will be changed to \n. */ var $fix_newlines = true; /**#@-*/ /** @access private */ var $_config_path = ""; var $_config_data = array(); /**#@-*/ /** * Constructs a new config file class. * * @param string $config_path (optional) path to the config files */ function Config_File($config_path = NULL) { if (isset($config_path)) $this->set_path($config_path); } /** * Set the path where configuration files can be found. * * @param string $config_path path to the config files */ function set_path($config_path) { if (!empty($config_path)) { if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { $this->_trigger_error_msg("Bad config file path '$config_path'"); return; } if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { $config_path .= DIRECTORY_SEPARATOR; } $this->_config_path = $config_path; } } /** * Retrieves config info based on the file, section, and variable name. * * @param string $file_name config file to get info for * @param string $section_name (optional) section to get info for * @param string $var_name (optional) variable to get info for * @return string|array a value or array of values */ function get($file_name, $section_name = NULL, $var_name = NULL) { if (empty($file_name)) { $this->_trigger_error_msg('Empty config file name'); return; } else { $file_name = $this->_config_path . $file_name; if (!isset($this->_config_data[$file_name])) $this->load_file($file_name, false); } if (!empty($var_name)) { if (empty($section_name)) { return $this->_config_data[$file_name]["vars"][$var_name]; } else { if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; else return array(); } } else { if (empty($section_name)) { return (array)$this->_config_data[$file_name]["vars"]; } else { if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; else return array(); } } } /** * Retrieves config info based on the key. * * @param $file_name string config key (filename/section/var) * @return string|array same as get() * @uses get() retrieves information from config file and returns it */ function &get_key($config_key) { list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); $result = &$this->get($file_name, $section_name, $var_name); return $result; } /** * Get all loaded config file names. * * @return array an array of loaded config file names */ function get_file_names() { return array_keys($this->_config_data); } /** * Get all section names from a loaded file. * * @param string $file_name config file to get section names from * @return array an array of section names from the specified file */ function get_section_names($file_name) { $file_name = $this->_config_path . $file_name; if (!isset($this->_config_data[$file_name])) { $this->_trigger_error_msg("Unknown config file '$file_name'"); return; } return array_keys($this->_config_data[$file_name]["sections"]); } /** * Get all global or section variable names. * * @param string $file_name config file to get info for * @param string $section_name (optional) section to get info for * @return array an array of variables names from the specified file/section */ function get_var_names($file_name, $section = NULL) { if (empty($file_name)) { $this->_trigger_error_msg('Empty config file name'); return; } else if (!isset($this->_config_data[$file_name])) { $this->_trigger_error_msg("Unknown config file '$file_name'"); return; } if (empty($section)) return array_keys($this->_config_data[$file_name]["vars"]); else return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); } /** * Clear loaded config data for a certain file or all files. * * @param string $file_name file to clear config data for */ function clear($file_name = NULL) { if ($file_name === NULL) $this->_config_data = array(); else if (isset($this->_config_data[$file_name])) $this->_config_data[$file_name] = array(); } /** * Load a configuration file manually. * * @param string $file_name file name to load * @param boolean $prepend_path whether current config path should be * prepended to the filename */ function load_file($file_name, $prepend_path = true) { if ($prepend_path && $this->_config_path != "") $config_file = $this->_config_path . $file_name; else $config_file = $file_name; ini_set('track_errors', true); $fp = @fopen($config_file, "r"); if (!is_resource($fp)) { $this->_trigger_error_msg("Could not open config file '$config_file'"); return false; } $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; fclose($fp); $this->_config_data[$config_file] = $this->parse_contents($contents); return true; } /** * Store the contents of a file manually. * * @param string $config_file file name of the related contents * @param string $contents the file-contents to parse */ function set_file_contents($config_file, $contents) { $this->_config_data[$config_file] = $this->parse_contents($contents); return true; } /** * parse the source of a configuration file manually. * * @param string $contents the file-contents to parse */ function parse_contents($contents) { if($this->fix_newlines) { // fix mac/dos formatted newlines $contents = preg_replace('!\r\n?!', "\n", $contents); } $config_data = array(); $config_data['sections'] = array(); $config_data['vars'] = array(); /* reference to fill with data */ $vars =& $config_data['vars']; /* parse file line by line */ preg_match_all('!^.*\r?\n?!m', $contents, $match); $lines = $match[0]; for ($i=0, $count=count($lines); $i<$count; $i++) { $line = $lines[$i]; if (empty($line)) continue; if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { /* section found */ if (substr($match[1], 0, 1) == '.') { /* hidden section */ if ($this->read_hidden) { $section_name = substr($match[1], 1); } else { /* break reference to $vars to ignore hidden section */ unset($vars); $vars = array(); continue; } } else { $section_name = $match[1]; } if (!isset($config_data['sections'][$section_name])) $config_data['sections'][$section_name] = array('vars' => array()); $vars =& $config_data['sections'][$section_name]['vars']; continue; } if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { /* variable found */ $var_name = rtrim($match[1]); if (strpos($match[2], '"""') === 0) { /* handle multiline-value */ $lines[$i] = substr($match[2], 3); $var_value = ''; while ($i<$count) { if (($pos = strpos($lines[$i], '"""')) === false) { $var_value .= $lines[$i++]; } else { /* end of multiline-value */ $var_value .= substr($lines[$i], 0, $pos); break; } } $booleanize = false; } else { /* handle simple value */ $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); $booleanize = $this->booleanize; } $this->_set_config_var($vars, $var_name, $var_value, $booleanize); } /* else unparsable line / means it is a comment / means ignore it */ } return $config_data; } /**#@+ @access private */ /** * @param array &$container * @param string $var_name * @param mixed $var_value * @param boolean $booleanize determines whether $var_value is converted to * to true/false */ function _set_config_var(&$container, $var_name, $var_value, $booleanize) { if (substr($var_name, 0, 1) == '.') { if (!$this->read_hidden) return; else $var_name = substr($var_name, 1); } if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { $this->_trigger_error_msg("Bad variable name '$var_name'"); return; } if ($booleanize) { if (preg_match("/^(on|true|yes)$/i", $var_value)) $var_value = true; else if (preg_match("/^(off|false|no)$/i", $var_value)) $var_value = false; } if (!isset($container[$var_name]) || $this->overwrite) $container[$var_name] = $var_value; else { settype($container[$var_name], 'array'); $container[$var_name][] = $var_value; } } /** * @uses trigger_error() creates a PHP warning/error * @param string $error_msg * @param integer $error_type one of */ function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) { trigger_error("Config_File error: $error_msg", $error_type); } /**#@-*/ } ?> ����������������������������������������������������������Collabtive-2.0/include/HTMLPurifier.standalone.php��������������������������������������������������0000664�0000000�0000000�00002452751�12372520637�0022223�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php /** * @file * This file was auto-generated by generate-includes.php and includes all of * the core files required by HTML Purifier. Use this if performance is a * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * FILE, changes will be overwritten the next time the script is run. * * @version 4.6.0 * * @warning * You must *not* include any other HTML Purifier files before this file, * because 'require' not 'require_once' is used. * * @warning * This file requires that the include path contains the HTML Purifier * library directory; this is not auto-set. */ /*! @mainpage * * HTML Purifier is an HTML filter that will take an arbitrary snippet of * HTML and rigorously test, validate and filter it into a version that * is safe for output onto webpages. It achieves this by: * * -# Lexing (parsing into tokens) the document, * -# Executing various strategies on the tokens: * -# Removing all elements not in the whitelist, * -# Making the tokens well-formed, * -# Fixing the nesting of the nodes, and * -# Validating attributes of the nodes; and * -# Generating HTML from the purified tokens. * * However, most users will only need to interface with the HTMLPurifier * and HTMLPurifier_Config. */ /* HTML Purifier 4.6.0 - Standards Compliant HTML Filtering Copyright (C) 2006-2008 Edward Z. Yang This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Facade that coordinates HTML Purifier's subsystems in order to purify HTML. * * @note There are several points in which configuration can be specified * for HTML Purifier. The precedence of these (from lowest to * highest) is as follows: * -# Instance: new HTMLPurifier($config) * -# Invocation: purify($html, $config) * These configurations are entirely independent of each other and * are *not* merged (this behavior may change in the future). * * @todo We need an easier way to inject strategies using the configuration * object. */ class HTMLPurifier { /** * Version of HTML Purifier. * @type string */ public $version = '4.6.0'; /** * Constant with version of HTML Purifier. */ const VERSION = '4.6.0'; /** * Global configuration object. * @type HTMLPurifier_Config */ public $config; /** * Array of extra filter objects to run on HTML, * for backwards compatibility. * @type HTMLPurifier_Filter[] */ private $filters = array(); /** * Single instance of HTML Purifier. * @type HTMLPurifier */ private static $instance; /** * @type HTMLPurifier_Strategy_Core */ protected $strategy; /** * @type HTMLPurifier_Generator */ protected $generator; /** * Resultant context of last run purification. * Is an array of contexts if the last called method was purifyArray(). * @type HTMLPurifier_Context */ public $context; /** * Initializes the purifier. * * @param HTMLPurifier_Config $config Optional HTMLPurifier_Config object * for all instances of the purifier, if omitted, a default * configuration is supplied (which can be overridden on a * per-use basis). * The parameter can also be any type that * HTMLPurifier_Config::create() supports. */ public function __construct($config = null) { $this->config = HTMLPurifier_Config::create($config); $this->strategy = new HTMLPurifier_Strategy_Core(); } /** * Adds a filter to process the output. First come first serve * * @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object */ public function addFilter($filter) { trigger_error( 'HTMLPurifier->addFilter() is deprecated, use configuration directives' . ' in the Filter namespace or Filter.Custom', E_USER_WARNING ); $this->filters[] = $filter; } /** * Filters an HTML snippet/document to be XSS-free and standards-compliant. * * @param string $html String of HTML to purify * @param HTMLPurifier_Config $config Config object for this operation, * if omitted, defaults to the config object specified during this * object's construction. The parameter can also be any type * that HTMLPurifier_Config::create() supports. * * @return string Purified HTML */ public function purify($html, $config = null) { // :TODO: make the config merge in, instead of replace $config = $config ? HTMLPurifier_Config::create($config) : $this->config; // implementation is partially environment dependant, partially // configuration dependant $lexer = HTMLPurifier_Lexer::create($config); $context = new HTMLPurifier_Context(); // setup HTML generator $this->generator = new HTMLPurifier_Generator($config, $context); $context->register('Generator', $this->generator); // set up global context variables if ($config->get('Core.CollectErrors')) { // may get moved out if other facilities use it $language_factory = HTMLPurifier_LanguageFactory::instance(); $language = $language_factory->create($config, $context); $context->register('Locale', $language); $error_collector = new HTMLPurifier_ErrorCollector($context); $context->register('ErrorCollector', $error_collector); } // setup id_accumulator context, necessary due to the fact that // AttrValidator can be called from many places $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); $context->register('IDAccumulator', $id_accumulator); $html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context); // setup filters $filter_flags = $config->getBatch('Filter'); $custom_filters = $filter_flags['Custom']; unset($filter_flags['Custom']); $filters = array(); foreach ($filter_flags as $filter => $flag) { if (!$flag) { continue; } if (strpos($filter, '.') !== false) { continue; } $class = "HTMLPurifier_Filter_$filter"; $filters[] = new $class; } foreach ($custom_filters as $filter) { // maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat $filters[] = $filter; } $filters = array_merge($filters, $this->filters); // maybe prepare(), but later for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) { $html = $filters[$i]->preFilter($html, $config, $context); } // purified HTML $html = $this->generator->generateFromTokens( // list of tokens $this->strategy->execute( // list of un-purified tokens $lexer->tokenizeHTML( // un-purified HTML $html, $config, $context ), $config, $context ) ); for ($i = $filter_size - 1; $i >= 0; $i--) { $html = $filters[$i]->postFilter($html, $config, $context); } $html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context); $this->context =& $context; return $html; } /** * Filters an array of HTML snippets * * @param string[] $array_of_html Array of html snippets * @param HTMLPurifier_Config $config Optional config object for this operation. * See HTMLPurifier::purify() for more details. * * @return string[] Array of purified HTML */ public function purifyArray($array_of_html, $config = null) { $context_array = array(); foreach ($array_of_html as $key => $html) { $array_of_html[$key] = $this->purify($html, $config); $context_array[$key] = $this->context; } $this->context = $context_array; return $array_of_html; } /** * Singleton for enforcing just one HTML Purifier in your system * * @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype * HTMLPurifier instance to overload singleton with, * or HTMLPurifier_Config instance to configure the * generated version with. * * @return HTMLPurifier */ public static function instance($prototype = null) { if (!self::$instance || $prototype) { if ($prototype instanceof HTMLPurifier) { self::$instance = $prototype; } elseif ($prototype) { self::$instance = new HTMLPurifier($prototype); } else { self::$instance = new HTMLPurifier(); } } return self::$instance; } /** * Singleton for enforcing just one HTML Purifier in your system * * @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype * HTMLPurifier instance to overload singleton with, * or HTMLPurifier_Config instance to configure the * generated version with. * * @return HTMLPurifier * @note Backwards compatibility, see instance() */ public static function getInstance($prototype = null) { return HTMLPurifier::instance($prototype); } } /** * Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node, * and back again. * * @note This transformation is not an equivalence. We mutate the input * token stream to make it so; see all [MUT] markers in code. */ class HTMLPurifier_Arborize { public static function arborize($tokens, $config, $context) { $definition = $config->getHTMLDefinition(); $parent = new HTMLPurifier_Token_Start($definition->info_parent); $stack = array($parent->toNode()); foreach ($tokens as $token) { $token->skip = null; // [MUT] $token->carryover = null; // [MUT] if ($token instanceof HTMLPurifier_Token_End) { $token->start = null; // [MUT] $r = array_pop($stack); assert($r->name === $token->name); assert(empty($token->attr)); $r->endCol = $token->col; $r->endLine = $token->line; $r->endArmor = $token->armor; continue; } $node = $token->toNode(); $stack[count($stack)-1]->children[] = $node; if ($token instanceof HTMLPurifier_Token_Start) { $stack[] = $node; } } assert(count($stack) == 1); return $stack[0]; } public static function flatten($node, $config, $context) { $level = 0; $nodes = array($level => new HTMLPurifier_Queue(array($node))); $closingTokens = array(); $tokens = array(); do { while (!$nodes[$level]->isEmpty()) { $node = $nodes[$level]->shift(); // FIFO list($start, $end) = $node->toTokenPair(); if ($level > 0) { $tokens[] = $start; } if ($end !== NULL) { $closingTokens[$level][] = $end; } if ($node instanceof HTMLPurifier_Node_Element) { $level++; $nodes[$level] = new HTMLPurifier_Queue(); foreach ($node->children as $childNode) { $nodes[$level]->push($childNode); } } } $level--; if ($level && isset($closingTokens[$level])) { while ($token = array_pop($closingTokens[$level])) { $tokens[] = $token; } } } while ($level > 0); return $tokens; } } /** * Defines common attribute collections that modules reference */ class HTMLPurifier_AttrCollections { /** * Associative array of attribute collections, indexed by name. * @type array */ public $info = array(); /** * Performs all expansions on internal data for use by other inclusions * It also collects all attribute collection extensions from * modules * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance * @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members */ public function __construct($attr_types, $modules) { // load extensions from the modules foreach ($modules as $module) { foreach ($module->attr_collections as $coll_i => $coll) { if (!isset($this->info[$coll_i])) { $this->info[$coll_i] = array(); } foreach ($coll as $attr_i => $attr) { if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { // merge in includes $this->info[$coll_i][$attr_i] = array_merge( $this->info[$coll_i][$attr_i], $attr ); continue; } $this->info[$coll_i][$attr_i] = $attr; } } } // perform internal expansions and inclusions foreach ($this->info as $name => $attr) { // merge attribute collections that include others $this->performInclusions($this->info[$name]); // replace string identifiers with actual attribute objects $this->expandIdentifiers($this->info[$name], $attr_types); } } /** * Takes a reference to an attribute associative array and performs * all inclusions specified by the zero index. * @param array &$attr Reference to attribute array */ public function performInclusions(&$attr) { if (!isset($attr[0])) { return; } $merge = $attr[0]; $seen = array(); // recursion guard // loop through all the inclusions for ($i = 0; isset($merge[$i]); $i++) { if (isset($seen[$merge[$i]])) { continue; } $seen[$merge[$i]] = true; // foreach attribute of the inclusion, copy it over if (!isset($this->info[$merge[$i]])) { continue; } foreach ($this->info[$merge[$i]] as $key => $value) { if (isset($attr[$key])) { continue; } // also catches more inclusions $attr[$key] = $value; } if (isset($this->info[$merge[$i]][0])) { // recursion $merge = array_merge($merge, $this->info[$merge[$i]][0]); } } unset($attr[0]); } /** * Expands all string identifiers in an attribute array by replacing * them with the appropriate values inside HTMLPurifier_AttrTypes * @param array &$attr Reference to attribute array * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance */ public function expandIdentifiers(&$attr, $attr_types) { // because foreach will process new elements we add, make sure we // skip duplicates $processed = array(); foreach ($attr as $def_i => $def) { // skip inclusions if ($def_i === 0) { continue; } if (isset($processed[$def_i])) { continue; } // determine whether or not attribute is required if ($required = (strpos($def_i, '*') !== false)) { // rename the definition unset($attr[$def_i]); $def_i = trim($def_i, '*'); $attr[$def_i] = $def; } $processed[$def_i] = true; // if we've already got a literal object, move on if (is_object($def)) { // preserve previous required $attr[$def_i]->required = ($required || $attr[$def_i]->required); continue; } if ($def === false) { unset($attr[$def_i]); continue; } if ($t = $attr_types->get($def)) { $attr[$def_i] = $t; $attr[$def_i]->required = $required; } else { unset($attr[$def_i]); } } } } /** * Base class for all validating attribute definitions. * * This family of classes forms the core for not only HTML attribute validation, * but also any sort of string that needs to be validated or cleaned (which * means CSS properties and composite definitions are defined here too). * Besides defining (through code) what precisely makes the string valid, * subclasses are also responsible for cleaning the code if possible. */ abstract class HTMLPurifier_AttrDef { /** * Tells us whether or not an HTML attribute is minimized. * Has no meaning in other contexts. * @type bool */ public $minimized = false; /** * Tells us whether or not an HTML attribute is required. * Has no meaning in other contexts * @type bool */ public $required = false; /** * Validates and cleans passed string according to a definition. * * @param string $string String to be validated and cleaned. * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object. * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object. */ abstract public function validate($string, $config, $context); /** * Convenience method that parses a string as if it were CDATA. * * This method process a string in the manner specified at * <http://www.w3.org/TR/html4/types.html#h-6.2> by removing * leading and trailing whitespace, ignoring line feeds, and replacing * carriage returns and tabs with spaces. While most useful for HTML * attributes specified as CDATA, it can also be applied to most CSS * values. * * @note This method is not entirely standards compliant, as trim() removes * more types of whitespace than specified in the spec. In practice, * this is rarely a problem, as those extra characters usually have * already been removed by HTMLPurifier_Encoder. * * @warning This processing is inconsistent with XML's whitespace handling * as specified by section 3.3.3 and referenced XHTML 1.0 section * 4.7. However, note that we are NOT necessarily * parsing XML, thus, this behavior may still be correct. We * assume that newlines have been normalized. */ public function parseCDATA($string) { $string = trim($string); $string = str_replace(array("\n", "\t", "\r"), ' ', $string); return $string; } /** * Factory method for creating this class from a string. * @param string $string String construction info * @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string */ public function make($string) { // default implementation, return a flyweight of this object. // If $string has an effect on the returned object (i.e. you // need to overload this method), it is best // to clone or instantiate new copies. (Instantiation is safer.) return $this; } /** * Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work * properly. THIS IS A HACK! * @param string $string a CSS colour definition * @return string */ protected function mungeRgb($string) { return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string); } /** * Parses a possibly escaped CSS string and returns the "pure" * version of it. */ protected function expandCSSEscape($string) { // flexibly parse it $ret = ''; for ($i = 0, $c = strlen($string); $i < $c; $i++) { if ($string[$i] === '\\') { $i++; if ($i >= $c) { $ret .= '\\'; break; } if (ctype_xdigit($string[$i])) { $code = $string[$i]; for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) { if (!ctype_xdigit($string[$i])) { break; } $code .= $string[$i]; } // We have to be extremely careful when adding // new characters, to make sure we're not breaking // the encoding. $char = HTMLPurifier_Encoder::unichr(hexdec($code)); if (HTMLPurifier_Encoder::cleanUTF8($char) === '') { continue; } $ret .= $char; if ($i < $c && trim($string[$i]) !== '') { $i--; } continue; } if ($string[$i] === "\n") { continue; } } $ret .= $string[$i]; } return $ret; } } /** * Processes an entire attribute array for corrections needing multiple values. * * Occasionally, a certain attribute will need to be removed and popped onto * another value. Instead of creating a complex return syntax for * HTMLPurifier_AttrDef, we just pass the whole attribute array to a * specialized object and have that do the special work. That is the * family of HTMLPurifier_AttrTransform. * * An attribute transformation can be assigned to run before or after * HTMLPurifier_AttrDef validation. See HTMLPurifier_HTMLDefinition for * more details. */ abstract class HTMLPurifier_AttrTransform { /** * Abstract: makes changes to the attributes dependent on multiple values. * * @param array $attr Assoc array of attributes, usually from * HTMLPurifier_Token_Tag::$attr * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object. * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object * @return array Processed attribute array. */ abstract public function transform($attr, $config, $context); /** * Prepends CSS properties to the style attribute, creating the * attribute if it doesn't exist. * @param array &$attr Attribute array to process (passed by reference) * @param string $css CSS to prepend */ public function prependCSS(&$attr, $css) { $attr['style'] = isset($attr['style']) ? $attr['style'] : ''; $attr['style'] = $css . $attr['style']; } /** * Retrieves and removes an attribute * @param array &$attr Attribute array to process (passed by reference) * @param mixed $key Key of attribute to confiscate * @return mixed */ public function confiscateAttr(&$attr, $key) { if (!isset($attr[$key])) { return null; } $value = $attr[$key]; unset($attr[$key]); return $value; } } /** * Provides lookup array of attribute types to HTMLPurifier_AttrDef objects */ class HTMLPurifier_AttrTypes { /** * Lookup array of attribute string identifiers to concrete implementations. * @type HTMLPurifier_AttrDef[] */ protected $info = array(); /** * Constructs the info array, supplying default implementations for attribute * types. */ public function __construct() { // XXX This is kind of poor, since we don't actually /clone/ // instances; instead, we use the supplied make() attribute. So, // the underlying class must know how to deal with arguments. // With the old implementation of Enum, that ignored its // arguments when handling a make dispatch, the IAlign // definition wouldn't work. // pseudo-types, must be instantiated via shorthand $this->info['Enum'] = new HTMLPurifier_AttrDef_Enum(); $this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool(); $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text(); $this->info['ID'] = new HTMLPurifier_AttrDef_HTML_ID(); $this->info['Length'] = new HTMLPurifier_AttrDef_HTML_Length(); $this->info['MultiLength'] = new HTMLPurifier_AttrDef_HTML_MultiLength(); $this->info['NMTOKENS'] = new HTMLPurifier_AttrDef_HTML_Nmtokens(); $this->info['Pixels'] = new HTMLPurifier_AttrDef_HTML_Pixels(); $this->info['Text'] = new HTMLPurifier_AttrDef_Text(); $this->info['URI'] = new HTMLPurifier_AttrDef_URI(); $this->info['LanguageCode'] = new HTMLPurifier_AttrDef_Lang(); $this->info['Color'] = new HTMLPurifier_AttrDef_HTML_Color(); $this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right'); $this->info['LAlign'] = self::makeEnum('top,bottom,left,right'); $this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget(); // unimplemented aliases $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); $this->info['ContentTypes'] = new HTMLPurifier_AttrDef_Text(); $this->info['Charsets'] = new HTMLPurifier_AttrDef_Text(); $this->info['Character'] = new HTMLPurifier_AttrDef_Text(); // "proprietary" types $this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class(); // number is really a positive integer (one or more digits) // FIXME: ^^ not always, see start and value of list items $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); } private static function makeEnum($in) { return new HTMLPurifier_AttrDef_Clone(new HTMLPurifier_AttrDef_Enum(explode(',', $in))); } /** * Retrieves a type * @param string $type String type name * @return HTMLPurifier_AttrDef Object AttrDef for type */ public function get($type) { // determine if there is any extra info tacked on if (strpos($type, '#') !== false) { list($type, $string) = explode('#', $type, 2); } else { $string = ''; } if (!isset($this->info[$type])) { trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR); return; } return $this->info[$type]->make($string); } /** * Sets a new implementation for a type * @param string $type String type name * @param HTMLPurifier_AttrDef $impl Object AttrDef for type */ public function set($type, $impl) { $this->info[$type] = $impl; } } /** * Validates the attributes of a token. Doesn't manage required attributes * very well. The only reason we factored this out was because RemoveForeignElements * also needed it besides ValidateAttributes. */ class HTMLPurifier_AttrValidator { /** * Validates the attributes of a token, mutating it as necessary. * that has valid tokens * @param HTMLPurifier_Token $token Token to validate. * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config * @param HTMLPurifier_Context $context Instance of HTMLPurifier_Context */ public function validateToken($token, $config, $context) { $definition = $config->getHTMLDefinition(); $e =& $context->get('ErrorCollector', true); // initialize IDAccumulator if necessary $ok =& $context->get('IDAccumulator', true); if (!$ok) { $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); $context->register('IDAccumulator', $id_accumulator); } // initialize CurrentToken if necessary $current_token =& $context->get('CurrentToken', true); if (!$current_token) { $context->register('CurrentToken', $token); } if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty ) { return; } // create alias to global definition array, see also $defs // DEFINITION CALL $d_defs = $definition->info_global_attr; // don't update token until the very end, to ensure an atomic update $attr = $token->attr; // do global transformations (pre) // nothing currently utilizes this foreach ($definition->info_attr_transform_pre as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { if ($attr != $o) { $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); } } } // do local transformations only applicable to this element (pre) // ex. <p align="right"> to <p style="text-align:right;"> foreach ($definition->info[$token->name]->attr_transform_pre as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { if ($attr != $o) { $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); } } } // create alias to this element's attribute definition array, see // also $d_defs (global attribute definition array) // DEFINITION CALL $defs = $definition->info[$token->name]->attr; $attr_key = false; $context->register('CurrentAttr', $attr_key); // iterate through all the attribute keypairs // Watch out for name collisions: $key has previously been used foreach ($attr as $attr_key => $value) { // call the definition if (isset($defs[$attr_key])) { // there is a local definition defined if ($defs[$attr_key] === false) { // We've explicitly been told not to allow this element. // This is usually when there's a global definition // that must be overridden. // Theoretically speaking, we could have a // AttrDef_DenyAll, but this is faster! $result = false; } else { // validate according to the element's definition $result = $defs[$attr_key]->validate( $value, $config, $context ); } } elseif (isset($d_defs[$attr_key])) { // there is a global definition defined, validate according // to the global definition $result = $d_defs[$attr_key]->validate( $value, $config, $context ); } else { // system never heard of the attribute? DELETE! $result = false; } // put the results into effect if ($result === false || $result === null) { // this is a generic error message that should replaced // with more specific ones when possible if ($e) { $e->send(E_ERROR, 'AttrValidator: Attribute removed'); } // remove the attribute unset($attr[$attr_key]); } elseif (is_string($result)) { // generally, if a substitution is happening, there // was some sort of implicit correction going on. We'll // delegate it to the attribute classes to say exactly what. // simple substitution $attr[$attr_key] = $result; } else { // nothing happens } // we'd also want slightly more complicated substitution // involving an array as the return value, // although we're not sure how colliding attributes would // resolve (certain ones would be completely overriden, // others would prepend themselves). } $context->destroy('CurrentAttr'); // post transforms // global (error reporting untested) foreach ($definition->info_attr_transform_post as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { if ($attr != $o) { $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); } } } // local (error reporting untested) foreach ($definition->info[$token->name]->attr_transform_post as $transform) { $attr = $transform->transform($o = $attr, $config, $context); if ($e) { if ($attr != $o) { $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); } } } $token->attr = $attr; // destroy CurrentToken if we made it ourselves if (!$current_token) { $context->destroy('CurrentToken'); } } } // constants are slow, so we use as few as possible if (!defined('HTMLPURIFIER_PREFIX')) { define('HTMLPURIFIER_PREFIX', dirname(__FILE__) . '/standalone'); set_include_path(HTMLPURIFIER_PREFIX . PATH_SEPARATOR . get_include_path()); } // accomodations for versions earlier than 5.0.2 // borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <aidan@php.net> if (!defined('PHP_EOL')) { switch (strtoupper(substr(PHP_OS, 0, 3))) { case 'WIN': define('PHP_EOL', "\r\n"); break; case 'DAR': define('PHP_EOL', "\r"); break; default: define('PHP_EOL', "\n"); } } /** * Bootstrap class that contains meta-functionality for HTML Purifier such as * the autoload function. * * @note * This class may be used without any other files from HTML Purifier. */ class HTMLPurifier_Bootstrap { /** * Autoload function for HTML Purifier * @param string $class Class to load * @return bool */ public static function autoload($class) { $file = HTMLPurifier_Bootstrap::getPath($class); if (!$file) { return false; } // Technically speaking, it should be ok and more efficient to // just do 'require', but Antonio Parraga reports that with // Zend extensions such as Zend debugger and APC, this invariant // may be broken. Since we have efficient alternatives, pay // the cost here and avoid the bug. require_once HTMLPURIFIER_PREFIX . '/' . $file; return true; } /** * Returns the path for a specific class. * @param string $class Class path to get * @return string */ public static function getPath($class) { if (strncmp('HTMLPurifier', $class, 12) !== 0) { return false; } // Custom implementations if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) { $code = str_replace('_', '-', substr($class, 22)); $file = 'HTMLPurifier/Language/classes/' . $code . '.php'; } else { $file = str_replace('_', '/', $class) . '.php'; } if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) { return false; } return $file; } /** * "Pre-registers" our autoloader on the SPL stack. */ public static function registerAutoload() { $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); if (($funcs = spl_autoload_functions()) === false) { spl_autoload_register($autoload); } elseif (function_exists('spl_autoload_unregister')) { if (version_compare(PHP_VERSION, '5.3.0', '>=')) { // prepend flag exists, no need for shenanigans spl_autoload_register($autoload, true, true); } else { $buggy = version_compare(PHP_VERSION, '5.2.11', '<'); $compat = version_compare(PHP_VERSION, '5.1.2', '<=') && version_compare(PHP_VERSION, '5.1.0', '>='); foreach ($funcs as $func) { if ($buggy && is_array($func)) { // :TRICKY: There are some compatibility issues and some // places where we need to error out $reflector = new ReflectionMethod($func[0], $func[1]); if (!$reflector->isStatic()) { throw new Exception( 'HTML Purifier autoloader registrar is not compatible with non-static object methods due to PHP Bug #44144; Please do not use HTMLPurifier.autoload.php (or any file that includes this file); instead, place the code: spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\')) after your own autoloaders.' ); } // Suprisingly, spl_autoload_register supports the // Class::staticMethod callback format, although call_user_func doesn't if ($compat) { $func = implode('::', $func); } } spl_autoload_unregister($func); } spl_autoload_register($autoload); foreach ($funcs as $func) { spl_autoload_register($func); } } } } } /** * Super-class for definition datatype objects, implements serialization * functions for the class. */ abstract class HTMLPurifier_Definition { /** * Has setup() been called yet? * @type bool */ public $setup = false; /** * If true, write out the final definition object to the cache after * setup. This will be true only if all invocations to get a raw * definition object are also optimized. This does not cause file * system thrashing because on subsequent calls the cached object * is used and any writes to the raw definition object are short * circuited. See enduser-customize.html for the high-level * picture. * @type bool */ public $optimized = null; /** * What type of definition is it? * @type string */ public $type; /** * Sets up the definition object into the final form, something * not done by the constructor * @param HTMLPurifier_Config $config */ abstract protected function doSetup($config); /** * Setup function that aborts if already setup * @param HTMLPurifier_Config $config */ public function setup($config) { if ($this->setup) { return; } $this->setup = true; $this->doSetup($config); } } /** * Defines allowed CSS attributes and what their values are. * @see HTMLPurifier_HTMLDefinition */ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition { public $type = 'CSS'; /** * Assoc array of attribute name to definition object. * @type HTMLPurifier_AttrDef[] */ public $info = array(); /** * Constructs the info array. The meat of this class. * @param HTMLPurifier_Config $config */ protected function doSetup($config) { $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( array('left', 'right', 'center', 'justify'), false ); $border_style = $this->info['border-bottom-style'] = $this->info['border-right-style'] = $this->info['border-left-style'] = $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( array( 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset' ), false ); $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( array('none', 'left', 'right', 'both'), false ); $this->info['float'] = new HTMLPurifier_AttrDef_Enum( array('none', 'left', 'right'), false ); $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( array('normal', 'italic', 'oblique'), false ); $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( array('normal', 'small-caps'), false ); $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum(array('none')), new HTMLPurifier_AttrDef_CSS_URI() ) ); $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( array('inside', 'outside'), false ); $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( array( 'disc', 'circle', 'square', 'decimal', 'lower-roman', 'upper-roman', 'lower-alpha', 'upper-alpha', 'none' ), false ); $this->info['list-style-image'] = $uri_or_none; $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( array('capitalize', 'uppercase', 'lowercase', 'none'), false ); $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['background-image'] = $uri_or_none; $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( array('repeat', 'repeat-x', 'repeat-y', 'no-repeat') ); $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( array('scroll', 'fixed') ); $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); $border_color = $this->info['border-top-color'] = $this->info['border-bottom-color'] = $this->info['border-left-color'] = $this->info['border-right-color'] = $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum(array('transparent')), new HTMLPurifier_AttrDef_CSS_Color() ) ); $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color); $border_width = $this->info['border-top-width'] = $this->info['border-bottom-width'] = $this->info['border-left-width'] = $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative ) ); $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum(array('normal')), new HTMLPurifier_AttrDef_CSS_Length() ) ); $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum(array('normal')), new HTMLPurifier_AttrDef_CSS_Length() ) ); $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum( array( 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'larger', 'smaller' ) ), new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Length() ) ); $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum(array('normal')), new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true) ) ); $margin = $this->info['margin-top'] = $this->info['margin-bottom'] = $this->info['margin-left'] = $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_Enum(array('auto')) ) ); $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); // non-negative $padding = $this->info['padding-top'] = $this->info['padding-bottom'] = $this->info['padding-left'] = $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true) ) ); $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage() ) ); $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Percentage(true), new HTMLPurifier_AttrDef_Enum(array('auto')) ) ); $max = $config->get('CSS.MaxImgLength'); $this->info['width'] = $this->info['height'] = $max === null ? $trusted_wh : new HTMLPurifier_AttrDef_Switch( 'img', // For img tags: new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_CSS_Length('0', $max), new HTMLPurifier_AttrDef_Enum(array('auto')) ) ), // For everyone else: $trusted_wh ); $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); // this could use specialized code $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( array( 'normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900' ), false ); // MUST be called after other font properties, as it references // a CSSDefinition object $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config); // same here $this->info['border'] = $this->info['border-bottom'] = $this->info['border-top'] = $this->info['border-left'] = $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( array('collapse', 'separate') ); $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( array('top', 'bottom') ); $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( array('auto', 'fixed') ); $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Enum( array( 'baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom' ) ), new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage() ) ); $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); // These CSS properties don't work on many browsers, but we live // in THE FUTURE! $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line') ); if ($config->get('CSS.Proprietary')) { $this->doSetupProprietary($config); } if ($config->get('CSS.AllowTricky')) { $this->doSetupTricky($config); } if ($config->get('CSS.Trusted')) { $this->doSetupTrusted($config); } $allow_important = $config->get('CSS.AllowImportant'); // wrap all attr-defs with decorator that handles !important foreach ($this->info as $k => $v) { $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important); } $this->setupConfigStuff($config); } /** * @param HTMLPurifier_Config $config */ protected function doSetupProprietary($config) { // Internet Explorer only scrollbar colors $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); // technically not proprietary, but CSS3, and no one supports it $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); // only opacity, for now $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter(); // more CSS3 $this->info['page-break-after'] = $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( array( 'auto', 'always', 'avoid', 'left', 'right' ) ); $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid')); } /** * @param HTMLPurifier_Config $config */ protected function doSetupTricky($config) { $this->info['display'] = new HTMLPurifier_AttrDef_Enum( array( 'inline', 'block', 'list-item', 'run-in', 'compact', 'marker', 'table', 'inline-block', 'inline-table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none' ) ); $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( array('visible', 'hidden', 'collapse') ); $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); } /** * @param HTMLPurifier_Config $config */ protected function doSetupTrusted($config) { $this->info['position'] = new HTMLPurifier_AttrDef_Enum( array('static', 'relative', 'absolute', 'fixed') ); $this->info['top'] = $this->info['left'] = $this->info['right'] = $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_Enum(array('auto')), ) ); $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( array( new HTMLPurifier_AttrDef_Integer(), new HTMLPurifier_AttrDef_Enum(array('auto')), ) ); } /** * Performs extra config-based processing. Based off of * HTMLPurifier_HTMLDefinition. * @param HTMLPurifier_Config $config * @todo Refactor duplicate elements into common class (probably using * composition, not inheritance). */ protected function setupConfigStuff($config) { // setup allowed elements $support = "(for information on implementing this, see the " . "support forums) "; $allowed_properties = $config->get('CSS.AllowedProperties'); if ($allowed_properties !== null) { foreach ($this->info as $name => $d) { if (!isset($allowed_properties[$name])) { unset($this->info[$name]); } unset($allowed_properties[$name]); } // emit errors foreach ($allowed_properties as $name => $d) { // :TODO: Is this htmlspecialchars() call really necessary? $name = htmlspecialchars($name); trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING); } } $forbidden_properties = $config->get('CSS.ForbiddenProperties'); if ($forbidden_properties !== null) { foreach ($this->info as $name => $d) { if (isset($forbidden_properties[$name])) { unset($this->info[$name]); } } } } } /** * Defines allowed child nodes and validates nodes against it. */ abstract class HTMLPurifier_ChildDef { /** * Type of child definition, usually right-most part of class name lowercase. * Used occasionally in terms of context. * @type string */ public $type; /** * Indicates whether or not an empty array of children is okay. * * This is necessary for redundant checking when changes affecting * a child node may cause a parent node to now be disallowed. * @type bool */ public $allow_empty; /** * Lookup array of all elements that this definition could possibly allow. * @type array */ public $elements = array(); /** * Get lookup of tag names that should not close this element automatically. * All other elements will do so. * @param HTMLPurifier_Config $config HTMLPurifier_Config object * @return array */ public function getAllowedElements($config) { return $this->elements; } /** * Validates nodes according to definition and returns modification. * * @param HTMLPurifier_Node[] $children Array of HTMLPurifier_Node * @param HTMLPurifier_Config $config HTMLPurifier_Config object * @param HTMLPurifier_Context $context HTMLPurifier_Context object * @return bool|array true to leave nodes as is, false to remove parent node, array of replacement children */ abstract public function validateChildren($children, $config, $context); } /** * Configuration object that triggers customizable behavior. * * @warning This class is strongly defined: that means that the class * will fail if an undefined directive is retrieved or set. * * @note Many classes that could (although many times don't) use the * configuration object make it a mandatory parameter. This is * because a configuration object should always be forwarded, * otherwise, you run the risk of missing a parameter and then * being stumped when a configuration directive doesn't work. * * @todo Reconsider some of the public member variables */ class HTMLPurifier_Config { /** * HTML Purifier's version * @type string */ public $version = '4.6.0'; /** * Whether or not to automatically finalize * the object if a read operation is done. * @type bool */ public $autoFinalize = true; // protected member variables /** * Namespace indexed array of serials for specific namespaces. * @see getSerial() for more info. * @type string[] */ protected $serials = array(); /** * Serial for entire configuration object. * @type string */ protected $serial; /** * Parser for variables. * @type HTMLPurifier_VarParser_Flexible */ protected $parser = null; /** * Reference HTMLPurifier_ConfigSchema for value checking. * @type HTMLPurifier_ConfigSchema * @note This is public for introspective purposes. Please don't * abuse! */ public $def; /** * Indexed array of definitions. * @type HTMLPurifier_Definition[] */ protected $definitions; /** * Whether or not config is finalized. * @type bool */ protected $finalized = false; /** * Property list containing configuration directives. * @type array */ protected $plist; /** * Whether or not a set is taking place due to an alias lookup. * @type bool */ private $aliasMode; /** * Set to false if you do not want line and file numbers in errors. * (useful when unit testing). This will also compress some errors * and exceptions. * @type bool */ public $chatty = true; /** * Current lock; only gets to this namespace are allowed. * @type string */ private $lock; /** * Constructor * @param HTMLPurifier_ConfigSchema $definition ConfigSchema that defines * what directives are allowed. * @param HTMLPurifier_PropertyList $parent */ public function __construct($definition, $parent = null) { $parent = $parent ? $parent : $definition->defaultPlist; $this->plist = new HTMLPurifier_PropertyList($parent); $this->def = $definition; // keep a copy around for checking $this->parser = new HTMLPurifier_VarParser_Flexible(); } /** * Convenience constructor that creates a config object based on a mixed var * @param mixed $config Variable that defines the state of the config * object. Can be: a HTMLPurifier_Config() object, * an array of directives based on loadArray(), * or a string filename of an ini file. * @param HTMLPurifier_ConfigSchema $schema Schema object * @return HTMLPurifier_Config Configured object */ public static function create($config, $schema = null) { if ($config instanceof HTMLPurifier_Config) { // pass-through return $config; } if (!$schema) { $ret = HTMLPurifier_Config::createDefault(); } else { $ret = new HTMLPurifier_Config($schema); } if (is_string($config)) { $ret->loadIni($config); } elseif (is_array($config)) $ret->loadArray($config); return $ret; } /** * Creates a new config object that inherits from a previous one. * @param HTMLPurifier_Config $config Configuration object to inherit from. * @return HTMLPurifier_Config object with $config as its parent. */ public static function inherit(HTMLPurifier_Config $config) { return new HTMLPurifier_Config($config->def, $config->plist); } /** * Convenience constructor that creates a default configuration object. * @return HTMLPurifier_Config default object. */ public static function createDefault() { $definition = HTMLPurifier_ConfigSchema::instance(); $config = new HTMLPurifier_Config($definition); return $config; } /** * Retrieves a value from the configuration. * * @param string $key String key * @param mixed $a * * @return mixed */ public function get($key, $a = null) { if ($a !== null) { $this->triggerError( "Using deprecated API: use \$config->get('$key.$a') instead", E_USER_WARNING ); $key = "$key.$a"; } if (!$this->finalized) { $this->autoFinalize(); } if (!isset($this->def->info[$key])) { // can't add % due to SimpleTest bug $this->triggerError( 'Cannot retrieve value of undefined directive ' . htmlspecialchars($key), E_USER_WARNING ); return; } if (isset($this->def->info[$key]->isAlias)) { $d = $this->def->info[$key]; $this->triggerError( 'Cannot get value from aliased directive, use real name ' . $d->key, E_USER_ERROR ); return; } if ($this->lock) { list($ns) = explode('.', $key); if ($ns !== $this->lock) { $this->triggerError( 'Cannot get value of namespace ' . $ns . ' when lock for ' . $this->lock . ' is active, this probably indicates a Definition setup method ' . 'is accessing directives that are not within its namespace', E_USER_ERROR ); return; } } return $this->plist->get($key); } /** * Retrieves an array of directives to values from a given namespace * * @param string $namespace String namespace * * @return array */ public function getBatch($namespace) { if (!$this->finalized) { $this->autoFinalize(); } $full = $this->getAll(); if (!isset($full[$namespace])) { $this->triggerError( 'Cannot retrieve undefined namespace ' . htmlspecialchars($namespace), E_USER_WARNING ); return; } return $full[$namespace]; } /** * Returns a SHA-1 signature of a segment of the configuration object * that uniquely identifies that particular configuration * * @param string $namespace Namespace to get serial for * * @return string * @note Revision is handled specially and is removed from the batch * before processing! */ public function getBatchSerial($namespace) { if (empty($this->serials[$namespace])) { $batch = $this->getBatch($namespace); unset($batch['DefinitionRev']); $this->serials[$namespace] = sha1(serialize($batch)); } return $this->serials[$namespace]; } /** * Returns a SHA-1 signature for the entire configuration object * that uniquely identifies that particular configuration * * @return string */ public function getSerial() { if (empty($this->serial)) { $this->serial = sha1(serialize($this->getAll())); } return $this->serial; } /** * Retrieves all directives, organized by namespace * * @warning This is a pretty inefficient function, avoid if you can */ public function getAll() { if (!$this->finalized) { $this->autoFinalize(); } $ret = array(); foreach ($this->plist->squash() as $name => $value) { list($ns, $key) = explode('.', $name, 2); $ret[$ns][$key] = $value; } return $ret; } /** * Sets a value to configuration. * * @param string $key key * @param mixed $value value * @param mixed $a */ public function set($key, $value, $a = null) { if (strpos($key, '.') === false) { $namespace = $key; $directive = $value; $value = $a; $key = "$key.$directive"; $this->triggerError("Using deprecated API: use \$config->set('$key', ...) instead", E_USER_NOTICE); } else { list($namespace) = explode('.', $key); } if ($this->isFinalized('Cannot set directive after finalization')) { return; } if (!isset($this->def->info[$key])) { $this->triggerError( 'Cannot set undefined directive ' . htmlspecialchars($key) . ' to value', E_USER_WARNING ); return; } $def = $this->def->info[$key]; if (isset($def->isAlias)) { if ($this->aliasMode) { $this->triggerError( 'Double-aliases not allowed, please fix '. 'ConfigSchema bug with' . $key, E_USER_ERROR ); return; } $this->aliasMode = true; $this->set($def->key, $value); $this->aliasMode = false; $this->triggerError("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE); return; } // Raw type might be negative when using the fully optimized form // of stdclass, which indicates allow_null == true $rtype = is_int($def) ? $def : $def->type; if ($rtype < 0) { $type = -$rtype; $allow_null = true; } else { $type = $rtype; $allow_null = isset($def->allow_null); } try { $value = $this->parser->parse($value, $type, $allow_null); } catch (HTMLPurifier_VarParserException $e) { $this->triggerError( 'Value for ' . $key . ' is of invalid type, should be ' . HTMLPurifier_VarParser::getTypeName($type), E_USER_WARNING ); return; } if (is_string($value) && is_object($def)) { // resolve value alias if defined if (isset($def->aliases[$value])) { $value = $def->aliases[$value]; } // check to see if the value is allowed if (isset($def->allowed) && !isset($def->allowed[$value])) { $this->triggerError( 'Value not supported, valid values are: ' . $this->_listify($def->allowed), E_USER_WARNING ); return; } } $this->plist->set($key, $value); // reset definitions if the directives they depend on changed // this is a very costly process, so it's discouraged // with finalization if ($namespace == 'HTML' || $namespace == 'CSS' || $namespace == 'URI') { $this->definitions[$namespace] = null; } $this->serials[$namespace] = false; } /** * Convenience function for error reporting * * @param array $lookup * * @return string */ private function _listify($lookup) { $list = array(); foreach ($lookup as $name => $b) { $list[] = $name; } return implode(', ', $list); } /** * Retrieves object reference to the HTML definition. * * @param bool $raw Return a copy that has not been setup yet. Must be * called before it's been setup, otherwise won't work. * @param bool $optimized If true, this method may return null, to * indicate that a cached version of the modified * definition object is available and no further edits * are necessary. Consider using * maybeGetRawHTMLDefinition, which is more explicitly * named, instead. * * @return HTMLPurifier_HTMLDefinition */ public function getHTMLDefinition($raw = false, $optimized = false) { return $this->getDefinition('HTML', $raw, $optimized); } /** * Retrieves object reference to the CSS definition * * @param bool $raw Return a copy that has not been setup yet. Must be * called before it's been setup, otherwise won't work. * @param bool $optimized If true, this method may return null, to * indicate that a cached version of the modified * definition object is available and no further edits * are necessary. Consider using * maybeGetRawCSSDefinition, which is more explicitly * named, instead. * * @return HTMLPurifier_CSSDefinition */ public function getCSSDefinition($raw = false, $optimized = false) { return $this->getDefinition('CSS', $raw, $optimized); } /** * Retrieves object reference to the URI definition * * @param bool $raw Return a copy that has not been setup yet. Must be * called before it's been setup, otherwise won't work. * @param bool $optimized If true, this method may return null, to * indicate that a cached version of the modified * definition object is available and no further edits * are necessary. Consider using * maybeGetRawURIDefinition, which is more explicitly * named, instead. * * @return HTMLPurifier_URIDefinition */ public function getURIDefinition($raw = false, $optimized = false) { return $this->getDefinition('URI', $raw, $optimized); } /** * Retrieves a definition * * @param string $type Type of definition: HTML, CSS, etc * @param bool $raw Whether or not definition should be returned raw * @param bool $optimized Only has an effect when $raw is true. Whether * or not to return null if the result is already present in * the cache. This is off by default for backwards * compatibility reasons, but you need to do things this * way in order to ensure that caching is done properly. * Check out enduser-customize.html for more details. * We probably won't ever change this default, as much as the * maybe semantics is the "right thing to do." * * @throws HTMLPurifier_Exception * @return HTMLPurifier_Definition */ public function getDefinition($type, $raw = false, $optimized = false) { if ($optimized && !$raw) { throw new HTMLPurifier_Exception("Cannot set optimized = true when raw = false"); } if (!$this->finalized) { $this->autoFinalize(); } // temporarily suspend locks, so we can handle recursive definition calls $lock = $this->lock; $this->lock = null; $factory = HTMLPurifier_DefinitionCacheFactory::instance(); $cache = $factory->create($type, $this); $this->lock = $lock; if (!$raw) { // full definition // --------------- // check if definition is in memory if (!empty($this->definitions[$type])) { $def = $this->definitions[$type]; // check if the definition is setup if ($def->setup) { return $def; } else { $def->setup($this); if ($def->optimized) { $cache->add($def, $this); } return $def; } } // check if definition is in cache $def = $cache->get($this); if ($def) { // definition in cache, save to memory and return it $this->definitions[$type] = $def; return $def; } // initialize it $def = $this->initDefinition($type); // set it up $this->lock = $type; $def->setup($this); $this->lock = null; // save in cache $cache->add($def, $this); // return it return $def; } else { // raw definition // -------------- // check preconditions $def = null; if ($optimized) { if (is_null($this->get($type . '.DefinitionID'))) { // fatally error out if definition ID not set throw new HTMLPurifier_Exception( "Cannot retrieve raw version without specifying %$type.DefinitionID" ); } } if (!empty($this->definitions[$type])) { $def = $this->definitions[$type]; if ($def->setup && !$optimized) { $extra = $this->chatty ? " (try moving this code block earlier in your initialization)" : ""; throw new HTMLPurifier_Exception( "Cannot retrieve raw definition after it has already been setup" . $extra ); } if ($def->optimized === null) { $extra = $this->chatty ? " (try flushing your cache)" : ""; throw new HTMLPurifier_Exception( "Optimization status of definition is unknown" . $extra ); } if ($def->optimized !== $optimized) { $msg = $optimized ? "optimized" : "unoptimized"; $extra = $this->chatty ? " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" : ""; throw new HTMLPurifier_Exception( "Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra ); } } // check if definition was in memory if ($def) { if ($def->setup) { // invariant: $optimized === true (checked above) return null; } else { return $def; } } // if optimized, check if definition was in cache // (because we do the memory check first, this formulation // is prone to cache slamming, but I think // guaranteeing that either /all/ of the raw // setup code or /none/ of it is run is more important.) if ($optimized) { // This code path only gets run once; once we put // something in $definitions (which is guaranteed by the // trailing code), we always short-circuit above. $def = $cache->get($this); if ($def) { // save the full definition for later, but don't // return it yet $this->definitions[$type] = $def; return null; } } // check invariants for creation if (!$optimized) { if (!is_null($this->get($type . '.DefinitionID'))) { if ($this->chatty) { $this->triggerError( 'Due to a documentation error in previous version of HTML Purifier, your ' . 'definitions are not being cached. If this is OK, you can remove the ' . '%$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, ' . 'modify your code to use maybeGetRawDefinition, and test if the returned ' . 'value is null before making any edits (if it is null, that means that a ' . 'cached version is available, and no raw operations are necessary). See ' . '<a href="http://htmlpurifier.org/docs/enduser-customize.html#optimized">' . 'Customize</a> for more details', E_USER_WARNING ); } else { $this->triggerError( "Useless DefinitionID declaration", E_USER_WARNING ); } } } // initialize it $def = $this->initDefinition($type); $def->optimized = $optimized; return $def; } throw new HTMLPurifier_Exception("The impossible happened!"); } /** * Initialise definition * * @param string $type What type of definition to create * * @return HTMLPurifier_CSSDefinition|HTMLPurifier_HTMLDefinition|HTMLPurifier_URIDefinition * @throws HTMLPurifier_Exception */ private function initDefinition($type) { // quick checks failed, let's create the object if ($type == 'HTML') { $def = new HTMLPurifier_HTMLDefinition(); } elseif ($type == 'CSS') { $def = new HTMLPurifier_CSSDefinition(); } elseif ($type == 'URI') { $def = new HTMLPurifier_URIDefinition(); } else { throw new HTMLPurifier_Exception( "Definition of $type type not supported" ); } $this->definitions[$type] = $def; return $def; } public function maybeGetRawDefinition($name) { return $this->getDefinition($name, true, true); } public function maybeGetRawHTMLDefinition() { return $this->getDefinition('HTML', true, true); } public function maybeGetRawCSSDefinition() { return $this->getDefinition('CSS', true, true); } public function maybeGetRawURIDefinition() { return $this->getDefinition('URI', true, true); } /** * Loads configuration values from an array with the following structure: * Namespace.Directive => Value * * @param array $config_array Configuration associative array */ public function loadArray($config_array) { if ($this->isFinalized('Cannot load directives after finalization')) { return; } foreach ($config_array as $key => $value) { $key = str_replace('_', '.', $key); if (strpos($key, '.') !== false) { $this->set($key, $value); } else { $namespace = $key; $namespace_values = $value; foreach ($namespace_values as $directive => $value2) { $this->set($namespace .'.'. $directive, $value2); } } } } /** * Returns a list of array(namespace, directive) for all directives * that are allowed in a web-form context as per an allowed * namespaces/directives list. * * @param array $allowed List of allowed namespaces/directives * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy * * @return array */ public static function getAllowedDirectivesForForm($allowed, $schema = null) { if (!$schema) { $schema = HTMLPurifier_ConfigSchema::instance(); } if ($allowed !== true) { if (is_string($allowed)) { $allowed = array($allowed); } $allowed_ns = array(); $allowed_directives = array(); $blacklisted_directives = array(); foreach ($allowed as $ns_or_directive) { if (strpos($ns_or_directive, '.') !== false) { // directive if ($ns_or_directive[0] == '-') { $blacklisted_directives[substr($ns_or_directive, 1)] = true; } else { $allowed_directives[$ns_or_directive] = true; } } else { // namespace $allowed_ns[$ns_or_directive] = true; } } } $ret = array(); foreach ($schema->info as $key => $def) { list($ns, $directive) = explode('.', $key, 2); if ($allowed !== true) { if (isset($blacklisted_directives["$ns.$directive"])) { continue; } if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) { continue; } } if (isset($def->isAlias)) { continue; } if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') { continue; } $ret[] = array($ns, $directive); } return $ret; } /** * Loads configuration values from $_GET/$_POST that were posted * via ConfigForm * * @param array $array $_GET or $_POST array to import * @param string|bool $index Index/name that the config variables are in * @param array|bool $allowed List of allowed namespaces/directives * @param bool $mq_fix Boolean whether or not to enable magic quotes fix * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy * * @return mixed */ public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) { $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema); $config = HTMLPurifier_Config::create($ret, $schema); return $config; } /** * Merges in configuration values from $_GET/$_POST to object. NOT STATIC. * * @param array $array $_GET or $_POST array to import * @param string|bool $index Index/name that the config variables are in * @param array|bool $allowed List of allowed namespaces/directives * @param bool $mq_fix Boolean whether or not to enable magic quotes fix */ public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) { $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def); $this->loadArray($ret); } /** * Prepares an array from a form into something usable for the more * strict parts of HTMLPurifier_Config * * @param array $array $_GET or $_POST array to import * @param string|bool $index Index/name that the config variables are in * @param array|bool $allowed List of allowed namespaces/directives * @param bool $mq_fix Boolean whether or not to enable magic quotes fix * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy * * @return array */ public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) { if ($index !== false) { $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); } $mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); $ret = array(); foreach ($allowed as $key) { list($ns, $directive) = $key; $skey = "$ns.$directive"; if (!empty($array["Null_$skey"])) { $ret[$ns][$directive] = null; continue; } if (!isset($array[$skey])) { continue; } $value = $mq ? stripslashes($array[$skey]) : $array[$skey]; $ret[$ns][$directive] = $value; } return $ret; } /** * Loads configuration values from an ini file * * @param string $filename Name of ini file */ public function loadIni($filename) { if ($this->isFinalized('Cannot load directives after finalization')) { return; } $array = parse_ini_file($filename, true); $this->loadArray($array); } /** * Checks whether or not the configuration object is finalized. * * @param string|bool $error String error message, or false for no error * * @return bool */ public function isFinalized($error = false) { if ($this->finalized && $error) { $this->triggerError($error, E_USER_ERROR); } return $this->finalized; } /** * Finalizes configuration only if auto finalize is on and not * already finalized */ public function autoFinalize() { if ($this->autoFinalize) { $this->finalize(); } else { $this->plist->squash(true); } } /** * Finalizes a configuration object, prohibiting further change */ public function finalize() { $this->finalized = true; $this->parser = null; } /** * Produces a nicely formatted error message by supplying the * stack frame information OUTSIDE of HTMLPurifier_Config. * * @param string $msg An error message * @param int $no An error number */ protected function triggerError($msg, $no) { // determine previous stack frame $extra = ''; if ($this->chatty) { $trace = debug_backtrace(); // zip(tail(trace), trace) -- but PHP is not Haskell har har for ($i = 0, $c = count($trace); $i < $c - 1; $i++) { // XXX this is not correct on some versions of HTML Purifier if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') { continue; } $frame = $trace[$i]; $extra = " invoked on line {$frame['line']} in file {$frame['file']}"; break; } } trigger_error($msg . $extra, $no); } /** * Returns a serialized form of the configuration object that can * be reconstituted. * * @return string */ public function serialize() { $this->getDefinition('HTML'); $this->getDefinition('CSS'); $this->getDefinition('URI'); return serialize($this); } } /** * Configuration definition, defines directives and their defaults. */ class HTMLPurifier_ConfigSchema { /** * Defaults of the directives and namespaces. * @type array * @note This shares the exact same structure as HTMLPurifier_Config::$conf */ public $defaults = array(); /** * The default property list. Do not edit this property list. * @type array */ public $defaultPlist; /** * Definition of the directives. * The structure of this is: * * array( * 'Namespace' => array( * 'Directive' => new stdclass(), * ) * ) * * The stdclass may have the following properties: * * - If isAlias isn't set: * - type: Integer type of directive, see HTMLPurifier_VarParser for definitions * - allow_null: If set, this directive allows null values * - aliases: If set, an associative array of value aliases to real values * - allowed: If set, a lookup array of allowed (string) values * - If isAlias is set: * - namespace: Namespace this directive aliases to * - name: Directive name this directive aliases to * * In certain degenerate cases, stdclass will actually be an integer. In * that case, the value is equivalent to an stdclass with the type * property set to the integer. If the integer is negative, type is * equal to the absolute value of integer, and allow_null is true. * * This class is friendly with HTMLPurifier_Config. If you need introspection * about the schema, you're better of using the ConfigSchema_Interchange, * which uses more memory but has much richer information. * @type array */ public $info = array(); /** * Application-wide singleton * @type HTMLPurifier_ConfigSchema */ protected static $singleton; public function __construct() { $this->defaultPlist = new HTMLPurifier_PropertyList(); } /** * Unserializes the default ConfigSchema. * @return HTMLPurifier_ConfigSchema */ public static function makeFromSerial() { $contents = file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'); $r = unserialize($contents); if (!$r) { $hash = sha1($contents); trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR); } return $r; } /** * Retrieves an instance of the application-wide configuration definition. * @param HTMLPurifier_ConfigSchema $prototype * @return HTMLPurifier_ConfigSchema */ public static function instance($prototype = null) { if ($prototype !== null) { HTMLPurifier_ConfigSchema::$singleton = $prototype; } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) { HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial(); } return HTMLPurifier_ConfigSchema::$singleton; } /** * Defines a directive for configuration * @warning Will fail of directive's namespace is defined. * @warning This method's signature is slightly different from the legacy * define() static method! Beware! * @param string $key Name of directive * @param mixed $default Default value of directive * @param string $type Allowed type of the directive. See * HTMLPurifier_DirectiveDef::$type for allowed values * @param bool $allow_null Whether or not to allow null values */ public function add($key, $default, $type, $allow_null) { $obj = new stdclass(); $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type]; if ($allow_null) { $obj->allow_null = true; } $this->info[$key] = $obj; $this->defaults[$key] = $default; $this->defaultPlist->set($key, $default); } /** * Defines a directive value alias. * * Directive value aliases are convenient for developers because it lets * them set a directive to several values and get the same result. * @param string $key Name of Directive * @param array $aliases Hash of aliased values to the real alias */ public function addValueAliases($key, $aliases) { if (!isset($this->info[$key]->aliases)) { $this->info[$key]->aliases = array(); } foreach ($aliases as $alias => $real) { $this->info[$key]->aliases[$alias] = $real; } } /** * Defines a set of allowed values for a directive. * @warning This is slightly different from the corresponding static * method definition. * @param string $key Name of directive * @param array $allowed Lookup array of allowed values */ public function addAllowedValues($key, $allowed) { $this->info[$key]->allowed = $allowed; } /** * Defines a directive alias for backwards compatibility * @param string $key Directive that will be aliased * @param string $new_key Directive that the alias will be to */ public function addAlias($key, $new_key) { $obj = new stdclass; $obj->key = $new_key; $obj->isAlias = true; $this->info[$key] = $obj; } /** * Replaces any stdclass that only has the type property with type integer. */ public function postProcess() { foreach ($this->info as $key => $v) { if (count((array) $v) == 1) { $this->info[$key] = $v->type; } elseif (count((array) $v) == 2 && isset($v->allow_null)) { $this->info[$key] = -$v->type; } } } } /** * @todo Unit test */ class HTMLPurifier_ContentSets { /** * List of content set strings (pipe separators) indexed by name. * @type array */ public $info = array(); /** * List of content set lookups (element => true) indexed by name. * @type array * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets */ public $lookup = array(); /** * Synchronized list of defined content sets (keys of info). * @type array */ protected $keys = array(); /** * Synchronized list of defined content values (values of info). * @type array */ protected $values = array(); /** * Merges in module's content sets, expands identifiers in the content * sets and populates the keys, values and lookup member variables. * @param HTMLPurifier_HTMLModule[] $modules List of HTMLPurifier_HTMLModule */ public function __construct($modules) { if (!is_array($modules)) { $modules = array($modules); } // populate content_sets based on module hints // sorry, no way of overloading foreach ($modules as $module) { foreach ($module->content_sets as $key => $value) { $temp = $this->convertToLookup($value); if (isset($this->lookup[$key])) { // add it into the existing content set $this->lookup[$key] = array_merge($this->lookup[$key], $temp); } else { $this->lookup[$key] = $temp; } } } $old_lookup = false; while ($old_lookup !== $this->lookup) { $old_lookup = $this->lookup; foreach ($this->lookup as $i => $set) { $add = array(); foreach ($set as $element => $x) { if (isset($this->lookup[$element])) { $add += $this->lookup[$element]; unset($this->lookup[$i][$element]); } } $this->lookup[$i] += $add; } } foreach ($this->lookup as $key => $lookup) { $this->info[$key] = implode(' | ', array_keys($lookup)); } $this->keys = array_keys($this->info); $this->values = array_values($this->info); } /** * Accepts a definition; generates and assigns a ChildDef for it * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef reference * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef */ public function generateChildDef(&$def, $module) { if (!empty($def->child)) { // already done! return; } $content_model = $def->content_model; if (is_string($content_model)) { // Assume that $this->keys is alphanumeric $def->content_model = preg_replace_callback( '/\b(' . implode('|', $this->keys) . ')\b/', array($this, 'generateChildDefCallback'), $content_model ); //$def->content_model = str_replace( // $this->keys, $this->values, $content_model); } $def->child = $this->getChildDef($def, $module); } public function generateChildDefCallback($matches) { return $this->info[$matches[0]]; } /** * Instantiates a ChildDef based on content_model and content_model_type * member variables in HTMLPurifier_ElementDef * @note This will also defer to modules for custom HTMLPurifier_ChildDef * subclasses that need content set expansion * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef to have ChildDef extracted * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef * @return HTMLPurifier_ChildDef corresponding to ElementDef */ public function getChildDef($def, $module) { $value = $def->content_model; if (is_object($value)) { trigger_error( 'Literal object child definitions should be stored in '. 'ElementDef->child not ElementDef->content_model', E_USER_NOTICE ); return $value; } switch ($def->content_model_type) { case 'required': return new HTMLPurifier_ChildDef_Required($value); case 'optional': return new HTMLPurifier_ChildDef_Optional($value); case 'empty': return new HTMLPurifier_ChildDef_Empty(); case 'custom': return new HTMLPurifier_ChildDef_Custom($value); } // defer to its module $return = false; if ($module->defines_child_def) { // save a func call $return = $module->getChildDef($def); } if ($return !== false) { return $return; } // error-out trigger_error( 'Could not determine which ChildDef class to instantiate', E_USER_ERROR ); return false; } /** * Converts a string list of elements separated by pipes into * a lookup array. * @param string $string List of elements * @return array Lookup array of elements */ protected function convertToLookup($string) { $array = explode('|', str_replace(' ', '', $string)); $ret = array(); foreach ($array as $k) { $ret[$k] = true; } return $ret; } } /** * Registry object that contains information about the current context. * @warning Is a bit buggy when variables are set to null: it thinks * they don't exist! So use false instead, please. * @note Since the variables Context deals with may not be objects, * references are very important here! Do not remove! */ class HTMLPurifier_Context { /** * Private array that stores the references. * @type array */ private $_storage = array(); /** * Registers a variable into the context. * @param string $name String name * @param mixed $ref Reference to variable to be registered */ public function register($name, &$ref) { if (array_key_exists($name, $this->_storage)) { trigger_error( "Name $name produces collision, cannot re-register", E_USER_ERROR ); return; } $this->_storage[$name] =& $ref; } /** * Retrieves a variable reference from the context. * @param string $name String name * @param bool $ignore_error Boolean whether or not to ignore error * @return mixed */ public function &get($name, $ignore_error = false) { if (!array_key_exists($name, $this->_storage)) { if (!$ignore_error) { trigger_error( "Attempted to retrieve non-existent variable $name", E_USER_ERROR ); } $var = null; // so we can return by reference return $var; } return $this->_storage[$name]; } /** * Destroys a variable in the context. * @param string $name String name */ public function destroy($name) { if (!array_key_exists($name, $this->_storage)) { trigger_error( "Attempted to destroy non-existent variable $name", E_USER_ERROR ); return; } unset($this->_storage[$name]); } /** * Checks whether or not the variable exists. * @param string $name String name * @return bool */ public function exists($name) { return array_key_exists($name, $this->_storage); } /** * Loads a series of variables from an associative array * @param array $context_array Assoc array of variables to load */ public function loadArray($context_array) { foreach ($context_array as $key => $discard) { $this->register($key, $context_array[$key]); } } } /** * Abstract class representing Definition cache managers that implements * useful common methods and is a factory. * @todo Create a separate maintenance file advanced users can use to * cache their custom HTMLDefinition, which can be loaded * via a configuration directive * @todo Implement memcached */ abstract class HTMLPurifier_DefinitionCache { /** * @type string */ public $type; /** * @param string $type Type of definition objects this instance of the * cache will handle. */ public function __construct($type) { $this->type = $type; } /** * Generates a unique identifier for a particular configuration * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config * @return string */ public function generateKey($config) { return $config->version . ',' . // possibly replace with function calls $config->getBatchSerial($this->type) . ',' . $config->get($this->type . '.DefinitionRev'); } /** * Tests whether or not a key is old with respect to the configuration's * version and revision number. * @param string $key Key to test * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config to test against * @return bool */ public function isOld($key, $config) { if (substr_count($key, ',') < 2) { return true; } list($version, $hash, $revision) = explode(',', $key, 3); $compare = version_compare($version, $config->version); // version mismatch, is always old if ($compare != 0) { return true; } // versions match, ids match, check revision number if ($hash == $config->getBatchSerial($this->type) && $revision < $config->get($this->type . '.DefinitionRev')) { return true; } return false; } /** * Checks if a definition's type jives with the cache's type * @note Throws an error on failure * @param HTMLPurifier_Definition $def Definition object to check * @return bool true if good, false if not */ public function checkDefType($def) { if ($def->type !== $this->type) { trigger_error("Cannot use definition of type {$def->type} in cache for {$this->type}"); return false; } return true; } /** * Adds a definition object to the cache * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config */ abstract public function add($def, $config); /** * Unconditionally saves a definition object to the cache * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config */ abstract public function set($def, $config); /** * Replace an object in the cache * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config */ abstract public function replace($def, $config); /** * Retrieves a definition object from the cache * @param HTMLPurifier_Config $config */ abstract public function get($config); /** * Removes a definition object to the cache * @param HTMLPurifier_Config $config */ abstract public function remove($config); /** * Clears all objects from cache * @param HTMLPurifier_Config $config */ abstract public function flush($config); /** * Clears all expired (older version or revision) objects from cache * @note Be carefuly implementing this method as flush. Flush must * not interfere with other Definition types, and cleanup() * should not be repeatedly called by userland code. * @param HTMLPurifier_Config $config */ abstract public function cleanup($config); } /** * Responsible for creating definition caches. */ class HTMLPurifier_DefinitionCacheFactory { /** * @type array */ protected $caches = array('Serializer' => array()); /** * @type array */ protected $implementations = array(); /** * @type HTMLPurifier_DefinitionCache_Decorator[] */ protected $decorators = array(); /** * Initialize default decorators */ public function setup() { $this->addDecorator('Cleanup'); } /** * Retrieves an instance of global definition cache factory. * @param HTMLPurifier_DefinitionCacheFactory $prototype * @return HTMLPurifier_DefinitionCacheFactory */ public static function instance($prototype = null) { static $instance; if ($prototype !== null) { $instance = $prototype; } elseif ($instance === null || $prototype === true) { $instance = new HTMLPurifier_DefinitionCacheFactory(); $instance->setup(); } return $instance; } /** * Registers a new definition cache object * @param string $short Short name of cache object, for reference * @param string $long Full class name of cache object, for construction */ public function register($short, $long) { $this->implementations[$short] = $long; } /** * Factory method that creates a cache object based on configuration * @param string $type Name of definitions handled by cache * @param HTMLPurifier_Config $config Config instance * @return mixed */ public function create($type, $config) { $method = $config->get('Cache.DefinitionImpl'); if ($method === null) { return new HTMLPurifier_DefinitionCache_Null($type); } if (!empty($this->caches[$method][$type])) { return $this->caches[$method][$type]; } if (isset($this->implementations[$method]) && class_exists($class = $this->implementations[$method], false)) { $cache = new $class($type); } else { if ($method != 'Serializer') { trigger_error("Unrecognized DefinitionCache $method, using Serializer instead", E_USER_WARNING); } $cache = new HTMLPurifier_DefinitionCache_Serializer($type); } foreach ($this->decorators as $decorator) { $new_cache = $decorator->decorate($cache); // prevent infinite recursion in PHP 4 unset($cache); $cache = $new_cache; } $this->caches[$method][$type] = $cache; return $this->caches[$method][$type]; } /** * Registers a decorator to add to all new cache objects * @param HTMLPurifier_DefinitionCache_Decorator|string $decorator An instance or the name of a decorator */ public function addDecorator($decorator) { if (is_string($decorator)) { $class = "HTMLPurifier_DefinitionCache_Decorator_$decorator"; $decorator = new $class; } $this->decorators[$decorator->name] = $decorator; } } /** * Represents a document type, contains information on which modules * need to be loaded. * @note This class is inspected by Printer_HTMLDefinition->renderDoctype. * If structure changes, please update that function. */ class HTMLPurifier_Doctype { /** * Full name of doctype * @type string */ public $name; /** * List of standard modules (string identifiers or literal objects) * that this doctype uses * @type array */ public $modules = array(); /** * List of modules to use for tidying up code * @type array */ public $tidyModules = array(); /** * Is the language derived from XML (i.e. XHTML)? * @type bool */ public $xml = true; /** * List of aliases for this doctype * @type array */ public $aliases = array(); /** * Public DTD identifier * @type string */ public $dtdPublic; /** * System DTD identifier * @type string */ public $dtdSystem; public function __construct( $name = null, $xml = true, $modules = array(), $tidyModules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null ) { $this->name = $name; $this->xml = $xml; $this->modules = $modules; $this->tidyModules = $tidyModules; $this->aliases = $aliases; $this->dtdPublic = $dtd_public; $this->dtdSystem = $dtd_system; } } class HTMLPurifier_DoctypeRegistry { /** * Hash of doctype names to doctype objects. * @type array */ protected $doctypes; /** * Lookup table of aliases to real doctype names. * @type array */ protected $aliases; /** * Registers a doctype to the registry * @note Accepts a fully-formed doctype object, or the * parameters for constructing a doctype object * @param string $doctype Name of doctype or literal doctype object * @param bool $xml * @param array $modules Modules doctype will load * @param array $tidy_modules Modules doctype will load for certain modes * @param array $aliases Alias names for doctype * @param string $dtd_public * @param string $dtd_system * @return HTMLPurifier_Doctype Editable registered doctype */ public function register( $doctype, $xml = true, $modules = array(), $tidy_modules = array(), $aliases = array(), $dtd_public = null, $dtd_system = null ) { if (!is_array($modules)) { $modules = array($modules); } if (!is_array($tidy_modules)) { $tidy_modules = array($tidy_modules); } if (!is_array($aliases)) { $aliases = array($aliases); } if (!is_object($doctype)) { $doctype = new HTMLPurifier_Doctype( $doctype, $xml, $modules, $tidy_modules, $aliases, $dtd_public, $dtd_system ); } $this->doctypes[$doctype->name] = $doctype; $name = $doctype->name; // hookup aliases foreach ($doctype->aliases as $alias) { if (isset($this->doctypes[$alias])) { continue; } $this->aliases[$alias] = $name; } // remove old aliases if (isset($this->aliases[$name])) { unset($this->aliases[$name]); } return $doctype; } /** * Retrieves reference to a doctype of a certain name * @note This function resolves aliases * @note When possible, use the more fully-featured make() * @param string $doctype Name of doctype * @return HTMLPurifier_Doctype Editable doctype object */ public function get($doctype) { if (isset($this->aliases[$doctype])) { $doctype = $this->aliases[$doctype]; } if (!isset($this->doctypes[$doctype])) { trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR); $anon = new HTMLPurifier_Doctype($doctype); return $anon; } return $this->doctypes[$doctype]; } /** * Creates a doctype based on a configuration object, * will perform initialization on the doctype * @note Use this function to get a copy of doctype that config * can hold on to (this is necessary in order to tell * Generator whether or not the current document is XML * based or not). * @param HTMLPurifier_Config $config * @return HTMLPurifier_Doctype */ public function make($config) { return clone $this->get($this->getDoctypeFromConfig($config)); } /** * Retrieves the doctype from the configuration object * @param HTMLPurifier_Config $config * @return string */ public function getDoctypeFromConfig($config) { // recommended test $doctype = $config->get('HTML.Doctype'); if (!empty($doctype)) { return $doctype; } $doctype = $config->get('HTML.CustomDoctype'); if (!empty($doctype)) { return $doctype; } // backwards-compatibility if ($config->get('HTML.XHTML')) { $doctype = 'XHTML 1.0'; } else { $doctype = 'HTML 4.01'; } if ($config->get('HTML.Strict')) { $doctype .= ' Strict'; } else { $doctype .= ' Transitional'; } return $doctype; } } /** * Structure that stores an HTML element definition. Used by * HTMLPurifier_HTMLDefinition and HTMLPurifier_HTMLModule. * @note This class is inspected by HTMLPurifier_Printer_HTMLDefinition. * Please update that class too. * @warning If you add new properties to this class, you MUST update * the mergeIn() method. */ class HTMLPurifier_ElementDef { /** * Does the definition work by itself, or is it created solely * for the purpose of merging into another definition? * @type bool */ public $standalone = true; /** * Associative array of attribute name to HTMLPurifier_AttrDef. * @type array * @note Before being processed by HTMLPurifier_AttrCollections * when modules are finalized during * HTMLPurifier_HTMLDefinition->setup(), this array may also * contain an array at index 0 that indicates which attribute * collections to load into the full array. It may also * contain string indentifiers in lieu of HTMLPurifier_AttrDef, * see HTMLPurifier_AttrTypes on how they are expanded during * HTMLPurifier_HTMLDefinition->setup() processing. */ public $attr = array(); // XXX: Design note: currently, it's not possible to override // previously defined AttrTransforms without messing around with // the final generated config. This is by design; a previous version // used an associated list of attr_transform, but it was extremely // easy to accidentally override other attribute transforms by // forgetting to specify an index (and just using 0.) While we // could check this by checking the index number and complaining, // there is a second problem which is that it is not at all easy to // tell when something is getting overridden. Combine this with a // codebase where this isn't really being used, and it's perfect for // nuking. /** * List of tags HTMLPurifier_AttrTransform to be done before validation. * @type array */ public $attr_transform_pre = array(); /** * List of tags HTMLPurifier_AttrTransform to be done after validation. * @type array */ public $attr_transform_post = array(); /** * HTMLPurifier_ChildDef of this tag. * @type HTMLPurifier_ChildDef */ public $child; /** * Abstract string representation of internal ChildDef rules. * @see HTMLPurifier_ContentSets for how this is parsed and then transformed * into an HTMLPurifier_ChildDef. * @warning This is a temporary variable that is not available after * being processed by HTMLDefinition * @type string */ public $content_model; /** * Value of $child->type, used to determine which ChildDef to use, * used in combination with $content_model. * @warning This must be lowercase * @warning This is a temporary variable that is not available after * being processed by HTMLDefinition * @type string */ public $content_model_type; /** * Does the element have a content model (#PCDATA | Inline)*? This * is important for chameleon ins and del processing in * HTMLPurifier_ChildDef_Chameleon. Dynamically set: modules don't * have to worry about this one. * @type bool */ public $descendants_are_inline = false; /** * List of the names of required attributes this element has. * Dynamically populated by HTMLPurifier_HTMLDefinition::getElement() * @type array */ public $required_attr = array(); /** * Lookup table of tags excluded from all descendants of this tag. * @type array * @note SGML permits exclusions for all descendants, but this is * not possible with DTDs or XML Schemas. W3C has elected to * use complicated compositions of content_models to simulate * exclusion for children, but we go the simpler, SGML-style * route of flat-out exclusions, which correctly apply to * all descendants and not just children. Note that the XHTML * Modularization Abstract Modules are blithely unaware of such * distinctions. */ public $excludes = array(); /** * This tag is explicitly auto-closed by the following tags. * @type array */ public $autoclose = array(); /** * If a foreign element is found in this element, test if it is * allowed by this sub-element; if it is, instead of closing the * current element, place it inside this element. * @type string */ public $wrap; /** * Whether or not this is a formatting element affected by the * "Active Formatting Elements" algorithm. * @type bool */ public $formatting; /** * Low-level factory constructor for creating new standalone element defs */ public static function create($content_model, $content_model_type, $attr) { $def = new HTMLPurifier_ElementDef(); $def->content_model = $content_model; $def->content_model_type = $content_model_type; $def->attr = $attr; return $def; } /** * Merges the values of another element definition into this one. * Values from the new element def take precedence if a value is * not mergeable. * @param HTMLPurifier_ElementDef $def */ public function mergeIn($def) { // later keys takes precedence foreach ($def->attr as $k => $v) { if ($k === 0) { // merge in the includes // sorry, no way to override an include foreach ($v as $v2) { $this->attr[0][] = $v2; } continue; } if ($v === false) { if (isset($this->attr[$k])) { unset($this->attr[$k]); } continue; } $this->attr[$k] = $v; } $this->_mergeAssocArray($this->excludes, $def->excludes); $this->attr_transform_pre = array_merge($this->attr_transform_pre, $def->attr_transform_pre); $this->attr_transform_post = array_merge($this->attr_transform_post, $def->attr_transform_post); if (!empty($def->content_model)) { $this->content_model = str_replace("#SUPER", $this->content_model, $def->content_model); $this->child = false; } if (!empty($def->content_model_type)) { $this->content_model_type = $def->content_model_type; $this->child = false; } if (!is_null($def->child)) { $this->child = $def->child; } if (!is_null($def->formatting)) { $this->formatting = $def->formatting; } if ($def->descendants_are_inline) { $this->descendants_are_inline = $def->descendants_are_inline; } } /** * Merges one array into another, removes values which equal false * @param $a1 Array by reference that is merged into * @param $a2 Array that merges into $a1 */ private function _mergeAssocArray(&$a1, $a2) { foreach ($a2 as $k => $v) { if ($v === false) { if (isset($a1[$k])) { unset($a1[$k]); } continue; } $a1[$k] = $v; } } } /** * A UTF-8 specific character encoder that handles cleaning and transforming. * @note All functions in this class should be static. */ class HTMLPurifier_Encoder { /** * Constructor throws fatal error if you attempt to instantiate class */ private function __construct() { trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR); } /** * Error-handler that mutes errors, alternative to shut-up operator. */ public static function muteErrorHandler() { } /** * iconv wrapper which mutes errors, but doesn't work around bugs. * @param string $in Input encoding * @param string $out Output encoding * @param string $text The text to convert * @return string */ public static function unsafeIconv($in, $out, $text) { set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler')); $r = iconv($in, $out, $text); restore_error_handler(); return $r; } /** * iconv wrapper which mutes errors and works around bugs. * @param string $in Input encoding * @param string $out Output encoding * @param string $text The text to convert * @param int $max_chunk_size * @return string */ public static function iconv($in, $out, $text, $max_chunk_size = 8000) { $code = self::testIconvTruncateBug(); if ($code == self::ICONV_OK) { return self::unsafeIconv($in, $out, $text); } elseif ($code == self::ICONV_TRUNCATES) { // we can only work around this if the input character set // is utf-8 if ($in == 'utf-8') { if ($max_chunk_size < 4) { trigger_error('max_chunk_size is too small', E_USER_WARNING); return false; } // split into 8000 byte chunks, but be careful to handle // multibyte boundaries properly if (($c = strlen($text)) <= $max_chunk_size) { return self::unsafeIconv($in, $out, $text); } $r = ''; $i = 0; while (true) { if ($i + $max_chunk_size >= $c) { $r .= self::unsafeIconv($in, $out, substr($text, $i)); break; } // wibble the boundary if (0x80 != (0xC0 & ord($text[$i + $max_chunk_size]))) { $chunk_size = $max_chunk_size; } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 1]))) { $chunk_size = $max_chunk_size - 1; } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 2]))) { $chunk_size = $max_chunk_size - 2; } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 3]))) { $chunk_size = $max_chunk_size - 3; } else { return false; // rather confusing UTF-8... } $chunk = substr($text, $i, $chunk_size); // substr doesn't mind overlong lengths $r .= self::unsafeIconv($in, $out, $chunk); $i += $chunk_size; } return $r; } else { return false; } } else { return false; } } /** * Cleans a UTF-8 string for well-formedness and SGML validity * * It will parse according to UTF-8 and return a valid UTF8 string, with * non-SGML codepoints excluded. * * @param string $str The string to clean * @param bool $force_php * @return string * * @note Just for reference, the non-SGML code points are 0 to 31 and * 127 to 159, inclusive. However, we allow code points 9, 10 * and 13, which are the tab, line feed and carriage return * respectively. 128 and above the code points map to multibyte * UTF-8 representations. * * @note Fallback code adapted from utf8ToUnicode by Henri Sivonen and * hsivonen@iki.fi at <http://iki.fi/hsivonen/php-utf8/> under the * LGPL license. Notes on what changed are inside, but in general, * the original code transformed UTF-8 text into an array of integer * Unicode codepoints. Understandably, transforming that back to * a string would be somewhat expensive, so the function was modded to * directly operate on the string. However, this discourages code * reuse, and the logic enumerated here would be useful for any * function that needs to be able to understand UTF-8 characters. * As of right now, only smart lossless character encoding converters * would need that, and I'm probably not going to implement them. * Once again, PHP 6 should solve all our problems. */ public static function cleanUTF8($str, $force_php = false) { // UTF-8 validity is checked since PHP 4.3.5 // This is an optimization: if the string is already valid UTF-8, no // need to do PHP stuff. 99% of the time, this will be the case. // The regexp matches the XML char production, as well as well as excluding // non-SGML codepoints U+007F to U+009F if (preg_match( '/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', $str )) { return $str; } $mState = 0; // cached expected number of octets after the current octet // until the beginning of the next UTF8 character sequence $mUcs4 = 0; // cached Unicode character $mBytes = 1; // cached expected number of octets in the current sequence // original code involved an $out that was an array of Unicode // codepoints. Instead of having to convert back into UTF-8, we've // decided to directly append valid UTF-8 characters onto a string // $out once they're done. $char accumulates raw bytes, while $mUcs4 // turns into the Unicode code point, so there's some redundancy. $out = ''; $char = ''; $len = strlen($str); for ($i = 0; $i < $len; $i++) { $in = ord($str{$i}); $char .= $str[$i]; // append byte to char if (0 == $mState) { // When mState is zero we expect either a US-ASCII character // or a multi-octet sequence. if (0 == (0x80 & ($in))) { // US-ASCII, pass straight through. if (($in <= 31 || $in == 127) && !($in == 9 || $in == 13 || $in == 10) // save \r\t\n ) { // control characters, remove } else { $out .= $char; } // reset $char = ''; $mBytes = 1; } elseif (0xC0 == (0xE0 & ($in))) { // First octet of 2 octet sequence $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x1F) << 6; $mState = 1; $mBytes = 2; } elseif (0xE0 == (0xF0 & ($in))) { // First octet of 3 octet sequence $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x0F) << 12; $mState = 2; $mBytes = 3; } elseif (0xF0 == (0xF8 & ($in))) { // First octet of 4 octet sequence $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x07) << 18; $mState = 3; $mBytes = 4; } elseif (0xF8 == (0xFC & ($in))) { // First octet of 5 octet sequence. // // This is illegal because the encoded codepoint must be // either: // (a) not the shortest form or // (b) outside the Unicode range of 0-0x10FFFF. // Rather than trying to resynchronize, we will carry on // until the end of the sequence and let the later error // handling code catch it. $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x03) << 24; $mState = 4; $mBytes = 5; } elseif (0xFC == (0xFE & ($in))) { // First octet of 6 octet sequence, see comments for 5 // octet sequence. $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 1) << 30; $mState = 5; $mBytes = 6; } else { // Current octet is neither in the US-ASCII range nor a // legal first octet of a multi-octet sequence. $mState = 0; $mUcs4 = 0; $mBytes = 1; $char = ''; } } else { // When mState is non-zero, we expect a continuation of the // multi-octet sequence if (0x80 == (0xC0 & ($in))) { // Legal continuation. $shift = ($mState - 1) * 6; $tmp = $in; $tmp = ($tmp & 0x0000003F) << $shift; $mUcs4 |= $tmp; if (0 == --$mState) { // End of the multi-octet sequence. mUcs4 now contains // the final Unicode codepoint to be output // Check for illegal sequences and codepoints. // From Unicode 3.1, non-shortest form is illegal if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || ((3 == $mBytes) && ($mUcs4 < 0x0800)) || ((4 == $mBytes) && ($mUcs4 < 0x10000)) || (4 < $mBytes) || // From Unicode 3.2, surrogate characters = illegal (($mUcs4 & 0xFFFFF800) == 0xD800) || // Codepoints outside the Unicode range are illegal ($mUcs4 > 0x10FFFF) ) { } elseif (0xFEFF != $mUcs4 && // omit BOM // check for valid Char unicode codepoints ( 0x9 == $mUcs4 || 0xA == $mUcs4 || 0xD == $mUcs4 || (0x20 <= $mUcs4 && 0x7E >= $mUcs4) || // 7F-9F is not strictly prohibited by XML, // but it is non-SGML, and thus we don't allow it (0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) || (0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4) ) ) { $out .= $char; } // initialize UTF8 cache (reset) $mState = 0; $mUcs4 = 0; $mBytes = 1; $char = ''; } } else { // ((0xC0 & (*in) != 0x80) && (mState != 0)) // Incomplete multi-octet sequence. // used to result in complete fail, but we'll reset $mState = 0; $mUcs4 = 0; $mBytes = 1; $char =''; } } } return $out; } /** * Translates a Unicode codepoint into its corresponding UTF-8 character. * @note Based on Feyd's function at * <http://forums.devnetwork.net/viewtopic.php?p=191404#191404>, * which is in public domain. * @note While we're going to do code point parsing anyway, a good * optimization would be to refuse to translate code points that * are non-SGML characters. However, this could lead to duplication. * @note This is very similar to the unichr function in * maintenance/generate-entity-file.php (although this is superior, * due to its sanity checks). */ // +----------+----------+----------+----------+ // | 33222222 | 22221111 | 111111 | | // | 10987654 | 32109876 | 54321098 | 76543210 | bit // +----------+----------+----------+----------+ // | | | | 0xxxxxxx | 1 byte 0x00000000..0x0000007F // | | | 110yyyyy | 10xxxxxx | 2 byte 0x00000080..0x000007FF // | | 1110zzzz | 10yyyyyy | 10xxxxxx | 3 byte 0x00000800..0x0000FFFF // | 11110www | 10wwzzzz | 10yyyyyy | 10xxxxxx | 4 byte 0x00010000..0x0010FFFF // +----------+----------+----------+----------+ // | 00000000 | 00011111 | 11111111 | 11111111 | Theoretical upper limit of legal scalars: 2097151 (0x001FFFFF) // | 00000000 | 00010000 | 11111111 | 11111111 | Defined upper limit of legal scalar codes // +----------+----------+----------+----------+ public static function unichr($code) { if ($code > 1114111 or $code < 0 or ($code >= 55296 and $code <= 57343) ) { // bits are set outside the "valid" range as defined // by UNICODE 4.1.0 return ''; } $x = $y = $z = $w = 0; if ($code < 128) { // regular ASCII character $x = $code; } else { // set up bits for UTF-8 $x = ($code & 63) | 128; if ($code < 2048) { $y = (($code & 2047) >> 6) | 192; } else { $y = (($code & 4032) >> 6) | 128; if ($code < 65536) { $z = (($code >> 12) & 15) | 224; } else { $z = (($code >> 12) & 63) | 128; $w = (($code >> 18) & 7) | 240; } } } // set up the actual character $ret = ''; if ($w) { $ret .= chr($w); } if ($z) { $ret .= chr($z); } if ($y) { $ret .= chr($y); } $ret .= chr($x); return $ret; } /** * @return bool */ public static function iconvAvailable() { static $iconv = null; if ($iconv === null) { $iconv = function_exists('iconv') && self::testIconvTruncateBug() != self::ICONV_UNUSABLE; } return $iconv; } /** * Convert a string to UTF-8 based on configuration. * @param string $str The string to convert * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ public static function convertToUTF8($str, $config, $context) { $encoding = $config->get('Core.Encoding'); if ($encoding === 'utf-8') { return $str; } static $iconv = null; if ($iconv === null) { $iconv = self::iconvAvailable(); } if ($iconv && !$config->get('Test.ForceNoIconv')) { // unaffected by bugs, since UTF-8 support all characters $str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str); if ($str === false) { // $encoding is not a valid encoding trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR); return ''; } // If the string is bjorked by Shift_JIS or a similar encoding // that doesn't support all of ASCII, convert the naughty // characters to their true byte-wise ASCII/UTF-8 equivalents. $str = strtr($str, self::testEncodingSupportsASCII($encoding)); return $str; } elseif ($encoding === 'iso-8859-1') { $str = utf8_encode($str); return $str; } $bug = HTMLPurifier_Encoder::testIconvTruncateBug(); if ($bug == self::ICONV_OK) { trigger_error('Encoding not supported, please install iconv', E_USER_ERROR); } else { trigger_error( 'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' . 'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541', E_USER_ERROR ); } } /** * Converts a string from UTF-8 based on configuration. * @param string $str The string to convert * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string * @note Currently, this is a lossy conversion, with unexpressable * characters being omitted. */ public static function convertFromUTF8($str, $config, $context) { $encoding = $config->get('Core.Encoding'); if ($escape = $config->get('Core.EscapeNonASCIICharacters')) { $str = self::convertToASCIIDumbLossless($str); } if ($encoding === 'utf-8') { return $str; } static $iconv = null; if ($iconv === null) { $iconv = self::iconvAvailable(); } if ($iconv && !$config->get('Test.ForceNoIconv')) { // Undo our previous fix in convertToUTF8, otherwise iconv will barf $ascii_fix = self::testEncodingSupportsASCII($encoding); if (!$escape && !empty($ascii_fix)) { $clear_fix = array(); foreach ($ascii_fix as $utf8 => $native) { $clear_fix[$utf8] = ''; } $str = strtr($str, $clear_fix); } $str = strtr($str, array_flip($ascii_fix)); // Normal stuff $str = self::iconv('utf-8', $encoding . '//IGNORE', $str); return $str; } elseif ($encoding === 'iso-8859-1') { $str = utf8_decode($str); return $str; } trigger_error('Encoding not supported', E_USER_ERROR); // You might be tempted to assume that the ASCII representation // might be OK, however, this is *not* universally true over all // encodings. So we take the conservative route here, rather // than forcibly turn on %Core.EscapeNonASCIICharacters } /** * Lossless (character-wise) conversion of HTML to ASCII * @param string $str UTF-8 string to be converted to ASCII * @return string ASCII encoded string with non-ASCII character entity-ized * @warning Adapted from MediaWiki, claiming fair use: this is a common * algorithm. If you disagree with this license fudgery, * implement it yourself. * @note Uses decimal numeric entities since they are best supported. * @note This is a DUMB function: it has no concept of keeping * character entities that the projected character encoding * can allow. We could possibly implement a smart version * but that would require it to also know which Unicode * codepoints the charset supported (not an easy task). * @note Sort of with cleanUTF8() but it assumes that $str is * well-formed UTF-8 */ public static function convertToASCIIDumbLossless($str) { $bytesleft = 0; $result = ''; $working = 0; $len = strlen($str); for ($i = 0; $i < $len; $i++) { $bytevalue = ord($str[$i]); if ($bytevalue <= 0x7F) { //0xxx xxxx $result .= chr($bytevalue); $bytesleft = 0; } elseif ($bytevalue <= 0xBF) { //10xx xxxx $working = $working << 6; $working += ($bytevalue & 0x3F); $bytesleft--; if ($bytesleft <= 0) { $result .= "&#" . $working . ";"; } } elseif ($bytevalue <= 0xDF) { //110x xxxx $working = $bytevalue & 0x1F; $bytesleft = 1; } elseif ($bytevalue <= 0xEF) { //1110 xxxx $working = $bytevalue & 0x0F; $bytesleft = 2; } else { //1111 0xxx $working = $bytevalue & 0x07; $bytesleft = 3; } } return $result; } /** No bugs detected in iconv. */ const ICONV_OK = 0; /** Iconv truncates output if converting from UTF-8 to another * character set with //IGNORE, and a non-encodable character is found */ const ICONV_TRUNCATES = 1; /** Iconv does not support //IGNORE, making it unusable for * transcoding purposes */ const ICONV_UNUSABLE = 2; /** * glibc iconv has a known bug where it doesn't handle the magic * //IGNORE stanza correctly. In particular, rather than ignore * characters, it will return an EILSEQ after consuming some number * of characters, and expect you to restart iconv as if it were * an E2BIG. Old versions of PHP did not respect the errno, and * returned the fragment, so as a result you would see iconv * mysteriously truncating output. We can work around this by * manually chopping our input into segments of about 8000 * characters, as long as PHP ignores the error code. If PHP starts * paying attention to the error code, iconv becomes unusable. * * @return int Error code indicating severity of bug. */ public static function testIconvTruncateBug() { static $code = null; if ($code === null) { // better not use iconv, otherwise infinite loop! $r = self::unsafeIconv('utf-8', 'ascii//IGNORE', "\xCE\xB1" . str_repeat('a', 9000)); if ($r === false) { $code = self::ICONV_UNUSABLE; } elseif (($c = strlen($r)) < 9000) { $code = self::ICONV_TRUNCATES; } elseif ($c > 9000) { trigger_error( 'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' . 'include your iconv version as per phpversion()', E_USER_ERROR ); } else { $code = self::ICONV_OK; } } return $code; } /** * This expensive function tests whether or not a given character * encoding supports ASCII. 7/8-bit encodings like Shift_JIS will * fail this test, and require special processing. Variable width * encodings shouldn't ever fail. * * @param string $encoding Encoding name to test, as per iconv format * @param bool $bypass Whether or not to bypass the precompiled arrays. * @return Array of UTF-8 characters to their corresponding ASCII, * which can be used to "undo" any overzealous iconv action. */ public static function testEncodingSupportsASCII($encoding, $bypass = false) { // All calls to iconv here are unsafe, proof by case analysis: // If ICONV_OK, no difference. // If ICONV_TRUNCATE, all calls involve one character inputs, // so bug is not triggered. // If ICONV_UNUSABLE, this call is irrelevant static $encodings = array(); if (!$bypass) { if (isset($encodings[$encoding])) { return $encodings[$encoding]; } $lenc = strtolower($encoding); switch ($lenc) { case 'shift_jis': return array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~'); case 'johab': return array("\xE2\x82\xA9" => '\\'); } if (strpos($lenc, 'iso-8859-') === 0) { return array(); } } $ret = array(); if (self::unsafeIconv('UTF-8', $encoding, 'a') === false) { return false; } for ($i = 0x20; $i <= 0x7E; $i++) { // all printable ASCII chars $c = chr($i); // UTF-8 char $r = self::unsafeIconv('UTF-8', "$encoding//IGNORE", $c); // initial conversion if ($r === '' || // This line is needed for iconv implementations that do not // omit characters that do not exist in the target character set ($r === $c && self::unsafeIconv($encoding, 'UTF-8//IGNORE', $r) !== $c) ) { // Reverse engineer: what's the UTF-8 equiv of this byte // sequence? This assumes that there's no variable width // encoding that doesn't support ASCII. $ret[self::unsafeIconv($encoding, 'UTF-8//IGNORE', $c)] = $c; } } $encodings[$encoding] = $ret; return $ret; } } /** * Object that provides entity lookup table from entity name to character */ class HTMLPurifier_EntityLookup { /** * Assoc array of entity name to character represented. * @type array */ public $table; /** * Sets up the entity lookup table from the serialized file contents. * @param bool $file * @note The serialized contents are versioned, but were generated * using the maintenance script generate_entity_file.php * @warning This is not in constructor to help enforce the Singleton */ public function setup($file = false) { if (!$file) { $file = HTMLPURIFIER_PREFIX . '/HTMLPurifier/EntityLookup/entities.ser'; } $this->table = unserialize(file_get_contents($file)); } /** * Retrieves sole instance of the object. * @param bool|HTMLPurifier_EntityLookup $prototype Optional prototype of custom lookup table to overload with. * @return HTMLPurifier_EntityLookup */ public static function instance($prototype = false) { // no references, since PHP doesn't copy unless modified static $instance = null; if ($prototype) { $instance = $prototype; } elseif (!$instance) { $instance = new HTMLPurifier_EntityLookup(); $instance->setup(); } return $instance; } } // if want to implement error collecting here, we'll need to use some sort // of global data (probably trigger_error) because it's impossible to pass // $config or $context to the callback functions. /** * Handles referencing and derefencing character entities */ class HTMLPurifier_EntityParser { /** * Reference to entity lookup table. * @type HTMLPurifier_EntityLookup */ protected $_entity_lookup; /** * Callback regex string for parsing entities. * @type string */ protected $_substituteEntitiesRegex = '/&(?:[#]x([a-fA-F0-9]+)|[#]0*(\d+)|([A-Za-z_:][A-Za-z0-9.\-_:]*));?/'; // 1. hex 2. dec 3. string (XML style) /** * Decimal to parsed string conversion table for special entities. * @type array */ protected $_special_dec2str = array( 34 => '"', 38 => '&', 39 => "'", 60 => '<', 62 => '>' ); /** * Stripped entity names to decimal conversion table for special entities. * @type array */ protected $_special_ent2dec = array( 'quot' => 34, 'amp' => 38, 'lt' => 60, 'gt' => 62 ); /** * Substitutes non-special entities with their parsed equivalents. Since * running this whenever you have parsed character is t3h 5uck, we run * it before everything else. * * @param string $string String to have non-special entities parsed. * @return string Parsed string. */ public function substituteNonSpecialEntities($string) { // it will try to detect missing semicolons, but don't rely on it return preg_replace_callback( $this->_substituteEntitiesRegex, array($this, 'nonSpecialEntityCallback'), $string ); } /** * Callback function for substituteNonSpecialEntities() that does the work. * * @param array $matches PCRE matches array, with 0 the entire match, and * either index 1, 2 or 3 set with a hex value, dec value, * or string (respectively). * @return string Replacement string. */ protected function nonSpecialEntityCallback($matches) { // replaces all but big five $entity = $matches[0]; $is_num = (@$matches[0][1] === '#'); if ($is_num) { $is_hex = (@$entity[2] === 'x'); $code = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; // abort for special characters if (isset($this->_special_dec2str[$code])) { return $entity; } return HTMLPurifier_Encoder::unichr($code); } else { if (isset($this->_special_ent2dec[$matches[3]])) { return $entity; } if (!$this->_entity_lookup) { $this->_entity_lookup = HTMLPurifier_EntityLookup::instance(); } if (isset($this->_entity_lookup->table[$matches[3]])) { return $this->_entity_lookup->table[$matches[3]]; } else { return $entity; } } } /** * Substitutes only special entities with their parsed equivalents. * * @notice We try to avoid calling this function because otherwise, it * would have to be called a lot (for every parsed section). * * @param string $string String to have non-special entities parsed. * @return string Parsed string. */ public function substituteSpecialEntities($string) { return preg_replace_callback( $this->_substituteEntitiesRegex, array($this, 'specialEntityCallback'), $string ); } /** * Callback function for substituteSpecialEntities() that does the work. * * This callback has same syntax as nonSpecialEntityCallback(). * * @param array $matches PCRE-style matches array, with 0 the entire match, and * either index 1, 2 or 3 set with a hex value, dec value, * or string (respectively). * @return string Replacement string. */ protected function specialEntityCallback($matches) { $entity = $matches[0]; $is_num = (@$matches[0][1] === '#'); if ($is_num) { $is_hex = (@$entity[2] === 'x'); $int = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; return isset($this->_special_dec2str[$int]) ? $this->_special_dec2str[$int] : $entity; } else { return isset($this->_special_ent2dec[$matches[3]]) ? $this->_special_ent2dec[$matches[3]] : $entity; } } } /** * Error collection class that enables HTML Purifier to report HTML * problems back to the user */ class HTMLPurifier_ErrorCollector { /** * Identifiers for the returned error array. These are purposely numeric * so list() can be used. */ const LINENO = 0; const SEVERITY = 1; const MESSAGE = 2; const CHILDREN = 3; /** * @type array */ protected $errors; /** * @type array */ protected $_current; /** * @type array */ protected $_stacks = array(array()); /** * @type HTMLPurifier_Language */ protected $locale; /** * @type HTMLPurifier_Generator */ protected $generator; /** * @type HTMLPurifier_Context */ protected $context; /** * @type array */ protected $lines = array(); /** * @param HTMLPurifier_Context $context */ public function __construct($context) { $this->locale =& $context->get('Locale'); $this->context = $context; $this->_current =& $this->_stacks[0]; $this->errors =& $this->_stacks[0]; } /** * Sends an error message to the collector for later use * @param int $severity Error severity, PHP error style (don't use E_USER_) * @param string $msg Error message text */ public function send($severity, $msg) { $args = array(); if (func_num_args() > 2) { $args = func_get_args(); array_shift($args); unset($args[0]); } $token = $this->context->get('CurrentToken', true); $line = $token ? $token->line : $this->context->get('CurrentLine', true); $col = $token ? $token->col : $this->context->get('CurrentCol', true); $attr = $this->context->get('CurrentAttr', true); // perform special substitutions, also add custom parameters $subst = array(); if (!is_null($token)) { $args['CurrentToken'] = $token; } if (!is_null($attr)) { $subst['$CurrentAttr.Name'] = $attr; if (isset($token->attr[$attr])) { $subst['$CurrentAttr.Value'] = $token->attr[$attr]; } } if (empty($args)) { $msg = $this->locale->getMessage($msg); } else { $msg = $this->locale->formatMessage($msg, $args); } if (!empty($subst)) { $msg = strtr($msg, $subst); } // (numerically indexed) $error = array( self::LINENO => $line, self::SEVERITY => $severity, self::MESSAGE => $msg, self::CHILDREN => array() ); $this->_current[] = $error; // NEW CODE BELOW ... // Top-level errors are either: // TOKEN type, if $value is set appropriately, or // "syntax" type, if $value is null $new_struct = new HTMLPurifier_ErrorStruct(); $new_struct->type = HTMLPurifier_ErrorStruct::TOKEN; if ($token) { $new_struct->value = clone $token; } if (is_int($line) && is_int($col)) { if (isset($this->lines[$line][$col])) { $struct = $this->lines[$line][$col]; } else { $struct = $this->lines[$line][$col] = $new_struct; } // These ksorts may present a performance problem ksort($this->lines[$line], SORT_NUMERIC); } else { if (isset($this->lines[-1])) { $struct = $this->lines[-1]; } else { $struct = $this->lines[-1] = $new_struct; } } ksort($this->lines, SORT_NUMERIC); // Now, check if we need to operate on a lower structure if (!empty($attr)) { $struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr); if (!$struct->value) { $struct->value = array($attr, 'PUT VALUE HERE'); } } if (!empty($cssprop)) { $struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop); if (!$struct->value) { // if we tokenize CSS this might be a little more difficult to do $struct->value = array($cssprop, 'PUT VALUE HERE'); } } // Ok, structs are all setup, now time to register the error $struct->addError($severity, $msg); } /** * Retrieves raw error data for custom formatter to use */ public function getRaw() { return $this->errors; } /** * Default HTML formatting implementation for error messages * @param HTMLPurifier_Config $config Configuration, vital for HTML output nature * @param array $errors Errors array to display; used for recursion. * @return string */ public function getHTMLFormatted($config, $errors = null) { $ret = array(); $this->generator = new HTMLPurifier_Generator($config, $this->context); if ($errors === null) { $errors = $this->errors; } // 'At line' message needs to be removed // generation code for new structure goes here. It needs to be recursive. foreach ($this->lines as $line => $col_array) { if ($line == -1) { continue; } foreach ($col_array as $col => $struct) { $this->_renderStruct($ret, $struct, $line, $col); } } if (isset($this->lines[-1])) { $this->_renderStruct($ret, $this->lines[-1]); } if (empty($errors)) { return '<p>' . $this->locale->getMessage('ErrorCollector: No errors') . '</p>'; } else { return '<ul><li>' . implode('</li><li>', $ret) . '</li></ul>'; } } private function _renderStruct(&$ret, $struct, $line = null, $col = null) { $stack = array($struct); $context_stack = array(array()); while ($current = array_pop($stack)) { $context = array_pop($context_stack); foreach ($current->errors as $error) { list($severity, $msg) = $error; $string = ''; $string .= '<div>'; // W3C uses an icon to indicate the severity of the error. $error = $this->locale->getErrorName($severity); $string .= "<span class=\"error e$severity\"><strong>$error</strong></span> "; if (!is_null($line) && !is_null($col)) { $string .= "<em class=\"location\">Line $line, Column $col: </em> "; } else { $string .= '<em class="location">End of Document: </em> '; } $string .= '<strong class="description">' . $this->generator->escape($msg) . '</strong> '; $string .= '</div>'; // Here, have a marker for the character on the column appropriate. // Be sure to clip extremely long lines. //$string .= '<pre>'; //$string .= ''; //$string .= '</pre>'; $ret[] = $string; } foreach ($current->children as $array) { $context[] = $current; $stack = array_merge($stack, array_reverse($array, true)); for ($i = count($array); $i > 0; $i--) { $context_stack[] = $context; } } } } } /** * Records errors for particular segments of an HTML document such as tokens, * attributes or CSS properties. They can contain error structs (which apply * to components of what they represent), but their main purpose is to hold * errors applying to whatever struct is being used. */ class HTMLPurifier_ErrorStruct { /** * Possible values for $children first-key. Note that top-level structures * are automatically token-level. */ const TOKEN = 0; const ATTR = 1; const CSSPROP = 2; /** * Type of this struct. * @type string */ public $type; /** * Value of the struct we are recording errors for. There are various * values for this: * - TOKEN: Instance of HTMLPurifier_Token * - ATTR: array('attr-name', 'value') * - CSSPROP: array('prop-name', 'value') * @type mixed */ public $value; /** * Errors registered for this structure. * @type array */ public $errors = array(); /** * Child ErrorStructs that are from this structure. For example, a TOKEN * ErrorStruct would contain ATTR ErrorStructs. This is a multi-dimensional * array in structure: [TYPE]['identifier'] * @type array */ public $children = array(); /** * @param string $type * @param string $id * @return mixed */ public function getChild($type, $id) { if (!isset($this->children[$type][$id])) { $this->children[$type][$id] = new HTMLPurifier_ErrorStruct(); $this->children[$type][$id]->type = $type; } return $this->children[$type][$id]; } /** * @param int $severity * @param string $message */ public function addError($severity, $message) { $this->errors[] = array($severity, $message); } } /** * Global exception class for HTML Purifier; any exceptions we throw * are from here. */ class HTMLPurifier_Exception extends Exception { } /** * Represents a pre or post processing filter on HTML Purifier's output * * Sometimes, a little ad-hoc fixing of HTML has to be done before * it gets sent through HTML Purifier: you can use filters to acheive * this effect. For instance, YouTube videos can be preserved using * this manner. You could have used a decorator for this task, but * PHP's support for them is not terribly robust, so we're going * to just loop through the filters. * * Filters should be exited first in, last out. If there are three filters, * named 1, 2 and 3, the order of execution should go 1->preFilter, * 2->preFilter, 3->preFilter, purify, 3->postFilter, 2->postFilter, * 1->postFilter. * * @note Methods are not declared abstract as it is perfectly legitimate * for an implementation not to want anything to happen on a step */ class HTMLPurifier_Filter { /** * Name of the filter for identification purposes. * @type string */ public $name; /** * Pre-processor function, handles HTML before HTML Purifier * @param string $html * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ public function preFilter($html, $config, $context) { return $html; } /** * Post-processor function, handles HTML after HTML Purifier * @param string $html * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ public function postFilter($html, $config, $context) { return $html; } } /** * Generates HTML from tokens. * @todo Refactor interface so that configuration/context is determined * upon instantiation, no need for messy generateFromTokens() calls * @todo Make some of the more internal functions protected, and have * unit tests work around that */ class HTMLPurifier_Generator { /** * Whether or not generator should produce XML output. * @type bool */ private $_xhtml = true; /** * :HACK: Whether or not generator should comment the insides of <script> tags. * @type bool */ private $_scriptFix = false; /** * Cache of HTMLDefinition during HTML output to determine whether or * not attributes should be minimized. * @type HTMLPurifier_HTMLDefinition */ private $_def; /** * Cache of %Output.SortAttr. * @type bool */ private $_sortAttr; /** * Cache of %Output.FlashCompat. * @type bool */ private $_flashCompat; /** * Cache of %Output.FixInnerHTML. * @type bool */ private $_innerHTMLFix; /** * Stack for keeping track of object information when outputting IE * compatibility code. * @type array */ private $_flashStack = array(); /** * Configuration for the generator * @type HTMLPurifier_Config */ protected $config; /** * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context */ public function __construct($config, $context) { $this->config = $config; $this->_scriptFix = $config->get('Output.CommentScriptContents'); $this->_innerHTMLFix = $config->get('Output.FixInnerHTML'); $this->_sortAttr = $config->get('Output.SortAttr'); $this->_flashCompat = $config->get('Output.FlashCompat'); $this->_def = $config->getHTMLDefinition(); $this->_xhtml = $this->_def->doctype->xml; } /** * Generates HTML from an array of tokens. * @param HTMLPurifier_Token[] $tokens Array of HTMLPurifier_Token * @return string Generated HTML */ public function generateFromTokens($tokens) { if (!$tokens) { return ''; } // Basic algorithm $html = ''; for ($i = 0, $size = count($tokens); $i < $size; $i++) { if ($this->_scriptFix && $tokens[$i]->name === 'script' && $i + 2 < $size && $tokens[$i+2] instanceof HTMLPurifier_Token_End) { // script special case // the contents of the script block must be ONE token // for this to work. $html .= $this->generateFromToken($tokens[$i++]); $html .= $this->generateScriptFromToken($tokens[$i++]); } $html .= $this->generateFromToken($tokens[$i]); } // Tidy cleanup if (extension_loaded('tidy') && $this->config->get('Output.TidyFormat')) { $tidy = new Tidy; $tidy->parseString( $html, array( 'indent'=> true, 'output-xhtml' => $this->_xhtml, 'show-body-only' => true, 'indent-spaces' => 2, 'wrap' => 68, ), 'utf8' ); $tidy->cleanRepair(); $html = (string) $tidy; // explicit cast necessary } // Normalize newlines to system defined value if ($this->config->get('Core.NormalizeNewlines')) { $nl = $this->config->get('Output.Newline'); if ($nl === null) { $nl = PHP_EOL; } if ($nl !== "\n") { $html = str_replace("\n", $nl, $html); } } return $html; } /** * Generates HTML from a single token. * @param HTMLPurifier_Token $token HTMLPurifier_Token object. * @return string Generated HTML */ public function generateFromToken($token) { if (!$token instanceof HTMLPurifier_Token) { trigger_error('Cannot generate HTML from non-HTMLPurifier_Token object', E_USER_WARNING); return ''; } elseif ($token instanceof HTMLPurifier_Token_Start) { $attr = $this->generateAttributes($token->attr, $token->name); if ($this->_flashCompat) { if ($token->name == "object") { $flash = new stdclass(); $flash->attr = $token->attr; $flash->param = array(); $this->_flashStack[] = $flash; } } return '<' . $token->name . ($attr ? ' ' : '') . $attr . '>'; } elseif ($token instanceof HTMLPurifier_Token_End) { $_extra = ''; if ($this->_flashCompat) { if ($token->name == "object" && !empty($this->_flashStack)) { // doesn't do anything for now } } return $_extra . '</' . $token->name . '>'; } elseif ($token instanceof HTMLPurifier_Token_Empty) { if ($this->_flashCompat && $token->name == "param" && !empty($this->_flashStack)) { $this->_flashStack[count($this->_flashStack)-1]->param[$token->attr['name']] = $token->attr['value']; } $attr = $this->generateAttributes($token->attr, $token->name); return '<' . $token->name . ($attr ? ' ' : '') . $attr . ( $this->_xhtml ? ' /': '' ) // <br /> v. <br> . '>'; } elseif ($token instanceof HTMLPurifier_Token_Text) { return $this->escape($token->data, ENT_NOQUOTES); } elseif ($token instanceof HTMLPurifier_Token_Comment) { return '<!--' . $token->data . '-->'; } else { return ''; } } /** * Special case processor for the contents of script tags * @param HTMLPurifier_Token $token HTMLPurifier_Token object. * @return string * @warning This runs into problems if there's already a literal * --> somewhere inside the script contents. */ public function generateScriptFromToken($token) { if (!$token instanceof HTMLPurifier_Token_Text) { return $this->generateFromToken($token); } // Thanks <http://lachy.id.au/log/2005/05/script-comments> $data = preg_replace('#//\s*$#', '', $token->data); return '<!--//--><![CDATA[//><!--' . "\n" . trim($data) . "\n" . '//--><!]]>'; } /** * Generates attribute declarations from attribute array. * @note This does not include the leading or trailing space. * @param array $assoc_array_of_attributes Attribute array * @param string $element Name of element attributes are for, used to check * attribute minimization. * @return string Generated HTML fragment for insertion. */ public function generateAttributes($assoc_array_of_attributes, $element = '') { $html = ''; if ($this->_sortAttr) { ksort($assoc_array_of_attributes); } foreach ($assoc_array_of_attributes as $key => $value) { if (!$this->_xhtml) { // Remove namespaced attributes if (strpos($key, ':') !== false) { continue; } // Check if we should minimize the attribute: val="val" -> val if ($element && !empty($this->_def->info[$element]->attr[$key]->minimized)) { $html .= $key . ' '; continue; } } // Workaround for Internet Explorer innerHTML bug. // Essentially, Internet Explorer, when calculating // innerHTML, omits quotes if there are no instances of // angled brackets, quotes or spaces. However, when parsing // HTML (for example, when you assign to innerHTML), it // treats backticks as quotes. Thus, // <img alt="``" /> // becomes // <img alt=`` /> // becomes // <img alt='' /> // Fortunately, all we need to do is trigger an appropriate // quoting style, which we do by adding an extra space. // This also is consistent with the W3C spec, which states // that user agents may ignore leading or trailing // whitespace (in fact, most don't, at least for attributes // like alt, but an extra space at the end is barely // noticeable). Still, we have a configuration knob for // this, since this transformation is not necesary if you // don't process user input with innerHTML or you don't plan // on supporting Internet Explorer. if ($this->_innerHTMLFix) { if (strpos($value, '`') !== false) { // check if correct quoting style would not already be // triggered if (strcspn($value, '"\' <>') === strlen($value)) { // protect! $value .= ' '; } } } $html .= $key.'="'.$this->escape($value).'" '; } return rtrim($html); } /** * Escapes raw text data. * @todo This really ought to be protected, but until we have a facility * for properly generating HTML here w/o using tokens, it stays * public. * @param string $string String data to escape for HTML. * @param int $quote Quoting style, like htmlspecialchars. ENT_NOQUOTES is * permissible for non-attribute output. * @return string escaped data. */ public function escape($string, $quote = null) { // Workaround for APC bug on Mac Leopard reported by sidepodcast // http://htmlpurifier.org/phorum/read.php?3,4823,4846 if ($quote === null) { $quote = ENT_COMPAT; } return htmlspecialchars($string, $quote, 'UTF-8'); } } /** * Definition of the purified HTML that describes allowed children, * attributes, and many other things. * * Conventions: * * All member variables that are prefixed with info * (including the main $info array) are used by HTML Purifier internals * and should not be directly edited when customizing the HTMLDefinition. * They can usually be set via configuration directives or custom * modules. * * On the other hand, member variables without the info prefix are used * internally by the HTMLDefinition and MUST NOT be used by other HTML * Purifier internals. Many of them, however, are public, and may be * edited by userspace code to tweak the behavior of HTMLDefinition. * * @note This class is inspected by Printer_HTMLDefinition; please * update that class if things here change. * * @warning Directives that change this object's structure must be in * the HTML or Attr namespace! */ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition { // FULLY-PUBLIC VARIABLES --------------------------------------------- /** * Associative array of element names to HTMLPurifier_ElementDef. * @type HTMLPurifier_ElementDef[] */ public $info = array(); /** * Associative array of global attribute name to attribute definition. * @type array */ public $info_global_attr = array(); /** * String name of parent element HTML will be going into. * @type string */ public $info_parent = 'div'; /** * Definition for parent element, allows parent element to be a * tag that's not allowed inside the HTML fragment. * @type HTMLPurifier_ElementDef */ public $info_parent_def; /** * String name of element used to wrap inline elements in block context. * @type string * @note This is rarely used except for BLOCKQUOTEs in strict mode */ public $info_block_wrapper = 'p'; /** * Associative array of deprecated tag name to HTMLPurifier_TagTransform. * @type array */ public $info_tag_transform = array(); /** * Indexed list of HTMLPurifier_AttrTransform to be performed before validation. * @type HTMLPurifier_AttrTransform[] */ public $info_attr_transform_pre = array(); /** * Indexed list of HTMLPurifier_AttrTransform to be performed after validation. * @type HTMLPurifier_AttrTransform[] */ public $info_attr_transform_post = array(); /** * Nested lookup array of content set name (Block, Inline) to * element name to whether or not it belongs in that content set. * @type array */ public $info_content_sets = array(); /** * Indexed list of HTMLPurifier_Injector to be used. * @type HTMLPurifier_Injector[] */ public $info_injector = array(); /** * Doctype object * @type HTMLPurifier_Doctype */ public $doctype; // RAW CUSTOMIZATION STUFF -------------------------------------------- /** * Adds a custom attribute to a pre-existing element * @note This is strictly convenience, and does not have a corresponding * method in HTMLPurifier_HTMLModule * @param string $element_name Element name to add attribute to * @param string $attr_name Name of attribute * @param mixed $def Attribute definition, can be string or object, see * HTMLPurifier_AttrTypes for details */ public function addAttribute($element_name, $attr_name, $def) { $module = $this->getAnonymousModule(); if (!isset($module->info[$element_name])) { $element = $module->addBlankElement($element_name); } else { $element = $module->info[$element_name]; } $element->attr[$attr_name] = $def; } /** * Adds a custom element to your HTML definition * @see HTMLPurifier_HTMLModule::addElement() for detailed * parameter and return value descriptions. */ public function addElement($element_name, $type, $contents, $attr_collections, $attributes = array()) { $module = $this->getAnonymousModule(); // assume that if the user is calling this, the element // is safe. This may not be a good idea $element = $module->addElement($element_name, $type, $contents, $attr_collections, $attributes); return $element; } /** * Adds a blank element to your HTML definition, for overriding * existing behavior * @param string $element_name * @return HTMLPurifier_ElementDef * @see HTMLPurifier_HTMLModule::addBlankElement() for detailed * parameter and return value descriptions. */ public function addBlankElement($element_name) { $module = $this->getAnonymousModule(); $element = $module->addBlankElement($element_name); return $element; } /** * Retrieves a reference to the anonymous module, so you can * bust out advanced features without having to make your own * module. * @return HTMLPurifier_HTMLModule */ public function getAnonymousModule() { if (!$this->_anonModule) { $this->_anonModule = new HTMLPurifier_HTMLModule(); $this->_anonModule->name = 'Anonymous'; } return $this->_anonModule; } private $_anonModule = null; // PUBLIC BUT INTERNAL VARIABLES -------------------------------------- /** * @type string */ public $type = 'HTML'; /** * @type HTMLPurifier_HTMLModuleManager */ public $manager; /** * Performs low-cost, preliminary initialization. */ public function __construct() { $this->manager = new HTMLPurifier_HTMLModuleManager(); } /** * @param HTMLPurifier_Config $config */ protected function doSetup($config) { $this->processModules($config); $this->setupConfigStuff($config); unset($this->manager); // cleanup some of the element definitions foreach ($this->info as $k => $v) { unset($this->info[$k]->content_model); unset($this->info[$k]->content_model_type); } } /** * Extract out the information from the manager * @param HTMLPurifier_Config $config */ protected function processModules($config) { if ($this->_anonModule) { // for user specific changes // this is late-loaded so we don't have to deal with PHP4 // reference wonky-ness $this->manager->addModule($this->_anonModule); unset($this->_anonModule); } $this->manager->setup($config); $this->doctype = $this->manager->doctype; foreach ($this->manager->modules as $module) { foreach ($module->info_tag_transform as $k => $v) { if ($v === false) { unset($this->info_tag_transform[$k]); } else { $this->info_tag_transform[$k] = $v; } } foreach ($module->info_attr_transform_pre as $k => $v) { if ($v === false) { unset($this->info_attr_transform_pre[$k]); } else { $this->info_attr_transform_pre[$k] = $v; } } foreach ($module->info_attr_transform_post as $k => $v) { if ($v === false) { unset($this->info_attr_transform_post[$k]); } else { $this->info_attr_transform_post[$k] = $v; } } foreach ($module->info_injector as $k => $v) { if ($v === false) { unset($this->info_injector[$k]); } else { $this->info_injector[$k] = $v; } } } $this->info = $this->manager->getElements(); $this->info_content_sets = $this->manager->contentSets->lookup; } /** * Sets up stuff based on config. We need a better way of doing this. * @param HTMLPurifier_Config $config */ protected function setupConfigStuff($config) { $block_wrapper = $config->get('HTML.BlockWrapper'); if (isset($this->info_content_sets['Block'][$block_wrapper])) { $this->info_block_wrapper = $block_wrapper; } else { trigger_error( 'Cannot use non-block element as block wrapper', E_USER_ERROR ); } $parent = $config->get('HTML.Parent'); $def = $this->manager->getElement($parent, true); if ($def) { $this->info_parent = $parent; $this->info_parent_def = $def; } else { trigger_error( 'Cannot use unrecognized element as parent', E_USER_ERROR ); $this->info_parent_def = $this->manager->getElement($this->info_parent, true); } // support template text $support = "(for information on implementing this, see the support forums) "; // setup allowed elements ----------------------------------------- $allowed_elements = $config->get('HTML.AllowedElements'); $allowed_attributes = $config->get('HTML.AllowedAttributes'); // retrieve early if (!is_array($allowed_elements) && !is_array($allowed_attributes)) { $allowed = $config->get('HTML.Allowed'); if (is_string($allowed)) { list($allowed_elements, $allowed_attributes) = $this->parseTinyMCEAllowedList($allowed); } } if (is_array($allowed_elements)) { foreach ($this->info as $name => $d) { if (!isset($allowed_elements[$name])) { unset($this->info[$name]); } unset($allowed_elements[$name]); } // emit errors foreach ($allowed_elements as $element => $d) { $element = htmlspecialchars($element); // PHP doesn't escape errors, be careful! trigger_error("Element '$element' is not supported $support", E_USER_WARNING); } } // setup allowed attributes --------------------------------------- $allowed_attributes_mutable = $allowed_attributes; // by copy! if (is_array($allowed_attributes)) { // This actually doesn't do anything, since we went away from // global attributes. It's possible that userland code uses // it, but HTMLModuleManager doesn't! foreach ($this->info_global_attr as $attr => $x) { $keys = array($attr, "*@$attr", "*.$attr"); $delete = true; foreach ($keys as $key) { if ($delete && isset($allowed_attributes[$key])) { $delete = false; } if (isset($allowed_attributes_mutable[$key])) { unset($allowed_attributes_mutable[$key]); } } if ($delete) { unset($this->info_global_attr[$attr]); } } foreach ($this->info as $tag => $info) { foreach ($info->attr as $attr => $x) { $keys = array("$tag@$attr", $attr, "*@$attr", "$tag.$attr", "*.$attr"); $delete = true; foreach ($keys as $key) { if ($delete && isset($allowed_attributes[$key])) { $delete = false; } if (isset($allowed_attributes_mutable[$key])) { unset($allowed_attributes_mutable[$key]); } } if ($delete) { if ($this->info[$tag]->attr[$attr]->required) { trigger_error( "Required attribute '$attr' in element '$tag' " . "was not allowed, which means '$tag' will not be allowed either", E_USER_WARNING ); } unset($this->info[$tag]->attr[$attr]); } } } // emit errors foreach ($allowed_attributes_mutable as $elattr => $d) { $bits = preg_split('/[.@]/', $elattr, 2); $c = count($bits); switch ($c) { case 2: if ($bits[0] !== '*') { $element = htmlspecialchars($bits[0]); $attribute = htmlspecialchars($bits[1]); if (!isset($this->info[$element])) { trigger_error( "Cannot allow attribute '$attribute' if element " . "'$element' is not allowed/supported $support" ); } else { trigger_error( "Attribute '$attribute' in element '$element' not supported $support", E_USER_WARNING ); } break; } // otherwise fall through case 1: $attribute = htmlspecialchars($bits[0]); trigger_error( "Global attribute '$attribute' is not ". "supported in any elements $support", E_USER_WARNING ); break; } } } // setup forbidden elements --------------------------------------- $forbidden_elements = $config->get('HTML.ForbiddenElements'); $forbidden_attributes = $config->get('HTML.ForbiddenAttributes'); foreach ($this->info as $tag => $info) { if (isset($forbidden_elements[$tag])) { unset($this->info[$tag]); continue; } foreach ($info->attr as $attr => $x) { if (isset($forbidden_attributes["$tag@$attr"]) || isset($forbidden_attributes["*@$attr"]) || isset($forbidden_attributes[$attr]) ) { unset($this->info[$tag]->attr[$attr]); continue; } elseif (isset($forbidden_attributes["$tag.$attr"])) { // this segment might get removed eventually // $tag.$attr are not user supplied, so no worries! trigger_error( "Error with $tag.$attr: tag.attr syntax not supported for " . "HTML.ForbiddenAttributes; use tag@attr instead", E_USER_WARNING ); } } } foreach ($forbidden_attributes as $key => $v) { if (strlen($key) < 2) { continue; } if ($key[0] != '*') { continue; } if ($key[1] == '.') { trigger_error( "Error with $key: *.attr syntax not supported for HTML.ForbiddenAttributes; use attr instead", E_USER_WARNING ); } } // setup injectors ----------------------------------------------------- foreach ($this->info_injector as $i => $injector) { if ($injector->checkNeeded($config) !== false) { // remove injector that does not have it's required // elements/attributes present, and is thus not needed. unset($this->info_injector[$i]); } } } /** * Parses a TinyMCE-flavored Allowed Elements and Attributes list into * separate lists for processing. Format is element[attr1|attr2],element2... * @warning Although it's largely drawn from TinyMCE's implementation, * it is different, and you'll probably have to modify your lists * @param array $list String list to parse * @return array * @todo Give this its own class, probably static interface */ public function parseTinyMCEAllowedList($list) { $list = str_replace(array(' ', "\t"), '', $list); $elements = array(); $attributes = array(); $chunks = preg_split('/(,|[\n\r]+)/', $list); foreach ($chunks as $chunk) { if (empty($chunk)) { continue; } // remove TinyMCE element control characters if (!strpos($chunk, '[')) { $element = $chunk; $attr = false; } else { list($element, $attr) = explode('[', $chunk); } if ($element !== '*') { $elements[$element] = true; } if (!$attr) { continue; } $attr = substr($attr, 0, strlen($attr) - 1); // remove trailing ] $attr = explode('|', $attr); foreach ($attr as $key) { $attributes["$element.$key"] = true; } } return array($elements, $attributes); } } /** * Represents an XHTML 1.1 module, with information on elements, tags * and attributes. * @note Even though this is technically XHTML 1.1, it is also used for * regular HTML parsing. We are using modulization as a convenient * way to represent the internals of HTMLDefinition, and our * implementation is by no means conforming and does not directly * use the normative DTDs or XML schemas. * @note The public variables in a module should almost directly * correspond to the variables in HTMLPurifier_HTMLDefinition. * However, the prefix info carries no special meaning in these * objects (include it anyway if that's the correspondence though). * @todo Consider making some member functions protected */ class HTMLPurifier_HTMLModule { // -- Overloadable ---------------------------------------------------- /** * Short unique string identifier of the module. * @type string */ public $name; /** * Informally, a list of elements this module changes. * Not used in any significant way. * @type array */ public $elements = array(); /** * Associative array of element names to element definitions. * Some definitions may be incomplete, to be merged in later * with the full definition. * @type array */ public $info = array(); /** * Associative array of content set names to content set additions. * This is commonly used to, say, add an A element to the Inline * content set. This corresponds to an internal variable $content_sets * and NOT info_content_sets member variable of HTMLDefinition. * @type array */ public $content_sets = array(); /** * Associative array of attribute collection names to attribute * collection additions. More rarely used for adding attributes to * the global collections. Example is the StyleAttribute module adding * the style attribute to the Core. Corresponds to HTMLDefinition's * attr_collections->info, since the object's data is only info, * with extra behavior associated with it. * @type array */ public $attr_collections = array(); /** * Associative array of deprecated tag name to HTMLPurifier_TagTransform. * @type array */ public $info_tag_transform = array(); /** * List of HTMLPurifier_AttrTransform to be performed before validation. * @type array */ public $info_attr_transform_pre = array(); /** * List of HTMLPurifier_AttrTransform to be performed after validation. * @type array */ public $info_attr_transform_post = array(); /** * List of HTMLPurifier_Injector to be performed during well-formedness fixing. * An injector will only be invoked if all of it's pre-requisites are met; * if an injector fails setup, there will be no error; it will simply be * silently disabled. * @type array */ public $info_injector = array(); /** * Boolean flag that indicates whether or not getChildDef is implemented. * For optimization reasons: may save a call to a function. Be sure * to set it if you do implement getChildDef(), otherwise it will have * no effect! * @type bool */ public $defines_child_def = false; /** * Boolean flag whether or not this module is safe. If it is not safe, all * of its members are unsafe. Modules are safe by default (this might be * slightly dangerous, but it doesn't make much sense to force HTML Purifier, * which is based off of safe HTML, to explicitly say, "This is safe," even * though there are modules which are "unsafe") * * @type bool * @note Previously, safety could be applied at an element level granularity. * We've removed this ability, so in order to add "unsafe" elements * or attributes, a dedicated module with this property set to false * must be used. */ public $safe = true; /** * Retrieves a proper HTMLPurifier_ChildDef subclass based on * content_model and content_model_type member variables of * the HTMLPurifier_ElementDef class. There is a similar function * in HTMLPurifier_HTMLDefinition. * @param HTMLPurifier_ElementDef $def * @return HTMLPurifier_ChildDef subclass */ public function getChildDef($def) { return false; } // -- Convenience ----------------------------------------------------- /** * Convenience function that sets up a new element * @param string $element Name of element to add * @param string|bool $type What content set should element be registered to? * Set as false to skip this step. * @param string $contents Allowed children in form of: * "$content_model_type: $content_model" * @param array $attr_includes What attribute collections to register to * element? * @param array $attr What unique attributes does the element define? * @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters. * @return HTMLPurifier_ElementDef Created element definition object, so you * can set advanced parameters */ public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array()) { $this->elements[] = $element; // parse content_model list($content_model_type, $content_model) = $this->parseContents($contents); // merge in attribute inclusions $this->mergeInAttrIncludes($attr, $attr_includes); // add element to content sets if ($type) { $this->addElementToContentSet($element, $type); } // create element $this->info[$element] = HTMLPurifier_ElementDef::create( $content_model, $content_model_type, $attr ); // literal object $contents means direct child manipulation if (!is_string($contents)) { $this->info[$element]->child = $contents; } return $this->info[$element]; } /** * Convenience function that creates a totally blank, non-standalone * element. * @param string $element Name of element to create * @return HTMLPurifier_ElementDef Created element */ public function addBlankElement($element) { if (!isset($this->info[$element])) { $this->elements[] = $element; $this->info[$element] = new HTMLPurifier_ElementDef(); $this->info[$element]->standalone = false; } else { trigger_error("Definition for $element already exists in module, cannot redefine"); } return $this->info[$element]; } /** * Convenience function that registers an element to a content set * @param string $element Element to register * @param string $type Name content set (warning: case sensitive, usually upper-case * first letter) */ public function addElementToContentSet($element, $type) { if (!isset($this->content_sets[$type])) { $this->content_sets[$type] = ''; } else { $this->content_sets[$type] .= ' | '; } $this->content_sets[$type] .= $element; } /** * Convenience function that transforms single-string contents * into separate content model and content model type * @param string $contents Allowed children in form of: * "$content_model_type: $content_model" * @return array * @note If contents is an object, an array of two nulls will be * returned, and the callee needs to take the original $contents * and use it directly. */ public function parseContents($contents) { if (!is_string($contents)) { return array(null, null); } // defer switch ($contents) { // check for shorthand content model forms case 'Empty': return array('empty', ''); case 'Inline': return array('optional', 'Inline | #PCDATA'); case 'Flow': return array('optional', 'Flow | #PCDATA'); } list($content_model_type, $content_model) = explode(':', $contents); $content_model_type = strtolower(trim($content_model_type)); $content_model = trim($content_model); return array($content_model_type, $content_model); } /** * Convenience function that merges a list of attribute includes into * an attribute array. * @param array $attr Reference to attr array to modify * @param array $attr_includes Array of includes / string include to merge in */ public function mergeInAttrIncludes(&$attr, $attr_includes) { if (!is_array($attr_includes)) { if (empty($attr_includes)) { $attr_includes = array(); } else { $attr_includes = array($attr_includes); } } $attr[0] = $attr_includes; } /** * Convenience function that generates a lookup table with boolean * true as value. * @param string $list List of values to turn into a lookup * @note You can also pass an arbitrary number of arguments in * place of the regular argument * @return array array equivalent of list */ public function makeLookup($list) { if (is_string($list)) { $list = func_get_args(); } $ret = array(); foreach ($list as $value) { if (is_null($value)) { continue; } $ret[$value] = true; } return $ret; } /** * Lazy load construction of the module after determining whether * or not it's needed, and also when a finalized configuration object * is available. * @param HTMLPurifier_Config $config */ public function setup($config) { } } class HTMLPurifier_HTMLModuleManager { /** * @type HTMLPurifier_DoctypeRegistry */ public $doctypes; /** * Instance of current doctype. * @type string */ public $doctype; /** * @type HTMLPurifier_AttrTypes */ public $attrTypes; /** * Active instances of modules for the specified doctype are * indexed, by name, in this array. * @type HTMLPurifier_HTMLModule[] */ public $modules = array(); /** * Array of recognized HTMLPurifier_HTMLModule instances, * indexed by module's class name. This array is usually lazy loaded, but a * user can overload a module by pre-emptively registering it. * @type HTMLPurifier_HTMLModule[] */ public $registeredModules = array(); /** * List of extra modules that were added by the user * using addModule(). These get unconditionally merged into the current doctype, whatever * it may be. * @type HTMLPurifier_HTMLModule[] */ public $userModules = array(); /** * Associative array of element name to list of modules that have * definitions for the element; this array is dynamically filled. * @type array */ public $elementLookup = array(); /** * List of prefixes we should use for registering small names. * @type array */ public $prefixes = array('HTMLPurifier_HTMLModule_'); /** * @type HTMLPurifier_ContentSets */ public $contentSets; /** * @type HTMLPurifier_AttrCollections */ public $attrCollections; /** * If set to true, unsafe elements and attributes will be allowed. * @type bool */ public $trusted = false; public function __construct() { // editable internal objects $this->attrTypes = new HTMLPurifier_AttrTypes(); $this->doctypes = new HTMLPurifier_DoctypeRegistry(); // setup basic modules $common = array( 'CommonAttributes', 'Text', 'Hypertext', 'List', 'Presentation', 'Edit', 'Bdo', 'Tables', 'Image', 'StyleAttribute', // Unsafe: 'Scripting', 'Object', 'Forms', // Sorta legacy, but present in strict: 'Name', ); $transitional = array('Legacy', 'Target', 'Iframe'); $xml = array('XMLCommonAttributes'); $non_xml = array('NonXMLCommonAttributes'); // setup basic doctypes $this->doctypes->register( 'HTML 4.01 Transitional', false, array_merge($common, $transitional, $non_xml), array('Tidy_Transitional', 'Tidy_Proprietary'), array(), '-//W3C//DTD HTML 4.01 Transitional//EN', 'http://www.w3.org/TR/html4/loose.dtd' ); $this->doctypes->register( 'HTML 4.01 Strict', false, array_merge($common, $non_xml), array('Tidy_Strict', 'Tidy_Proprietary', 'Tidy_Name'), array(), '-//W3C//DTD HTML 4.01//EN', 'http://www.w3.org/TR/html4/strict.dtd' ); $this->doctypes->register( 'XHTML 1.0 Transitional', true, array_merge($common, $transitional, $xml, $non_xml), array('Tidy_Transitional', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Name'), array(), '-//W3C//DTD XHTML 1.0 Transitional//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd' ); $this->doctypes->register( 'XHTML 1.0 Strict', true, array_merge($common, $xml, $non_xml), array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Strict', 'Tidy_Proprietary', 'Tidy_Name'), array(), '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' ); $this->doctypes->register( 'XHTML 1.1', true, // Iframe is a real XHTML 1.1 module, despite being // "transitional"! array_merge($common, $xml, array('Ruby', 'Iframe')), array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Strict', 'Tidy_Name'), // Tidy_XHTML1_1 array(), '-//W3C//DTD XHTML 1.1//EN', 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd' ); } /** * Registers a module to the recognized module list, useful for * overloading pre-existing modules. * @param $module Mixed: string module name, with or without * HTMLPurifier_HTMLModule prefix, or instance of * subclass of HTMLPurifier_HTMLModule. * @param $overload Boolean whether or not to overload previous modules. * If this is not set, and you do overload a module, * HTML Purifier will complain with a warning. * @note This function will not call autoload, you must instantiate * (and thus invoke) autoload outside the method. * @note If a string is passed as a module name, different variants * will be tested in this order: * - Check for HTMLPurifier_HTMLModule_$name * - Check all prefixes with $name in order they were added * - Check for literal object name * - Throw fatal error * If your object name collides with an internal class, specify * your module manually. All modules must have been included * externally: registerModule will not perform inclusions for you! */ public function registerModule($module, $overload = false) { if (is_string($module)) { // attempt to load the module $original_module = $module; $ok = false; foreach ($this->prefixes as $prefix) { $module = $prefix . $original_module; if (class_exists($module)) { $ok = true; break; } } if (!$ok) { $module = $original_module; if (!class_exists($module)) { trigger_error( $original_module . ' module does not exist', E_USER_ERROR ); return; } } $module = new $module(); } if (empty($module->name)) { trigger_error('Module instance of ' . get_class($module) . ' must have name'); return; } if (!$overload && isset($this->registeredModules[$module->name])) { trigger_error('Overloading ' . $module->name . ' without explicit overload parameter', E_USER_WARNING); } $this->registeredModules[$module->name] = $module; } /** * Adds a module to the current doctype by first registering it, * and then tacking it on to the active doctype */ public function addModule($module) { $this->registerModule($module); if (is_object($module)) { $module = $module->name; } $this->userModules[] = $module; } /** * Adds a class prefix that registerModule() will use to resolve a * string name to a concrete class */ public function addPrefix($prefix) { $this->prefixes[] = $prefix; } /** * Performs processing on modules, after being called you may * use getElement() and getElements() * @param HTMLPurifier_Config $config */ public function setup($config) { $this->trusted = $config->get('HTML.Trusted'); // generate $this->doctype = $this->doctypes->make($config); $modules = $this->doctype->modules; // take out the default modules that aren't allowed $lookup = $config->get('HTML.AllowedModules'); $special_cases = $config->get('HTML.CoreModules'); if (is_array($lookup)) { foreach ($modules as $k => $m) { if (isset($special_cases[$m])) { continue; } if (!isset($lookup[$m])) { unset($modules[$k]); } } } // custom modules if ($config->get('HTML.Proprietary')) { $modules[] = 'Proprietary'; } if ($config->get('HTML.SafeObject')) { $modules[] = 'SafeObject'; } if ($config->get('HTML.SafeEmbed')) { $modules[] = 'SafeEmbed'; } if ($config->get('HTML.SafeScripting') !== array()) { $modules[] = 'SafeScripting'; } if ($config->get('HTML.Nofollow')) { $modules[] = 'Nofollow'; } if ($config->get('HTML.TargetBlank')) { $modules[] = 'TargetBlank'; } // merge in custom modules $modules = array_merge($modules, $this->userModules); foreach ($modules as $module) { $this->processModule($module); $this->modules[$module]->setup($config); } foreach ($this->doctype->tidyModules as $module) { $this->processModule($module); $this->modules[$module]->setup($config); } // prepare any injectors foreach ($this->modules as $module) { $n = array(); foreach ($module->info_injector as $injector) { if (!is_object($injector)) { $class = "HTMLPurifier_Injector_$injector"; $injector = new $class; } $n[$injector->name] = $injector; } $module->info_injector = $n; } // setup lookup table based on all valid modules foreach ($this->modules as $module) { foreach ($module->info as $name => $def) { if (!isset($this->elementLookup[$name])) { $this->elementLookup[$name] = array(); } $this->elementLookup[$name][] = $module->name; } } // note the different choice $this->contentSets = new HTMLPurifier_ContentSets( // content set assembly deals with all possible modules, // not just ones deemed to be "safe" $this->modules ); $this->attrCollections = new HTMLPurifier_AttrCollections( $this->attrTypes, // there is no way to directly disable a global attribute, // but using AllowedAttributes or simply not including // the module in your custom doctype should be sufficient $this->modules ); } /** * Takes a module and adds it to the active module collection, * registering it if necessary. */ public function processModule($module) { if (!isset($this->registeredModules[$module]) || is_object($module)) { $this->registerModule($module); } $this->modules[$module] = $this->registeredModules[$module]; } /** * Retrieves merged element definitions. * @return Array of HTMLPurifier_ElementDef */ public function getElements() { $elements = array(); foreach ($this->modules as $module) { if (!$this->trusted && !$module->safe) { continue; } foreach ($module->info as $name => $v) { if (isset($elements[$name])) { continue; } $elements[$name] = $this->getElement($name); } } // remove dud elements, this happens when an element that // appeared to be safe actually wasn't foreach ($elements as $n => $v) { if ($v === false) { unset($elements[$n]); } } return $elements; } /** * Retrieves a single merged element definition * @param string $name Name of element * @param bool $trusted Boolean trusted overriding parameter: set to true * if you want the full version of an element * @return HTMLPurifier_ElementDef Merged HTMLPurifier_ElementDef * @note You may notice that modules are getting iterated over twice (once * in getElements() and once here). This * is because */ public function getElement($name, $trusted = null) { if (!isset($this->elementLookup[$name])) { return false; } // setup global state variables $def = false; if ($trusted === null) { $trusted = $this->trusted; } // iterate through each module that has registered itself to this // element foreach ($this->elementLookup[$name] as $module_name) { $module = $this->modules[$module_name]; // refuse to create/merge from a module that is deemed unsafe-- // pretend the module doesn't exist--when trusted mode is not on. if (!$trusted && !$module->safe) { continue; } // clone is used because, ideally speaking, the original // definition should not be modified. Usually, this will // make no difference, but for consistency's sake $new_def = clone $module->info[$name]; if (!$def && $new_def->standalone) { $def = $new_def; } elseif ($def) { // This will occur even if $new_def is standalone. In practice, // this will usually result in a full replacement. $def->mergeIn($new_def); } else { // :TODO: // non-standalone definitions that don't have a standalone // to merge into could be deferred to the end // HOWEVER, it is perfectly valid for a non-standalone // definition to lack a standalone definition, even // after all processing: this allows us to safely // specify extra attributes for elements that may not be // enabled all in one place. In particular, this might // be the case for trusted elements. WARNING: care must // be taken that the /extra/ definitions are all safe. continue; } // attribute value expansions $this->attrCollections->performInclusions($def->attr); $this->attrCollections->expandIdentifiers($def->attr, $this->attrTypes); // descendants_are_inline, for ChildDef_Chameleon if (is_string($def->content_model) && strpos($def->content_model, 'Inline') !== false) { if ($name != 'del' && $name != 'ins') { // this is for you, ins/del $def->descendants_are_inline = true; } } $this->contentSets->generateChildDef($def, $module); } // This can occur if there is a blank definition, but no base to // mix it in with if (!$def) { return false; } // add information on required attributes foreach ($def->attr as $attr_name => $attr_def) { if ($attr_def->required) { $def->required_attr[] = $attr_name; } } return $def; } } /** * Component of HTMLPurifier_AttrContext that accumulates IDs to prevent dupes * @note In Slashdot-speak, dupe means duplicate. * @note The default constructor does not accept $config or $context objects: * use must use the static build() factory method to perform initialization. */ class HTMLPurifier_IDAccumulator { /** * Lookup table of IDs we've accumulated. * @public */ public $ids = array(); /** * Builds an IDAccumulator, also initializing the default blacklist * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config * @param HTMLPurifier_Context $context Instance of HTMLPurifier_Context * @return HTMLPurifier_IDAccumulator Fully initialized HTMLPurifier_IDAccumulator */ public static function build($config, $context) { $id_accumulator = new HTMLPurifier_IDAccumulator(); $id_accumulator->load($config->get('Attr.IDBlacklist')); return $id_accumulator; } /** * Add an ID to the lookup table. * @param string $id ID to be added. * @return bool status, true if success, false if there's a dupe */ public function add($id) { if (isset($this->ids[$id])) { return false; } return $this->ids[$id] = true; } /** * Load a list of IDs into the lookup table * @param $array_of_ids Array of IDs to load * @note This function doesn't care about duplicates */ public function load($array_of_ids) { foreach ($array_of_ids as $id) { $this->ids[$id] = true; } } } /** * Injects tokens into the document while parsing for well-formedness. * This enables "formatter-like" functionality such as auto-paragraphing, * smiley-ification and linkification to take place. * * A note on how handlers create changes; this is done by assigning a new * value to the $token reference. These values can take a variety of forms and * are best described HTMLPurifier_Strategy_MakeWellFormed->processToken() * documentation. * * @todo Allow injectors to request a re-run on their output. This * would help if an operation is recursive. */ abstract class HTMLPurifier_Injector { /** * Advisory name of injector, this is for friendly error messages. * @type string */ public $name; /** * @type HTMLPurifier_HTMLDefinition */ protected $htmlDefinition; /** * Reference to CurrentNesting variable in Context. This is an array * list of tokens that we are currently "inside" * @type array */ protected $currentNesting; /** * Reference to current token. * @type HTMLPurifier_Token */ protected $currentToken; /** * Reference to InputZipper variable in Context. * @type HTMLPurifier_Zipper */ protected $inputZipper; /** * Array of elements and attributes this injector creates and therefore * need to be allowed by the definition. Takes form of * array('element' => array('attr', 'attr2'), 'element2') * @type array */ public $needed = array(); /** * Number of elements to rewind backwards (relative). * @type bool|int */ protected $rewindOffset = false; /** * Rewind to a spot to re-perform processing. This is useful if you * deleted a node, and now need to see if this change affected any * earlier nodes. Rewinding does not affect other injectors, and can * result in infinite loops if not used carefully. * @param bool|int $offset * @warning HTML Purifier will prevent you from fast-forwarding with this * function. */ public function rewindOffset($offset) { $this->rewindOffset = $offset; } /** * Retrieves rewind offset, and then unsets it. * @return bool|int */ public function getRewindOffset() { $r = $this->rewindOffset; $this->rewindOffset = false; return $r; } /** * Prepares the injector by giving it the config and context objects: * this allows references to important variables to be made within * the injector. This function also checks if the HTML environment * will work with the Injector (see checkNeeded()). * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string Boolean false if success, string of missing needed element/attribute if failure */ public function prepare($config, $context) { $this->htmlDefinition = $config->getHTMLDefinition(); // Even though this might fail, some unit tests ignore this and // still test checkNeeded, so be careful. Maybe get rid of that // dependency. $result = $this->checkNeeded($config); if ($result !== false) { return $result; } $this->currentNesting =& $context->get('CurrentNesting'); $this->currentToken =& $context->get('CurrentToken'); $this->inputZipper =& $context->get('InputZipper'); return false; } /** * This function checks if the HTML environment * will work with the Injector: if p tags are not allowed, the * Auto-Paragraphing injector should not be enabled. * @param HTMLPurifier_Config $config * @return bool|string Boolean false if success, string of missing needed element/attribute if failure */ public function checkNeeded($config) { $def = $config->getHTMLDefinition(); foreach ($this->needed as $element => $attributes) { if (is_int($element)) { $element = $attributes; } if (!isset($def->info[$element])) { return $element; } if (!is_array($attributes)) { continue; } foreach ($attributes as $name) { if (!isset($def->info[$element]->attr[$name])) { return "$element.$name"; } } } return false; } /** * Tests if the context node allows a certain element * @param string $name Name of element to test for * @return bool True if element is allowed, false if it is not */ public function allowsElement($name) { if (!empty($this->currentNesting)) { $parent_token = array_pop($this->currentNesting); $this->currentNesting[] = $parent_token; $parent = $this->htmlDefinition->info[$parent_token->name]; } else { $parent = $this->htmlDefinition->info_parent_def; } if (!isset($parent->child->elements[$name]) || isset($parent->excludes[$name])) { return false; } // check for exclusion for ($i = count($this->currentNesting) - 2; $i >= 0; $i--) { $node = $this->currentNesting[$i]; $def = $this->htmlDefinition->info[$node->name]; if (isset($def->excludes[$name])) { return false; } } return true; } /** * Iterator function, which starts with the next token and continues until * you reach the end of the input tokens. * @warning Please prevent previous references from interfering with this * functions by setting $i = null beforehand! * @param int $i Current integer index variable for inputTokens * @param HTMLPurifier_Token $current Current token variable. * Do NOT use $token, as that variable is also a reference * @return bool */ protected function forward(&$i, &$current) { if ($i === null) { $i = count($this->inputZipper->back) - 1; } else { $i--; } if ($i < 0) { return false; } $current = $this->inputZipper->back[$i]; return true; } /** * Similar to _forward, but accepts a third parameter $nesting (which * should be initialized at 0) and stops when we hit the end tag * for the node $this->inputIndex starts in. * @param int $i Current integer index variable for inputTokens * @param HTMLPurifier_Token $current Current token variable. * Do NOT use $token, as that variable is also a reference * @param int $nesting * @return bool */ protected function forwardUntilEndToken(&$i, &$current, &$nesting) { $result = $this->forward($i, $current); if (!$result) { return false; } if ($nesting === null) { $nesting = 0; } if ($current instanceof HTMLPurifier_Token_Start) { $nesting++; } elseif ($current instanceof HTMLPurifier_Token_End) { if ($nesting <= 0) { return false; } $nesting--; } return true; } /** * Iterator function, starts with the previous token and continues until * you reach the beginning of input tokens. * @warning Please prevent previous references from interfering with this * functions by setting $i = null beforehand! * @param int $i Current integer index variable for inputTokens * @param HTMLPurifier_Token $current Current token variable. * Do NOT use $token, as that variable is also a reference * @return bool */ protected function backward(&$i, &$current) { if ($i === null) { $i = count($this->inputZipper->front) - 1; } else { $i--; } if ($i < 0) { return false; } $current = $this->inputZipper->front[$i]; return true; } /** * Handler that is called when a text token is processed */ public function handleText(&$token) { } /** * Handler that is called when a start or empty token is processed */ public function handleElement(&$token) { } /** * Handler that is called when an end token is processed */ public function handleEnd(&$token) { $this->notifyEnd($token); } /** * Notifier that is called when an end token is processed * @param HTMLPurifier_Token $token Current token variable. * @note This differs from handlers in that the token is read-only * @deprecated */ public function notifyEnd($token) { } } /** * Represents a language and defines localizable string formatting and * other functions, as well as the localized messages for HTML Purifier. */ class HTMLPurifier_Language { /** * ISO 639 language code of language. Prefers shortest possible version. * @type string */ public $code = 'en'; /** * Fallback language code. * @type bool|string */ public $fallback = false; /** * Array of localizable messages. * @type array */ public $messages = array(); /** * Array of localizable error codes. * @type array */ public $errorNames = array(); /** * True if no message file was found for this language, so English * is being used instead. Check this if you'd like to notify the * user that they've used a non-supported language. * @type bool */ public $error = false; /** * Has the language object been loaded yet? * @type bool * @todo Make it private, fix usage in HTMLPurifier_LanguageTest */ public $_loaded = false; /** * @type HTMLPurifier_Config */ protected $config; /** * @type HTMLPurifier_Context */ protected $context; /** * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context */ public function __construct($config, $context) { $this->config = $config; $this->context = $context; } /** * Loads language object with necessary info from factory cache * @note This is a lazy loader */ public function load() { if ($this->_loaded) { return; } $factory = HTMLPurifier_LanguageFactory::instance(); $factory->loadLanguage($this->code); foreach ($factory->keys as $key) { $this->$key = $factory->cache[$this->code][$key]; } $this->_loaded = true; } /** * Retrieves a localised message. * @param string $key string identifier of message * @return string localised message */ public function getMessage($key) { if (!$this->_loaded) { $this->load(); } if (!isset($this->messages[$key])) { return "[$key]"; } return $this->messages[$key]; } /** * Retrieves a localised error name. * @param int $int error number, corresponding to PHP's error reporting * @return string localised message */ public function getErrorName($int) { if (!$this->_loaded) { $this->load(); } if (!isset($this->errorNames[$int])) { return "[Error: $int]"; } return $this->errorNames[$int]; } /** * Converts an array list into a string readable representation * @param array $array * @return string */ public function listify($array) { $sep = $this->getMessage('Item separator'); $sep_last = $this->getMessage('Item separator last'); $ret = ''; for ($i = 0, $c = count($array); $i < $c; $i++) { if ($i == 0) { } elseif ($i + 1 < $c) { $ret .= $sep; } else { $ret .= $sep_last; } $ret .= $array[$i]; } return $ret; } /** * Formats a localised message with passed parameters * @param string $key string identifier of message * @param array $args Parameters to substitute in * @return string localised message * @todo Implement conditionals? Right now, some messages make * reference to line numbers, but those aren't always available */ public function formatMessage($key, $args = array()) { if (!$this->_loaded) { $this->load(); } if (!isset($this->messages[$key])) { return "[$key]"; } $raw = $this->messages[$key]; $subst = array(); $generator = false; foreach ($args as $i => $value) { if (is_object($value)) { if ($value instanceof HTMLPurifier_Token) { // factor this out some time if (!$generator) { $generator = $this->context->get('Generator'); } if (isset($value->name)) { $subst['$'.$i.'.Name'] = $value->name; } if (isset($value->data)) { $subst['$'.$i.'.Data'] = $value->data; } $subst['$'.$i.'.Compact'] = $subst['$'.$i.'.Serialized'] = $generator->generateFromToken($value); // a more complex algorithm for compact representation // could be introduced for all types of tokens. This // may need to be factored out into a dedicated class if (!empty($value->attr)) { $stripped_token = clone $value; $stripped_token->attr = array(); $subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token); } $subst['$'.$i.'.Line'] = $value->line ? $value->line : 'unknown'; } continue; } elseif (is_array($value)) { $keys = array_keys($value); if (array_keys($keys) === $keys) { // list $subst['$'.$i] = $this->listify($value); } else { // associative array // no $i implementation yet, sorry $subst['$'.$i.'.Keys'] = $this->listify($keys); $subst['$'.$i.'.Values'] = $this->listify(array_values($value)); } continue; } $subst['$' . $i] = $value; } return strtr($raw, $subst); } } /** * Class responsible for generating HTMLPurifier_Language objects, managing * caching and fallbacks. * @note Thanks to MediaWiki for the general logic, although this version * has been entirely rewritten * @todo Serialized cache for languages */ class HTMLPurifier_LanguageFactory { /** * Cache of language code information used to load HTMLPurifier_Language objects. * Structure is: $factory->cache[$language_code][$key] = $value * @type array */ public $cache; /** * Valid keys in the HTMLPurifier_Language object. Designates which * variables to slurp out of a message file. * @type array */ public $keys = array('fallback', 'messages', 'errorNames'); /** * Instance to validate language codes. * @type HTMLPurifier_AttrDef_Lang * */ protected $validator; /** * Cached copy of dirname(__FILE__), directory of current file without * trailing slash. * @type string */ protected $dir; /** * Keys whose contents are a hash map and can be merged. * @type array */ protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true); /** * Keys whose contents are a list and can be merged. * @value array lookup */ protected $mergeable_keys_list = array(); /** * Retrieve sole instance of the factory. * @param HTMLPurifier_LanguageFactory $prototype Optional prototype to overload sole instance with, * or bool true to reset to default factory. * @return HTMLPurifier_LanguageFactory */ public static function instance($prototype = null) { static $instance = null; if ($prototype !== null) { $instance = $prototype; } elseif ($instance === null || $prototype == true) { $instance = new HTMLPurifier_LanguageFactory(); $instance->setup(); } return $instance; } /** * Sets up the singleton, much like a constructor * @note Prevents people from getting this outside of the singleton */ public function setup() { $this->validator = new HTMLPurifier_AttrDef_Lang(); $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier'; } /** * Creates a language object, handles class fallbacks * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @param bool|string $code Code to override configuration with. Private parameter. * @return HTMLPurifier_Language */ public function create($config, $context, $code = false) { // validate language code if ($code === false) { $code = $this->validator->validate( $config->get('Core.Language'), $config, $context ); } else { $code = $this->validator->validate($code, $config, $context); } if ($code === false) { $code = 'en'; // malformed code becomes English } $pcode = str_replace('-', '_', $code); // make valid PHP classname static $depth = 0; // recursion protection if ($code == 'en') { $lang = new HTMLPurifier_Language($config, $context); } else { $class = 'HTMLPurifier_Language_' . $pcode; $file = $this->dir . '/Language/classes/' . $code . '.php'; if (file_exists($file) || class_exists($class, false)) { $lang = new $class($config, $context); } else { // Go fallback $raw_fallback = $this->getFallbackFor($code); $fallback = $raw_fallback ? $raw_fallback : 'en'; $depth++; $lang = $this->create($config, $context, $fallback); if (!$raw_fallback) { $lang->error = true; } $depth--; } } $lang->code = $code; return $lang; } /** * Returns the fallback language for language * @note Loads the original language into cache * @param string $code language code * @return string|bool */ public function getFallbackFor($code) { $this->loadLanguage($code); return $this->cache[$code]['fallback']; } /** * Loads language into the cache, handles message file and fallbacks * @param string $code language code */ public function loadLanguage($code) { static $languages_seen = array(); // recursion guard // abort if we've already loaded it if (isset($this->cache[$code])) { return; } // generate filename $filename = $this->dir . '/Language/messages/' . $code . '.php'; // default fallback : may be overwritten by the ensuing include $fallback = ($code != 'en') ? 'en' : false; // load primary localisation if (!file_exists($filename)) { // skip the include: will rely solely on fallback $filename = $this->dir . '/Language/messages/en.php'; $cache = array(); } else { include $filename; $cache = compact($this->keys); } // load fallback localisation if (!empty($fallback)) { // infinite recursion guard if (isset($languages_seen[$code])) { trigger_error( 'Circular fallback reference in language ' . $code, E_USER_ERROR ); $fallback = 'en'; } $language_seen[$code] = true; // load the fallback recursively $this->loadLanguage($fallback); $fallback_cache = $this->cache[$fallback]; // merge fallback with current language foreach ($this->keys as $key) { if (isset($cache[$key]) && isset($fallback_cache[$key])) { if (isset($this->mergeable_keys_map[$key])) { $cache[$key] = $cache[$key] + $fallback_cache[$key]; } elseif (isset($this->mergeable_keys_list[$key])) { $cache[$key] = array_merge($fallback_cache[$key], $cache[$key]); } } else { $cache[$key] = $fallback_cache[$key]; } } } // save to cache for later retrieval $this->cache[$code] = $cache; return; } } /** * Represents a measurable length, with a string numeric magnitude * and a unit. This object is immutable. */ class HTMLPurifier_Length { /** * String numeric magnitude. * @type string */ protected $n; /** * String unit. False is permitted if $n = 0. * @type string|bool */ protected $unit; /** * Whether or not this length is valid. Null if not calculated yet. * @type bool */ protected $isValid; /** * Array Lookup array of units recognized by CSS 2.1 * @type array */ protected static $allowedUnits = array( 'em' => true, 'ex' => true, 'px' => true, 'in' => true, 'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true ); /** * @param string $n Magnitude * @param bool|string $u Unit */ public function __construct($n = '0', $u = false) { $this->n = (string) $n; $this->unit = $u !== false ? (string) $u : false; } /** * @param string $s Unit string, like '2em' or '3.4in' * @return HTMLPurifier_Length * @warning Does not perform validation. */ public static function make($s) { if ($s instanceof HTMLPurifier_Length) { return $s; } $n_length = strspn($s, '1234567890.+-'); $n = substr($s, 0, $n_length); $unit = substr($s, $n_length); if ($unit === '') { $unit = false; } return new HTMLPurifier_Length($n, $unit); } /** * Validates the number and unit. * @return bool */ protected function validate() { // Special case: if ($this->n === '+0' || $this->n === '-0') { $this->n = '0'; } if ($this->n === '0' && $this->unit === false) { return true; } if (!ctype_lower($this->unit)) { $this->unit = strtolower($this->unit); } if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) { return false; } // Hack: $def = new HTMLPurifier_AttrDef_CSS_Number(); $result = $def->validate($this->n, false, false); if ($result === false) { return false; } $this->n = $result; return true; } /** * Returns string representation of number. * @return string */ public function toString() { if (!$this->isValid()) { return false; } return $this->n . $this->unit; } /** * Retrieves string numeric magnitude. * @return string */ public function getN() { return $this->n; } /** * Retrieves string unit. * @return string */ public function getUnit() { return $this->unit; } /** * Returns true if this length unit is valid. * @return bool */ public function isValid() { if ($this->isValid === null) { $this->isValid = $this->validate(); } return $this->isValid; } /** * Compares two lengths, and returns 1 if greater, -1 if less and 0 if equal. * @param HTMLPurifier_Length $l * @return int * @warning If both values are too large or small, this calculation will * not work properly */ public function compareTo($l) { if ($l === false) { return false; } if ($l->unit !== $this->unit) { $converter = new HTMLPurifier_UnitConverter(); $l = $converter->convert($l, $this->unit); if ($l === false) { return false; } } return $this->n - $l->n; } } /** * Forgivingly lexes HTML (SGML-style) markup into tokens. * * A lexer parses a string of SGML-style markup and converts them into * corresponding tokens. It doesn't check for well-formedness, although its * internal mechanism may make this automatic (such as the case of * HTMLPurifier_Lexer_DOMLex). There are several implementations to choose * from. * * A lexer is HTML-oriented: it might work with XML, but it's not * recommended, as we adhere to a subset of the specification for optimization * reasons. This might change in the future. Also, most tokenizers are not * expected to handle DTDs or PIs. * * This class should not be directly instantiated, but you may use create() to * retrieve a default copy of the lexer. Being a supertype, this class * does not actually define any implementation, but offers commonly used * convenience functions for subclasses. * * @note The unit tests will instantiate this class for testing purposes, as * many of the utility functions require a class to be instantiated. * This means that, even though this class is not runnable, it will * not be declared abstract. * * @par * * @note * We use tokens rather than create a DOM representation because DOM would: * * @par * -# Require more processing and memory to create, * -# Is not streamable, and * -# Has the entire document structure (html and body not needed). * * @par * However, DOM is helpful in that it makes it easy to move around nodes * without a lot of lookaheads to see when a tag is closed. This is a * limitation of the token system and some workarounds would be nice. */ class HTMLPurifier_Lexer { /** * Whether or not this lexer implements line-number/column-number tracking. * If it does, set to true. */ public $tracksLineNumbers = false; // -- STATIC ---------------------------------------------------------- /** * Retrieves or sets the default Lexer as a Prototype Factory. * * By default HTMLPurifier_Lexer_DOMLex will be returned. There are * a few exceptions involving special features that only DirectLex * implements. * * @note The behavior of this class has changed, rather than accepting * a prototype object, it now accepts a configuration object. * To specify your own prototype, set %Core.LexerImpl to it. * This change in behavior de-singletonizes the lexer object. * * @param HTMLPurifier_Config $config * @return HTMLPurifier_Lexer * @throws HTMLPurifier_Exception */ public static function create($config) { if (!($config instanceof HTMLPurifier_Config)) { $lexer = $config; trigger_error( "Passing a prototype to HTMLPurifier_Lexer::create() is deprecated, please instead use %Core.LexerImpl", E_USER_WARNING ); } else { $lexer = $config->get('Core.LexerImpl'); } $needs_tracking = $config->get('Core.MaintainLineNumbers') || $config->get('Core.CollectErrors'); $inst = null; if (is_object($lexer)) { $inst = $lexer; } else { if (is_null($lexer)) { do { // auto-detection algorithm if ($needs_tracking) { $lexer = 'DirectLex'; break; } if (class_exists('DOMDocument') && method_exists('DOMDocument', 'loadHTML') && !extension_loaded('domxml') ) { // check for DOM support, because while it's part of the // core, it can be disabled compile time. Also, the PECL // domxml extension overrides the default DOM, and is evil // and nasty and we shan't bother to support it $lexer = 'DOMLex'; } else { $lexer = 'DirectLex'; } } while (0); } // do..while so we can break // instantiate recognized string names switch ($lexer) { case 'DOMLex': $inst = new HTMLPurifier_Lexer_DOMLex(); break; case 'DirectLex': $inst = new HTMLPurifier_Lexer_DirectLex(); break; case 'PH5P': $inst = new HTMLPurifier_Lexer_PH5P(); break; default: throw new HTMLPurifier_Exception( "Cannot instantiate unrecognized Lexer type " . htmlspecialchars($lexer) ); } } if (!$inst) { throw new HTMLPurifier_Exception('No lexer was instantiated'); } // once PHP DOM implements native line numbers, or we // hack out something using XSLT, remove this stipulation if ($needs_tracking && !$inst->tracksLineNumbers) { throw new HTMLPurifier_Exception( 'Cannot use lexer that does not support line numbers with ' . 'Core.MaintainLineNumbers or Core.CollectErrors (use DirectLex instead)' ); } return $inst; } // -- CONVENIENCE MEMBERS --------------------------------------------- public function __construct() { $this->_entity_parser = new HTMLPurifier_EntityParser(); } /** * Most common entity to raw value conversion table for special entities. * @type array */ protected $_special_entity2str = array( '"' => '"', '&' => '&', '<' => '<', '>' => '>', ''' => "'", ''' => "'", ''' => "'" ); /** * Parses special entities into the proper characters. * * This string will translate escaped versions of the special characters * into the correct ones. * * @warning * You should be able to treat the output of this function as * completely parsed, but that's only because all other entities should * have been handled previously in substituteNonSpecialEntities() * * @param string $string String character data to be parsed. * @return string Parsed character data. */ public function parseData($string) { // following functions require at least one character if ($string === '') { return ''; } // subtracts amps that cannot possibly be escaped $num_amp = substr_count($string, '&') - substr_count($string, '& ') - ($string[strlen($string) - 1] === '&' ? 1 : 0); if (!$num_amp) { return $string; } // abort if no entities $num_esc_amp = substr_count($string, '&'); $string = strtr($string, $this->_special_entity2str); // code duplication for sake of optimization, see above $num_amp_2 = substr_count($string, '&') - substr_count($string, '& ') - ($string[strlen($string) - 1] === '&' ? 1 : 0); if ($num_amp_2 <= $num_esc_amp) { return $string; } // hmm... now we have some uncommon entities. Use the callback. $string = $this->_entity_parser->substituteSpecialEntities($string); return $string; } /** * Lexes an HTML string into tokens. * @param $string String HTML. * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token[] array representation of HTML. */ public function tokenizeHTML($string, $config, $context) { trigger_error('Call to abstract class', E_USER_ERROR); } /** * Translates CDATA sections into regular sections (through escaping). * @param string $string HTML string to process. * @return string HTML with CDATA sections escaped. */ protected static function escapeCDATA($string) { return preg_replace_callback( '/<!\[CDATA\[(.+?)\]\]>/s', array('HTMLPurifier_Lexer', 'CDATACallback'), $string ); } /** * Special CDATA case that is especially convoluted for <script> * @param string $string HTML string to process. * @return string HTML with CDATA sections escaped. */ protected static function escapeCommentedCDATA($string) { return preg_replace_callback( '#<!--//--><!\[CDATA\[//><!--(.+?)//--><!\]\]>#s', array('HTMLPurifier_Lexer', 'CDATACallback'), $string ); } /** * Special Internet Explorer conditional comments should be removed. * @param string $string HTML string to process. * @return string HTML with conditional comments removed. */ protected static function removeIEConditional($string) { return preg_replace( '#<!--\[if [^>]+\]>.*?<!\[endif\]-->#si', // probably should generalize for all strings '', $string ); } /** * Callback function for escapeCDATA() that does the work. * * @warning Though this is public in order to let the callback happen, * calling it directly is not recommended. * @param array $matches PCRE matches array, with index 0 the entire match * and 1 the inside of the CDATA section. * @return string Escaped internals of the CDATA section. */ protected static function CDATACallback($matches) { // not exactly sure why the character set is needed, but whatever return htmlspecialchars($matches[1], ENT_COMPAT, 'UTF-8'); } /** * Takes a piece of HTML and normalizes it by converting entities, fixing * encoding, extracting bits, and other good stuff. * @param string $html HTML. * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string * @todo Consider making protected */ public function normalize($html, $config, $context) { // normalize newlines to \n if ($config->get('Core.NormalizeNewlines')) { $html = str_replace("\r\n", "\n", $html); $html = str_replace("\r", "\n", $html); } if ($config->get('HTML.Trusted')) { // escape convoluted CDATA $html = $this->escapeCommentedCDATA($html); } // escape CDATA $html = $this->escapeCDATA($html); $html = $this->removeIEConditional($html); // extract body from document if applicable if ($config->get('Core.ConvertDocumentToFragment')) { $e = false; if ($config->get('Core.CollectErrors')) { $e =& $context->get('ErrorCollector'); } $new_html = $this->extractBody($html); if ($e && $new_html != $html) { $e->send(E_WARNING, 'Lexer: Extracted body'); } $html = $new_html; } // expand entities that aren't the big five $html = $this->_entity_parser->substituteNonSpecialEntities($html); // clean into wellformed UTF-8 string for an SGML context: this has // to be done after entity expansion because the entities sometimes // represent non-SGML characters (horror, horror!) $html = HTMLPurifier_Encoder::cleanUTF8($html); // if processing instructions are to removed, remove them now if ($config->get('Core.RemoveProcessingInstructions')) { $html = preg_replace('#<\?.+?\?>#s', '', $html); } return $html; } /** * Takes a string of HTML (fragment or document) and returns the content * @todo Consider making protected */ public function extractBody($html) { $matches = array(); $result = preg_match('!<body[^>]*>(.*)</body>!is', $html, $matches); if ($result) { return $matches[1]; } else { return $html; } } } /** * Abstract base node class that all others inherit from. * * Why do we not use the DOM extension? (1) It is not always available, * (2) it has funny constraints on the data it can represent, * whereas we want a maximally flexible representation, and (3) its * interface is a bit cumbersome. */ abstract class HTMLPurifier_Node { /** * Line number of the start token in the source document * @type int */ public $line; /** * Column number of the start token in the source document. Null if unknown. * @type int */ public $col; /** * Lookup array of processing that this token is exempt from. * Currently, valid values are "ValidateAttributes". * @type array */ public $armor = array(); /** * When true, this node should be ignored as non-existent. * * Who is responsible for ignoring dead nodes? FixNesting is * responsible for removing them before passing on to child * validators. */ public $dead = false; /** * Returns a pair of start and end tokens, where the end token * is null if it is not necessary. Does not include children. * @type array */ abstract public function toTokenPair(); } /** * Class that handles operations involving percent-encoding in URIs. * * @warning * Be careful when reusing instances of PercentEncoder. The object * you use for normalize() SHOULD NOT be used for encode(), or * vice-versa. */ class HTMLPurifier_PercentEncoder { /** * Reserved characters to preserve when using encode(). * @type array */ protected $preserve = array(); /** * String of characters that should be preserved while using encode(). * @param bool $preserve */ public function __construct($preserve = false) { // unreserved letters, ought to const-ify for ($i = 48; $i <= 57; $i++) { // digits $this->preserve[$i] = true; } for ($i = 65; $i <= 90; $i++) { // upper-case $this->preserve[$i] = true; } for ($i = 97; $i <= 122; $i++) { // lower-case $this->preserve[$i] = true; } $this->preserve[45] = true; // Dash - $this->preserve[46] = true; // Period . $this->preserve[95] = true; // Underscore _ $this->preserve[126]= true; // Tilde ~ // extra letters not to escape if ($preserve !== false) { for ($i = 0, $c = strlen($preserve); $i < $c; $i++) { $this->preserve[ord($preserve[$i])] = true; } } } /** * Our replacement for urlencode, it encodes all non-reserved characters, * as well as any extra characters that were instructed to be preserved. * @note * Assumes that the string has already been normalized, making any * and all percent escape sequences valid. Percents will not be * re-escaped, regardless of their status in $preserve * @param string $string String to be encoded * @return string Encoded string. */ public function encode($string) { $ret = ''; for ($i = 0, $c = strlen($string); $i < $c; $i++) { if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])])) { $ret .= '%' . sprintf('%02X', $int); } else { $ret .= $string[$i]; } } return $ret; } /** * Fix up percent-encoding by decoding unreserved characters and normalizing. * @warning This function is affected by $preserve, even though the * usual desired behavior is for this not to preserve those * characters. Be careful when reusing instances of PercentEncoder! * @param string $string String to normalize * @return string */ public function normalize($string) { if ($string == '') { return ''; } $parts = explode('%', $string); $ret = array_shift($parts); foreach ($parts as $part) { $length = strlen($part); if ($length < 2) { $ret .= '%25' . $part; continue; } $encoding = substr($part, 0, 2); $text = substr($part, 2); if (!ctype_xdigit($encoding)) { $ret .= '%25' . $part; continue; } $int = hexdec($encoding); if (isset($this->preserve[$int])) { $ret .= chr($int) . $text; continue; } $encoding = strtoupper($encoding); $ret .= '%' . $encoding . $text; } return $ret; } } /** * Generic property list implementation */ class HTMLPurifier_PropertyList { /** * Internal data-structure for properties. * @type array */ protected $data = array(); /** * Parent plist. * @type HTMLPurifier_PropertyList */ protected $parent; /** * Cache. * @type array */ protected $cache; /** * @param HTMLPurifier_PropertyList $parent Parent plist */ public function __construct($parent = null) { $this->parent = $parent; } /** * Recursively retrieves the value for a key * @param string $name * @throws HTMLPurifier_Exception */ public function get($name) { if ($this->has($name)) { return $this->data[$name]; } // possible performance bottleneck, convert to iterative if necessary if ($this->parent) { return $this->parent->get($name); } throw new HTMLPurifier_Exception("Key '$name' not found"); } /** * Sets the value of a key, for this plist * @param string $name * @param mixed $value */ public function set($name, $value) { $this->data[$name] = $value; } /** * Returns true if a given key exists * @param string $name * @return bool */ public function has($name) { return array_key_exists($name, $this->data); } /** * Resets a value to the value of it's parent, usually the default. If * no value is specified, the entire plist is reset. * @param string $name */ public function reset($name = null) { if ($name == null) { $this->data = array(); } else { unset($this->data[$name]); } } /** * Squashes this property list and all of its property lists into a single * array, and returns the array. This value is cached by default. * @param bool $force If true, ignores the cache and regenerates the array. * @return array */ public function squash($force = false) { if ($this->cache !== null && !$force) { return $this->cache; } if ($this->parent) { return $this->cache = array_merge($this->parent->squash($force), $this->data); } else { return $this->cache = $this->data; } } /** * Returns the parent plist. * @return HTMLPurifier_PropertyList */ public function getParent() { return $this->parent; } /** * Sets the parent plist. * @param HTMLPurifier_PropertyList $plist Parent plist */ public function setParent($plist) { $this->parent = $plist; } } /** * Property list iterator. Do not instantiate this class directly. */ class HTMLPurifier_PropertyListIterator extends FilterIterator { /** * @type int */ protected $l; /** * @type string */ protected $filter; /** * @param Iterator $iterator Array of data to iterate over * @param string $filter Optional prefix to only allow values of */ public function __construct(Iterator $iterator, $filter = null) { parent::__construct($iterator); $this->l = strlen($filter); $this->filter = $filter; } /** * @return bool */ public function accept() { $key = $this->getInnerIterator()->key(); if (strncmp($key, $this->filter, $this->l) !== 0) { return false; } return true; } } /** * A simple array-backed queue, based off of the classic Okasaki * persistent amortized queue. The basic idea is to maintain two * stacks: an input stack and an output stack. When the output * stack runs out, reverse the input stack and use it as the output * stack. * * We don't use the SPL implementation because it's only supported * on PHP 5.3 and later. * * Exercise: Prove that push/pop on this queue take amortized O(1) time. * * Exercise: Extend this queue to be a deque, while preserving amortized * O(1) time. Some care must be taken on rebalancing to avoid quadratic * behaviour caused by repeatedly shuffling data from the input stack * to the output stack and back. */ class HTMLPurifier_Queue { private $input; private $output; public function __construct($input = array()) { $this->input = $input; $this->output = array(); } /** * Shifts an element off the front of the queue. */ public function shift() { if (empty($this->output)) { $this->output = array_reverse($this->input); $this->input = array(); } if (empty($this->output)) { return NULL; } return array_pop($this->output); } /** * Pushes an element onto the front of the queue. */ public function push($x) { array_push($this->input, $x); } /** * Checks if it's empty. */ public function isEmpty() { return empty($this->input) && empty($this->output); } } /** * Supertype for classes that define a strategy for modifying/purifying tokens. * * While HTMLPurifier's core purpose is fixing HTML into something proper, * strategies provide plug points for extra configuration or even extra * features, such as custom tags, custom parsing of text, etc. */ abstract class HTMLPurifier_Strategy { /** * Executes the strategy on the tokens. * * @param HTMLPurifier_Token[] $tokens Array of HTMLPurifier_Token objects to be operated on. * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token[] Processed array of token objects. */ abstract public function execute($tokens, $config, $context); } /** * This is in almost every respect equivalent to an array except * that it keeps track of which keys were accessed. * * @warning For the sake of backwards compatibility with early versions * of PHP 5, you must not use the $hash[$key] syntax; if you do * our version of offsetGet is never called. */ class HTMLPurifier_StringHash extends ArrayObject { /** * @type array */ protected $accessed = array(); /** * Retrieves a value, and logs the access. * @param mixed $index * @return mixed */ public function offsetGet($index) { $this->accessed[$index] = true; return parent::offsetGet($index); } /** * Returns a lookup array of all array indexes that have been accessed. * @return array in form array($index => true). */ public function getAccessed() { return $this->accessed; } /** * Resets the access array. */ public function resetAccessed() { $this->accessed = array(); } } /** * Parses string hash files. File format is as such: * * DefaultKeyValue * KEY: Value * KEY2: Value2 * --MULTILINE-KEY-- * Multiline * value. * * Which would output something similar to: * * array( * 'ID' => 'DefaultKeyValue', * 'KEY' => 'Value', * 'KEY2' => 'Value2', * 'MULTILINE-KEY' => "Multiline\nvalue.\n", * ) * * We use this as an easy to use file-format for configuration schema * files, but the class itself is usage agnostic. * * You can use ---- to forcibly terminate parsing of a single string-hash; * this marker is used in multi string-hashes to delimit boundaries. */ class HTMLPurifier_StringHashParser { /** * @type string */ public $default = 'ID'; /** * Parses a file that contains a single string-hash. * @param string $file * @return array */ public function parseFile($file) { if (!file_exists($file)) { return false; } $fh = fopen($file, 'r'); if (!$fh) { return false; } $ret = $this->parseHandle($fh); fclose($fh); return $ret; } /** * Parses a file that contains multiple string-hashes delimited by '----' * @param string $file * @return array */ public function parseMultiFile($file) { if (!file_exists($file)) { return false; } $ret = array(); $fh = fopen($file, 'r'); if (!$fh) { return false; } while (!feof($fh)) { $ret[] = $this->parseHandle($fh); } fclose($fh); return $ret; } /** * Internal parser that acepts a file handle. * @note While it's possible to simulate in-memory parsing by using * custom stream wrappers, if such a use-case arises we should * factor out the file handle into its own class. * @param resource $fh File handle with pointer at start of valid string-hash * block. * @return array */ protected function parseHandle($fh) { $state = false; $single = false; $ret = array(); do { $line = fgets($fh); if ($line === false) { break; } $line = rtrim($line, "\n\r"); if (!$state && $line === '') { continue; } if ($line === '----') { break; } if (strncmp('--#', $line, 3) === 0) { // Comment continue; } elseif (strncmp('--', $line, 2) === 0) { // Multiline declaration $state = trim($line, '- '); if (!isset($ret[$state])) { $ret[$state] = ''; } continue; } elseif (!$state) { $single = true; if (strpos($line, ':') !== false) { // Single-line declaration list($state, $line) = explode(':', $line, 2); $line = trim($line); } else { // Use default declaration $state = $this->default; } } if ($single) { $ret[$state] = $line; $single = false; $state = false; } else { $ret[$state] .= "$line\n"; } } while (!feof($fh)); return $ret; } } /** * Defines a mutation of an obsolete tag into a valid tag. */ abstract class HTMLPurifier_TagTransform { /** * Tag name to transform the tag to. * @type string */ public $transform_to; /** * Transforms the obsolete tag into the valid tag. * @param HTMLPurifier_Token_Tag $tag Tag to be transformed. * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object */ abstract public function transform($tag, $config, $context); /** * Prepends CSS properties to the style attribute, creating the * attribute if it doesn't exist. * @warning Copied over from AttrTransform, be sure to keep in sync * @param array $attr Attribute array to process (passed by reference) * @param string $css CSS to prepend */ protected function prependCSS(&$attr, $css) { $attr['style'] = isset($attr['style']) ? $attr['style'] : ''; $attr['style'] = $css . $attr['style']; } } /** * Abstract base token class that all others inherit from. */ abstract class HTMLPurifier_Token { /** * Line number node was on in source document. Null if unknown. * @type int */ public $line; /** * Column of line node was on in source document. Null if unknown. * @type int */ public $col; /** * Lookup array of processing that this token is exempt from. * Currently, valid values are "ValidateAttributes" and * "MakeWellFormed_TagClosedError" * @type array */ public $armor = array(); /** * Used during MakeWellFormed. * @type */ public $skip; /** * @type */ public $rewind; /** * @type */ public $carryover; /** * @param string $n * @return null|string */ public function __get($n) { if ($n === 'type') { trigger_error('Deprecated type property called; use instanceof', E_USER_NOTICE); switch (get_class($this)) { case 'HTMLPurifier_Token_Start': return 'start'; case 'HTMLPurifier_Token_Empty': return 'empty'; case 'HTMLPurifier_Token_End': return 'end'; case 'HTMLPurifier_Token_Text': return 'text'; case 'HTMLPurifier_Token_Comment': return 'comment'; default: return null; } } } /** * Sets the position of the token in the source document. * @param int $l * @param int $c */ public function position($l = null, $c = null) { $this->line = $l; $this->col = $c; } /** * Convenience function for DirectLex settings line/col position. * @param int $l * @param int $c */ public function rawPosition($l, $c) { if ($c === -1) { $l++; } $this->line = $l; $this->col = $c; } /** * Converts a token into its corresponding node. */ abstract public function toNode(); } /** * Factory for token generation. * * @note Doing some benchmarking indicates that the new operator is much * slower than the clone operator (even discounting the cost of the * constructor). This class is for that optimization. * Other then that, there's not much point as we don't * maintain parallel HTMLPurifier_Token hierarchies (the main reason why * you'd want to use an abstract factory). * @todo Port DirectLex to use this */ class HTMLPurifier_TokenFactory { // p stands for prototype /** * @type HTMLPurifier_Token_Start */ private $p_start; /** * @type HTMLPurifier_Token_End */ private $p_end; /** * @type HTMLPurifier_Token_Empty */ private $p_empty; /** * @type HTMLPurifier_Token_Text */ private $p_text; /** * @type HTMLPurifier_Token_Comment */ private $p_comment; /** * Generates blank prototypes for cloning. */ public function __construct() { $this->p_start = new HTMLPurifier_Token_Start('', array()); $this->p_end = new HTMLPurifier_Token_End(''); $this->p_empty = new HTMLPurifier_Token_Empty('', array()); $this->p_text = new HTMLPurifier_Token_Text(''); $this->p_comment = new HTMLPurifier_Token_Comment(''); } /** * Creates a HTMLPurifier_Token_Start. * @param string $name Tag name * @param array $attr Associative array of attributes * @return HTMLPurifier_Token_Start Generated HTMLPurifier_Token_Start */ public function createStart($name, $attr = array()) { $p = clone $this->p_start; $p->__construct($name, $attr); return $p; } /** * Creates a HTMLPurifier_Token_End. * @param string $name Tag name * @return HTMLPurifier_Token_End Generated HTMLPurifier_Token_End */ public function createEnd($name) { $p = clone $this->p_end; $p->__construct($name); return $p; } /** * Creates a HTMLPurifier_Token_Empty. * @param string $name Tag name * @param array $attr Associative array of attributes * @return HTMLPurifier_Token_Empty Generated HTMLPurifier_Token_Empty */ public function createEmpty($name, $attr = array()) { $p = clone $this->p_empty; $p->__construct($name, $attr); return $p; } /** * Creates a HTMLPurifier_Token_Text. * @param string $data Data of text token * @return HTMLPurifier_Token_Text Generated HTMLPurifier_Token_Text */ public function createText($data) { $p = clone $this->p_text; $p->__construct($data); return $p; } /** * Creates a HTMLPurifier_Token_Comment. * @param string $data Data of comment token * @return HTMLPurifier_Token_Comment Generated HTMLPurifier_Token_Comment */ public function createComment($data) { $p = clone $this->p_comment; $p->__construct($data); return $p; } } /** * HTML Purifier's internal representation of a URI. * @note * Internal data-structures are completely escaped. If the data needs * to be used in a non-URI context (which is very unlikely), be sure * to decode it first. The URI may not necessarily be well-formed until * validate() is called. */ class HTMLPurifier_URI { /** * @type string */ public $scheme; /** * @type string */ public $userinfo; /** * @type string */ public $host; /** * @type int */ public $port; /** * @type string */ public $path; /** * @type string */ public $query; /** * @type string */ public $fragment; /** * @param string $scheme * @param string $userinfo * @param string $host * @param int $port * @param string $path * @param string $query * @param string $fragment * @note Automatically normalizes scheme and port */ public function __construct($scheme, $userinfo, $host, $port, $path, $query, $fragment) { $this->scheme = is_null($scheme) || ctype_lower($scheme) ? $scheme : strtolower($scheme); $this->userinfo = $userinfo; $this->host = $host; $this->port = is_null($port) ? $port : (int)$port; $this->path = $path; $this->query = $query; $this->fragment = $fragment; } /** * Retrieves a scheme object corresponding to the URI's scheme/default * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_URIScheme Scheme object appropriate for validating this URI */ public function getSchemeObj($config, $context) { $registry = HTMLPurifier_URISchemeRegistry::instance(); if ($this->scheme !== null) { $scheme_obj = $registry->getScheme($this->scheme, $config, $context); if (!$scheme_obj) { return false; } // invalid scheme, clean it out } else { // no scheme: retrieve the default one $def = $config->getDefinition('URI'); $scheme_obj = $def->getDefaultScheme($config, $context); if (!$scheme_obj) { // something funky happened to the default scheme object trigger_error( 'Default scheme object "' . $def->defaultScheme . '" was not readable', E_USER_WARNING ); return false; } } return $scheme_obj; } /** * Generic validation method applicable for all schemes. May modify * this URI in order to get it into a compliant form. * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool True if validation/filtering succeeds, false if failure */ public function validate($config, $context) { // ABNF definitions from RFC 3986 $chars_sub_delims = '!$&\'()*+,;='; $chars_gen_delims = ':/?#[]@'; $chars_pchar = $chars_sub_delims . ':@'; // validate host if (!is_null($this->host)) { $host_def = new HTMLPurifier_AttrDef_URI_Host(); $this->host = $host_def->validate($this->host, $config, $context); if ($this->host === false) { $this->host = null; } } // validate scheme // NOTE: It's not appropriate to check whether or not this // scheme is in our registry, since a URIFilter may convert a // URI that we don't allow into one we do. So instead, we just // check if the scheme can be dropped because there is no host // and it is our default scheme. if (!is_null($this->scheme) && is_null($this->host) || $this->host === '') { // support for relative paths is pretty abysmal when the // scheme is present, so axe it when possible $def = $config->getDefinition('URI'); if ($def->defaultScheme === $this->scheme) { $this->scheme = null; } } // validate username if (!is_null($this->userinfo)) { $encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':'); $this->userinfo = $encoder->encode($this->userinfo); } // validate port if (!is_null($this->port)) { if ($this->port < 1 || $this->port > 65535) { $this->port = null; } } // validate path $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/'); if (!is_null($this->host)) { // this catches $this->host === '' // path-abempty (hier and relative) // http://www.example.com/my/path // //www.example.com/my/path (looks odd, but works, and // recognized by most browsers) // (this set is valid or invalid on a scheme by scheme // basis, so we'll deal with it later) // file:///my/path // ///my/path $this->path = $segments_encoder->encode($this->path); } elseif ($this->path !== '') { if ($this->path[0] === '/') { // path-absolute (hier and relative) // http:/my/path // /my/path if (strlen($this->path) >= 2 && $this->path[1] === '/') { // This could happen if both the host gets stripped // out // http://my/path // //my/path $this->path = ''; } else { $this->path = $segments_encoder->encode($this->path); } } elseif (!is_null($this->scheme)) { // path-rootless (hier) // http:my/path // Short circuit evaluation means we don't need to check nz $this->path = $segments_encoder->encode($this->path); } else { // path-noscheme (relative) // my/path // (once again, not checking nz) $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@'); $c = strpos($this->path, '/'); if ($c !== false) { $this->path = $segment_nc_encoder->encode(substr($this->path, 0, $c)) . $segments_encoder->encode(substr($this->path, $c)); } else { $this->path = $segment_nc_encoder->encode($this->path); } } } else { // path-empty (hier and relative) $this->path = ''; // just to be safe } // qf = query and fragment $qf_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/?'); if (!is_null($this->query)) { $this->query = $qf_encoder->encode($this->query); } if (!is_null($this->fragment)) { $this->fragment = $qf_encoder->encode($this->fragment); } return true; } /** * Convert URI back to string * @return string URI appropriate for output */ public function toString() { // reconstruct authority $authority = null; // there is a rendering difference between a null authority // (http:foo-bar) and an empty string authority // (http:///foo-bar). if (!is_null($this->host)) { $authority = ''; if (!is_null($this->userinfo)) { $authority .= $this->userinfo . '@'; } $authority .= $this->host; if (!is_null($this->port)) { $authority .= ':' . $this->port; } } // Reconstruct the result // One might wonder about parsing quirks from browsers after // this reconstruction. Unfortunately, parsing behavior depends // on what *scheme* was employed (file:///foo is handled *very* // differently than http:///foo), so unfortunately we have to // defer to the schemes to do the right thing. $result = ''; if (!is_null($this->scheme)) { $result .= $this->scheme . ':'; } if (!is_null($authority)) { $result .= '//' . $authority; } $result .= $this->path; if (!is_null($this->query)) { $result .= '?' . $this->query; } if (!is_null($this->fragment)) { $result .= '#' . $this->fragment; } return $result; } /** * Returns true if this URL might be considered a 'local' URL given * the current context. This is true when the host is null, or * when it matches the host supplied to the configuration. * * Note that this does not do any scheme checking, so it is mostly * only appropriate for metadata that doesn't care about protocol * security. isBenign is probably what you actually want. * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function isLocal($config, $context) { if ($this->host === null) { return true; } $uri_def = $config->getDefinition('URI'); if ($uri_def->host === $this->host) { return true; } return false; } /** * Returns true if this URL should be considered a 'benign' URL, * that is: * * - It is a local URL (isLocal), and * - It has a equal or better level of security * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function isBenign($config, $context) { if (!$this->isLocal($config, $context)) { return false; } $scheme_obj = $this->getSchemeObj($config, $context); if (!$scheme_obj) { return false; } // conservative approach $current_scheme_obj = $config->getDefinition('URI')->getDefaultScheme($config, $context); if ($current_scheme_obj->secure) { if (!$scheme_obj->secure) { return false; } } return true; } } class HTMLPurifier_URIDefinition extends HTMLPurifier_Definition { public $type = 'URI'; protected $filters = array(); protected $postFilters = array(); protected $registeredFilters = array(); /** * HTMLPurifier_URI object of the base specified at %URI.Base */ public $base; /** * String host to consider "home" base, derived off of $base */ public $host; /** * Name of default scheme based on %URI.DefaultScheme and %URI.Base */ public $defaultScheme; public function __construct() { $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternal()); $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources()); $this->registerFilter(new HTMLPurifier_URIFilter_DisableResources()); $this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist()); $this->registerFilter(new HTMLPurifier_URIFilter_SafeIframe()); $this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute()); $this->registerFilter(new HTMLPurifier_URIFilter_Munge()); } public function registerFilter($filter) { $this->registeredFilters[$filter->name] = $filter; } public function addFilter($filter, $config) { $r = $filter->prepare($config); if ($r === false) return; // null is ok, for backwards compat if ($filter->post) { $this->postFilters[$filter->name] = $filter; } else { $this->filters[$filter->name] = $filter; } } protected function doSetup($config) { $this->setupMemberVariables($config); $this->setupFilters($config); } protected function setupFilters($config) { foreach ($this->registeredFilters as $name => $filter) { if ($filter->always_load) { $this->addFilter($filter, $config); } else { $conf = $config->get('URI.' . $name); if ($conf !== false && $conf !== null) { $this->addFilter($filter, $config); } } } unset($this->registeredFilters); } protected function setupMemberVariables($config) { $this->host = $config->get('URI.Host'); $base_uri = $config->get('URI.Base'); if (!is_null($base_uri)) { $parser = new HTMLPurifier_URIParser(); $this->base = $parser->parse($base_uri); $this->defaultScheme = $this->base->scheme; if (is_null($this->host)) $this->host = $this->base->host; } if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme'); } public function getDefaultScheme($config, $context) { return HTMLPurifier_URISchemeRegistry::instance()->getScheme($this->defaultScheme, $config, $context); } public function filter(&$uri, $config, $context) { foreach ($this->filters as $name => $f) { $result = $f->filter($uri, $config, $context); if (!$result) return false; } return true; } public function postFilter(&$uri, $config, $context) { foreach ($this->postFilters as $name => $f) { $result = $f->filter($uri, $config, $context); if (!$result) return false; } return true; } } /** * Chainable filters for custom URI processing. * * These filters can perform custom actions on a URI filter object, * including transformation or blacklisting. A filter named Foo * must have a corresponding configuration directive %URI.Foo, * unless always_load is specified to be true. * * The following contexts may be available while URIFilters are being * processed: * * - EmbeddedURI: true if URI is an embedded resource that will * be loaded automatically on page load * - CurrentToken: a reference to the token that is currently * being processed * - CurrentAttr: the name of the attribute that is currently being * processed * - CurrentCSSProperty: the name of the CSS property that is * currently being processed (if applicable) * * @warning This filter is called before scheme object validation occurs. * Make sure, if you require a specific scheme object, you * you check that it exists. This allows filters to convert * proprietary URI schemes into regular ones. */ abstract class HTMLPurifier_URIFilter { /** * Unique identifier of filter. * @type string */ public $name; /** * True if this filter should be run after scheme validation. * @type bool */ public $post = false; /** * True if this filter should always be loaded. * This permits a filter to be named Foo without the corresponding * %URI.Foo directive existing. * @type bool */ public $always_load = false; /** * Performs initialization for the filter. If the filter returns * false, this means that it shouldn't be considered active. * @param HTMLPurifier_Config $config * @return bool */ public function prepare($config) { return true; } /** * Filter a URI object * @param HTMLPurifier_URI $uri Reference to URI object variable * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool Whether or not to continue processing: false indicates * URL is no good, true indicates continue processing. Note that * all changes are committed directly on the URI object */ abstract public function filter(&$uri, $config, $context); } /** * Parses a URI into the components and fragment identifier as specified * by RFC 3986. */ class HTMLPurifier_URIParser { /** * Instance of HTMLPurifier_PercentEncoder to do normalization with. */ protected $percentEncoder; public function __construct() { $this->percentEncoder = new HTMLPurifier_PercentEncoder(); } /** * Parses a URI. * @param $uri string URI to parse * @return HTMLPurifier_URI representation of URI. This representation has * not been validated yet and may not conform to RFC. */ public function parse($uri) { $uri = $this->percentEncoder->normalize($uri); // Regexp is as per Appendix B. // Note that ["<>] are an addition to the RFC's recommended // characters, because they represent external delimeters. $r_URI = '!'. '(([a-zA-Z0-9\.\+\-]+):)?'. // 2. Scheme '(//([^/?#"<>]*))?'. // 4. Authority '([^?#"<>]*)'. // 5. Path '(\?([^#"<>]*))?'. // 7. Query '(#([^"<>]*))?'. // 8. Fragment '!'; $matches = array(); $result = preg_match($r_URI, $uri, $matches); if (!$result) return false; // *really* invalid URI // seperate out parts $scheme = !empty($matches[1]) ? $matches[2] : null; $authority = !empty($matches[3]) ? $matches[4] : null; $path = $matches[5]; // always present, can be empty $query = !empty($matches[6]) ? $matches[7] : null; $fragment = !empty($matches[8]) ? $matches[9] : null; // further parse authority if ($authority !== null) { $r_authority = "/^((.+?)@)?(\[[^\]]+\]|[^:]*)(:(\d*))?/"; $matches = array(); preg_match($r_authority, $authority, $matches); $userinfo = !empty($matches[1]) ? $matches[2] : null; $host = !empty($matches[3]) ? $matches[3] : ''; $port = !empty($matches[4]) ? (int) $matches[5] : null; } else { $port = $host = $userinfo = null; } return new HTMLPurifier_URI( $scheme, $userinfo, $host, $port, $path, $query, $fragment); } } /** * Validator for the components of a URI for a specific scheme */ abstract class HTMLPurifier_URIScheme { /** * Scheme's default port (integer). If an explicit port number is * specified that coincides with the default port, it will be * elided. * @type int */ public $default_port = null; /** * Whether or not URIs of this scheme are locatable by a browser * http and ftp are accessible, while mailto and news are not. * @type bool */ public $browsable = false; /** * Whether or not data transmitted over this scheme is encrypted. * https is secure, http is not. * @type bool */ public $secure = false; /** * Whether or not the URI always uses <hier_part>, resolves edge cases * with making relative URIs absolute * @type bool */ public $hierarchical = false; /** * Whether or not the URI may omit a hostname when the scheme is * explicitly specified, ala file:///path/to/file. As of writing, * 'file' is the only scheme that browsers support his properly. * @type bool */ public $may_omit_host = false; /** * Validates the components of a URI for a specific scheme. * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool success or failure */ abstract public function doValidate(&$uri, $config, $context); /** * Public interface for validating components of a URI. Performs a * bunch of default actions. Don't overload this method. * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool success or failure */ public function validate(&$uri, $config, $context) { if ($this->default_port == $uri->port) { $uri->port = null; } // kludge: browsers do funny things when the scheme but not the // authority is set if (!$this->may_omit_host && // if the scheme is present, a missing host is always in error (!is_null($uri->scheme) && ($uri->host === '' || is_null($uri->host))) || // if the scheme is not present, a *blank* host is in error, // since this translates into '///path' which most browsers // interpret as being 'http://path'. (is_null($uri->scheme) && $uri->host === '') ) { do { if (is_null($uri->scheme)) { if (substr($uri->path, 0, 2) != '//') { $uri->host = null; break; } // URI is '////path', so we cannot nullify the // host to preserve semantics. Try expanding the // hostname instead (fall through) } // first see if we can manually insert a hostname $host = $config->get('URI.Host'); if (!is_null($host)) { $uri->host = $host; } else { // we can't do anything sensible, reject the URL. return false; } } while (false); } return $this->doValidate($uri, $config, $context); } } /** * Registry for retrieving specific URI scheme validator objects. */ class HTMLPurifier_URISchemeRegistry { /** * Retrieve sole instance of the registry. * @param HTMLPurifier_URISchemeRegistry $prototype Optional prototype to overload sole instance with, * or bool true to reset to default registry. * @return HTMLPurifier_URISchemeRegistry * @note Pass a registry object $prototype with a compatible interface and * the function will copy it and return it all further times. */ public static function instance($prototype = null) { static $instance = null; if ($prototype !== null) { $instance = $prototype; } elseif ($instance === null || $prototype == true) { $instance = new HTMLPurifier_URISchemeRegistry(); } return $instance; } /** * Cache of retrieved schemes. * @type HTMLPurifier_URIScheme[] */ protected $schemes = array(); /** * Retrieves a scheme validator object * @param string $scheme String scheme name like http or mailto * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_URIScheme */ public function getScheme($scheme, $config, $context) { if (!$config) { $config = HTMLPurifier_Config::createDefault(); } // important, otherwise attacker could include arbitrary file $allowed_schemes = $config->get('URI.AllowedSchemes'); if (!$config->get('URI.OverrideAllowedSchemes') && !isset($allowed_schemes[$scheme]) ) { return; } if (isset($this->schemes[$scheme])) { return $this->schemes[$scheme]; } if (!isset($allowed_schemes[$scheme])) { return; } $class = 'HTMLPurifier_URIScheme_' . $scheme; if (!class_exists($class)) { return; } $this->schemes[$scheme] = new $class(); return $this->schemes[$scheme]; } /** * Registers a custom scheme to the cache, bypassing reflection. * @param string $scheme Scheme name * @param HTMLPurifier_URIScheme $scheme_obj */ public function register($scheme, $scheme_obj) { $this->schemes[$scheme] = $scheme_obj; } } /** * Class for converting between different unit-lengths as specified by * CSS. */ class HTMLPurifier_UnitConverter { const ENGLISH = 1; const METRIC = 2; const DIGITAL = 3; /** * Units information array. Units are grouped into measuring systems * (English, Metric), and are assigned an integer representing * the conversion factor between that unit and the smallest unit in * the system. Numeric indexes are actually magical constants that * encode conversion data from one system to the next, with a O(n^2) * constraint on memory (this is generally not a problem, since * the number of measuring systems is small.) */ protected static $units = array( self::ENGLISH => array( 'px' => 3, // This is as per CSS 2.1 and Firefox. Your mileage may vary 'pt' => 4, 'pc' => 48, 'in' => 288, self::METRIC => array('pt', '0.352777778', 'mm'), ), self::METRIC => array( 'mm' => 1, 'cm' => 10, self::ENGLISH => array('mm', '2.83464567', 'pt'), ), ); /** * Minimum bcmath precision for output. * @type int */ protected $outputPrecision; /** * Bcmath precision for internal calculations. * @type int */ protected $internalPrecision; /** * Whether or not BCMath is available. * @type bool */ private $bcmath; public function __construct($output_precision = 4, $internal_precision = 10, $force_no_bcmath = false) { $this->outputPrecision = $output_precision; $this->internalPrecision = $internal_precision; $this->bcmath = !$force_no_bcmath && function_exists('bcmul'); } /** * Converts a length object of one unit into another unit. * @param HTMLPurifier_Length $length * Instance of HTMLPurifier_Length to convert. You must validate() * it before passing it here! * @param string $to_unit * Unit to convert to. * @return HTMLPurifier_Length|bool * @note * About precision: This conversion function pays very special * attention to the incoming precision of values and attempts * to maintain a number of significant figure. Results are * fairly accurate up to nine digits. Some caveats: * - If a number is zero-padded as a result of this significant * figure tracking, the zeroes will be eliminated. * - If a number contains less than four sigfigs ($outputPrecision) * and this causes some decimals to be excluded, those * decimals will be added on. */ public function convert($length, $to_unit) { if (!$length->isValid()) { return false; } $n = $length->getN(); $unit = $length->getUnit(); if ($n === '0' || $unit === false) { return new HTMLPurifier_Length('0', false); } $state = $dest_state = false; foreach (self::$units as $k => $x) { if (isset($x[$unit])) { $state = $k; } if (isset($x[$to_unit])) { $dest_state = $k; } } if (!$state || !$dest_state) { return false; } // Some calculations about the initial precision of the number; // this will be useful when we need to do final rounding. $sigfigs = $this->getSigFigs($n); if ($sigfigs < $this->outputPrecision) { $sigfigs = $this->outputPrecision; } // BCMath's internal precision deals only with decimals. Use // our default if the initial number has no decimals, or increase // it by how ever many decimals, thus, the number of guard digits // will always be greater than or equal to internalPrecision. $log = (int)floor(log(abs($n), 10)); $cp = ($log < 0) ? $this->internalPrecision - $log : $this->internalPrecision; // internal precision for ($i = 0; $i < 2; $i++) { // Determine what unit IN THIS SYSTEM we need to convert to if ($dest_state === $state) { // Simple conversion $dest_unit = $to_unit; } else { // Convert to the smallest unit, pending a system shift $dest_unit = self::$units[$state][$dest_state][0]; } // Do the conversion if necessary if ($dest_unit !== $unit) { $factor = $this->div(self::$units[$state][$unit], self::$units[$state][$dest_unit], $cp); $n = $this->mul($n, $factor, $cp); $unit = $dest_unit; } // Output was zero, so bail out early. Shouldn't ever happen. if ($n === '') { $n = '0'; $unit = $to_unit; break; } // It was a simple conversion, so bail out if ($dest_state === $state) { break; } if ($i !== 0) { // Conversion failed! Apparently, the system we forwarded // to didn't have this unit. This should never happen! return false; } // Pre-condition: $i == 0 // Perform conversion to next system of units $n = $this->mul($n, self::$units[$state][$dest_state][1], $cp); $unit = self::$units[$state][$dest_state][2]; $state = $dest_state; // One more loop around to convert the unit in the new system. } // Post-condition: $unit == $to_unit if ($unit !== $to_unit) { return false; } // Useful for debugging: //echo "<pre>n"; //echo "$n\nsigfigs = $sigfigs\nnew_log = $new_log\nlog = $log\nrp = $rp\n</pre>\n"; $n = $this->round($n, $sigfigs); if (strpos($n, '.') !== false) { $n = rtrim($n, '0'); } $n = rtrim($n, '.'); return new HTMLPurifier_Length($n, $unit); } /** * Returns the number of significant figures in a string number. * @param string $n Decimal number * @return int number of sigfigs */ public function getSigFigs($n) { $n = ltrim($n, '0+-'); $dp = strpos($n, '.'); // decimal position if ($dp === false) { $sigfigs = strlen(rtrim($n, '0')); } else { $sigfigs = strlen(ltrim($n, '0.')); // eliminate extra decimal character if ($dp !== 0) { $sigfigs--; } } return $sigfigs; } /** * Adds two numbers, using arbitrary precision when available. * @param string $s1 * @param string $s2 * @param int $scale * @return string */ private function add($s1, $s2, $scale) { if ($this->bcmath) { return bcadd($s1, $s2, $scale); } else { return $this->scale((float)$s1 + (float)$s2, $scale); } } /** * Multiples two numbers, using arbitrary precision when available. * @param string $s1 * @param string $s2 * @param int $scale * @return string */ private function mul($s1, $s2, $scale) { if ($this->bcmath) { return bcmul($s1, $s2, $scale); } else { return $this->scale((float)$s1 * (float)$s2, $scale); } } /** * Divides two numbers, using arbitrary precision when available. * @param string $s1 * @param string $s2 * @param int $scale * @return string */ private function div($s1, $s2, $scale) { if ($this->bcmath) { return bcdiv($s1, $s2, $scale); } else { return $this->scale((float)$s1 / (float)$s2, $scale); } } /** * Rounds a number according to the number of sigfigs it should have, * using arbitrary precision when available. * @param float $n * @param int $sigfigs * @return string */ private function round($n, $sigfigs) { $new_log = (int)floor(log(abs($n), 10)); // Number of digits left of decimal - 1 $rp = $sigfigs - $new_log - 1; // Number of decimal places needed $neg = $n < 0 ? '-' : ''; // Negative sign if ($this->bcmath) { if ($rp >= 0) { $n = bcadd($n, $neg . '0.' . str_repeat('0', $rp) . '5', $rp + 1); $n = bcdiv($n, '1', $rp); } else { // This algorithm partially depends on the standardized // form of numbers that comes out of bcmath. $n = bcadd($n, $neg . '5' . str_repeat('0', $new_log - $sigfigs), 0); $n = substr($n, 0, $sigfigs + strlen($neg)) . str_repeat('0', $new_log - $sigfigs + 1); } return $n; } else { return $this->scale(round($n, $sigfigs - $new_log - 1), $rp + 1); } } /** * Scales a float to $scale digits right of decimal point, like BCMath. * @param float $r * @param int $scale * @return string */ private function scale($r, $scale) { if ($scale < 0) { // The f sprintf type doesn't support negative numbers, so we // need to cludge things manually. First get the string. $r = sprintf('%.0f', (float)$r); // Due to floating point precision loss, $r will more than likely // look something like 4652999999999.9234. We grab one more digit // than we need to precise from $r and then use that to round // appropriately. $precise = (string)round(substr($r, 0, strlen($r) + $scale), -1); // Now we return it, truncating the zero that was rounded off. return substr($precise, 0, -1) . str_repeat('0', -$scale + 1); } return sprintf('%.' . $scale . 'f', (float)$r); } } /** * Parses string representations into their corresponding native PHP * variable type. The base implementation does a simple type-check. */ class HTMLPurifier_VarParser { const STRING = 1; const ISTRING = 2; const TEXT = 3; const ITEXT = 4; const INT = 5; const FLOAT = 6; const BOOL = 7; const LOOKUP = 8; const ALIST = 9; const HASH = 10; const MIXED = 11; /** * Lookup table of allowed types. Mainly for backwards compatibility, but * also convenient for transforming string type names to the integer constants. */ public static $types = array( 'string' => self::STRING, 'istring' => self::ISTRING, 'text' => self::TEXT, 'itext' => self::ITEXT, 'int' => self::INT, 'float' => self::FLOAT, 'bool' => self::BOOL, 'lookup' => self::LOOKUP, 'list' => self::ALIST, 'hash' => self::HASH, 'mixed' => self::MIXED ); /** * Lookup table of types that are string, and can have aliases or * allowed value lists. */ public static $stringTypes = array( self::STRING => true, self::ISTRING => true, self::TEXT => true, self::ITEXT => true, ); /** * Validate a variable according to type. * It may return NULL as a valid type if $allow_null is true. * * @param mixed $var Variable to validate * @param int $type Type of variable, see HTMLPurifier_VarParser->types * @param bool $allow_null Whether or not to permit null as a value * @return string Validated and type-coerced variable * @throws HTMLPurifier_VarParserException */ final public function parse($var, $type, $allow_null = false) { if (is_string($type)) { if (!isset(HTMLPurifier_VarParser::$types[$type])) { throw new HTMLPurifier_VarParserException("Invalid type '$type'"); } else { $type = HTMLPurifier_VarParser::$types[$type]; } } $var = $this->parseImplementation($var, $type, $allow_null); if ($allow_null && $var === null) { return null; } // These are basic checks, to make sure nothing horribly wrong // happened in our implementations. switch ($type) { case (self::STRING): case (self::ISTRING): case (self::TEXT): case (self::ITEXT): if (!is_string($var)) { break; } if ($type == self::ISTRING || $type == self::ITEXT) { $var = strtolower($var); } return $var; case (self::INT): if (!is_int($var)) { break; } return $var; case (self::FLOAT): if (!is_float($var)) { break; } return $var; case (self::BOOL): if (!is_bool($var)) { break; } return $var; case (self::LOOKUP): case (self::ALIST): case (self::HASH): if (!is_array($var)) { break; } if ($type === self::LOOKUP) { foreach ($var as $k) { if ($k !== true) { $this->error('Lookup table contains value other than true'); } } } elseif ($type === self::ALIST) { $keys = array_keys($var); if (array_keys($keys) !== $keys) { $this->error('Indices for list are not uniform'); } } return $var; case (self::MIXED): return $var; default: $this->errorInconsistent(get_class($this), $type); } $this->errorGeneric($var, $type); } /** * Actually implements the parsing. Base implementation does not * do anything to $var. Subclasses should overload this! * @param mixed $var * @param int $type * @param bool $allow_null * @return string */ protected function parseImplementation($var, $type, $allow_null) { return $var; } /** * Throws an exception. * @throws HTMLPurifier_VarParserException */ protected function error($msg) { throw new HTMLPurifier_VarParserException($msg); } /** * Throws an inconsistency exception. * @note This should not ever be called. It would be called if we * extend the allowed values of HTMLPurifier_VarParser without * updating subclasses. * @param string $class * @param int $type * @throws HTMLPurifier_Exception */ protected function errorInconsistent($class, $type) { throw new HTMLPurifier_Exception( "Inconsistency in $class: " . HTMLPurifier_VarParser::getTypeName($type) . " not implemented" ); } /** * Generic error for if a type didn't work. * @param mixed $var * @param int $type */ protected function errorGeneric($var, $type) { $vtype = gettype($var); $this->error("Expected type " . HTMLPurifier_VarParser::getTypeName($type) . ", got $vtype"); } /** * @param int $type * @return string */ public static function getTypeName($type) { static $lookup; if (!$lookup) { // Lazy load the alternative lookup table $lookup = array_flip(HTMLPurifier_VarParser::$types); } if (!isset($lookup[$type])) { return 'unknown'; } return $lookup[$type]; } } /** * Exception type for HTMLPurifier_VarParser */ class HTMLPurifier_VarParserException extends HTMLPurifier_Exception { } /** * A zipper is a purely-functional data structure which contains * a focus that can be efficiently manipulated. It is known as * a "one-hole context". This mutable variant implements a zipper * for a list as a pair of two arrays, laid out as follows: * * Base list: 1 2 3 4 [ ] 6 7 8 9 * Front list: 1 2 3 4 * Back list: 9 8 7 6 * * User is expected to keep track of the "current element" and properly * fill it back in as necessary. (ToDo: Maybe it's more user friendly * to implicitly track the current element?) * * Nota bene: the current class gets confused if you try to store NULLs * in the list. */ class HTMLPurifier_Zipper { public $front, $back; public function __construct($front, $back) { $this->front = $front; $this->back = $back; } /** * Creates a zipper from an array, with a hole in the * 0-index position. * @param Array to zipper-ify. * @return Tuple of zipper and element of first position. */ static public function fromArray($array) { $z = new self(array(), array_reverse($array)); $t = $z->delete(); // delete the "dummy hole" return array($z, $t); } /** * Convert zipper back into a normal array, optionally filling in * the hole with a value. (Usually you should supply a $t, unless you * are at the end of the array.) */ public function toArray($t = NULL) { $a = $this->front; if ($t !== NULL) $a[] = $t; for ($i = count($this->back)-1; $i >= 0; $i--) { $a[] = $this->back[$i]; } return $a; } /** * Move hole to the next element. * @param $t Element to fill hole with * @return Original contents of new hole. */ public function next($t) { if ($t !== NULL) array_push($this->front, $t); return empty($this->back) ? NULL : array_pop($this->back); } /** * Iterated hole advancement. * @param $t Element to fill hole with * @param $i How many forward to advance hole * @return Original contents of new hole, i away */ public function advance($t, $n) { for ($i = 0; $i < $n; $i++) { $t = $this->next($t); } return $t; } /** * Move hole to the previous element * @param $t Element to fill hole with * @return Original contents of new hole. */ public function prev($t) { if ($t !== NULL) array_push($this->back, $t); return empty($this->front) ? NULL : array_pop($this->front); } /** * Delete contents of current hole, shifting hole to * next element. * @return Original contents of new hole. */ public function delete() { return empty($this->back) ? NULL : array_pop($this->back); } /** * Returns true if we are at the end of the list. * @return bool */ public function done() { return empty($this->back); } /** * Insert element before hole. * @param Element to insert */ public function insertBefore($t) { if ($t !== NULL) array_push($this->front, $t); } /** * Insert element after hole. * @param Element to insert */ public function insertAfter($t) { if ($t !== NULL) array_push($this->back, $t); } /** * Splice in multiple elements at hole. Functional specification * in terms of array_splice: * * $arr1 = $arr; * $old1 = array_splice($arr1, $i, $delete, $replacement); * * list($z, $t) = HTMLPurifier_Zipper::fromArray($arr); * $t = $z->advance($t, $i); * list($old2, $t) = $z->splice($t, $delete, $replacement); * $arr2 = $z->toArray($t); * * assert($old1 === $old2); * assert($arr1 === $arr2); * * NB: the absolute index location after this operation is * *unchanged!* * * @param Current contents of hole. */ public function splice($t, $delete, $replacement) { // delete $old = array(); $r = $t; for ($i = $delete; $i > 0; $i--) { $old[] = $r; $r = $this->delete(); } // insert for ($i = count($replacement)-1; $i >= 0; $i--) { $this->insertAfter($r); $r = $replacement[$i]; } return array($old, $r); } } /** * Validates the HTML attribute style, otherwise known as CSS. * @note We don't implement the whole CSS specification, so it might be * difficult to reuse this component in the context of validating * actual stylesheet declarations. * @note If we were really serious about validating the CSS, we would * tokenize the styles and then parse the tokens. Obviously, we * are not doing that. Doing that could seriously harm performance, * but would make these components a lot more viable for a CSS * filtering solution. */ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef { /** * @param string $css * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($css, $config, $context) { $css = $this->parseCDATA($css); $definition = $config->getCSSDefinition(); // we're going to break the spec and explode by semicolons. // This is because semicolon rarely appears in escaped form // Doing this is generally flaky but fast // IT MIGHT APPEAR IN URIs, see HTMLPurifier_AttrDef_CSSURI // for details $declarations = explode(';', $css); $propvalues = array(); /** * Name of the current CSS property being validated. */ $property = false; $context->register('CurrentCSSProperty', $property); foreach ($declarations as $declaration) { if (!$declaration) { continue; } if (!strpos($declaration, ':')) { continue; } list($property, $value) = explode(':', $declaration, 2); $property = trim($property); $value = trim($value); $ok = false; do { if (isset($definition->info[$property])) { $ok = true; break; } if (ctype_lower($property)) { break; } $property = strtolower($property); if (isset($definition->info[$property])) { $ok = true; break; } } while (0); if (!$ok) { continue; } // inefficient call, since the validator will do this again if (strtolower(trim($value)) !== 'inherit') { // inherit works for everything (but only on the base property) $result = $definition->info[$property]->validate( $value, $config, $context ); } else { $result = 'inherit'; } if ($result === false) { continue; } $propvalues[$property] = $result; } $context->destroy('CurrentCSSProperty'); // procedure does not write the new CSS simultaneously, so it's // slightly inefficient, but it's the only way of getting rid of // duplicates. Perhaps config to optimize it, but not now. $new_declarations = ''; foreach ($propvalues as $prop => $value) { $new_declarations .= "$prop:$value;"; } return $new_declarations ? $new_declarations : false; } } /** * Dummy AttrDef that mimics another AttrDef, BUT it generates clones * with make. */ class HTMLPurifier_AttrDef_Clone extends HTMLPurifier_AttrDef { /** * What we're cloning. * @type HTMLPurifier_AttrDef */ protected $clone; /** * @param HTMLPurifier_AttrDef $clone */ public function __construct($clone) { $this->clone = $clone; } /** * @param string $v * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($v, $config, $context) { return $this->clone->validate($v, $config, $context); } /** * @param string $string * @return HTMLPurifier_AttrDef */ public function make($string) { return clone $this->clone; } } // Enum = Enumerated /** * Validates a keyword against a list of valid values. * @warning The case-insensitive compare of this function uses PHP's * built-in strtolower and ctype_lower functions, which may * cause problems with international comparisons */ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef { /** * Lookup table of valid values. * @type array * @todo Make protected */ public $valid_values = array(); /** * Bool indicating whether or not enumeration is case sensitive. * @note In general this is always case insensitive. */ protected $case_sensitive = false; // values according to W3C spec /** * @param array $valid_values List of valid values * @param bool $case_sensitive Whether or not case sensitive */ public function __construct($valid_values = array(), $case_sensitive = false) { $this->valid_values = array_flip($valid_values); $this->case_sensitive = $case_sensitive; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); if (!$this->case_sensitive) { // we may want to do full case-insensitive libraries $string = ctype_lower($string) ? $string : strtolower($string); } $result = isset($this->valid_values[$string]); return $result ? $string : false; } /** * @param string $string In form of comma-delimited list of case-insensitive * valid values. Example: "foo,bar,baz". Prepend "s:" to make * case sensitive * @return HTMLPurifier_AttrDef_Enum */ public function make($string) { if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') { $string = substr($string, 2); $sensitive = true; } else { $sensitive = false; } $values = explode(',', $string); return new HTMLPurifier_AttrDef_Enum($values, $sensitive); } } /** * Validates an integer. * @note While this class was modeled off the CSS definition, no currently * allowed CSS uses this type. The properties that do are: widows, * orphans, z-index, counter-increment, counter-reset. Some of the * HTML attributes, however, find use for a non-negative version of this. */ class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef { /** * Whether or not negative values are allowed. * @type bool */ protected $negative = true; /** * Whether or not zero is allowed. * @type bool */ protected $zero = true; /** * Whether or not positive values are allowed. * @type bool */ protected $positive = true; /** * @param $negative Bool indicating whether or not negative values are allowed * @param $zero Bool indicating whether or not zero is allowed * @param $positive Bool indicating whether or not positive values are allowed */ public function __construct($negative = true, $zero = true, $positive = true) { $this->negative = $negative; $this->zero = $zero; $this->positive = $positive; } /** * @param string $integer * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($integer, $config, $context) { $integer = $this->parseCDATA($integer); if ($integer === '') { return false; } // we could possibly simply typecast it to integer, but there are // certain fringe cases that must not return an integer. // clip leading sign if ($this->negative && $integer[0] === '-') { $digits = substr($integer, 1); if ($digits === '0') { $integer = '0'; } // rm minus sign for zero } elseif ($this->positive && $integer[0] === '+') { $digits = $integer = substr($integer, 1); // rm unnecessary plus } else { $digits = $integer; } // test if it's numeric if (!ctype_digit($digits)) { return false; } // perform scope tests if (!$this->zero && $integer == 0) { return false; } if (!$this->positive && $integer > 0) { return false; } if (!$this->negative && $integer < 0) { return false; } return $integer; } } /** * Validates the HTML attribute lang, effectively a language code. * @note Built according to RFC 3066, which obsoleted RFC 1766 */ class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); if (!$string) { return false; } $subtags = explode('-', $string); $num_subtags = count($subtags); if ($num_subtags == 0) { // sanity check return false; } // process primary subtag : $subtags[0] $length = strlen($subtags[0]); switch ($length) { case 0: return false; case 1: if (!($subtags[0] == 'x' || $subtags[0] == 'i')) { return false; } break; case 2: case 3: if (!ctype_alpha($subtags[0])) { return false; } elseif (!ctype_lower($subtags[0])) { $subtags[0] = strtolower($subtags[0]); } break; default: return false; } $new_string = $subtags[0]; if ($num_subtags == 1) { return $new_string; } // process second subtag : $subtags[1] $length = strlen($subtags[1]); if ($length == 0 || ($length == 1 && $subtags[1] != 'x') || $length > 8 || !ctype_alnum($subtags[1])) { return $new_string; } if (!ctype_lower($subtags[1])) { $subtags[1] = strtolower($subtags[1]); } $new_string .= '-' . $subtags[1]; if ($num_subtags == 2) { return $new_string; } // process all other subtags, index 2 and up for ($i = 2; $i < $num_subtags; $i++) { $length = strlen($subtags[$i]); if ($length == 0 || $length > 8 || !ctype_alnum($subtags[$i])) { return $new_string; } if (!ctype_lower($subtags[$i])) { $subtags[$i] = strtolower($subtags[$i]); } $new_string .= '-' . $subtags[$i]; } return $new_string; } } /** * Decorator that, depending on a token, switches between two definitions. */ class HTMLPurifier_AttrDef_Switch { /** * @type string */ protected $tag; /** * @type HTMLPurifier_AttrDef */ protected $withTag; /** * @type HTMLPurifier_AttrDef */ protected $withoutTag; /** * @param string $tag Tag name to switch upon * @param HTMLPurifier_AttrDef $with_tag Call if token matches tag * @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token */ public function __construct($tag, $with_tag, $without_tag) { $this->tag = $tag; $this->withTag = $with_tag; $this->withoutTag = $without_tag; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $token = $context->get('CurrentToken', true); if (!$token || $token->name !== $this->tag) { return $this->withoutTag->validate($string, $config, $context); } else { return $this->withTag->validate($string, $config, $context); } } } /** * Validates arbitrary text according to the HTML spec. */ class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { return $this->parseCDATA($string); } } /** * Validates a URI as defined by RFC 3986. * @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme */ class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef { /** * @type HTMLPurifier_URIParser */ protected $parser; /** * @type bool */ protected $embedsResource; /** * @param bool $embeds_resource Does the URI here result in an extra HTTP request? */ public function __construct($embeds_resource = false) { $this->parser = new HTMLPurifier_URIParser(); $this->embedsResource = (bool)$embeds_resource; } /** * @param string $string * @return HTMLPurifier_AttrDef_URI */ public function make($string) { $embeds = ($string === 'embedded'); return new HTMLPurifier_AttrDef_URI($embeds); } /** * @param string $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($uri, $config, $context) { if ($config->get('URI.Disable')) { return false; } $uri = $this->parseCDATA($uri); // parse the URI $uri = $this->parser->parse($uri); if ($uri === false) { return false; } // add embedded flag to context for validators $context->register('EmbeddedURI', $this->embedsResource); $ok = false; do { // generic validation $result = $uri->validate($config, $context); if (!$result) { break; } // chained filtering $uri_def = $config->getDefinition('URI'); $result = $uri_def->filter($uri, $config, $context); if (!$result) { break; } // scheme-specific validation $scheme_obj = $uri->getSchemeObj($config, $context); if (!$scheme_obj) { break; } if ($this->embedsResource && !$scheme_obj->browsable) { break; } $result = $scheme_obj->validate($uri, $config, $context); if (!$result) { break; } // Post chained filtering $result = $uri_def->postFilter($uri, $config, $context); if (!$result) { break; } // survived gauntlet $ok = true; } while (false); $context->destroy('EmbeddedURI'); if (!$ok) { return false; } // back to string return $uri->toString(); } } /** * Validates a number as defined by the CSS spec. */ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef { /** * Indicates whether or not only positive values are allowed. * @type bool */ protected $non_negative = false; /** * @param bool $non_negative indicates whether negatives are forbidden */ public function __construct($non_negative = false) { $this->non_negative = $non_negative; } /** * @param string $number * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string|bool * @warning Some contexts do not pass $config, $context. These * variables should not be used without checking HTMLPurifier_Length */ public function validate($number, $config, $context) { $number = $this->parseCDATA($number); if ($number === '') { return false; } if ($number === '0') { return '0'; } $sign = ''; switch ($number[0]) { case '-': if ($this->non_negative) { return false; } $sign = '-'; case '+': $number = substr($number, 1); } if (ctype_digit($number)) { $number = ltrim($number, '0'); return $number ? $sign . $number : '0'; } // Period is the only non-numeric character allowed if (strpos($number, '.') === false) { return false; } list($left, $right) = explode('.', $number, 2); if ($left === '' && $right === '') { return false; } if ($left !== '' && !ctype_digit($left)) { return false; } $left = ltrim($left, '0'); $right = rtrim($right, '0'); if ($right === '') { return $left ? $sign . $left : '0'; } elseif (!ctype_digit($right)) { return false; } return $sign . $left . '.' . $right; } } class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number { public function __construct() { parent::__construct(false); // opacity is non-negative, but we will clamp it } /** * @param string $number * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ public function validate($number, $config, $context) { $result = parent::validate($number, $config, $context); if ($result === false) { return $result; } $float = (float)$result; if ($float < 0.0) { $result = '0'; } if ($float > 1.0) { $result = '1'; } return $result; } } /** * Validates shorthand CSS property background. * @warning Does not support url tokens that have internal spaces. */ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef { /** * Local copy of component validators. * @type HTMLPurifier_AttrDef[] * @note See HTMLPurifier_AttrDef_Font::$info for a similar impl. */ protected $info; /** * @param HTMLPurifier_Config $config */ public function __construct($config) { $def = $config->getCSSDefinition(); $this->info['background-color'] = $def->info['background-color']; $this->info['background-image'] = $def->info['background-image']; $this->info['background-repeat'] = $def->info['background-repeat']; $this->info['background-attachment'] = $def->info['background-attachment']; $this->info['background-position'] = $def->info['background-position']; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { // regular pre-processing $string = $this->parseCDATA($string); if ($string === '') { return false; } // munge rgb() decl if necessary $string = $this->mungeRgb($string); // assumes URI doesn't have spaces in it $bits = explode(' ', $string); // bits to process $caught = array(); $caught['color'] = false; $caught['image'] = false; $caught['repeat'] = false; $caught['attachment'] = false; $caught['position'] = false; $i = 0; // number of catches foreach ($bits as $bit) { if ($bit === '') { continue; } foreach ($caught as $key => $status) { if ($key != 'position') { if ($status !== false) { continue; } $r = $this->info['background-' . $key]->validate($bit, $config, $context); } else { $r = $bit; } if ($r === false) { continue; } if ($key == 'position') { if ($caught[$key] === false) { $caught[$key] = ''; } $caught[$key] .= $r . ' '; } else { $caught[$key] = $r; } $i++; break; } } if (!$i) { return false; } if ($caught['position'] !== false) { $caught['position'] = $this->info['background-position']-> validate($caught['position'], $config, $context); } $ret = array(); foreach ($caught as $value) { if ($value === false) { continue; } $ret[] = $value; } if (empty($ret)) { return false; } return implode(' ', $ret); } } /* W3C says: [ // adjective and number must be in correct order, even if // you could switch them without introducing ambiguity. // some browsers support that syntax [ <percentage> | <length> | left | center | right ] [ <percentage> | <length> | top | center | bottom ]? ] | [ // this signifies that the vertical and horizontal adjectives // can be arbitrarily ordered, however, there can only be two, // one of each, or none at all [ left | center | right ] || [ top | center | bottom ] ] top, left = 0% center, (none) = 50% bottom, right = 100% */ /* QuirksMode says: keyword + length/percentage must be ordered correctly, as per W3C Internet Explorer and Opera, however, support arbitrary ordering. We should fix it up. Minor issue though, not strictly necessary. */ // control freaks may appreciate the ability to convert these to // percentages or something, but it's not necessary /** * Validates the value of background-position. */ class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef { /** * @type HTMLPurifier_AttrDef_CSS_Length */ protected $length; /** * @type HTMLPurifier_AttrDef_CSS_Percentage */ protected $percentage; public function __construct() { $this->length = new HTMLPurifier_AttrDef_CSS_Length(); $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage(); } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = $this->parseCDATA($string); $bits = explode(' ', $string); $keywords = array(); $keywords['h'] = false; // left, right $keywords['v'] = false; // top, bottom $keywords['ch'] = false; // center (first word) $keywords['cv'] = false; // center (second word) $measures = array(); $i = 0; $lookup = array( 'top' => 'v', 'bottom' => 'v', 'left' => 'h', 'right' => 'h', 'center' => 'c' ); foreach ($bits as $bit) { if ($bit === '') { continue; } // test for keyword $lbit = ctype_lower($bit) ? $bit : strtolower($bit); if (isset($lookup[$lbit])) { $status = $lookup[$lbit]; if ($status == 'c') { if ($i == 0) { $status = 'ch'; } else { $status = 'cv'; } } $keywords[$status] = $lbit; $i++; } // test for length $r = $this->length->validate($bit, $config, $context); if ($r !== false) { $measures[] = $r; $i++; } // test for percentage $r = $this->percentage->validate($bit, $config, $context); if ($r !== false) { $measures[] = $r; $i++; } } if (!$i) { return false; } // no valid values were caught $ret = array(); // first keyword if ($keywords['h']) { $ret[] = $keywords['h']; } elseif ($keywords['ch']) { $ret[] = $keywords['ch']; $keywords['cv'] = false; // prevent re-use: center = center center } elseif (count($measures)) { $ret[] = array_shift($measures); } if ($keywords['v']) { $ret[] = $keywords['v']; } elseif ($keywords['cv']) { $ret[] = $keywords['cv']; } elseif (count($measures)) { $ret[] = array_shift($measures); } if (empty($ret)) { return false; } return implode(' ', $ret); } } /** * Validates the border property as defined by CSS. */ class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef { /** * Local copy of properties this property is shorthand for. * @type HTMLPurifier_AttrDef[] */ protected $info = array(); /** * @param HTMLPurifier_Config $config */ public function __construct($config) { $def = $config->getCSSDefinition(); $this->info['border-width'] = $def->info['border-width']; $this->info['border-style'] = $def->info['border-style']; $this->info['border-top-color'] = $def->info['border-top-color']; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = $this->parseCDATA($string); $string = $this->mungeRgb($string); $bits = explode(' ', $string); $done = array(); // segments we've finished $ret = ''; // return value foreach ($bits as $bit) { foreach ($this->info as $propname => $validator) { if (isset($done[$propname])) { continue; } $r = $validator->validate($bit, $config, $context); if ($r !== false) { $ret .= $r . ' '; $done[$propname] = true; break; } } } return rtrim($ret); } } /** * Validates Color as defined by CSS. */ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef { /** * @param string $color * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($color, $config, $context) { static $colors = null; if ($colors === null) { $colors = $config->get('Core.ColorKeywords'); } $color = trim($color); if ($color === '') { return false; } $lower = strtolower($color); if (isset($colors[$lower])) { return $colors[$lower]; } if (strpos($color, 'rgb(') !== false) { // rgb literal handling $length = strlen($color); if (strpos($color, ')') !== $length - 1) { return false; } $triad = substr($color, 4, $length - 4 - 1); $parts = explode(',', $triad); if (count($parts) !== 3) { return false; } $type = false; // to ensure that they're all the same type $new_parts = array(); foreach ($parts as $part) { $part = trim($part); if ($part === '') { return false; } $length = strlen($part); if ($part[$length - 1] === '%') { // handle percents if (!$type) { $type = 'percentage'; } elseif ($type !== 'percentage') { return false; } $num = (float)substr($part, 0, $length - 1); if ($num < 0) { $num = 0; } if ($num > 100) { $num = 100; } $new_parts[] = "$num%"; } else { // handle integers if (!$type) { $type = 'integer'; } elseif ($type !== 'integer') { return false; } $num = (int)$part; if ($num < 0) { $num = 0; } if ($num > 255) { $num = 255; } $new_parts[] = (string)$num; } } $new_triad = implode(',', $new_parts); $color = "rgb($new_triad)"; } else { // hexadecimal handling if ($color[0] === '#') { $hex = substr($color, 1); } else { $hex = $color; $color = '#' . $color; } $length = strlen($hex); if ($length !== 3 && $length !== 6) { return false; } if (!ctype_xdigit($hex)) { return false; } } return $color; } } /** * Allows multiple validators to attempt to validate attribute. * * Composite is just what it sounds like: a composite of many validators. * This means that multiple HTMLPurifier_AttrDef objects will have a whack * at the string. If one of them passes, that's what is returned. This is * especially useful for CSS values, which often are a choice between * an enumerated set of predefined values or a flexible data type. */ class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef { /** * List of objects that may process strings. * @type HTMLPurifier_AttrDef[] * @todo Make protected */ public $defs; /** * @param HTMLPurifier_AttrDef[] $defs List of HTMLPurifier_AttrDef objects */ public function __construct($defs) { $this->defs = $defs; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { foreach ($this->defs as $i => $def) { $result = $this->defs[$i]->validate($string, $config, $context); if ($result !== false) { return $result; } } return false; } } /** * Decorator which enables CSS properties to be disabled for specific elements. */ class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef { /** * @type HTMLPurifier_AttrDef */ public $def; /** * @type string */ public $element; /** * @param HTMLPurifier_AttrDef $def Definition to wrap * @param string $element Element to deny */ public function __construct($def, $element) { $this->def = $def; $this->element = $element; } /** * Checks if CurrentToken is set and equal to $this->element * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $token = $context->get('CurrentToken', true); if ($token && $token->name == $this->element) { return false; } return $this->def->validate($string, $config, $context); } } /** * Microsoft's proprietary filter: CSS property * @note Currently supports the alpha filter. In the future, this will * probably need an extensible framework */ class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef { /** * @type HTMLPurifier_AttrDef_Integer */ protected $intValidator; public function __construct() { $this->intValidator = new HTMLPurifier_AttrDef_Integer(); } /** * @param string $value * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($value, $config, $context) { $value = $this->parseCDATA($value); if ($value === 'none') { return $value; } // if we looped this we could support multiple filters $function_length = strcspn($value, '('); $function = trim(substr($value, 0, $function_length)); if ($function !== 'alpha' && $function !== 'Alpha' && $function !== 'progid:DXImageTransform.Microsoft.Alpha' ) { return false; } $cursor = $function_length + 1; $parameters_length = strcspn($value, ')', $cursor); $parameters = substr($value, $cursor, $parameters_length); $params = explode(',', $parameters); $ret_params = array(); $lookup = array(); foreach ($params as $param) { list($key, $value) = explode('=', $param); $key = trim($key); $value = trim($value); if (isset($lookup[$key])) { continue; } if ($key !== 'opacity') { continue; } $value = $this->intValidator->validate($value, $config, $context); if ($value === false) { continue; } $int = (int)$value; if ($int > 100) { $value = '100'; } if ($int < 0) { $value = '0'; } $ret_params[] = "$key=$value"; $lookup[$key] = true; } $ret_parameters = implode(',', $ret_params); $ret_function = "$function($ret_parameters)"; return $ret_function; } } /** * Validates shorthand CSS property font. */ class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef { /** * Local copy of validators * @type HTMLPurifier_AttrDef[] * @note If we moved specific CSS property definitions to their own * classes instead of having them be assembled at run time by * CSSDefinition, this wouldn't be necessary. We'd instantiate * our own copies. */ protected $info = array(); /** * @param HTMLPurifier_Config $config */ public function __construct($config) { $def = $config->getCSSDefinition(); $this->info['font-style'] = $def->info['font-style']; $this->info['font-variant'] = $def->info['font-variant']; $this->info['font-weight'] = $def->info['font-weight']; $this->info['font-size'] = $def->info['font-size']; $this->info['line-height'] = $def->info['line-height']; $this->info['font-family'] = $def->info['font-family']; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { static $system_fonts = array( 'caption' => true, 'icon' => true, 'menu' => true, 'message-box' => true, 'small-caption' => true, 'status-bar' => true ); // regular pre-processing $string = $this->parseCDATA($string); if ($string === '') { return false; } // check if it's one of the keywords $lowercase_string = strtolower($string); if (isset($system_fonts[$lowercase_string])) { return $lowercase_string; } $bits = explode(' ', $string); // bits to process $stage = 0; // this indicates what we're looking for $caught = array(); // which stage 0 properties have we caught? $stage_1 = array('font-style', 'font-variant', 'font-weight'); $final = ''; // output for ($i = 0, $size = count($bits); $i < $size; $i++) { if ($bits[$i] === '') { continue; } switch ($stage) { case 0: // attempting to catch font-style, font-variant or font-weight foreach ($stage_1 as $validator_name) { if (isset($caught[$validator_name])) { continue; } $r = $this->info[$validator_name]->validate( $bits[$i], $config, $context ); if ($r !== false) { $final .= $r . ' '; $caught[$validator_name] = true; break; } } // all three caught, continue on if (count($caught) >= 3) { $stage = 1; } if ($r !== false) { break; } case 1: // attempting to catch font-size and perhaps line-height $found_slash = false; if (strpos($bits[$i], '/') !== false) { list($font_size, $line_height) = explode('/', $bits[$i]); if ($line_height === '') { // ooh, there's a space after the slash! $line_height = false; $found_slash = true; } } else { $font_size = $bits[$i]; $line_height = false; } $r = $this->info['font-size']->validate( $font_size, $config, $context ); if ($r !== false) { $final .= $r; // attempt to catch line-height if ($line_height === false) { // we need to scroll forward for ($j = $i + 1; $j < $size; $j++) { if ($bits[$j] === '') { continue; } if ($bits[$j] === '/') { if ($found_slash) { return false; } else { $found_slash = true; continue; } } $line_height = $bits[$j]; break; } } else { // slash already found $found_slash = true; $j = $i; } if ($found_slash) { $i = $j; $r = $this->info['line-height']->validate( $line_height, $config, $context ); if ($r !== false) { $final .= '/' . $r; } } $final .= ' '; $stage = 2; break; } return false; case 2: // attempting to catch font-family $font_family = implode(' ', array_slice($bits, $i, $size - $i)); $r = $this->info['font-family']->validate( $font_family, $config, $context ); if ($r !== false) { $final .= $r . ' '; // processing completed successfully return rtrim($final); } return false; } } return false; } } /** * Validates a font family list according to CSS spec */ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef { protected $mask = null; public function __construct() { $this->mask = '_- '; for ($c = 'a'; $c <= 'z'; $c++) { $this->mask .= $c; } for ($c = 'A'; $c <= 'Z'; $c++) { $this->mask .= $c; } for ($c = '0'; $c <= '9'; $c++) { $this->mask .= $c; } // cast-y, but should be fine // special bytes used by UTF-8 for ($i = 0x80; $i <= 0xFF; $i++) { // We don't bother excluding invalid bytes in this range, // because the our restriction of well-formed UTF-8 will // prevent these from ever occurring. $this->mask .= chr($i); } /* PHP's internal strcspn implementation is O(length of string * length of mask), making it inefficient for large masks. However, it's still faster than preg_match 8) for (p = s1;;) { spanp = s2; do { if (*spanp == c || p == s1_end) { return p - s1; } } while (spanp++ < (s2_end - 1)); c = *++p; } */ // possible optimization: invert the mask. } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { static $generic_names = array( 'serif' => true, 'sans-serif' => true, 'monospace' => true, 'fantasy' => true, 'cursive' => true ); $allowed_fonts = $config->get('CSS.AllowedFonts'); // assume that no font names contain commas in them $fonts = explode(',', $string); $final = ''; foreach ($fonts as $font) { $font = trim($font); if ($font === '') { continue; } // match a generic name if (isset($generic_names[$font])) { if ($allowed_fonts === null || isset($allowed_fonts[$font])) { $final .= $font . ', '; } continue; } // match a quoted name if ($font[0] === '"' || $font[0] === "'") { $length = strlen($font); if ($length <= 2) { continue; } $quote = $font[0]; if ($font[$length - 1] !== $quote) { continue; } $font = substr($font, 1, $length - 2); } $font = $this->expandCSSEscape($font); // $font is a pure representation of the font name if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) { continue; } if (ctype_alnum($font) && $font !== '') { // very simple font, allow it in unharmed $final .= $font . ', '; continue; } // bugger out on whitespace. form feed (0C) really // shouldn't show up regardless $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font); // Here, there are various classes of characters which need // to be treated differently: // - Alphanumeric characters are essentially safe. We // handled these above. // - Spaces require quoting, though most parsers will do // the right thing if there aren't any characters that // can be misinterpreted // - Dashes rarely occur, but they fairly unproblematic // for parsing/rendering purposes. // The above characters cover the majority of Western font // names. // - Arbitrary Unicode characters not in ASCII. Because // most parsers give little thought to Unicode, treatment // of these codepoints is basically uniform, even for // punctuation-like codepoints. These characters can // show up in non-Western pages and are supported by most // major browsers, for example: "MS 明朝" is a // legitimate font-name // <http://ja.wikipedia.org/wiki/MS_明朝>. See // the CSS3 spec for more examples: // <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png> // You can see live samples of these on the Internet: // <http://www.google.co.jp/search?q=font-family+MS+明朝|ゴシック> // However, most of these fonts have ASCII equivalents: // for example, 'MS Mincho', and it's considered // professional to use ASCII font names instead of // Unicode font names. Thanks Takeshi Terada for // providing this information. // The following characters, to my knowledge, have not been // used to name font names. // - Single quote. While theoretically you might find a // font name that has a single quote in its name (serving // as an apostrophe, e.g. Dave's Scribble), I haven't // been able to find any actual examples of this. // Internet Explorer's cssText translation (which I // believe is invoked by innerHTML) normalizes any // quoting to single quotes, and fails to escape single // quotes. (Note that this is not IE's behavior for all // CSS properties, just some sort of special casing for // font-family). So a single quote *cannot* be used // safely in the font-family context if there will be an // innerHTML/cssText translation. Note that Firefox 3.x // does this too. // - Double quote. In IE, these get normalized to // single-quotes, no matter what the encoding. (Fun // fact, in IE8, the 'content' CSS property gained // support, where they special cased to preserve encoded // double quotes, but still translate unadorned double // quotes into single quotes.) So, because their // fixpoint behavior is identical to single quotes, they // cannot be allowed either. Firefox 3.x displays // single-quote style behavior. // - Backslashes are reduced by one (so \\ -> \) every // iteration, so they cannot be used safely. This shows // up in IE7, IE8 and FF3 // - Semicolons, commas and backticks are handled properly. // - The rest of the ASCII punctuation is handled properly. // We haven't checked what browsers do to unadorned // versions, but this is not important as long as the // browser doesn't /remove/ surrounding quotes (as IE does // for HTML). // // With these results in hand, we conclude that there are // various levels of safety: // - Paranoid: alphanumeric, spaces and dashes(?) // - International: Paranoid + non-ASCII Unicode // - Edgy: Everything except quotes, backslashes // - NoJS: Standards compliance, e.g. sod IE. Note that // with some judicious character escaping (since certain // types of escaping doesn't work) this is theoretically // OK as long as innerHTML/cssText is not called. // We believe that international is a reasonable default // (that we will implement now), and once we do more // extensive research, we may feel comfortable with dropping // it down to edgy. // Edgy: alphanumeric, spaces, dashes, underscores and Unicode. Use of // str(c)spn assumes that the string was already well formed // Unicode (which of course it is). if (strspn($font, $this->mask) !== strlen($font)) { continue; } // Historical: // In the absence of innerHTML/cssText, these ugly // transforms don't pose a security risk (as \\ and \" // might--these escapes are not supported by most browsers). // We could try to be clever and use single-quote wrapping // when there is a double quote present, but I have choosen // not to implement that. (NOTE: you can reduce the amount // of escapes by one depending on what quoting style you use) // $font = str_replace('\\', '\\5C ', $font); // $font = str_replace('"', '\\22 ', $font); // $font = str_replace("'", '\\27 ', $font); // font possibly with spaces, requires quoting $final .= "'$font', "; } $final = rtrim($final, ', '); if ($final === '') { return false; } return $final; } } /** * Validates based on {ident} CSS grammar production */ class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); // early abort: '' and '0' (strings that convert to false) are invalid if (!$string) { return false; } $pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/'; if (!preg_match($pattern, $string)) { return false; } return $string; } } /** * Decorator which enables !important to be used in CSS values. */ class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef { /** * @type HTMLPurifier_AttrDef */ public $def; /** * @type bool */ public $allow; /** * @param HTMLPurifier_AttrDef $def Definition to wrap * @param bool $allow Whether or not to allow !important */ public function __construct($def, $allow = false) { $this->def = $def; $this->allow = $allow; } /** * Intercepts and removes !important if necessary * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { // test for ! and important tokens $string = trim($string); $is_important = false; // :TODO: optimization: test directly for !important and ! important if (strlen($string) >= 9 && substr($string, -9) === 'important') { $temp = rtrim(substr($string, 0, -9)); // use a temp, because we might want to restore important if (strlen($temp) >= 1 && substr($temp, -1) === '!') { $string = rtrim(substr($temp, 0, -1)); $is_important = true; } } $string = $this->def->validate($string, $config, $context); if ($this->allow && $is_important) { $string .= ' !important'; } return $string; } } /** * Represents a Length as defined by CSS. */ class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef { /** * @type HTMLPurifier_Length|string */ protected $min; /** * @type HTMLPurifier_Length|string */ protected $max; /** * @param HTMLPurifier_Length|string $min Minimum length, or null for no bound. String is also acceptable. * @param HTMLPurifier_Length|string $max Maximum length, or null for no bound. String is also acceptable. */ public function __construct($min = null, $max = null) { $this->min = $min !== null ? HTMLPurifier_Length::make($min) : null; $this->max = $max !== null ? HTMLPurifier_Length::make($max) : null; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = $this->parseCDATA($string); // Optimizations if ($string === '') { return false; } if ($string === '0') { return '0'; } if (strlen($string) === 1) { return false; } $length = HTMLPurifier_Length::make($string); if (!$length->isValid()) { return false; } if ($this->min) { $c = $length->compareTo($this->min); if ($c === false) { return false; } if ($c < 0) { return false; } } if ($this->max) { $c = $length->compareTo($this->max); if ($c === false) { return false; } if ($c > 0) { return false; } } return $length->toString(); } } /** * Validates shorthand CSS property list-style. * @warning Does not support url tokens that have internal spaces. */ class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef { /** * Local copy of validators. * @type HTMLPurifier_AttrDef[] * @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl. */ protected $info; /** * @param HTMLPurifier_Config $config */ public function __construct($config) { $def = $config->getCSSDefinition(); $this->info['list-style-type'] = $def->info['list-style-type']; $this->info['list-style-position'] = $def->info['list-style-position']; $this->info['list-style-image'] = $def->info['list-style-image']; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { // regular pre-processing $string = $this->parseCDATA($string); if ($string === '') { return false; } // assumes URI doesn't have spaces in it $bits = explode(' ', strtolower($string)); // bits to process $caught = array(); $caught['type'] = false; $caught['position'] = false; $caught['image'] = false; $i = 0; // number of catches $none = false; foreach ($bits as $bit) { if ($i >= 3) { return; } // optimization bit if ($bit === '') { continue; } foreach ($caught as $key => $status) { if ($status !== false) { continue; } $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); if ($r === false) { continue; } if ($r === 'none') { if ($none) { continue; } else { $none = true; } if ($key == 'image') { continue; } } $caught[$key] = $r; $i++; break; } } if (!$i) { return false; } $ret = array(); // construct type if ($caught['type']) { $ret[] = $caught['type']; } // construct image if ($caught['image']) { $ret[] = $caught['image']; } // construct position if ($caught['position']) { $ret[] = $caught['position']; } if (empty($ret)) { return false; } return implode(' ', $ret); } } /** * Framework class for strings that involve multiple values. * * Certain CSS properties such as border-width and margin allow multiple * lengths to be specified. This class can take a vanilla border-width * definition and multiply it, usually into a max of four. * * @note Even though the CSS specification isn't clear about it, inherit * can only be used alone: it will never manifest as part of a multi * shorthand declaration. Thus, this class does not allow inherit. */ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef { /** * Instance of component definition to defer validation to. * @type HTMLPurifier_AttrDef * @todo Make protected */ public $single; /** * Max number of values allowed. * @todo Make protected */ public $max; /** * @param HTMLPurifier_AttrDef $single HTMLPurifier_AttrDef to multiply * @param int $max Max number of values allowed (usually four) */ public function __construct($single, $max = 4) { $this->single = $single; $this->max = $max; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = $this->parseCDATA($string); if ($string === '') { return false; } $parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n $length = count($parts); $final = ''; for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) { if (ctype_space($parts[$i])) { continue; } $result = $this->single->validate($parts[$i], $config, $context); if ($result !== false) { $final .= $result . ' '; $num++; } } if ($final === '') { return false; } return rtrim($final); } } /** * Validates a Percentage as defined by the CSS spec. */ class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef { /** * Instance to defer number validation to. * @type HTMLPurifier_AttrDef_CSS_Number */ protected $number_def; /** * @param bool $non_negative Whether to forbid negative values */ public function __construct($non_negative = false) { $this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative); } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = $this->parseCDATA($string); if ($string === '') { return false; } $length = strlen($string); if ($length === 1) { return false; } if ($string[$length - 1] !== '%') { return false; } $number = substr($string, 0, $length - 1); $number = $this->number_def->validate($number, $config, $context); if ($number === false) { return false; } return "$number%"; } } /** * Validates the value for the CSS property text-decoration * @note This class could be generalized into a version that acts sort of * like Enum except you can compound the allowed values. */ class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { static $allowed_values = array( 'line-through' => true, 'overline' => true, 'underline' => true, ); $string = strtolower($this->parseCDATA($string)); if ($string === 'none') { return $string; } $parts = explode(' ', $string); $final = ''; foreach ($parts as $part) { if (isset($allowed_values[$part])) { $final .= $part . ' '; } } $final = rtrim($final); if ($final === '') { return false; } return $final; } } /** * Validates a URI in CSS syntax, which uses url('http://example.com') * @note While theoretically speaking a URI in a CSS document could * be non-embedded, as of CSS2 there is no such usage so we're * generalizing it. This may need to be changed in the future. * @warning Since HTMLPurifier_AttrDef_CSS blindly uses semicolons as * the separator, you cannot put a literal semicolon in * in the URI. Try percent encoding it, in that case. */ class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI { public function __construct() { parent::__construct(true); // always embedded } /** * @param string $uri_string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($uri_string, $config, $context) { // parse the URI out of the string and then pass it onto // the parent object $uri_string = $this->parseCDATA($uri_string); if (strpos($uri_string, 'url(') !== 0) { return false; } $uri_string = substr($uri_string, 4); $new_length = strlen($uri_string) - 1; if ($uri_string[$new_length] != ')') { return false; } $uri = trim(substr($uri_string, 0, $new_length)); if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) { $quote = $uri[0]; $new_length = strlen($uri) - 1; if ($uri[$new_length] !== $quote) { return false; } $uri = substr($uri, 1, $new_length - 1); } $uri = $this->expandCSSEscape($uri); $result = parent::validate($uri, $config, $context); if ($result === false) { return false; } // extra sanity check; should have been done by URI $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); // suspicious characters are ()'; we're going to percent encode // them for safety. $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result); // there's an extra bug where ampersands lose their escaping on // an innerHTML cycle, so a very unlucky query parameter could // then change the meaning of the URL. Unfortunately, there's // not much we can do about that... return "url(\"$result\")"; } } /** * Validates a boolean attribute */ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef { /** * @type bool */ protected $name; /** * @type bool */ public $minimized = true; /** * @param bool $name */ public function __construct($name = false) { $this->name = $name; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { if (empty($string)) { return false; } return $this->name; } /** * @param string $string Name of attribute * @return HTMLPurifier_AttrDef_HTML_Bool */ public function make($string) { return new HTMLPurifier_AttrDef_HTML_Bool($string); } } /** * Validates contents based on NMTOKENS attribute type. */ class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); // early abort: '' and '0' (strings that convert to false) are invalid if (!$string) { return false; } $tokens = $this->split($string, $config, $context); $tokens = $this->filter($tokens, $config, $context); if (empty($tokens)) { return false; } return implode(' ', $tokens); } /** * Splits a space separated list of tokens into its constituent parts. * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ protected function split($string, $config, $context) { // OPTIMIZABLE! // do the preg_match, capture all subpatterns for reformulation // we don't support U+00A1 and up codepoints or // escaping because I don't know how to do that with regexps // and plus it would complicate optimization efforts (you never // see that anyway). $pattern = '/(?:(?<=\s)|\A)' . // look behind for space or string start '((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)' . '(?:(?=\s)|\z)/'; // look ahead for space or string end preg_match_all($pattern, $string, $matches); return $matches[1]; } /** * Template method for removing certain tokens based on arbitrary criteria. * @note If we wanted to be really functional, we'd do an array_filter * with a callback. But... we're not. * @param array $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ protected function filter($tokens, $config, $context) { return $tokens; } } /** * Implements special behavior for class attribute (normally NMTOKENS) */ class HTMLPurifier_AttrDef_HTML_Class extends HTMLPurifier_AttrDef_HTML_Nmtokens { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ protected function split($string, $config, $context) { // really, this twiddle should be lazy loaded $name = $config->getDefinition('HTML')->doctype->name; if ($name == "XHTML 1.1" || $name == "XHTML 2.0") { return parent::split($string, $config, $context); } else { return preg_split('/\s+/', $string); } } /** * @param array $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ protected function filter($tokens, $config, $context) { $allowed = $config->get('Attr.AllowedClasses'); $forbidden = $config->get('Attr.ForbiddenClasses'); $ret = array(); foreach ($tokens as $token) { if (($allowed === null || isset($allowed[$token])) && !isset($forbidden[$token]) && // We need this O(n) check because of PHP's array // implementation that casts -0 to 0. !in_array($token, $ret, true) ) { $ret[] = $token; } } return $ret; } } /** * Validates a color according to the HTML spec. */ class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { static $colors = null; if ($colors === null) { $colors = $config->get('Core.ColorKeywords'); } $string = trim($string); if (empty($string)) { return false; } $lower = strtolower($string); if (isset($colors[$lower])) { return $colors[$lower]; } if ($string[0] === '#') { $hex = substr($string, 1); } else { $hex = $string; } $length = strlen($hex); if ($length !== 3 && $length !== 6) { return false; } if (!ctype_xdigit($hex)) { return false; } if ($length === 3) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } return "#$hex"; } } /** * Special-case enum attribute definition that lazy loads allowed frame targets */ class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum { /** * @type array */ public $valid_values = false; // uninitialized value /** * @type bool */ protected $case_sensitive = false; public function __construct() { } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { if ($this->valid_values === false) { $this->valid_values = $config->get('Attr.AllowedFrameTargets'); } return parent::validate($string, $config, $context); } } /** * Validates the HTML attribute ID. * @warning Even though this is the id processor, it * will ignore the directive Attr:IDBlacklist, since it will only * go according to the ID accumulator. Since the accumulator is * automatically generated, it will have already absorbed the * blacklist. If you're hacking around, make sure you use load()! */ class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef { // selector is NOT a valid thing to use for IDREFs, because IDREFs // *must* target IDs that exist, whereas selector #ids do not. /** * Determines whether or not we're validating an ID in a CSS * selector context. * @type bool */ protected $selector; /** * @param bool $selector */ public function __construct($selector = false) { $this->selector = $selector; } /** * @param string $id * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($id, $config, $context) { if (!$this->selector && !$config->get('Attr.EnableID')) { return false; } $id = trim($id); // trim it first if ($id === '') { return false; } $prefix = $config->get('Attr.IDPrefix'); if ($prefix !== '') { $prefix .= $config->get('Attr.IDPrefixLocal'); // prevent re-appending the prefix if (strpos($id, $prefix) !== 0) { $id = $prefix . $id; } } elseif ($config->get('Attr.IDPrefixLocal') !== '') { trigger_error( '%Attr.IDPrefixLocal cannot be used unless ' . '%Attr.IDPrefix is set', E_USER_WARNING ); } if (!$this->selector) { $id_accumulator =& $context->get('IDAccumulator'); if (isset($id_accumulator->ids[$id])) { return false; } } // we purposely avoid using regex, hopefully this is faster if (ctype_alpha($id)) { $result = true; } else { if (!ctype_alpha(@$id[0])) { return false; } // primitive style of regexps, I suppose $trim = trim( $id, 'A..Za..z0..9:-._' ); $result = ($trim === ''); } $regexp = $config->get('Attr.IDBlacklistRegexp'); if ($regexp && preg_match($regexp, $id)) { return false; } if (!$this->selector && $result) { $id_accumulator->add($id); } // if no change was made to the ID, return the result // else, return the new id if stripping whitespace made it // valid, or return false. return $result ? $id : false; } } /** * Validates an integer representation of pixels according to the HTML spec. */ class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef { /** * @type int */ protected $max; /** * @param int $max */ public function __construct($max = null) { $this->max = $max; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); if ($string === '0') { return $string; } if ($string === '') { return false; } $length = strlen($string); if (substr($string, $length - 2) == 'px') { $string = substr($string, 0, $length - 2); } if (!is_numeric($string)) { return false; } $int = (int)$string; if ($int < 0) { return '0'; } // upper-bound value, extremely high values can // crash operating systems, see <http://ha.ckers.org/imagecrash.html> // WARNING, above link WILL crash you if you're using Windows if ($this->max !== null && $int > $this->max) { return (string)$this->max; } return (string)$int; } /** * @param string $string * @return HTMLPurifier_AttrDef */ public function make($string) { if ($string === '') { $max = null; } else { $max = (int)$string; } $class = get_class($this); return new $class($max); } } /** * Validates the HTML type length (not to be confused with CSS's length). * * This accepts integer pixels or percentages as lengths for certain * HTML attributes. */ class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); if ($string === '') { return false; } $parent_result = parent::validate($string, $config, $context); if ($parent_result !== false) { return $parent_result; } $length = strlen($string); $last_char = $string[$length - 1]; if ($last_char !== '%') { return false; } $points = substr($string, 0, $length - 1); if (!is_numeric($points)) { return false; } $points = (int)$points; if ($points < 0) { return '0%'; } if ($points > 100) { return '100%'; } return ((string)$points) . '%'; } } /** * Validates a rel/rev link attribute against a directive of allowed values * @note We cannot use Enum because link types allow multiple * values. * @note Assumes link types are ASCII text */ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef { /** * Name config attribute to pull. * @type string */ protected $name; /** * @param string $name */ public function __construct($name) { $configLookup = array( 'rel' => 'AllowedRel', 'rev' => 'AllowedRev' ); if (!isset($configLookup[$name])) { trigger_error( 'Unrecognized attribute name for link ' . 'relationship.', E_USER_ERROR ); return; } $this->name = $configLookup[$name]; } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $allowed = $config->get('Attr.' . $this->name); if (empty($allowed)) { return false; } $string = $this->parseCDATA($string); $parts = explode(' ', $string); // lookup to prevent duplicates $ret_lookup = array(); foreach ($parts as $part) { $part = strtolower(trim($part)); if (!isset($allowed[$part])) { continue; } $ret_lookup[$part] = true; } if (empty($ret_lookup)) { return false; } $string = implode(' ', array_keys($ret_lookup)); return $string; } } /** * Validates a MultiLength as defined by the HTML spec. * * A multilength is either a integer (pixel count), a percentage, or * a relative number. */ class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $string = trim($string); if ($string === '') { return false; } $parent_result = parent::validate($string, $config, $context); if ($parent_result !== false) { return $parent_result; } $length = strlen($string); $last_char = $string[$length - 1]; if ($last_char !== '*') { return false; } $int = substr($string, 0, $length - 1); if ($int == '') { return '*'; } if (!is_numeric($int)) { return false; } $int = (int)$int; if ($int < 0) { return false; } if ($int == 0) { return '0'; } if ($int == 1) { return '*'; } return ((string)$int) . '*'; } } abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef { /** * Unpacks a mailbox into its display-name and address * @param string $string * @return mixed */ public function unpack($string) { // needs to be implemented } } // sub-implementations /** * Validates a host according to the IPv4, IPv6 and DNS (future) specifications. */ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef { /** * IPv4 sub-validator. * @type HTMLPurifier_AttrDef_URI_IPv4 */ protected $ipv4; /** * IPv6 sub-validator. * @type HTMLPurifier_AttrDef_URI_IPv6 */ protected $ipv6; public function __construct() { $this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4(); $this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6(); } /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { $length = strlen($string); // empty hostname is OK; it's usually semantically equivalent: // the default host as defined by a URI scheme is used: // // If the URI scheme defines a default for host, then that // default applies when the host subcomponent is undefined // or when the registered name is empty (zero length). if ($string === '') { return ''; } if ($length > 1 && $string[0] === '[' && $string[$length - 1] === ']') { //IPv6 $ip = substr($string, 1, $length - 2); $valid = $this->ipv6->validate($ip, $config, $context); if ($valid === false) { return false; } return '[' . $valid . ']'; } // need to do checks on unusual encodings too $ipv4 = $this->ipv4->validate($string, $config, $context); if ($ipv4 !== false) { return $ipv4; } // A regular domain name. // This doesn't match I18N domain names, but we don't have proper IRI support, // so force users to insert Punycode. // There is not a good sense in which underscores should be // allowed, since it's technically not! (And if you go as // far to allow everything as specified by the DNS spec... // well, that's literally everything, modulo some space limits // for the components and the overall name (which, by the way, // we are NOT checking!). So we (arbitrarily) decide this: // let's allow underscores wherever we would have allowed // hyphens, if they are enabled. This is a pretty good match // for browser behavior, for example, a large number of browsers // cannot handle foo_.example.com, but foo_bar.example.com is // fairly well supported. $underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : ''; // The productions describing this are: $a = '[a-z]'; // alpha $an = '[a-z0-9]'; // alphanum $and = "[a-z0-9-$underscore]"; // alphanum | "-" // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum $domainlabel = "$an($and*$an)?"; // toplabel = alpha | alpha *( alphanum | "-" ) alphanum $toplabel = "$a($and*$an)?"; // hostname = *( domainlabel "." ) toplabel [ "." ] if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) { return $string; } // If we have Net_IDNA2 support, we can support IRIs by // punycoding them. (This is the most portable thing to do, // since otherwise we have to assume browsers support if ($config->get('Core.EnableIDNA')) { $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true)); // we need to encode each period separately $parts = explode('.', $string); try { $new_parts = array(); foreach ($parts as $part) { $encodable = false; for ($i = 0, $c = strlen($part); $i < $c; $i++) { if (ord($part[$i]) > 0x7a) { $encodable = true; break; } } if (!$encodable) { $new_parts[] = $part; } else { $new_parts[] = $idna->encode($part); } } $string = implode('.', $new_parts); if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) { return $string; } } catch (Exception $e) { // XXX error reporting } } return false; } } /** * Validates an IPv4 address * @author Feyd @ forums.devnetwork.net (public domain) */ class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef { /** * IPv4 regex, protected so that IPv6 can reuse it. * @type string */ protected $ip4; /** * @param string $aIP * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($aIP, $config, $context) { if (!$this->ip4) { $this->_loadRegex(); } if (preg_match('#^' . $this->ip4 . '$#s', $aIP)) { return $aIP; } return false; } /** * Lazy load function to prevent regex from being stuffed in * cache. */ protected function _loadRegex() { $oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255 $this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})"; } } /** * Validates an IPv6 address. * @author Feyd @ forums.devnetwork.net (public domain) * @note This function requires brackets to have been removed from address * in URI. */ class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4 { /** * @param string $aIP * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($aIP, $config, $context) { if (!$this->ip4) { $this->_loadRegex(); } $original = $aIP; $hex = '[0-9a-fA-F]'; $blk = '(?:' . $hex . '{1,4})'; $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128 // prefix check if (strpos($aIP, '/') !== false) { if (preg_match('#' . $pre . '$#s', $aIP, $find)) { $aIP = substr($aIP, 0, 0 - strlen($find[0])); unset($find); } else { return false; } } // IPv4-compatiblity check if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) { $aIP = substr($aIP, 0, 0 - strlen($find[0])); $ip = explode('.', $find[0]); $ip = array_map('dechex', $ip); $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3]; unset($find, $ip); } // compression check $aIP = explode('::', $aIP); $c = count($aIP); if ($c > 2) { return false; } elseif ($c == 2) { list($first, $second) = $aIP; $first = explode(':', $first); $second = explode(':', $second); if (count($first) + count($second) > 8) { return false; } while (count($first) < 8) { array_push($first, '0'); } array_splice($first, 8 - count($second), 8, $second); $aIP = $first; unset($first, $second); } else { $aIP = explode(':', $aIP[0]); } $c = count($aIP); if ($c != 8) { return false; } // All the pieces should be 16-bit hex strings. Are they? foreach ($aIP as $piece) { if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) { return false; } } return $original; } } /** * Primitive email validation class based on the regexp found at * http://www.regular-expressions.info/email.html */ class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email { /** * @param string $string * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool|string */ public function validate($string, $config, $context) { // no support for named mailboxes i.e. "Bob <bob@example.com>" // that needs more percent encoding to be done if ($string == '') { return false; } $string = trim($string); $result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string); return $result ? $string : false; } } /** * Pre-transform that changes proprietary background attribute to CSS. */ class HTMLPurifier_AttrTransform_Background extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['background'])) { return $attr; } $background = $this->confiscateAttr($attr, 'background'); // some validation should happen here $this->prependCSS($attr, "background-image:url($background);"); return $attr; } } // this MUST be placed in post, as it assumes that any value in dir is valid /** * Post-trasnform that ensures that bdo tags have the dir attribute set. */ class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (isset($attr['dir'])) { return $attr; } $attr['dir'] = $config->get('Attr.DefaultTextDir'); return $attr; } } /** * Pre-transform that changes deprecated bgcolor attribute to CSS. */ class HTMLPurifier_AttrTransform_BgColor extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['bgcolor'])) { return $attr; } $bgcolor = $this->confiscateAttr($attr, 'bgcolor'); // some validation should happen here $this->prependCSS($attr, "background-color:$bgcolor;"); return $attr; } } /** * Pre-transform that changes converts a boolean attribute to fixed CSS */ class HTMLPurifier_AttrTransform_BoolToCSS extends HTMLPurifier_AttrTransform { /** * Name of boolean attribute that is trigger. * @type string */ protected $attr; /** * CSS declarations to add to style, needs trailing semicolon. * @type string */ protected $css; /** * @param string $attr attribute name to convert from * @param string $css CSS declarations to add to style (needs semicolon) */ public function __construct($attr, $css) { $this->attr = $attr; $this->css = $css; } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr[$this->attr])) { return $attr; } unset($attr[$this->attr]); $this->prependCSS($attr, $this->css); return $attr; } } /** * Pre-transform that changes deprecated border attribute to CSS. */ class HTMLPurifier_AttrTransform_Border extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['border'])) { return $attr; } $border_width = $this->confiscateAttr($attr, 'border'); // some validation should happen here $this->prependCSS($attr, "border:{$border_width}px solid;"); return $attr; } } /** * Generic pre-transform that converts an attribute with a fixed number of * values (enumerated) to CSS. */ class HTMLPurifier_AttrTransform_EnumToCSS extends HTMLPurifier_AttrTransform { /** * Name of attribute to transform from. * @type string */ protected $attr; /** * Lookup array of attribute values to CSS. * @type array */ protected $enumToCSS = array(); /** * Case sensitivity of the matching. * @type bool * @warning Currently can only be guaranteed to work with ASCII * values. */ protected $caseSensitive = false; /** * @param string $attr Attribute name to transform from * @param array $enum_to_css Lookup array of attribute values to CSS * @param bool $case_sensitive Case sensitivity indicator, default false */ public function __construct($attr, $enum_to_css, $case_sensitive = false) { $this->attr = $attr; $this->enumToCSS = $enum_to_css; $this->caseSensitive = (bool)$case_sensitive; } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr[$this->attr])) { return $attr; } $value = trim($attr[$this->attr]); unset($attr[$this->attr]); if (!$this->caseSensitive) { $value = strtolower($value); } if (!isset($this->enumToCSS[$value])) { return $attr; } $this->prependCSS($attr, $this->enumToCSS[$value]); return $attr; } } // must be called POST validation /** * Transform that supplies default values for the src and alt attributes * in img tags, as well as prevents the img tag from being removed * because of a missing alt tag. This needs to be registered as both * a pre and post attribute transform. */ class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { $src = true; if (!isset($attr['src'])) { if ($config->get('Core.RemoveInvalidImg')) { return $attr; } $attr['src'] = $config->get('Attr.DefaultInvalidImage'); $src = false; } if (!isset($attr['alt'])) { if ($src) { $alt = $config->get('Attr.DefaultImageAlt'); if ($alt === null) { // truncate if the alt is too long $attr['alt'] = substr(basename($attr['src']), 0, 40); } else { $attr['alt'] = $alt; } } else { $attr['alt'] = $config->get('Attr.DefaultInvalidImageAlt'); } } return $attr; } } /** * Pre-transform that changes deprecated hspace and vspace attributes to CSS */ class HTMLPurifier_AttrTransform_ImgSpace extends HTMLPurifier_AttrTransform { /** * @type string */ protected $attr; /** * @type array */ protected $css = array( 'hspace' => array('left', 'right'), 'vspace' => array('top', 'bottom') ); /** * @param string $attr */ public function __construct($attr) { $this->attr = $attr; if (!isset($this->css[$attr])) { trigger_error(htmlspecialchars($attr) . ' is not valid space attribute'); } } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr[$this->attr])) { return $attr; } $width = $this->confiscateAttr($attr, $this->attr); // some validation could happen here if (!isset($this->css[$this->attr])) { return $attr; } $style = ''; foreach ($this->css[$this->attr] as $suffix) { $property = "margin-$suffix"; $style .= "$property:{$width}px;"; } $this->prependCSS($attr, $style); return $attr; } } /** * Performs miscellaneous cross attribute validation and filtering for * input elements. This is meant to be a post-transform. */ class HTMLPurifier_AttrTransform_Input extends HTMLPurifier_AttrTransform { /** * @type HTMLPurifier_AttrDef_HTML_Pixels */ protected $pixels; public function __construct() { $this->pixels = new HTMLPurifier_AttrDef_HTML_Pixels(); } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['type'])) { $t = 'text'; } else { $t = strtolower($attr['type']); } if (isset($attr['checked']) && $t !== 'radio' && $t !== 'checkbox') { unset($attr['checked']); } if (isset($attr['maxlength']) && $t !== 'text' && $t !== 'password') { unset($attr['maxlength']); } if (isset($attr['size']) && $t !== 'text' && $t !== 'password') { $result = $this->pixels->validate($attr['size'], $config, $context); if ($result === false) { unset($attr['size']); } else { $attr['size'] = $result; } } if (isset($attr['src']) && $t !== 'image') { unset($attr['src']); } if (!isset($attr['value']) && ($t === 'radio' || $t === 'checkbox')) { $attr['value'] = ''; } return $attr; } } /** * Post-transform that copies lang's value to xml:lang (and vice-versa) * @note Theoretically speaking, this could be a pre-transform, but putting * post is more efficient. */ class HTMLPurifier_AttrTransform_Lang extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { $lang = isset($attr['lang']) ? $attr['lang'] : false; $xml_lang = isset($attr['xml:lang']) ? $attr['xml:lang'] : false; if ($lang !== false && $xml_lang === false) { $attr['xml:lang'] = $lang; } elseif ($xml_lang !== false) { $attr['lang'] = $xml_lang; } return $attr; } } /** * Class for handling width/height length attribute transformations to CSS */ class HTMLPurifier_AttrTransform_Length extends HTMLPurifier_AttrTransform { /** * @type string */ protected $name; /** * @type string */ protected $cssName; public function __construct($name, $css_name = null) { $this->name = $name; $this->cssName = $css_name ? $css_name : $name; } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr[$this->name])) { return $attr; } $length = $this->confiscateAttr($attr, $this->name); if (ctype_digit($length)) { $length .= 'px'; } $this->prependCSS($attr, $this->cssName . ":$length;"); return $attr; } } /** * Pre-transform that changes deprecated name attribute to ID if necessary */ class HTMLPurifier_AttrTransform_Name extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { // Abort early if we're using relaxed definition of name if ($config->get('HTML.Attr.Name.UseCDATA')) { return $attr; } if (!isset($attr['name'])) { return $attr; } $id = $this->confiscateAttr($attr, 'name'); if (isset($attr['id'])) { return $attr; } $attr['id'] = $id; return $attr; } } /** * Post-transform that performs validation to the name attribute; if * it is present with an equivalent id attribute, it is passed through; * otherwise validation is performed. */ class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform { public function __construct() { $this->idDef = new HTMLPurifier_AttrDef_HTML_ID(); } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['name'])) { return $attr; } $name = $attr['name']; if (isset($attr['id']) && $attr['id'] === $name) { return $attr; } $result = $this->idDef->validate($name, $config, $context); if ($result === false) { unset($attr['name']); } else { $attr['name'] = $result; } return $attr; } } // must be called POST validation /** * Adds rel="nofollow" to all outbound links. This transform is * only attached if Attr.Nofollow is TRUE. */ class HTMLPurifier_AttrTransform_Nofollow extends HTMLPurifier_AttrTransform { /** * @type HTMLPurifier_URIParser */ private $parser; public function __construct() { $this->parser = new HTMLPurifier_URIParser(); } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['href'])) { return $attr; } // XXX Kind of inefficient $url = $this->parser->parse($attr['href']); $scheme = $url->getSchemeObj($config, $context); if ($scheme->browsable && !$url->isLocal($config, $context)) { if (isset($attr['rel'])) { $rels = explode(' ', $attr['rel']); if (!in_array('nofollow', $rels)) { $rels[] = 'nofollow'; } $attr['rel'] = implode(' ', $rels); } else { $attr['rel'] = 'nofollow'; } } return $attr; } } class HTMLPurifier_AttrTransform_SafeEmbed extends HTMLPurifier_AttrTransform { /** * @type string */ public $name = "SafeEmbed"; /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { $attr['allowscriptaccess'] = 'never'; $attr['allownetworking'] = 'internal'; $attr['type'] = 'application/x-shockwave-flash'; return $attr; } } /** * Writes default type for all objects. Currently only supports flash. */ class HTMLPurifier_AttrTransform_SafeObject extends HTMLPurifier_AttrTransform { /** * @type string */ public $name = "SafeObject"; /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['type'])) { $attr['type'] = 'application/x-shockwave-flash'; } return $attr; } } /** * Validates name/value pairs in param tags to be used in safe objects. This * will only allow name values it recognizes, and pre-fill certain attributes * with required values. * * @note * This class only supports Flash. In the future, Quicktime support * may be added. * * @warning * This class expects an injector to add the necessary parameters tags. */ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform { /** * @type string */ public $name = "SafeParam"; /** * @type HTMLPurifier_AttrDef_URI */ private $uri; public function __construct() { $this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded $this->wmode = new HTMLPurifier_AttrDef_Enum(array('window', 'opaque', 'transparent')); } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { // If we add support for other objects, we'll need to alter the // transforms. switch ($attr['name']) { // application/x-shockwave-flash // Keep this synchronized with Injector/SafeObject.php case 'allowScriptAccess': $attr['value'] = 'never'; break; case 'allowNetworking': $attr['value'] = 'internal'; break; case 'allowFullScreen': if ($config->get('HTML.FlashAllowFullScreen')) { $attr['value'] = ($attr['value'] == 'true') ? 'true' : 'false'; } else { $attr['value'] = 'false'; } break; case 'wmode': $attr['value'] = $this->wmode->validate($attr['value'], $config, $context); break; case 'movie': case 'src': $attr['name'] = "movie"; $attr['value'] = $this->uri->validate($attr['value'], $config, $context); break; case 'flashvars': // we're going to allow arbitrary inputs to the SWF, on // the reasoning that it could only hack the SWF, not us. break; // add other cases to support other param name/value pairs default: $attr['name'] = $attr['value'] = null; } return $attr; } } /** * Implements required attribute stipulation for <script> */ class HTMLPurifier_AttrTransform_ScriptRequired extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['type'])) { $attr['type'] = 'text/javascript'; } return $attr; } } // must be called POST validation /** * Adds target="blank" to all outbound links. This transform is * only attached if Attr.TargetBlank is TRUE. This works regardless * of whether or not Attr.AllowedFrameTargets */ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform { /** * @type HTMLPurifier_URIParser */ private $parser; public function __construct() { $this->parser = new HTMLPurifier_URIParser(); } /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { if (!isset($attr['href'])) { return $attr; } // XXX Kind of inefficient $url = $this->parser->parse($attr['href']); $scheme = $url->getSchemeObj($config, $context); if ($scheme->browsable && !$url->isBenign($config, $context)) { $attr['target'] = '_blank'; } return $attr; } } /** * Sets height/width defaults for <textarea> */ class HTMLPurifier_AttrTransform_Textarea extends HTMLPurifier_AttrTransform { /** * @param array $attr * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function transform($attr, $config, $context) { // Calculated from Firefox if (!isset($attr['cols'])) { $attr['cols'] = '22'; } if (!isset($attr['rows'])) { $attr['rows'] = '3'; } return $attr; } } /** * Definition that uses different definitions depending on context. * * The del and ins tags are notable because they allow different types of * elements depending on whether or not they're in a block or inline context. * Chameleon allows this behavior to happen by using two different * definitions depending on context. While this somewhat generalized, * it is specifically intended for those two tags. */ class HTMLPurifier_ChildDef_Chameleon extends HTMLPurifier_ChildDef { /** * Instance of the definition object to use when inline. Usually stricter. * @type HTMLPurifier_ChildDef_Optional */ public $inline; /** * Instance of the definition object to use when block. * @type HTMLPurifier_ChildDef_Optional */ public $block; /** * @type string */ public $type = 'chameleon'; /** * @param array $inline List of elements to allow when inline. * @param array $block List of elements to allow when block. */ public function __construct($inline, $block) { $this->inline = new HTMLPurifier_ChildDef_Optional($inline); $this->block = new HTMLPurifier_ChildDef_Optional($block); $this->elements = $this->block->elements; } /** * @param HTMLPurifier_Node[] $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function validateChildren($children, $config, $context) { if ($context->get('IsInline') === false) { return $this->block->validateChildren( $children, $config, $context ); } else { return $this->inline->validateChildren( $children, $config, $context ); } } } /** * Custom validation class, accepts DTD child definitions * * @warning Currently this class is an all or nothing proposition, that is, * it will only give a bool return value. */ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef { /** * @type string */ public $type = 'custom'; /** * @type bool */ public $allow_empty = false; /** * Allowed child pattern as defined by the DTD. * @type string */ public $dtd_regex; /** * PCRE regex derived from $dtd_regex. * @type string */ private $_pcre_regex; /** * @param $dtd_regex Allowed child pattern from the DTD */ public function __construct($dtd_regex) { $this->dtd_regex = $dtd_regex; $this->_compileRegex(); } /** * Compiles the PCRE regex from a DTD regex ($dtd_regex to $_pcre_regex) */ protected function _compileRegex() { $raw = str_replace(' ', '', $this->dtd_regex); if ($raw{0} != '(') { $raw = "($raw)"; } $el = '[#a-zA-Z0-9_.-]+'; $reg = $raw; // COMPLICATED! AND MIGHT BE BUGGY! I HAVE NO CLUE WHAT I'M // DOING! Seriously: if there's problems, please report them. // collect all elements into the $elements array preg_match_all("/$el/", $reg, $matches); foreach ($matches[0] as $match) { $this->elements[$match] = true; } // setup all elements as parentheticals with leading commas $reg = preg_replace("/$el/", '(,\\0)', $reg); // remove commas when they were not solicited $reg = preg_replace("/([^,(|]\(+),/", '\\1', $reg); // remove all non-paranthetical commas: they are handled by first regex $reg = preg_replace("/,\(/", '(', $reg); $this->_pcre_regex = $reg; } /** * @param HTMLPurifier_Node[] $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function validateChildren($children, $config, $context) { $list_of_children = ''; $nesting = 0; // depth into the nest foreach ($children as $node) { if (!empty($node->is_whitespace)) { continue; } $list_of_children .= $node->name . ','; } // add leading comma to deal with stray comma declarations $list_of_children = ',' . rtrim($list_of_children, ','); $okay = preg_match( '/^,?' . $this->_pcre_regex . '$/', $list_of_children ); return (bool)$okay; } } /** * Definition that disallows all elements. * @warning validateChildren() in this class is actually never called, because * empty elements are corrected in HTMLPurifier_Strategy_MakeWellFormed * before child definitions are parsed in earnest by * HTMLPurifier_Strategy_FixNesting. */ class HTMLPurifier_ChildDef_Empty extends HTMLPurifier_ChildDef { /** * @type bool */ public $allow_empty = true; /** * @type string */ public $type = 'empty'; public function __construct() { } /** * @param HTMLPurifier_Node[] $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function validateChildren($children, $config, $context) { return array(); } } /** * Definition for list containers ul and ol. * * What does this do? The big thing is to handle ol/ul at the top * level of list nodes, which should be handled specially by /folding/ * them into the previous list node. We generally shouldn't ever * see other disallowed elements, because the autoclose behavior * in MakeWellFormed handles it. */ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef { /** * @type string */ public $type = 'list'; /** * @type array */ // lying a little bit, so that we can handle ul and ol ourselves // XXX: This whole business with 'wrap' is all a bit unsatisfactory public $elements = array('li' => true, 'ul' => true, 'ol' => true); /** * @param array $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function validateChildren($children, $config, $context) { // Flag for subclasses $this->whitespace = false; // if there are no tokens, delete parent node if (empty($children)) { return false; } // the new set of children $result = array(); // a little sanity check to make sure it's not ALL whitespace $all_whitespace = true; $current_li = false; foreach ($children as $node) { if (!empty($node->is_whitespace)) { $result[] = $node; continue; } $all_whitespace = false; // phew, we're not talking about whitespace if ($node->name === 'li') { // good $current_li = $node; $result[] = $node; } else { // we want to tuck this into the previous li // Invariant: we expect the node to be ol/ul // ToDo: Make this more robust in the case of not ol/ul // by distinguishing between existing li and li created // to handle non-list elements; non-list elements should // not be appended to an existing li; only li created // for non-list. This distinction is not currently made. if ($current_li === false) { $current_li = new HTMLPurifier_Node_Element('li'); $result[] = $current_li; } $current_li->children[] = $node; $current_li->empty = false; // XXX fascinating! Check for this error elsewhere ToDo } } if (empty($result)) { return false; } if ($all_whitespace) { return false; } return $result; } } /** * Definition that allows a set of elements, but disallows empty children. */ class HTMLPurifier_ChildDef_Required extends HTMLPurifier_ChildDef { /** * Lookup table of allowed elements. * @type array */ public $elements = array(); /** * Whether or not the last passed node was all whitespace. * @type bool */ protected $whitespace = false; /** * @param array|string $elements List of allowed element names (lowercase). */ public function __construct($elements) { if (is_string($elements)) { $elements = str_replace(' ', '', $elements); $elements = explode('|', $elements); } $keys = array_keys($elements); if ($keys == array_keys($keys)) { $elements = array_flip($elements); foreach ($elements as $i => $x) { $elements[$i] = true; if (empty($i)) { unset($elements[$i]); } // remove blank } } $this->elements = $elements; } /** * @type bool */ public $allow_empty = false; /** * @type string */ public $type = 'required'; /** * @param array $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function validateChildren($children, $config, $context) { // Flag for subclasses $this->whitespace = false; // if there are no tokens, delete parent node if (empty($children)) { return false; } // the new set of children $result = array(); // whether or not parsed character data is allowed // this controls whether or not we silently drop a tag // or generate escaped HTML from it $pcdata_allowed = isset($this->elements['#PCDATA']); // a little sanity check to make sure it's not ALL whitespace $all_whitespace = true; $stack = array_reverse($children); while (!empty($stack)) { $node = array_pop($stack); if (!empty($node->is_whitespace)) { $result[] = $node; continue; } $all_whitespace = false; // phew, we're not talking about whitespace if (!isset($this->elements[$node->name])) { // special case text // XXX One of these ought to be redundant or something if ($pcdata_allowed && $node instanceof HTMLPurifier_Node_Text) { $result[] = $node; continue; } // spill the child contents in // ToDo: Make configurable if ($node instanceof HTMLPurifier_Node_Element) { for ($i = count($node->children) - 1; $i >= 0; $i--) { $stack[] = $node->children[$i]; } continue; } continue; } $result[] = $node; } if (empty($result)) { return false; } if ($all_whitespace) { $this->whitespace = true; return false; } return $result; } } /** * Definition that allows a set of elements, and allows no children. * @note This is a hack to reuse code from HTMLPurifier_ChildDef_Required, * really, one shouldn't inherit from the other. Only altered behavior * is to overload a returned false with an array. Thus, it will never * return false. */ class HTMLPurifier_ChildDef_Optional extends HTMLPurifier_ChildDef_Required { /** * @type bool */ public $allow_empty = true; /** * @type string */ public $type = 'optional'; /** * @param array $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function validateChildren($children, $config, $context) { $result = parent::validateChildren($children, $config, $context); // we assume that $children is not modified if ($result === false) { if (empty($children)) { return true; } elseif ($this->whitespace) { return $children; } else { return array(); } } return $result; } } /** * Takes the contents of blockquote when in strict and reformats for validation. */ class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Required { /** * @type array */ protected $real_elements; /** * @type array */ protected $fake_elements; /** * @type bool */ public $allow_empty = true; /** * @type string */ public $type = 'strictblockquote'; /** * @type bool */ protected $init = false; /** * @param HTMLPurifier_Config $config * @return array * @note We don't want MakeWellFormed to auto-close inline elements since * they might be allowed. */ public function getAllowedElements($config) { $this->init($config); return $this->fake_elements; } /** * @param array $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function validateChildren($children, $config, $context) { $this->init($config); // trick the parent class into thinking it allows more $this->elements = $this->fake_elements; $result = parent::validateChildren($children, $config, $context); $this->elements = $this->real_elements; if ($result === false) { return array(); } if ($result === true) { $result = $children; } $def = $config->getHTMLDefinition(); $block_wrap_name = $def->info_block_wrapper; $block_wrap = false; $ret = array(); foreach ($result as $node) { if ($block_wrap === false) { if (($node instanceof HTMLPurifier_Node_Text && !$node->is_whitespace) || ($node instanceof HTMLPurifier_Node_Element && !isset($this->elements[$node->name]))) { $block_wrap = new HTMLPurifier_Node_Element($def->info_block_wrapper); $ret[] = $block_wrap; } } else { if ($node instanceof HTMLPurifier_Node_Element && isset($this->elements[$node->name])) { $block_wrap = false; } } if ($block_wrap) { $block_wrap->children[] = $node; } else { $ret[] = $node; } } return $ret; } /** * @param HTMLPurifier_Config $config */ private function init($config) { if (!$this->init) { $def = $config->getHTMLDefinition(); // allow all inline elements $this->real_elements = $this->elements; $this->fake_elements = $def->info_content_sets['Flow']; $this->fake_elements['#PCDATA'] = true; $this->init = true; } } } /** * Definition for tables. The general idea is to extract out all of the * essential bits, and then reconstruct it later. * * This is a bit confusing, because the DTDs and the W3C * validators seem to disagree on the appropriate definition. The * DTD claims: * * (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+) * * But actually, the HTML4 spec then has this to say: * * The TBODY start tag is always required except when the table * contains only one table body and no table head or foot sections. * The TBODY end tag may always be safely omitted. * * So the DTD is kind of wrong. The validator is, unfortunately, kind * of on crack. * * The definition changed again in XHTML1.1; and in my opinion, this * formulation makes the most sense. * * caption?, ( col* | colgroup* ), (( thead?, tfoot?, tbody+ ) | ( tr+ )) * * Essentially, we have two modes: thead/tfoot/tbody mode, and tr mode. * If we encounter a thead, tfoot or tbody, we are placed in the former * mode, and we *must* wrap any stray tr segments with a tbody. But if * we don't run into any of them, just have tr tags is OK. */ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef { /** * @type bool */ public $allow_empty = false; /** * @type string */ public $type = 'table'; /** * @type array */ public $elements = array( 'tr' => true, 'tbody' => true, 'thead' => true, 'tfoot' => true, 'caption' => true, 'colgroup' => true, 'col' => true ); public function __construct() { } /** * @param array $children * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array */ public function validateChildren($children, $config, $context) { if (empty($children)) { return false; } // only one of these elements is allowed in a table $caption = false; $thead = false; $tfoot = false; // whitespace $initial_ws = array(); $after_caption_ws = array(); $after_thead_ws = array(); $after_tfoot_ws = array(); // as many of these as you want $cols = array(); $content = array(); $tbody_mode = false; // if true, then we need to wrap any stray // <tr>s with a <tbody>. $ws_accum =& $initial_ws; foreach ($children as $node) { if ($node instanceof HTMLPurifier_Node_Comment) { $ws_accum[] = $node; continue; } switch ($node->name) { case 'tbody': $tbody_mode = true; // fall through case 'tr': $content[] = $node; $ws_accum =& $content; break; case 'caption': // there can only be one caption! if ($caption !== false) break; $caption = $node; $ws_accum =& $after_caption_ws; break; case 'thead': $tbody_mode = true; // XXX This breaks rendering properties with // Firefox, which never floats a <thead> to // the top. Ever. (Our scheme will float the // first <thead> to the top.) So maybe // <thead>s that are not first should be // turned into <tbody>? Very tricky, indeed. if ($thead === false) { $thead = $node; $ws_accum =& $after_thead_ws; } else { // Oops, there's a second one! What // should we do? Current behavior is to // transmutate the first and last entries into // tbody tags, and then put into content. // Maybe a better idea is to *attach // it* to the existing thead or tfoot? // We don't do this, because Firefox // doesn't float an extra tfoot to the // bottom like it does for the first one. $node->name = 'tbody'; $content[] = $node; $ws_accum =& $content; } break; case 'tfoot': // see above for some aveats $tbody_mode = true; if ($tfoot === false) { $tfoot = $node; $ws_accum =& $after_tfoot_ws; } else { $node->name = 'tbody'; $content[] = $node; $ws_accum =& $content; } break; case 'colgroup': case 'col': $cols[] = $node; $ws_accum =& $cols; break; case '#PCDATA': // How is whitespace handled? We treat is as sticky to // the *end* of the previous element. So all of the // nonsense we have worked on is to keep things // together. if (!empty($node->is_whitespace)) { $ws_accum[] = $node; } break; } } if (empty($content)) { return false; } $ret = $initial_ws; if ($caption !== false) { $ret[] = $caption; $ret = array_merge($ret, $after_caption_ws); } if ($cols !== false) { $ret = array_merge($ret, $cols); } if ($thead !== false) { $ret[] = $thead; $ret = array_merge($ret, $after_thead_ws); } if ($tfoot !== false) { $ret[] = $tfoot; $ret = array_merge($ret, $after_tfoot_ws); } if ($tbody_mode) { // we have to shuffle tr into tbody $current_tr_tbody = null; foreach($content as $node) { switch ($node->name) { case 'tbody': $current_tr_tbody = null; $ret[] = $node; break; case 'tr': if ($current_tr_tbody === null) { $current_tr_tbody = new HTMLPurifier_Node_Element('tbody'); $ret[] = $current_tr_tbody; } $current_tr_tbody->children[] = $node; break; case '#PCDATA': assert($node->is_whitespace); if ($current_tr_tbody === null) { $ret[] = $node; } else { $current_tr_tbody->children[] = $node; } break; } } } else { $ret = array_merge($ret, $content); } return $ret; } } class HTMLPurifier_DefinitionCache_Decorator extends HTMLPurifier_DefinitionCache { /** * Cache object we are decorating * @type HTMLPurifier_DefinitionCache */ public $cache; /** * The name of the decorator * @var string */ public $name; public function __construct() { } /** * Lazy decorator function * @param HTMLPurifier_DefinitionCache $cache Reference to cache object to decorate * @return HTMLPurifier_DefinitionCache_Decorator */ public function decorate(&$cache) { $decorator = $this->copy(); // reference is necessary for mocks in PHP 4 $decorator->cache =& $cache; $decorator->type = $cache->type; return $decorator; } /** * Cross-compatible clone substitute * @return HTMLPurifier_DefinitionCache_Decorator */ public function copy() { return new HTMLPurifier_DefinitionCache_Decorator(); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function add($def, $config) { return $this->cache->add($def, $config); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function set($def, $config) { return $this->cache->set($def, $config); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function replace($def, $config) { return $this->cache->replace($def, $config); } /** * @param HTMLPurifier_Config $config * @return mixed */ public function get($config) { return $this->cache->get($config); } /** * @param HTMLPurifier_Config $config * @return mixed */ public function remove($config) { return $this->cache->remove($config); } /** * @param HTMLPurifier_Config $config * @return mixed */ public function flush($config) { return $this->cache->flush($config); } /** * @param HTMLPurifier_Config $config * @return mixed */ public function cleanup($config) { return $this->cache->cleanup($config); } } /** * Null cache object to use when no caching is on. */ class HTMLPurifier_DefinitionCache_Null extends HTMLPurifier_DefinitionCache { /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return bool */ public function add($def, $config) { return false; } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return bool */ public function set($def, $config) { return false; } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return bool */ public function replace($def, $config) { return false; } /** * @param HTMLPurifier_Config $config * @return bool */ public function remove($config) { return false; } /** * @param HTMLPurifier_Config $config * @return bool */ public function get($config) { return false; } /** * @param HTMLPurifier_Config $config * @return bool */ public function flush($config) { return false; } /** * @param HTMLPurifier_Config $config * @return bool */ public function cleanup($config) { return false; } } class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCache { /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return int|bool */ public function add($def, $config) { if (!$this->checkDefType($def)) { return; } $file = $this->generateFilePath($config); if (file_exists($file)) { return false; } if (!$this->_prepareDir($config)) { return false; } return $this->_write($file, serialize($def), $config); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return int|bool */ public function set($def, $config) { if (!$this->checkDefType($def)) { return; } $file = $this->generateFilePath($config); if (!$this->_prepareDir($config)) { return false; } return $this->_write($file, serialize($def), $config); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return int|bool */ public function replace($def, $config) { if (!$this->checkDefType($def)) { return; } $file = $this->generateFilePath($config); if (!file_exists($file)) { return false; } if (!$this->_prepareDir($config)) { return false; } return $this->_write($file, serialize($def), $config); } /** * @param HTMLPurifier_Config $config * @return bool|HTMLPurifier_Config */ public function get($config) { $file = $this->generateFilePath($config); if (!file_exists($file)) { return false; } return unserialize(file_get_contents($file)); } /** * @param HTMLPurifier_Config $config * @return bool */ public function remove($config) { $file = $this->generateFilePath($config); if (!file_exists($file)) { return false; } return unlink($file); } /** * @param HTMLPurifier_Config $config * @return bool */ public function flush($config) { if (!$this->_prepareDir($config)) { return false; } $dir = $this->generateDirectoryPath($config); $dh = opendir($dir); while (false !== ($filename = readdir($dh))) { if (empty($filename)) { continue; } if ($filename[0] === '.') { continue; } unlink($dir . '/' . $filename); } } /** * @param HTMLPurifier_Config $config * @return bool */ public function cleanup($config) { if (!$this->_prepareDir($config)) { return false; } $dir = $this->generateDirectoryPath($config); $dh = opendir($dir); while (false !== ($filename = readdir($dh))) { if (empty($filename)) { continue; } if ($filename[0] === '.') { continue; } $key = substr($filename, 0, strlen($filename) - 4); if ($this->isOld($key, $config)) { unlink($dir . '/' . $filename); } } } /** * Generates the file path to the serial file corresponding to * the configuration and definition name * @param HTMLPurifier_Config $config * @return string * @todo Make protected */ public function generateFilePath($config) { $key = $this->generateKey($config); return $this->generateDirectoryPath($config) . '/' . $key . '.ser'; } /** * Generates the path to the directory contain this cache's serial files * @param HTMLPurifier_Config $config * @return string * @note No trailing slash * @todo Make protected */ public function generateDirectoryPath($config) { $base = $this->generateBaseDirectoryPath($config); return $base . '/' . $this->type; } /** * Generates path to base directory that contains all definition type * serials * @param HTMLPurifier_Config $config * @return mixed|string * @todo Make protected */ public function generateBaseDirectoryPath($config) { $base = $config->get('Cache.SerializerPath'); $base = is_null($base) ? HTMLPURIFIER_PREFIX . '/HTMLPurifier/DefinitionCache/Serializer' : $base; return $base; } /** * Convenience wrapper function for file_put_contents * @param string $file File name to write to * @param string $data Data to write into file * @param HTMLPurifier_Config $config * @return int|bool Number of bytes written if success, or false if failure. */ private function _write($file, $data, $config) { $result = file_put_contents($file, $data); if ($result !== false) { // set permissions of the new file (no execute) $chmod = $config->get('Cache.SerializerPermissions'); if (!$chmod) { $chmod = 0644; // invalid config or simpletest } $chmod = $chmod & 0666; chmod($file, $chmod); } return $result; } /** * Prepares the directory that this type stores the serials in * @param HTMLPurifier_Config $config * @return bool True if successful */ private function _prepareDir($config) { $directory = $this->generateDirectoryPath($config); $chmod = $config->get('Cache.SerializerPermissions'); if (!$chmod) { $chmod = 0755; // invalid config or simpletest } if (!is_dir($directory)) { $base = $this->generateBaseDirectoryPath($config); if (!is_dir($base)) { trigger_error( 'Base directory ' . $base . ' does not exist, please create or change using %Cache.SerializerPath', E_USER_WARNING ); return false; } elseif (!$this->_testPermissions($base, $chmod)) { return false; } $old = umask(0000); mkdir($directory, $chmod); umask($old); } elseif (!$this->_testPermissions($directory, $chmod)) { return false; } return true; } /** * Tests permissions on a directory and throws out friendly * error messages and attempts to chmod it itself if possible * @param string $dir Directory path * @param int $chmod Permissions * @return bool True if directory is writable */ private function _testPermissions($dir, $chmod) { // early abort, if it is writable, everything is hunky-dory if (is_writable($dir)) { return true; } if (!is_dir($dir)) { // generally, you'll want to handle this beforehand // so a more specific error message can be given trigger_error( 'Directory ' . $dir . ' does not exist', E_USER_WARNING ); return false; } if (function_exists('posix_getuid')) { // POSIX system, we can give more specific advice if (fileowner($dir) === posix_getuid()) { // we can chmod it ourselves $chmod = $chmod | 0700; if (chmod($dir, $chmod)) { return true; } } elseif (filegroup($dir) === posix_getgid()) { $chmod = $chmod | 0070; } else { // PHP's probably running as nobody, so we'll // need to give global permissions $chmod = $chmod | 0777; } trigger_error( 'Directory ' . $dir . ' not writable, ' . 'please chmod to ' . decoct($chmod), E_USER_WARNING ); } else { // generic error message trigger_error( 'Directory ' . $dir . ' not writable, ' . 'please alter file permissions', E_USER_WARNING ); } return false; } } /** * Definition cache decorator class that cleans up the cache * whenever there is a cache miss. */ class HTMLPurifier_DefinitionCache_Decorator_Cleanup extends HTMLPurifier_DefinitionCache_Decorator { /** * @type string */ public $name = 'Cleanup'; /** * @return HTMLPurifier_DefinitionCache_Decorator_Cleanup */ public function copy() { return new HTMLPurifier_DefinitionCache_Decorator_Cleanup(); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function add($def, $config) { $status = parent::add($def, $config); if (!$status) { parent::cleanup($config); } return $status; } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function set($def, $config) { $status = parent::set($def, $config); if (!$status) { parent::cleanup($config); } return $status; } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function replace($def, $config) { $status = parent::replace($def, $config); if (!$status) { parent::cleanup($config); } return $status; } /** * @param HTMLPurifier_Config $config * @return mixed */ public function get($config) { $ret = parent::get($config); if (!$ret) { parent::cleanup($config); } return $ret; } } /** * Definition cache decorator class that saves all cache retrievals * to PHP's memory; good for unit tests or circumstances where * there are lots of configuration objects floating around. */ class HTMLPurifier_DefinitionCache_Decorator_Memory extends HTMLPurifier_DefinitionCache_Decorator { /** * @type array */ protected $definitions; /** * @type string */ public $name = 'Memory'; /** * @return HTMLPurifier_DefinitionCache_Decorator_Memory */ public function copy() { return new HTMLPurifier_DefinitionCache_Decorator_Memory(); } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function add($def, $config) { $status = parent::add($def, $config); if ($status) { $this->definitions[$this->generateKey($config)] = $def; } return $status; } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function set($def, $config) { $status = parent::set($def, $config); if ($status) { $this->definitions[$this->generateKey($config)] = $def; } return $status; } /** * @param HTMLPurifier_Definition $def * @param HTMLPurifier_Config $config * @return mixed */ public function replace($def, $config) { $status = parent::replace($def, $config); if ($status) { $this->definitions[$this->generateKey($config)] = $def; } return $status; } /** * @param HTMLPurifier_Config $config * @return mixed */ public function get($config) { $key = $this->generateKey($config); if (isset($this->definitions[$key])) { return $this->definitions[$key]; } $this->definitions[$key] = parent::get($config); return $this->definitions[$key]; } } /** * XHTML 1.1 Bi-directional Text Module, defines elements that * declare directionality of content. Text Extension Module. */ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Bdo'; /** * @type array */ public $attr_collections = array( 'I18N' => array('dir' => false) ); /** * @param HTMLPurifier_Config $config */ public function setup($config) { $bdo = $this->addElement( 'bdo', 'Inline', 'Inline', array('Core', 'Lang'), array( 'dir' => 'Enum#ltr,rtl', // required // The Abstract Module specification has the attribute // inclusions wrong for bdo: bdo allows Lang ) ); $bdo->attr_transform_post[] = new HTMLPurifier_AttrTransform_BdoDir(); $this->attr_collections['I18N']['dir'] = 'Enum#ltr,rtl'; } } class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'CommonAttributes'; /** * @type array */ public $attr_collections = array( 'Core' => array( 0 => array('Style'), // 'xml:space' => false, 'class' => 'Class', 'id' => 'ID', 'title' => 'CDATA', ), 'Lang' => array(), 'I18N' => array( 0 => array('Lang'), // proprietary, for xml:lang/lang ), 'Common' => array( 0 => array('Core', 'I18N') ) ); } /** * XHTML 1.1 Edit Module, defines editing-related elements. Text Extension * Module. */ class HTMLPurifier_HTMLModule_Edit extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Edit'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $contents = 'Chameleon: #PCDATA | Inline ! #PCDATA | Flow'; $attr = array( 'cite' => 'URI', // 'datetime' => 'Datetime', // not implemented ); $this->addElement('del', 'Inline', $contents, 'Common', $attr); $this->addElement('ins', 'Inline', $contents, 'Common', $attr); } // HTML 4.01 specifies that ins/del must not contain block // elements when used in an inline context, chameleon is // a complicated workaround to acheive this effect // Inline context ! Block context (exclamation mark is // separator, see getChildDef for parsing) /** * @type bool */ public $defines_child_def = true; /** * @param HTMLPurifier_ElementDef $def * @return HTMLPurifier_ChildDef_Chameleon */ public function getChildDef($def) { if ($def->content_model_type != 'chameleon') { return false; } $value = explode('!', $def->content_model); return new HTMLPurifier_ChildDef_Chameleon($value[0], $value[1]); } } /** * XHTML 1.1 Forms module, defines all form-related elements found in HTML 4. */ class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Forms'; /** * @type bool */ public $safe = false; /** * @type array */ public $content_sets = array( 'Block' => 'Form', 'Inline' => 'Formctrl', ); /** * @param HTMLPurifier_Config $config */ public function setup($config) { $form = $this->addElement( 'form', 'Form', 'Required: Heading | List | Block | fieldset', 'Common', array( 'accept' => 'ContentTypes', 'accept-charset' => 'Charsets', 'action*' => 'URI', 'method' => 'Enum#get,post', // really ContentType, but these two are the only ones used today 'enctype' => 'Enum#application/x-www-form-urlencoded,multipart/form-data', ) ); $form->excludes = array('form' => true); $input = $this->addElement( 'input', 'Formctrl', 'Empty', 'Common', array( 'accept' => 'ContentTypes', 'accesskey' => 'Character', 'alt' => 'Text', 'checked' => 'Bool#checked', 'disabled' => 'Bool#disabled', 'maxlength' => 'Number', 'name' => 'CDATA', 'readonly' => 'Bool#readonly', 'size' => 'Number', 'src' => 'URI#embedded', 'tabindex' => 'Number', 'type' => 'Enum#text,password,checkbox,button,radio,submit,reset,file,hidden,image', 'value' => 'CDATA', ) ); $input->attr_transform_post[] = new HTMLPurifier_AttrTransform_Input(); $this->addElement( 'select', 'Formctrl', 'Required: optgroup | option', 'Common', array( 'disabled' => 'Bool#disabled', 'multiple' => 'Bool#multiple', 'name' => 'CDATA', 'size' => 'Number', 'tabindex' => 'Number', ) ); $this->addElement( 'option', false, 'Optional: #PCDATA', 'Common', array( 'disabled' => 'Bool#disabled', 'label' => 'Text', 'selected' => 'Bool#selected', 'value' => 'CDATA', ) ); // It's illegal for there to be more than one selected, but not // be multiple. Also, no selected means undefined behavior. This might // be difficult to implement; perhaps an injector, or a context variable. $textarea = $this->addElement( 'textarea', 'Formctrl', 'Optional: #PCDATA', 'Common', array( 'accesskey' => 'Character', 'cols*' => 'Number', 'disabled' => 'Bool#disabled', 'name' => 'CDATA', 'readonly' => 'Bool#readonly', 'rows*' => 'Number', 'tabindex' => 'Number', ) ); $textarea->attr_transform_pre[] = new HTMLPurifier_AttrTransform_Textarea(); $button = $this->addElement( 'button', 'Formctrl', 'Optional: #PCDATA | Heading | List | Block | Inline', 'Common', array( 'accesskey' => 'Character', 'disabled' => 'Bool#disabled', 'name' => 'CDATA', 'tabindex' => 'Number', 'type' => 'Enum#button,submit,reset', 'value' => 'CDATA', ) ); // For exclusions, ideally we'd specify content sets, not literal elements $button->excludes = $this->makeLookup( 'form', 'fieldset', // Form 'input', 'select', 'textarea', 'label', 'button', // Formctrl 'a', // as per HTML 4.01 spec, this is omitted by modularization 'isindex', 'iframe' // legacy items ); // Extra exclusion: img usemap="" is not permitted within this element. // We'll omit this for now, since we don't have any good way of // indicating it yet. // This is HIGHLY user-unfriendly; we need a custom child-def for this $this->addElement('fieldset', 'Form', 'Custom: (#WS?,legend,(Flow|#PCDATA)*)', 'Common'); $label = $this->addElement( 'label', 'Formctrl', 'Optional: #PCDATA | Inline', 'Common', array( 'accesskey' => 'Character', // 'for' => 'IDREF', // IDREF not implemented, cannot allow ) ); $label->excludes = array('label' => true); $this->addElement( 'legend', false, 'Optional: #PCDATA | Inline', 'Common', array( 'accesskey' => 'Character', ) ); $this->addElement( 'optgroup', false, 'Required: option', 'Common', array( 'disabled' => 'Bool#disabled', 'label*' => 'Text', ) ); // Don't forget an injector for <isindex>. This one's a little complex // because it maps to multiple elements. } } /** * XHTML 1.1 Hypertext Module, defines hypertext links. Core Module. */ class HTMLPurifier_HTMLModule_Hypertext extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Hypertext'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $a = $this->addElement( 'a', 'Inline', 'Inline', 'Common', array( // 'accesskey' => 'Character', // 'charset' => 'Charset', 'href' => 'URI', // 'hreflang' => 'LanguageCode', 'rel' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rel'), 'rev' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rev'), // 'tabindex' => 'Number', // 'type' => 'ContentType', ) ); $a->formatting = true; $a->excludes = array('a' => true); } } /** * XHTML 1.1 Iframe Module provides inline frames. * * @note This module is not considered safe unless an Iframe * whitelisting mechanism is specified. Currently, the only * such mechanism is %URL.SafeIframeRegexp */ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Iframe'; /** * @type bool */ public $safe = false; /** * @param HTMLPurifier_Config $config */ public function setup($config) { if ($config->get('HTML.SafeIframe')) { $this->safe = true; } $this->addElement( 'iframe', 'Inline', 'Flow', 'Common', array( 'src' => 'URI#embedded', 'width' => 'Length', 'height' => 'Length', 'name' => 'ID', 'scrolling' => 'Enum#yes,no,auto', 'frameborder' => 'Enum#0,1', 'longdesc' => 'URI', 'marginheight' => 'Pixels', 'marginwidth' => 'Pixels', ) ); } } /** * XHTML 1.1 Image Module provides basic image embedding. * @note There is specialized code for removing empty images in * HTMLPurifier_Strategy_RemoveForeignElements */ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Image'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $max = $config->get('HTML.MaxImgLength'); $img = $this->addElement( 'img', 'Inline', 'Empty', 'Common', array( 'alt*' => 'Text', // According to the spec, it's Length, but percents can // be abused, so we allow only Pixels. 'height' => 'Pixels#' . $max, 'width' => 'Pixels#' . $max, 'longdesc' => 'URI', 'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded ) ); if ($max === null || $config->get('HTML.Trusted')) { $img->attr['height'] = $img->attr['width'] = 'Length'; } // kind of strange, but splitting things up would be inefficient $img->attr_transform_pre[] = $img->attr_transform_post[] = new HTMLPurifier_AttrTransform_ImgRequired(); } } /** * XHTML 1.1 Legacy module defines elements that were previously * deprecated. * * @note Not all legacy elements have been implemented yet, which * is a bit of a reverse problem as compared to browsers! In * addition, this legacy module may implement a bit more than * mandated by XHTML 1.1. * * This module can be used in combination with TransformToStrict in order * to transform as many deprecated elements as possible, but retain * questionably deprecated elements that do not have good alternatives * as well as transform elements that don't have an implementation. * See docs/ref-strictness.txt for more details. */ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Legacy'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->addElement( 'basefont', 'Inline', 'Empty', null, array( 'color' => 'Color', 'face' => 'Text', // extremely broad, we should 'size' => 'Text', // tighten it 'id' => 'ID' ) ); $this->addElement('center', 'Block', 'Flow', 'Common'); $this->addElement( 'dir', 'Block', 'Required: li', 'Common', array( 'compact' => 'Bool#compact' ) ); $this->addElement( 'font', 'Inline', 'Inline', array('Core', 'I18N'), array( 'color' => 'Color', 'face' => 'Text', // extremely broad, we should 'size' => 'Text', // tighten it ) ); $this->addElement( 'menu', 'Block', 'Required: li', 'Common', array( 'compact' => 'Bool#compact' ) ); $s = $this->addElement('s', 'Inline', 'Inline', 'Common'); $s->formatting = true; $strike = $this->addElement('strike', 'Inline', 'Inline', 'Common'); $strike->formatting = true; $u = $this->addElement('u', 'Inline', 'Inline', 'Common'); $u->formatting = true; // setup modifications to old elements $align = 'Enum#left,right,center,justify'; $address = $this->addBlankElement('address'); $address->content_model = 'Inline | #PCDATA | p'; $address->content_model_type = 'optional'; $address->child = false; $blockquote = $this->addBlankElement('blockquote'); $blockquote->content_model = 'Flow | #PCDATA'; $blockquote->content_model_type = 'optional'; $blockquote->child = false; $br = $this->addBlankElement('br'); $br->attr['clear'] = 'Enum#left,all,right,none'; $caption = $this->addBlankElement('caption'); $caption->attr['align'] = 'Enum#top,bottom,left,right'; $div = $this->addBlankElement('div'); $div->attr['align'] = $align; $dl = $this->addBlankElement('dl'); $dl->attr['compact'] = 'Bool#compact'; for ($i = 1; $i <= 6; $i++) { $h = $this->addBlankElement("h$i"); $h->attr['align'] = $align; } $hr = $this->addBlankElement('hr'); $hr->attr['align'] = $align; $hr->attr['noshade'] = 'Bool#noshade'; $hr->attr['size'] = 'Pixels'; $hr->attr['width'] = 'Length'; $img = $this->addBlankElement('img'); $img->attr['align'] = 'IAlign'; $img->attr['border'] = 'Pixels'; $img->attr['hspace'] = 'Pixels'; $img->attr['vspace'] = 'Pixels'; // figure out this integer business $li = $this->addBlankElement('li'); $li->attr['value'] = new HTMLPurifier_AttrDef_Integer(); $li->attr['type'] = 'Enum#s:1,i,I,a,A,disc,square,circle'; $ol = $this->addBlankElement('ol'); $ol->attr['compact'] = 'Bool#compact'; $ol->attr['start'] = new HTMLPurifier_AttrDef_Integer(); $ol->attr['type'] = 'Enum#s:1,i,I,a,A'; $p = $this->addBlankElement('p'); $p->attr['align'] = $align; $pre = $this->addBlankElement('pre'); $pre->attr['width'] = 'Number'; // script omitted $table = $this->addBlankElement('table'); $table->attr['align'] = 'Enum#left,center,right'; $table->attr['bgcolor'] = 'Color'; $tr = $this->addBlankElement('tr'); $tr->attr['bgcolor'] = 'Color'; $th = $this->addBlankElement('th'); $th->attr['bgcolor'] = 'Color'; $th->attr['height'] = 'Length'; $th->attr['nowrap'] = 'Bool#nowrap'; $th->attr['width'] = 'Length'; $td = $this->addBlankElement('td'); $td->attr['bgcolor'] = 'Color'; $td->attr['height'] = 'Length'; $td->attr['nowrap'] = 'Bool#nowrap'; $td->attr['width'] = 'Length'; $ul = $this->addBlankElement('ul'); $ul->attr['compact'] = 'Bool#compact'; $ul->attr['type'] = 'Enum#square,disc,circle'; // "safe" modifications to "unsafe" elements // WARNING: If you want to add support for an unsafe, legacy // attribute, make a new TrustedLegacy module with the trusted // bit set appropriately $form = $this->addBlankElement('form'); $form->content_model = 'Flow | #PCDATA'; $form->content_model_type = 'optional'; $form->attr['target'] = 'FrameTarget'; $input = $this->addBlankElement('input'); $input->attr['align'] = 'IAlign'; $legend = $this->addBlankElement('legend'); $legend->attr['align'] = 'LAlign'; } } /** * XHTML 1.1 List Module, defines list-oriented elements. Core Module. */ class HTMLPurifier_HTMLModule_List extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'List'; // According to the abstract schema, the List content set is a fully formed // one or more expr, but it invariably occurs in an optional declaration // so we're not going to do that subtlety. It might cause trouble // if a user defines "List" and expects that multiple lists are // allowed to be specified, but then again, that's not very intuitive. // Furthermore, the actual XML Schema may disagree. Regardless, // we don't have support for such nested expressions without using // the incredibly inefficient and draconic Custom ChildDef. /** * @type array */ public $content_sets = array('Flow' => 'List'); /** * @param HTMLPurifier_Config $config */ public function setup($config) { $ol = $this->addElement('ol', 'List', new HTMLPurifier_ChildDef_List(), 'Common'); $ul = $this->addElement('ul', 'List', new HTMLPurifier_ChildDef_List(), 'Common'); // XXX The wrap attribute is handled by MakeWellFormed. This is all // quite unsatisfactory, because we generated this // *specifically* for lists, and now a big chunk of the handling // is done properly by the List ChildDef. So actually, we just // want enough information to make autoclosing work properly, // and then hand off the tricky stuff to the ChildDef. $ol->wrap = 'li'; $ul->wrap = 'li'; $this->addElement('dl', 'List', 'Required: dt | dd', 'Common'); $this->addElement('li', false, 'Flow', 'Common'); $this->addElement('dd', false, 'Flow', 'Common'); $this->addElement('dt', false, 'Inline', 'Common'); } } class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Name'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $elements = array('a', 'applet', 'form', 'frame', 'iframe', 'img', 'map'); foreach ($elements as $name) { $element = $this->addBlankElement($name); $element->attr['name'] = 'CDATA'; if (!$config->get('HTML.Attr.Name.UseCDATA')) { $element->attr_transform_post[] = new HTMLPurifier_AttrTransform_NameSync(); } } } } /** * Module adds the nofollow attribute transformation to a tags. It * is enabled by HTML.Nofollow */ class HTMLPurifier_HTMLModule_Nofollow extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Nofollow'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $a = $this->addBlankElement('a'); $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_Nofollow(); } } class HTMLPurifier_HTMLModule_NonXMLCommonAttributes extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'NonXMLCommonAttributes'; /** * @type array */ public $attr_collections = array( 'Lang' => array( 'lang' => 'LanguageCode', ) ); } /** * XHTML 1.1 Object Module, defines elements for generic object inclusion * @warning Users will commonly use <embed> to cater to legacy browsers: this * module does not allow this sort of behavior */ class HTMLPurifier_HTMLModule_Object extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Object'; /** * @type bool */ public $safe = false; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->addElement( 'object', 'Inline', 'Optional: #PCDATA | Flow | param', 'Common', array( 'archive' => 'URI', 'classid' => 'URI', 'codebase' => 'URI', 'codetype' => 'Text', 'data' => 'URI', 'declare' => 'Bool#declare', 'height' => 'Length', 'name' => 'CDATA', 'standby' => 'Text', 'tabindex' => 'Number', 'type' => 'ContentType', 'width' => 'Length' ) ); $this->addElement( 'param', false, 'Empty', null, array( 'id' => 'ID', 'name*' => 'Text', 'type' => 'Text', 'value' => 'Text', 'valuetype' => 'Enum#data,ref,object' ) ); } } /** * XHTML 1.1 Presentation Module, defines simple presentation-related * markup. Text Extension Module. * @note The official XML Schema and DTD specs further divide this into * two modules: * - Block Presentation (hr) * - Inline Presentation (b, big, i, small, sub, sup, tt) * We have chosen not to heed this distinction, as content_sets * provides satisfactory disambiguation. */ class HTMLPurifier_HTMLModule_Presentation extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Presentation'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->addElement('hr', 'Block', 'Empty', 'Common'); $this->addElement('sub', 'Inline', 'Inline', 'Common'); $this->addElement('sup', 'Inline', 'Inline', 'Common'); $b = $this->addElement('b', 'Inline', 'Inline', 'Common'); $b->formatting = true; $big = $this->addElement('big', 'Inline', 'Inline', 'Common'); $big->formatting = true; $i = $this->addElement('i', 'Inline', 'Inline', 'Common'); $i->formatting = true; $small = $this->addElement('small', 'Inline', 'Inline', 'Common'); $small->formatting = true; $tt = $this->addElement('tt', 'Inline', 'Inline', 'Common'); $tt->formatting = true; } } /** * Module defines proprietary tags and attributes in HTML. * @warning If this module is enabled, standards-compliance is off! */ class HTMLPurifier_HTMLModule_Proprietary extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Proprietary'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->addElement( 'marquee', 'Inline', 'Flow', 'Common', array( 'direction' => 'Enum#left,right,up,down', 'behavior' => 'Enum#alternate', 'width' => 'Length', 'height' => 'Length', 'scrolldelay' => 'Number', 'scrollamount' => 'Number', 'loop' => 'Number', 'bgcolor' => 'Color', 'hspace' => 'Pixels', 'vspace' => 'Pixels', ) ); } } /** * XHTML 1.1 Ruby Annotation Module, defines elements that indicate * short runs of text alongside base text for annotation or pronounciation. */ class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Ruby'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->addElement( 'ruby', 'Inline', 'Custom: ((rb, (rt | (rp, rt, rp))) | (rbc, rtc, rtc?))', 'Common' ); $this->addElement('rbc', false, 'Required: rb', 'Common'); $this->addElement('rtc', false, 'Required: rt', 'Common'); $rb = $this->addElement('rb', false, 'Inline', 'Common'); $rb->excludes = array('ruby' => true); $rt = $this->addElement('rt', false, 'Inline', 'Common', array('rbspan' => 'Number')); $rt->excludes = array('ruby' => true); $this->addElement('rp', false, 'Optional: #PCDATA', 'Common'); } } /** * A "safe" embed module. See SafeObject. This is a proprietary element. */ class HTMLPurifier_HTMLModule_SafeEmbed extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'SafeEmbed'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $max = $config->get('HTML.MaxImgLength'); $embed = $this->addElement( 'embed', 'Inline', 'Empty', 'Common', array( 'src*' => 'URI#embedded', 'type' => 'Enum#application/x-shockwave-flash', 'width' => 'Pixels#' . $max, 'height' => 'Pixels#' . $max, 'allowscriptaccess' => 'Enum#never', 'allownetworking' => 'Enum#internal', 'flashvars' => 'Text', 'wmode' => 'Enum#window,transparent,opaque', 'name' => 'ID', ) ); $embed->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeEmbed(); } } /** * A "safe" object module. In theory, objects permitted by this module will * be safe, and untrusted users can be allowed to embed arbitrary flash objects * (maybe other types too, but only Flash is supported as of right now). * Highly experimental. */ class HTMLPurifier_HTMLModule_SafeObject extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'SafeObject'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { // These definitions are not intrinsically safe: the attribute transforms // are a vital part of ensuring safety. $max = $config->get('HTML.MaxImgLength'); $object = $this->addElement( 'object', 'Inline', 'Optional: param | Flow | #PCDATA', 'Common', array( // While technically not required by the spec, we're forcing // it to this value. 'type' => 'Enum#application/x-shockwave-flash', 'width' => 'Pixels#' . $max, 'height' => 'Pixels#' . $max, 'data' => 'URI#embedded', 'codebase' => new HTMLPurifier_AttrDef_Enum( array( 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0' ) ), ) ); $object->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeObject(); $param = $this->addElement( 'param', false, 'Empty', false, array( 'id' => 'ID', 'name*' => 'Text', 'value' => 'Text' ) ); $param->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeParam(); $this->info_injector[] = 'SafeObject'; } } /** * A "safe" script module. No inline JS is allowed, and pointed to JS * files must match whitelist. */ class HTMLPurifier_HTMLModule_SafeScripting extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'SafeScripting'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { // These definitions are not intrinsically safe: the attribute transforms // are a vital part of ensuring safety. $allowed = $config->get('HTML.SafeScripting'); $script = $this->addElement( 'script', 'Inline', 'Empty', null, array( // While technically not required by the spec, we're forcing // it to this value. 'type' => 'Enum#text/javascript', 'src*' => new HTMLPurifier_AttrDef_Enum(array_keys($allowed)) ) ); $script->attr_transform_pre[] = $script->attr_transform_post[] = new HTMLPurifier_AttrTransform_ScriptRequired(); } } /* WARNING: THIS MODULE IS EXTREMELY DANGEROUS AS IT ENABLES INLINE SCRIPTING INSIDE HTML PURIFIER DOCUMENTS. USE ONLY WITH TRUSTED USER INPUT!!! */ /** * XHTML 1.1 Scripting module, defines elements that are used to contain * information pertaining to executable scripts or the lack of support * for executable scripts. * @note This module does not contain inline scripting elements */ class HTMLPurifier_HTMLModule_Scripting extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Scripting'; /** * @type array */ public $elements = array('script', 'noscript'); /** * @type array */ public $content_sets = array('Block' => 'script | noscript', 'Inline' => 'script | noscript'); /** * @type bool */ public $safe = false; /** * @param HTMLPurifier_Config $config */ public function setup($config) { // TODO: create custom child-definition for noscript that // auto-wraps stray #PCDATA in a similar manner to // blockquote's custom definition (we would use it but // blockquote's contents are optional while noscript's contents // are required) // TODO: convert this to new syntax, main problem is getting // both content sets working // In theory, this could be safe, but I don't see any reason to // allow it. $this->info['noscript'] = new HTMLPurifier_ElementDef(); $this->info['noscript']->attr = array(0 => array('Common')); $this->info['noscript']->content_model = 'Heading | List | Block'; $this->info['noscript']->content_model_type = 'required'; $this->info['script'] = new HTMLPurifier_ElementDef(); $this->info['script']->attr = array( 'defer' => new HTMLPurifier_AttrDef_Enum(array('defer')), 'src' => new HTMLPurifier_AttrDef_URI(true), 'type' => new HTMLPurifier_AttrDef_Enum(array('text/javascript')) ); $this->info['script']->content_model = '#PCDATA'; $this->info['script']->content_model_type = 'optional'; $this->info['script']->attr_transform_pre[] = $this->info['script']->attr_transform_post[] = new HTMLPurifier_AttrTransform_ScriptRequired(); } } /** * XHTML 1.1 Edit Module, defines editing-related elements. Text Extension * Module. */ class HTMLPurifier_HTMLModule_StyleAttribute extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'StyleAttribute'; /** * @type array */ public $attr_collections = array( // The inclusion routine differs from the Abstract Modules but // is in line with the DTD and XML Schemas. 'Style' => array('style' => false), // see constructor 'Core' => array(0 => array('Style')) ); /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->attr_collections['Style']['style'] = new HTMLPurifier_AttrDef_CSS(); } } /** * XHTML 1.1 Tables Module, fully defines accessible table elements. */ class HTMLPurifier_HTMLModule_Tables extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Tables'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $this->addElement('caption', false, 'Inline', 'Common'); $this->addElement( 'table', 'Block', new HTMLPurifier_ChildDef_Table(), 'Common', array( 'border' => 'Pixels', 'cellpadding' => 'Length', 'cellspacing' => 'Length', 'frame' => 'Enum#void,above,below,hsides,lhs,rhs,vsides,box,border', 'rules' => 'Enum#none,groups,rows,cols,all', 'summary' => 'Text', 'width' => 'Length' ) ); // common attributes $cell_align = array( 'align' => 'Enum#left,center,right,justify,char', 'charoff' => 'Length', 'valign' => 'Enum#top,middle,bottom,baseline', ); $cell_t = array_merge( array( 'abbr' => 'Text', 'colspan' => 'Number', 'rowspan' => 'Number', // Apparently, as of HTML5 this attribute only applies // to 'th' elements. 'scope' => 'Enum#row,col,rowgroup,colgroup', ), $cell_align ); $this->addElement('td', false, 'Flow', 'Common', $cell_t); $this->addElement('th', false, 'Flow', 'Common', $cell_t); $this->addElement('tr', false, 'Required: td | th', 'Common', $cell_align); $cell_col = array_merge( array( 'span' => 'Number', 'width' => 'MultiLength', ), $cell_align ); $this->addElement('col', false, 'Empty', 'Common', $cell_col); $this->addElement('colgroup', false, 'Optional: col', 'Common', $cell_col); $this->addElement('tbody', false, 'Required: tr', 'Common', $cell_align); $this->addElement('thead', false, 'Required: tr', 'Common', $cell_align); $this->addElement('tfoot', false, 'Required: tr', 'Common', $cell_align); } } /** * XHTML 1.1 Target Module, defines target attribute in link elements. */ class HTMLPurifier_HTMLModule_Target extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Target'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $elements = array('a'); foreach ($elements as $name) { $e = $this->addBlankElement($name); $e->attr = array( 'target' => new HTMLPurifier_AttrDef_HTML_FrameTarget() ); } } } /** * Module adds the target=blank attribute transformation to a tags. It * is enabled by HTML.TargetBlank */ class HTMLPurifier_HTMLModule_TargetBlank extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'TargetBlank'; /** * @param HTMLPurifier_Config $config */ public function setup($config) { $a = $this->addBlankElement('a'); $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_TargetBlank(); } } /** * XHTML 1.1 Text Module, defines basic text containers. Core Module. * @note In the normative XML Schema specification, this module * is further abstracted into the following modules: * - Block Phrasal (address, blockquote, pre, h1, h2, h3, h4, h5, h6) * - Block Structural (div, p) * - Inline Phrasal (abbr, acronym, cite, code, dfn, em, kbd, q, samp, strong, var) * - Inline Structural (br, span) * This module, functionally, does not distinguish between these * sub-modules, but the code is internally structured to reflect * these distinctions. */ class HTMLPurifier_HTMLModule_Text extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'Text'; /** * @type array */ public $content_sets = array( 'Flow' => 'Heading | Block | Inline' ); /** * @param HTMLPurifier_Config $config */ public function setup($config) { // Inline Phrasal ------------------------------------------------- $this->addElement('abbr', 'Inline', 'Inline', 'Common'); $this->addElement('acronym', 'Inline', 'Inline', 'Common'); $this->addElement('cite', 'Inline', 'Inline', 'Common'); $this->addElement('dfn', 'Inline', 'Inline', 'Common'); $this->addElement('kbd', 'Inline', 'Inline', 'Common'); $this->addElement('q', 'Inline', 'Inline', 'Common', array('cite' => 'URI')); $this->addElement('samp', 'Inline', 'Inline', 'Common'); $this->addElement('var', 'Inline', 'Inline', 'Common'); $em = $this->addElement('em', 'Inline', 'Inline', 'Common'); $em->formatting = true; $strong = $this->addElement('strong', 'Inline', 'Inline', 'Common'); $strong->formatting = true; $code = $this->addElement('code', 'Inline', 'Inline', 'Common'); $code->formatting = true; // Inline Structural ---------------------------------------------- $this->addElement('span', 'Inline', 'Inline', 'Common'); $this->addElement('br', 'Inline', 'Empty', 'Core'); // Block Phrasal -------------------------------------------------- $this->addElement('address', 'Block', 'Inline', 'Common'); $this->addElement('blockquote', 'Block', 'Optional: Heading | Block | List', 'Common', array('cite' => 'URI')); $pre = $this->addElement('pre', 'Block', 'Inline', 'Common'); $pre->excludes = $this->makeLookup( 'img', 'big', 'small', 'object', 'applet', 'font', 'basefont' ); $this->addElement('h1', 'Heading', 'Inline', 'Common'); $this->addElement('h2', 'Heading', 'Inline', 'Common'); $this->addElement('h3', 'Heading', 'Inline', 'Common'); $this->addElement('h4', 'Heading', 'Inline', 'Common'); $this->addElement('h5', 'Heading', 'Inline', 'Common'); $this->addElement('h6', 'Heading', 'Inline', 'Common'); // Block Structural ----------------------------------------------- $p = $this->addElement('p', 'Block', 'Inline', 'Common'); $p->autoclose = array_flip( array("address", "blockquote", "center", "dir", "div", "dl", "fieldset", "ol", "p", "ul") ); $this->addElement('div', 'Block', 'Flow', 'Common'); } } /** * Abstract class for a set of proprietary modules that clean up (tidy) * poorly written HTML. * @todo Figure out how to protect some of these methods/properties */ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule { /** * List of supported levels. * Index zero is a special case "no fixes" level. * @type array */ public $levels = array(0 => 'none', 'light', 'medium', 'heavy'); /** * Default level to place all fixes in. * Disabled by default. * @type string */ public $defaultLevel = null; /** * Lists of fixes used by getFixesForLevel(). * Format is: * HTMLModule_Tidy->fixesForLevel[$level] = array('fix-1', 'fix-2'); * @type array */ public $fixesForLevel = array( 'light' => array(), 'medium' => array(), 'heavy' => array() ); /** * Lazy load constructs the module by determining the necessary * fixes to create and then delegating to the populate() function. * @param HTMLPurifier_Config $config * @todo Wildcard matching and error reporting when an added or * subtracted fix has no effect. */ public function setup($config) { // create fixes, initialize fixesForLevel $fixes = $this->makeFixes(); $this->makeFixesForLevel($fixes); // figure out which fixes to use $level = $config->get('HTML.TidyLevel'); $fixes_lookup = $this->getFixesForLevel($level); // get custom fix declarations: these need namespace processing $add_fixes = $config->get('HTML.TidyAdd'); $remove_fixes = $config->get('HTML.TidyRemove'); foreach ($fixes as $name => $fix) { // needs to be refactored a little to implement globbing if (isset($remove_fixes[$name]) || (!isset($add_fixes[$name]) && !isset($fixes_lookup[$name]))) { unset($fixes[$name]); } } // populate this module with necessary fixes $this->populate($fixes); } /** * Retrieves all fixes per a level, returning fixes for that specific * level as well as all levels below it. * @param string $level level identifier, see $levels for valid values * @return array Lookup up table of fixes */ public function getFixesForLevel($level) { if ($level == $this->levels[0]) { return array(); } $activated_levels = array(); for ($i = 1, $c = count($this->levels); $i < $c; $i++) { $activated_levels[] = $this->levels[$i]; if ($this->levels[$i] == $level) { break; } } if ($i == $c) { trigger_error( 'Tidy level ' . htmlspecialchars($level) . ' not recognized', E_USER_WARNING ); return array(); } $ret = array(); foreach ($activated_levels as $level) { foreach ($this->fixesForLevel[$level] as $fix) { $ret[$fix] = true; } } return $ret; } /** * Dynamically populates the $fixesForLevel member variable using * the fixes array. It may be custom overloaded, used in conjunction * with $defaultLevel, or not used at all. * @param array $fixes */ public function makeFixesForLevel($fixes) { if (!isset($this->defaultLevel)) { return; } if (!isset($this->fixesForLevel[$this->defaultLevel])) { trigger_error( 'Default level ' . $this->defaultLevel . ' does not exist', E_USER_ERROR ); return; } $this->fixesForLevel[$this->defaultLevel] = array_keys($fixes); } /** * Populates the module with transforms and other special-case code * based on a list of fixes passed to it * @param array $fixes Lookup table of fixes to activate */ public function populate($fixes) { foreach ($fixes as $name => $fix) { // determine what the fix is for list($type, $params) = $this->getFixType($name); switch ($type) { case 'attr_transform_pre': case 'attr_transform_post': $attr = $params['attr']; if (isset($params['element'])) { $element = $params['element']; if (empty($this->info[$element])) { $e = $this->addBlankElement($element); } else { $e = $this->info[$element]; } } else { $type = "info_$type"; $e = $this; } // PHP does some weird parsing when I do // $e->$type[$attr], so I have to assign a ref. $f =& $e->$type; $f[$attr] = $fix; break; case 'tag_transform': $this->info_tag_transform[$params['element']] = $fix; break; case 'child': case 'content_model_type': $element = $params['element']; if (empty($this->info[$element])) { $e = $this->addBlankElement($element); } else { $e = $this->info[$element]; } $e->$type = $fix; break; default: trigger_error("Fix type $type not supported", E_USER_ERROR); break; } } } /** * Parses a fix name and determines what kind of fix it is, as well * as other information defined by the fix * @param $name String name of fix * @return array(string $fix_type, array $fix_parameters) * @note $fix_parameters is type dependant, see populate() for usage * of these parameters */ public function getFixType($name) { // parse it $property = $attr = null; if (strpos($name, '#') !== false) { list($name, $property) = explode('#', $name); } if (strpos($name, '@') !== false) { list($name, $attr) = explode('@', $name); } // figure out the parameters $params = array(); if ($name !== '') { $params['element'] = $name; } if (!is_null($attr)) { $params['attr'] = $attr; } // special case: attribute transform if (!is_null($attr)) { if (is_null($property)) { $property = 'pre'; } $type = 'attr_transform_' . $property; return array($type, $params); } // special case: tag transform if (is_null($property)) { return array('tag_transform', $params); } return array($property, $params); } /** * Defines all fixes the module will perform in a compact * associative array of fix name to fix implementation. * @return array */ public function makeFixes() { } } class HTMLPurifier_HTMLModule_XMLCommonAttributes extends HTMLPurifier_HTMLModule { /** * @type string */ public $name = 'XMLCommonAttributes'; /** * @type array */ public $attr_collections = array( 'Lang' => array( 'xml:lang' => 'LanguageCode', ) ); } /** * Name is deprecated, but allowed in strict doctypes, so onl */ class HTMLPurifier_HTMLModule_Tidy_Name extends HTMLPurifier_HTMLModule_Tidy { /** * @type string */ public $name = 'Tidy_Name'; /** * @type string */ public $defaultLevel = 'heavy'; /** * @return array */ public function makeFixes() { $r = array(); // @name for img, a ----------------------------------------------- // Technically, it's allowed even on strict, so we allow authors to use // it. However, it's deprecated in future versions of XHTML. $r['img@name'] = $r['a@name'] = new HTMLPurifier_AttrTransform_Name(); return $r; } } class HTMLPurifier_HTMLModule_Tidy_Proprietary extends HTMLPurifier_HTMLModule_Tidy { /** * @type string */ public $name = 'Tidy_Proprietary'; /** * @type string */ public $defaultLevel = 'light'; /** * @return array */ public function makeFixes() { $r = array(); $r['table@background'] = new HTMLPurifier_AttrTransform_Background(); $r['td@background'] = new HTMLPurifier_AttrTransform_Background(); $r['th@background'] = new HTMLPurifier_AttrTransform_Background(); $r['tr@background'] = new HTMLPurifier_AttrTransform_Background(); $r['thead@background'] = new HTMLPurifier_AttrTransform_Background(); $r['tfoot@background'] = new HTMLPurifier_AttrTransform_Background(); $r['tbody@background'] = new HTMLPurifier_AttrTransform_Background(); $r['table@height'] = new HTMLPurifier_AttrTransform_Length('height'); return $r; } } class HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 extends HTMLPurifier_HTMLModule_Tidy { /** * @return array */ public function makeFixes() { $r = array(); // == deprecated tag transforms =================================== $r['font'] = new HTMLPurifier_TagTransform_Font(); $r['menu'] = new HTMLPurifier_TagTransform_Simple('ul'); $r['dir'] = new HTMLPurifier_TagTransform_Simple('ul'); $r['center'] = new HTMLPurifier_TagTransform_Simple('div', 'text-align:center;'); $r['u'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration:underline;'); $r['s'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration:line-through;'); $r['strike'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration:line-through;'); // == deprecated attribute transforms ============================= $r['caption@align'] = new HTMLPurifier_AttrTransform_EnumToCSS( 'align', array( // we're following IE's behavior, not Firefox's, due // to the fact that no one supports caption-side:right, // W3C included (with CSS 2.1). This is a slightly // unreasonable attribute! 'left' => 'text-align:left;', 'right' => 'text-align:right;', 'top' => 'caption-side:top;', 'bottom' => 'caption-side:bottom;' // not supported by IE ) ); // @align for img ------------------------------------------------- $r['img@align'] = new HTMLPurifier_AttrTransform_EnumToCSS( 'align', array( 'left' => 'float:left;', 'right' => 'float:right;', 'top' => 'vertical-align:top;', 'middle' => 'vertical-align:middle;', 'bottom' => 'vertical-align:baseline;', ) ); // @align for table ----------------------------------------------- $r['table@align'] = new HTMLPurifier_AttrTransform_EnumToCSS( 'align', array( 'left' => 'float:left;', 'center' => 'margin-left:auto;margin-right:auto;', 'right' => 'float:right;' ) ); // @align for hr ----------------------------------------------- $r['hr@align'] = new HTMLPurifier_AttrTransform_EnumToCSS( 'align', array( // we use both text-align and margin because these work // for different browsers (IE and Firefox, respectively) // and the melange makes for a pretty cross-compatible // solution 'left' => 'margin-left:0;margin-right:auto;text-align:left;', 'center' => 'margin-left:auto;margin-right:auto;text-align:center;', 'right' => 'margin-left:auto;margin-right:0;text-align:right;' ) ); // @align for h1, h2, h3, h4, h5, h6, p, div ---------------------- // {{{ $align_lookup = array(); $align_values = array('left', 'right', 'center', 'justify'); foreach ($align_values as $v) { $align_lookup[$v] = "text-align:$v;"; } // }}} $r['h1@align'] = $r['h2@align'] = $r['h3@align'] = $r['h4@align'] = $r['h5@align'] = $r['h6@align'] = $r['p@align'] = $r['div@align'] = new HTMLPurifier_AttrTransform_EnumToCSS('align', $align_lookup); // @bgcolor for table, tr, td, th --------------------------------- $r['table@bgcolor'] = $r['td@bgcolor'] = $r['th@bgcolor'] = new HTMLPurifier_AttrTransform_BgColor(); // @border for img ------------------------------------------------ $r['img@border'] = new HTMLPurifier_AttrTransform_Border(); // @clear for br -------------------------------------------------- $r['br@clear'] = new HTMLPurifier_AttrTransform_EnumToCSS( 'clear', array( 'left' => 'clear:left;', 'right' => 'clear:right;', 'all' => 'clear:both;', 'none' => 'clear:none;', ) ); // @height for td, th --------------------------------------------- $r['td@height'] = $r['th@height'] = new HTMLPurifier_AttrTransform_Length('height'); // @hspace for img ------------------------------------------------ $r['img@hspace'] = new HTMLPurifier_AttrTransform_ImgSpace('hspace'); // @noshade for hr ------------------------------------------------ // this transformation is not precise but often good enough. // different browsers use different styles to designate noshade $r['hr@noshade'] = new HTMLPurifier_AttrTransform_BoolToCSS( 'noshade', 'color:#808080;background-color:#808080;border:0;' ); // @nowrap for td, th --------------------------------------------- $r['td@nowrap'] = $r['th@nowrap'] = new HTMLPurifier_AttrTransform_BoolToCSS( 'nowrap', 'white-space:nowrap;' ); // @size for hr -------------------------------------------------- $r['hr@size'] = new HTMLPurifier_AttrTransform_Length('size', 'height'); // @type for li, ol, ul ------------------------------------------- // {{{ $ul_types = array( 'disc' => 'list-style-type:disc;', 'square' => 'list-style-type:square;', 'circle' => 'list-style-type:circle;' ); $ol_types = array( '1' => 'list-style-type:decimal;', 'i' => 'list-style-type:lower-roman;', 'I' => 'list-style-type:upper-roman;', 'a' => 'list-style-type:lower-alpha;', 'A' => 'list-style-type:upper-alpha;' ); $li_types = $ul_types + $ol_types; // }}} $r['ul@type'] = new HTMLPurifier_AttrTransform_EnumToCSS('type', $ul_types); $r['ol@type'] = new HTMLPurifier_AttrTransform_EnumToCSS('type', $ol_types, true); $r['li@type'] = new HTMLPurifier_AttrTransform_EnumToCSS('type', $li_types, true); // @vspace for img ------------------------------------------------ $r['img@vspace'] = new HTMLPurifier_AttrTransform_ImgSpace('vspace'); // @width for hr, td, th ------------------------------------------ $r['td@width'] = $r['th@width'] = $r['hr@width'] = new HTMLPurifier_AttrTransform_Length('width'); return $r; } } class HTMLPurifier_HTMLModule_Tidy_Strict extends HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 { /** * @type string */ public $name = 'Tidy_Strict'; /** * @type string */ public $defaultLevel = 'light'; /** * @return array */ public function makeFixes() { $r = parent::makeFixes(); $r['blockquote#content_model_type'] = 'strictblockquote'; return $r; } /** * @type bool */ public $defines_child_def = true; /** * @param HTMLPurifier_ElementDef $def * @return HTMLPurifier_ChildDef_StrictBlockquote */ public function getChildDef($def) { if ($def->content_model_type != 'strictblockquote') { return parent::getChildDef($def); } return new HTMLPurifier_ChildDef_StrictBlockquote($def->content_model); } } class HTMLPurifier_HTMLModule_Tidy_Transitional extends HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 { /** * @type string */ public $name = 'Tidy_Transitional'; /** * @type string */ public $defaultLevel = 'heavy'; } class HTMLPurifier_HTMLModule_Tidy_XHTML extends HTMLPurifier_HTMLModule_Tidy { /** * @type string */ public $name = 'Tidy_XHTML'; /** * @type string */ public $defaultLevel = 'medium'; /** * @return array */ public function makeFixes() { $r = array(); $r['@lang'] = new HTMLPurifier_AttrTransform_Lang(); return $r; } } /** * Injector that auto paragraphs text in the root node based on * double-spacing. * @todo Ensure all states are unit tested, including variations as well. * @todo Make a graph of the flow control for this Injector. */ class HTMLPurifier_Injector_AutoParagraph extends HTMLPurifier_Injector { /** * @type string */ public $name = 'AutoParagraph'; /** * @type array */ public $needed = array('p'); /** * @return HTMLPurifier_Token_Start */ private function _pStart() { $par = new HTMLPurifier_Token_Start('p'); $par->armor['MakeWellFormed_TagClosedError'] = true; return $par; } /** * @param HTMLPurifier_Token_Text $token */ public function handleText(&$token) { $text = $token->data; // Does the current parent allow <p> tags? if ($this->allowsElement('p')) { if (empty($this->currentNesting) || strpos($text, "\n\n") !== false) { // Note that we have differing behavior when dealing with text // in the anonymous root node, or a node inside the document. // If the text as a double-newline, the treatment is the same; // if it doesn't, see the next if-block if you're in the document. $i = $nesting = null; if (!$this->forwardUntilEndToken($i, $current, $nesting) && $token->is_whitespace) { // State 1.1: ... ^ (whitespace, then document end) // ---- // This is a degenerate case } else { if (!$token->is_whitespace || $this->_isInline($current)) { // State 1.2: PAR1 // ---- // State 1.3: PAR1\n\nPAR2 // ------------ // State 1.4: <div>PAR1\n\nPAR2 (see State 2) // ------------ $token = array($this->_pStart()); $this->_splitText($text, $token); } else { // State 1.5: \n<hr /> // -- } } } else { // State 2: <div>PAR1... (similar to 1.4) // ---- // We're in an element that allows paragraph tags, but we're not // sure if we're going to need them. if ($this->_pLookAhead()) { // State 2.1: <div>PAR1<b>PAR1\n\nPAR2 // ---- // Note: This will always be the first child, since any // previous inline element would have triggered this very // same routine, and found the double newline. One possible // exception would be a comment. $token = array($this->_pStart(), $token); } else { // State 2.2.1: <div>PAR1<div> // ---- // State 2.2.2: <div>PAR1<b>PAR1</b></div> // ---- } } // Is the current parent a <p> tag? } elseif (!empty($this->currentNesting) && $this->currentNesting[count($this->currentNesting) - 1]->name == 'p') { // State 3.1: ...<p>PAR1 // ---- // State 3.2: ...<p>PAR1\n\nPAR2 // ------------ $token = array(); $this->_splitText($text, $token); // Abort! } else { // State 4.1: ...<b>PAR1 // ---- // State 4.2: ...<b>PAR1\n\nPAR2 // ------------ } } /** * @param HTMLPurifier_Token $token */ public function handleElement(&$token) { // We don't have to check if we're already in a <p> tag for block // tokens, because the tag would have been autoclosed by MakeWellFormed. if ($this->allowsElement('p')) { if (!empty($this->currentNesting)) { if ($this->_isInline($token)) { // State 1: <div>...<b> // --- // Check if this token is adjacent to the parent token // (seek backwards until token isn't whitespace) $i = null; $this->backward($i, $prev); if (!$prev instanceof HTMLPurifier_Token_Start) { // Token wasn't adjacent if ($prev instanceof HTMLPurifier_Token_Text && substr($prev->data, -2) === "\n\n" ) { // State 1.1.4: <div><p>PAR1</p>\n\n<b> // --- // Quite frankly, this should be handled by splitText $token = array($this->_pStart(), $token); } else { // State 1.1.1: <div><p>PAR1</p><b> // --- // State 1.1.2: <div><br /><b> // --- // State 1.1.3: <div>PAR<b> // --- } } else { // State 1.2.1: <div><b> // --- // Lookahead to see if <p> is needed. if ($this->_pLookAhead()) { // State 1.3.1: <div><b>PAR1\n\nPAR2 // --- $token = array($this->_pStart(), $token); } else { // State 1.3.2: <div><b>PAR1</b></div> // --- // State 1.3.3: <div><b>PAR1</b><div></div>\n\n</div> // --- } } } else { // State 2.3: ...<div> // ----- } } else { if ($this->_isInline($token)) { // State 3.1: <b> // --- // This is where the {p} tag is inserted, not reflected in // inputTokens yet, however. $token = array($this->_pStart(), $token); } else { // State 3.2: <div> // ----- } $i = null; if ($this->backward($i, $prev)) { if (!$prev instanceof HTMLPurifier_Token_Text) { // State 3.1.1: ...</p>{p}<b> // --- // State 3.2.1: ...</p><div> // ----- if (!is_array($token)) { $token = array($token); } array_unshift($token, new HTMLPurifier_Token_Text("\n\n")); } else { // State 3.1.2: ...</p>\n\n{p}<b> // --- // State 3.2.2: ...</p>\n\n<div> // ----- // Note: PAR<ELEM> cannot occur because PAR would have been // wrapped in <p> tags. } } } } else { // State 2.2: <ul><li> // ---- // State 2.4: <p><b> // --- } } /** * Splits up a text in paragraph tokens and appends them * to the result stream that will replace the original * @param string $data String text data that will be processed * into paragraphs * @param HTMLPurifier_Token[] $result Reference to array of tokens that the * tags will be appended onto */ private function _splitText($data, &$result) { $raw_paragraphs = explode("\n\n", $data); $paragraphs = array(); // without empty paragraphs $needs_start = false; $needs_end = false; $c = count($raw_paragraphs); if ($c == 1) { // There were no double-newlines, abort quickly. In theory this // should never happen. $result[] = new HTMLPurifier_Token_Text($data); return; } for ($i = 0; $i < $c; $i++) { $par = $raw_paragraphs[$i]; if (trim($par) !== '') { $paragraphs[] = $par; } else { if ($i == 0) { // Double newline at the front if (empty($result)) { // The empty result indicates that the AutoParagraph // injector did not add any start paragraph tokens. // This means that we have been in a paragraph for // a while, and the newline means we should start a new one. $result[] = new HTMLPurifier_Token_End('p'); $result[] = new HTMLPurifier_Token_Text("\n\n"); // However, the start token should only be added if // there is more processing to be done (i.e. there are // real paragraphs in here). If there are none, the // next start paragraph tag will be handled by the // next call to the injector $needs_start = true; } else { // We just started a new paragraph! // Reinstate a double-newline for presentation's sake, since // it was in the source code. array_unshift($result, new HTMLPurifier_Token_Text("\n\n")); } } elseif ($i + 1 == $c) { // Double newline at the end // There should be a trailing </p> when we're finally done. $needs_end = true; } } } // Check if this was just a giant blob of whitespace. Move this earlier, // perhaps? if (empty($paragraphs)) { return; } // Add the start tag indicated by \n\n at the beginning of $data if ($needs_start) { $result[] = $this->_pStart(); } // Append the paragraphs onto the result foreach ($paragraphs as $par) { $result[] = new HTMLPurifier_Token_Text($par); $result[] = new HTMLPurifier_Token_End('p'); $result[] = new HTMLPurifier_Token_Text("\n\n"); $result[] = $this->_pStart(); } // Remove trailing start token; Injector will handle this later if // it was indeed needed. This prevents from needing to do a lookahead, // at the cost of a lookbehind later. array_pop($result); // If there is no need for an end tag, remove all of it and let // MakeWellFormed close it later. if (!$needs_end) { array_pop($result); // removes \n\n array_pop($result); // removes </p> } } /** * Returns true if passed token is inline (and, ergo, allowed in * paragraph tags) * @param HTMLPurifier_Token $token * @return bool */ private function _isInline($token) { return isset($this->htmlDefinition->info['p']->child->elements[$token->name]); } /** * Looks ahead in the token list and determines whether or not we need * to insert a <p> tag. * @return bool */ private function _pLookAhead() { if ($this->currentToken instanceof HTMLPurifier_Token_Start) { $nesting = 1; } else { $nesting = 0; } $ok = false; $i = null; while ($this->forwardUntilEndToken($i, $current, $nesting)) { $result = $this->_checkNeedsP($current); if ($result !== null) { $ok = $result; break; } } return $ok; } /** * Determines if a particular token requires an earlier inline token * to get a paragraph. This should be used with _forwardUntilEndToken * @param HTMLPurifier_Token $current * @return bool */ private function _checkNeedsP($current) { if ($current instanceof HTMLPurifier_Token_Start) { if (!$this->_isInline($current)) { // <div>PAR1<div> // ---- // Terminate early, since we hit a block element return false; } } elseif ($current instanceof HTMLPurifier_Token_Text) { if (strpos($current->data, "\n\n") !== false) { // <div>PAR1<b>PAR1\n\nPAR2 // ---- return true; } else { // <div>PAR1<b>PAR1... // ---- } } return null; } } /** * Injector that displays the URL of an anchor instead of linking to it, in addition to showing the text of the link. */ class HTMLPurifier_Injector_DisplayLinkURI extends HTMLPurifier_Injector { /** * @type string */ public $name = 'DisplayLinkURI'; /** * @type array */ public $needed = array('a'); /** * @param $token */ public function handleElement(&$token) { } /** * @param HTMLPurifier_Token $token */ public function handleEnd(&$token) { if (isset($token->start->attr['href'])) { $url = $token->start->attr['href']; unset($token->start->attr['href']); $token = array($token, new HTMLPurifier_Token_Text(" ($url)")); } else { // nothing to display } } } /** * Injector that converts http, https and ftp text URLs to actual links. */ class HTMLPurifier_Injector_Linkify extends HTMLPurifier_Injector { /** * @type string */ public $name = 'Linkify'; /** * @type array */ public $needed = array('a' => array('href')); /** * @param HTMLPurifier_Token $token */ public function handleText(&$token) { if (!$this->allowsElement('a')) { return; } if (strpos($token->data, '://') === false) { // our really quick heuristic failed, abort // this may not work so well if we want to match things like // "google.com", but then again, most people don't return; } // there is/are URL(s). Let's split the string: // Note: this regex is extremely permissive $bits = preg_split('#((?:https?|ftp)://[^\s\'",<>()]+)#Su', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE); $token = array(); // $i = index // $c = count // $l = is link for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) { if (!$l) { if ($bits[$i] === '') { continue; } $token[] = new HTMLPurifier_Token_Text($bits[$i]); } else { $token[] = new HTMLPurifier_Token_Start('a', array('href' => $bits[$i])); $token[] = new HTMLPurifier_Token_Text($bits[$i]); $token[] = new HTMLPurifier_Token_End('a'); } } } } /** * Injector that converts configuration directive syntax %Namespace.Directive * to links */ class HTMLPurifier_Injector_PurifierLinkify extends HTMLPurifier_Injector { /** * @type string */ public $name = 'PurifierLinkify'; /** * @type string */ public $docURL; /** * @type array */ public $needed = array('a' => array('href')); /** * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ public function prepare($config, $context) { $this->docURL = $config->get('AutoFormat.PurifierLinkify.DocURL'); return parent::prepare($config, $context); } /** * @param HTMLPurifier_Token $token */ public function handleText(&$token) { if (!$this->allowsElement('a')) { return; } if (strpos($token->data, '%') === false) { return; } $bits = preg_split('#%([a-z0-9]+\.[a-z0-9]+)#Si', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE); $token = array(); // $i = index // $c = count // $l = is link for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) { if (!$l) { if ($bits[$i] === '') { continue; } $token[] = new HTMLPurifier_Token_Text($bits[$i]); } else { $token[] = new HTMLPurifier_Token_Start( 'a', array('href' => str_replace('%s', $bits[$i], $this->docURL)) ); $token[] = new HTMLPurifier_Token_Text('%' . $bits[$i]); $token[] = new HTMLPurifier_Token_End('a'); } } } } class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector { /** * @type HTMLPurifier_Context */ private $context; /** * @type HTMLPurifier_Config */ private $config; /** * @type HTMLPurifier_AttrValidator */ private $attrValidator; /** * @type bool */ private $removeNbsp; /** * @type bool */ private $removeNbspExceptions; /** * @type array * TODO: make me configurable */ private $_exclude = array('colgroup' => 1, 'th' => 1, 'td' => 1, 'iframe' => 1); /** * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return void */ public function prepare($config, $context) { parent::prepare($config, $context); $this->config = $config; $this->context = $context; $this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp'); $this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions'); $this->attrValidator = new HTMLPurifier_AttrValidator(); } /** * @param HTMLPurifier_Token $token */ public function handleElement(&$token) { if (!$token instanceof HTMLPurifier_Token_Start) { return; } $next = false; $deleted = 1; // the current tag for ($i = count($this->inputZipper->back) - 1; $i >= 0; $i--, $deleted++) { $next = $this->inputZipper->back[$i]; if ($next instanceof HTMLPurifier_Token_Text) { if ($next->is_whitespace) { continue; } if ($this->removeNbsp && !isset($this->removeNbspExceptions[$token->name])) { $plain = str_replace("\xC2\xA0", "", $next->data); $isWsOrNbsp = $plain === '' || ctype_space($plain); if ($isWsOrNbsp) { continue; } } } break; } if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) { if (isset($this->_exclude[$token->name])) { return; } $this->attrValidator->validateToken($token, $this->config, $this->context); $token->armor['ValidateAttributes'] = true; if (isset($token->attr['id']) || isset($token->attr['name'])) { return; } $token = $deleted + 1; for ($b = 0, $c = count($this->inputZipper->front); $b < $c; $b++) { $prev = $this->inputZipper->front[$b]; if ($prev instanceof HTMLPurifier_Token_Text && $prev->is_whitespace) { continue; } break; } // This is safe because we removed the token that triggered this. $this->rewindOffset($b+$deleted); return; } } } /** * Injector that removes spans with no attributes */ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_Injector { /** * @type string */ public $name = 'RemoveSpansWithoutAttributes'; /** * @type array */ public $needed = array('span'); /** * @type HTMLPurifier_AttrValidator */ private $attrValidator; /** * Used by AttrValidator. * @type HTMLPurifier_Config */ private $config; /** * @type HTMLPurifier_Context */ private $context; public function prepare($config, $context) { $this->attrValidator = new HTMLPurifier_AttrValidator(); $this->config = $config; $this->context = $context; return parent::prepare($config, $context); } /** * @param HTMLPurifier_Token $token */ public function handleElement(&$token) { if ($token->name !== 'span' || !$token instanceof HTMLPurifier_Token_Start) { return; } // We need to validate the attributes now since this doesn't normally // happen until after MakeWellFormed. If all the attributes are removed // the span needs to be removed too. $this->attrValidator->validateToken($token, $this->config, $this->context); $token->armor['ValidateAttributes'] = true; if (!empty($token->attr)) { return; } $nesting = 0; while ($this->forwardUntilEndToken($i, $current, $nesting)) { } if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') { // Mark closing span tag for deletion $current->markForDeletion = true; // Delete open span tag $token = false; } } /** * @param HTMLPurifier_Token $token */ public function handleEnd(&$token) { if ($token->markForDeletion) { $token = false; } } } /** * Adds important param elements to inside of object in order to make * things safe. */ class HTMLPurifier_Injector_SafeObject extends HTMLPurifier_Injector { /** * @type string */ public $name = 'SafeObject'; /** * @type array */ public $needed = array('object', 'param'); /** * @type array */ protected $objectStack = array(); /** * @type array */ protected $paramStack = array(); /** * Keep this synchronized with AttrTransform/SafeParam.php. * @type array */ protected $addParam = array( 'allowScriptAccess' => 'never', 'allowNetworking' => 'internal', ); /** * @type array */ protected $allowedParam = array( 'wmode' => true, 'movie' => true, 'flashvars' => true, 'src' => true, 'allowFullScreen' => true, // if omitted, assume to be 'false' ); /** * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return void */ public function prepare($config, $context) { parent::prepare($config, $context); } /** * @param HTMLPurifier_Token $token */ public function handleElement(&$token) { if ($token->name == 'object') { $this->objectStack[] = $token; $this->paramStack[] = array(); $new = array($token); foreach ($this->addParam as $name => $value) { $new[] = new HTMLPurifier_Token_Empty('param', array('name' => $name, 'value' => $value)); } $token = $new; } elseif ($token->name == 'param') { $nest = count($this->currentNesting) - 1; if ($nest >= 0 && $this->currentNesting[$nest]->name === 'object') { $i = count($this->objectStack) - 1; if (!isset($token->attr['name'])) { $token = false; return; } $n = $token->attr['name']; // We need this fix because YouTube doesn't supply a data // attribute, which we need if a type is specified. This is // *very* Flash specific. if (!isset($this->objectStack[$i]->attr['data']) && ($token->attr['name'] == 'movie' || $token->attr['name'] == 'src') ) { $this->objectStack[$i]->attr['data'] = $token->attr['value']; } // Check if the parameter is the correct value but has not // already been added if (!isset($this->paramStack[$i][$n]) && isset($this->addParam[$n]) && $token->attr['name'] === $this->addParam[$n]) { // keep token, and add to param stack $this->paramStack[$i][$n] = true; } elseif (isset($this->allowedParam[$n])) { // keep token, don't do anything to it // (could possibly check for duplicates here) } else { $token = false; } } else { // not directly inside an object, DENY! $token = false; } } } public function handleEnd(&$token) { // This is the WRONG way of handling the object and param stacks; // we should be inserting them directly on the relevant object tokens // so that the global stack handling handles it. if ($token->name == 'object') { array_pop($this->objectStack); array_pop($this->paramStack); } } } /** * Parser that uses PHP 5's DOM extension (part of the core). * * In PHP 5, the DOM XML extension was revamped into DOM and added to the core. * It gives us a forgiving HTML parser, which we use to transform the HTML * into a DOM, and then into the tokens. It is blazingly fast (for large * documents, it performs twenty times faster than * HTMLPurifier_Lexer_DirectLex,and is the default choice for PHP 5. * * @note Any empty elements will have empty tokens associated with them, even if * this is prohibited by the spec. This is cannot be fixed until the spec * comes into play. * * @note PHP's DOM extension does not actually parse any entities, we use * our own function to do that. * * @warning DOM tends to drop whitespace, which may wreak havoc on indenting. * If this is a huge problem, due to the fact that HTML is hand * edited and you are unable to get a parser cache that caches the * the output of HTML Purifier while keeping the original HTML lying * around, you may want to run Tidy on the resulting output or use * HTMLPurifier_DirectLex */ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer { /** * @type HTMLPurifier_TokenFactory */ private $factory; public function __construct() { // setup the factory parent::__construct(); $this->factory = new HTMLPurifier_TokenFactory(); } /** * @param string $html * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token[] */ public function tokenizeHTML($html, $config, $context) { $html = $this->normalize($html, $config, $context); // attempt to armor stray angled brackets that cannot possibly // form tags and thus are probably being used as emoticons if ($config->get('Core.AggressivelyFixLt')) { $char = '[^a-z!\/]'; $comment = "/<!--(.*?)(-->|\z)/is"; $html = preg_replace_callback($comment, array($this, 'callbackArmorCommentEntities'), $html); do { $old = $html; $html = preg_replace("/<($char)/i", '<\\1', $html); } while ($html !== $old); $html = preg_replace_callback($comment, array($this, 'callbackUndoCommentSubst'), $html); // fix comments } // preprocess html, essential for UTF-8 $html = $this->wrapHTML($html, $config, $context); $doc = new DOMDocument(); $doc->encoding = 'UTF-8'; // theoretically, the above has this covered set_error_handler(array($this, 'muteErrorHandler')); $doc->loadHTML($html); restore_error_handler(); $tokens = array(); $this->tokenizeDOM( $doc->getElementsByTagName('html')->item(0)-> // <html> getElementsByTagName('body')->item(0)-> // <body> getElementsByTagName('div')->item(0), // <div> $tokens ); return $tokens; } /** * Iterative function that tokenizes a node, putting it into an accumulator. * To iterate is human, to recurse divine - L. Peter Deutsch * @param DOMNode $node DOMNode to be tokenized. * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. * @return HTMLPurifier_Token of node appended to previously passed tokens. */ protected function tokenizeDOM($node, &$tokens) { $level = 0; $nodes = array($level => new HTMLPurifier_Queue(array($node))); $closingNodes = array(); do { while (!$nodes[$level]->isEmpty()) { $node = $nodes[$level]->shift(); // FIFO $collect = $level > 0 ? true : false; $needEndingTag = $this->createStartNode($node, $tokens, $collect); if ($needEndingTag) { $closingNodes[$level][] = $node; } if ($node->childNodes && $node->childNodes->length) { $level++; $nodes[$level] = new HTMLPurifier_Queue(); foreach ($node->childNodes as $childNode) { $nodes[$level]->push($childNode); } } } $level--; if ($level && isset($closingNodes[$level])) { while ($node = array_pop($closingNodes[$level])) { $this->createEndNode($node, $tokens); } } } while ($level > 0); } /** * @param DOMNode $node DOMNode to be tokenized. * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. * @param bool $collect Says whether or start and close are collected, set to * false at first recursion because it's the implicit DIV * tag you're dealing with. * @return bool if the token needs an endtoken * @todo data and tagName properties don't seem to exist in DOMNode? */ protected function createStartNode($node, &$tokens, $collect) { // intercept non element nodes. WE MUST catch all of them, // but we're not getting the character reference nodes because // those should have been preprocessed if ($node->nodeType === XML_TEXT_NODE) { $tokens[] = $this->factory->createText($node->data); return false; } elseif ($node->nodeType === XML_CDATA_SECTION_NODE) { // undo libxml's special treatment of <script> and <style> tags $last = end($tokens); $data = $node->data; // (note $node->tagname is already normalized) if ($last instanceof HTMLPurifier_Token_Start && ($last->name == 'script' || $last->name == 'style')) { $new_data = trim($data); if (substr($new_data, 0, 4) === '<!--') { $data = substr($new_data, 4); if (substr($data, -3) === '-->') { $data = substr($data, 0, -3); } else { // Highly suspicious! Not sure what to do... } } } $tokens[] = $this->factory->createText($this->parseData($data)); return false; } elseif ($node->nodeType === XML_COMMENT_NODE) { // this is code is only invoked for comments in script/style in versions // of libxml pre-2.6.28 (regular comments, of course, are still // handled regularly) $tokens[] = $this->factory->createComment($node->data); return false; } elseif ($node->nodeType !== XML_ELEMENT_NODE) { // not-well tested: there may be other nodes we have to grab return false; } $attr = $node->hasAttributes() ? $this->transformAttrToAssoc($node->attributes) : array(); // We still have to make sure that the element actually IS empty if (!$node->childNodes->length) { if ($collect) { $tokens[] = $this->factory->createEmpty($node->tagName, $attr); } return false; } else { if ($collect) { $tokens[] = $this->factory->createStart( $tag_name = $node->tagName, // somehow, it get's dropped $attr ); } return true; } } /** * @param DOMNode $node * @param HTMLPurifier_Token[] $tokens */ protected function createEndNode($node, &$tokens) { $tokens[] = $this->factory->createEnd($node->tagName); } /** * Converts a DOMNamedNodeMap of DOMAttr objects into an assoc array. * * @param DOMNamedNodeMap $node_map DOMNamedNodeMap of DOMAttr objects. * @return array Associative array of attributes. */ protected function transformAttrToAssoc($node_map) { // NamedNodeMap is documented very well, so we're using undocumented // features, namely, the fact that it implements Iterator and // has a ->length attribute if ($node_map->length === 0) { return array(); } $array = array(); foreach ($node_map as $attr) { $array[$attr->name] = $attr->value; } return $array; } /** * An error handler that mutes all errors * @param int $errno * @param string $errstr */ public function muteErrorHandler($errno, $errstr) { } /** * Callback function for undoing escaping of stray angled brackets * in comments * @param array $matches * @return string */ public function callbackUndoCommentSubst($matches) { return '<!--' . strtr($matches[1], array('&' => '&', '<' => '<')) . $matches[2]; } /** * Callback function that entity-izes ampersands in comments so that * callbackUndoCommentSubst doesn't clobber them * @param array $matches * @return string */ public function callbackArmorCommentEntities($matches) { return '<!--' . str_replace('&', '&', $matches[1]) . $matches[2]; } /** * Wraps an HTML fragment in the necessary HTML * @param string $html * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ protected function wrapHTML($html, $config, $context) { $def = $config->getDefinition('HTML'); $ret = ''; if (!empty($def->doctype->dtdPublic) || !empty($def->doctype->dtdSystem)) { $ret .= '<!DOCTYPE html '; if (!empty($def->doctype->dtdPublic)) { $ret .= 'PUBLIC "' . $def->doctype->dtdPublic . '" '; } if (!empty($def->doctype->dtdSystem)) { $ret .= '"' . $def->doctype->dtdSystem . '" '; } $ret .= '>'; } $ret .= '<html><head>'; $ret .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'; // No protection if $html contains a stray </div>! $ret .= '</head><body><div>' . $html . '</div></body></html>'; return $ret; } } /** * Our in-house implementation of a parser. * * A pure PHP parser, DirectLex has absolutely no dependencies, making * it a reasonably good default for PHP4. Written with efficiency in mind, * it can be four times faster than HTMLPurifier_Lexer_PEARSax3, although it * pales in comparison to HTMLPurifier_Lexer_DOMLex. * * @todo Reread XML spec and document differences. */ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer { /** * @type bool */ public $tracksLineNumbers = true; /** * Whitespace characters for str(c)spn. * @type string */ protected $_whitespace = "\x20\x09\x0D\x0A"; /** * Callback function for script CDATA fudge * @param array $matches, in form of array(opening tag, contents, closing tag) * @return string */ protected function scriptCallback($matches) { return $matches[1] . htmlspecialchars($matches[2], ENT_COMPAT, 'UTF-8') . $matches[3]; } /** * @param String $html * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array|HTMLPurifier_Token[] */ public function tokenizeHTML($html, $config, $context) { // special normalization for script tags without any armor // our "armor" heurstic is a < sign any number of whitespaces after // the first script tag if ($config->get('HTML.Trusted')) { $html = preg_replace_callback( '#(<script[^>]*>)(\s*[^<].+?)(</script>)#si', array($this, 'scriptCallback'), $html ); } $html = $this->normalize($html, $config, $context); $cursor = 0; // our location in the text $inside_tag = false; // whether or not we're parsing the inside of a tag $array = array(); // result array // This is also treated to mean maintain *column* numbers too $maintain_line_numbers = $config->get('Core.MaintainLineNumbers'); if ($maintain_line_numbers === null) { // automatically determine line numbering by checking // if error collection is on $maintain_line_numbers = $config->get('Core.CollectErrors'); } if ($maintain_line_numbers) { $current_line = 1; $current_col = 0; $length = strlen($html); } else { $current_line = false; $current_col = false; $length = false; } $context->register('CurrentLine', $current_line); $context->register('CurrentCol', $current_col); $nl = "\n"; // how often to manually recalculate. This will ALWAYS be right, // but it's pretty wasteful. Set to 0 to turn off $synchronize_interval = $config->get('Core.DirectLexLineNumberSyncInterval'); $e = false; if ($config->get('Core.CollectErrors')) { $e =& $context->get('ErrorCollector'); } // for testing synchronization $loops = 0; while (++$loops) { // $cursor is either at the start of a token, or inside of // a tag (i.e. there was a < immediately before it), as indicated // by $inside_tag if ($maintain_line_numbers) { // $rcursor, however, is always at the start of a token. $rcursor = $cursor - (int)$inside_tag; // Column number is cheap, so we calculate it every round. // We're interested at the *end* of the newline string, so // we need to add strlen($nl) == 1 to $nl_pos before subtracting it // from our "rcursor" position. $nl_pos = strrpos($html, $nl, $rcursor - $length); $current_col = $rcursor - (is_bool($nl_pos) ? 0 : $nl_pos + 1); // recalculate lines if ($synchronize_interval && // synchronization is on $cursor > 0 && // cursor is further than zero $loops % $synchronize_interval === 0) { // time to synchronize! $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor); } } $position_next_lt = strpos($html, '<', $cursor); $position_next_gt = strpos($html, '>', $cursor); // triggers on "<b>asdf</b>" but not "asdf <b></b>" // special case to set up context if ($position_next_lt === $cursor) { $inside_tag = true; $cursor++; } if (!$inside_tag && $position_next_lt !== false) { // We are not inside tag and there still is another tag to parse $token = new HTMLPurifier_Token_Text( $this->parseData( substr( $html, $cursor, $position_next_lt - $cursor ) ) ); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor); } $array[] = $token; $cursor = $position_next_lt + 1; $inside_tag = true; continue; } elseif (!$inside_tag) { // We are not inside tag but there are no more tags // If we're already at the end, break if ($cursor === strlen($html)) { break; } // Create Text of rest of string $token = new HTMLPurifier_Token_Text( $this->parseData( substr( $html, $cursor ) ) ); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); } $array[] = $token; break; } elseif ($inside_tag && $position_next_gt !== false) { // We are in tag and it is well formed // Grab the internals of the tag $strlen_segment = $position_next_gt - $cursor; if ($strlen_segment < 1) { // there's nothing to process! $token = new HTMLPurifier_Token_Text('<'); $cursor++; continue; } $segment = substr($html, $cursor, $strlen_segment); if ($segment === false) { // somehow, we attempted to access beyond the end of // the string, defense-in-depth, reported by Nate Abele break; } // Check if it's a comment if (substr($segment, 0, 3) === '!--') { // re-determine segment length, looking for --> $position_comment_end = strpos($html, '-->', $cursor); if ($position_comment_end === false) { // uh oh, we have a comment that extends to // infinity. Can't be helped: set comment // end position to end of string if ($e) { $e->send(E_WARNING, 'Lexer: Unclosed comment'); } $position_comment_end = strlen($html); $end = true; } else { $end = false; } $strlen_segment = $position_comment_end - $cursor; $segment = substr($html, $cursor, $strlen_segment); $token = new HTMLPurifier_Token_Comment( substr( $segment, 3, $strlen_segment - 3 ) ); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment); } $array[] = $token; $cursor = $end ? $position_comment_end : $position_comment_end + 3; $inside_tag = false; continue; } // Check if it's an end tag $is_end_tag = (strpos($segment, '/') === 0); if ($is_end_tag) { $type = substr($segment, 1); $token = new HTMLPurifier_Token_End($type); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); } $array[] = $token; $inside_tag = false; $cursor = $position_next_gt + 1; continue; } // Check leading character is alnum, if not, we may // have accidently grabbed an emoticon. Translate into // text and go our merry way if (!ctype_alpha($segment[0])) { // XML: $segment[0] !== '_' && $segment[0] !== ':' if ($e) { $e->send(E_NOTICE, 'Lexer: Unescaped lt'); } $token = new HTMLPurifier_Token_Text('<'); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); } $array[] = $token; $inside_tag = false; continue; } // Check if it is explicitly self closing, if so, remove // trailing slash. Remember, we could have a tag like <br>, so // any later token processing scripts must convert improperly // classified EmptyTags from StartTags. $is_self_closing = (strrpos($segment, '/') === $strlen_segment - 1); if ($is_self_closing) { $strlen_segment--; $segment = substr($segment, 0, $strlen_segment); } // Check if there are any attributes $position_first_space = strcspn($segment, $this->_whitespace); if ($position_first_space >= $strlen_segment) { if ($is_self_closing) { $token = new HTMLPurifier_Token_Empty($segment); } else { $token = new HTMLPurifier_Token_Start($segment); } if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); } $array[] = $token; $inside_tag = false; $cursor = $position_next_gt + 1; continue; } // Grab out all the data $type = substr($segment, 0, $position_first_space); $attribute_string = trim( substr( $segment, $position_first_space ) ); if ($attribute_string) { $attr = $this->parseAttributeString( $attribute_string, $config, $context ); } else { $attr = array(); } if ($is_self_closing) { $token = new HTMLPurifier_Token_Empty($type, $attr); } else { $token = new HTMLPurifier_Token_Start($type, $attr); } if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); } $array[] = $token; $cursor = $position_next_gt + 1; $inside_tag = false; continue; } else { // inside tag, but there's no ending > sign if ($e) { $e->send(E_WARNING, 'Lexer: Missing gt'); } $token = new HTMLPurifier_Token_Text( '<' . $this->parseData( substr($html, $cursor) ) ); if ($maintain_line_numbers) { $token->rawPosition($current_line, $current_col); } // no cursor scroll? Hmm... $array[] = $token; break; } break; } $context->destroy('CurrentLine'); $context->destroy('CurrentCol'); return $array; } /** * PHP 5.0.x compatible substr_count that implements offset and length * @param string $haystack * @param string $needle * @param int $offset * @param int $length * @return int */ protected function substrCount($haystack, $needle, $offset, $length) { static $oldVersion; if ($oldVersion === null) { $oldVersion = version_compare(PHP_VERSION, '5.1', '<'); } if ($oldVersion) { $haystack = substr($haystack, $offset, $length); return substr_count($haystack, $needle); } else { return substr_count($haystack, $needle, $offset, $length); } } /** * Takes the inside of an HTML tag and makes an assoc array of attributes. * * @param string $string Inside of tag excluding name. * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array Assoc array of attributes. */ public function parseAttributeString($string, $config, $context) { $string = (string)$string; // quick typecast if ($string == '') { return array(); } // no attributes $e = false; if ($config->get('Core.CollectErrors')) { $e =& $context->get('ErrorCollector'); } // let's see if we can abort as quickly as possible // one equal sign, no spaces => one attribute $num_equal = substr_count($string, '='); $has_space = strpos($string, ' '); if ($num_equal === 0 && !$has_space) { // bool attribute return array($string => $string); } elseif ($num_equal === 1 && !$has_space) { // only one attribute list($key, $quoted_value) = explode('=', $string); $quoted_value = trim($quoted_value); if (!$key) { if ($e) { $e->send(E_ERROR, 'Lexer: Missing attribute key'); } return array(); } if (!$quoted_value) { return array($key => ''); } $first_char = @$quoted_value[0]; $last_char = @$quoted_value[strlen($quoted_value) - 1]; $same_quote = ($first_char == $last_char); $open_quote = ($first_char == '"' || $first_char == "'"); if ($same_quote && $open_quote) { // well behaved $value = substr($quoted_value, 1, strlen($quoted_value) - 2); } else { // not well behaved if ($open_quote) { if ($e) { $e->send(E_ERROR, 'Lexer: Missing end quote'); } $value = substr($quoted_value, 1); } else { $value = $quoted_value; } } if ($value === false) { $value = ''; } return array($key => $this->parseData($value)); } // setup loop environment $array = array(); // return assoc array of attributes $cursor = 0; // current position in string (moves forward) $size = strlen($string); // size of the string (stays the same) // if we have unquoted attributes, the parser expects a terminating // space, so let's guarantee that there's always a terminating space. $string .= ' '; $old_cursor = -1; while ($cursor < $size) { if ($old_cursor >= $cursor) { throw new Exception("Infinite loop detected"); } $old_cursor = $cursor; $cursor += ($value = strspn($string, $this->_whitespace, $cursor)); // grab the key $key_begin = $cursor; //we're currently at the start of the key // scroll past all characters that are the key (not whitespace or =) $cursor += strcspn($string, $this->_whitespace . '=', $cursor); $key_end = $cursor; // now at the end of the key $key = substr($string, $key_begin, $key_end - $key_begin); if (!$key) { if ($e) { $e->send(E_ERROR, 'Lexer: Missing attribute key'); } $cursor += 1 + strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop continue; // empty key } // scroll past all whitespace $cursor += strspn($string, $this->_whitespace, $cursor); if ($cursor >= $size) { $array[$key] = $key; break; } // if the next character is an equal sign, we've got a regular // pair, otherwise, it's a bool attribute $first_char = @$string[$cursor]; if ($first_char == '=') { // key="value" $cursor++; $cursor += strspn($string, $this->_whitespace, $cursor); if ($cursor === false) { $array[$key] = ''; break; } // we might be in front of a quote right now $char = @$string[$cursor]; if ($char == '"' || $char == "'") { // it's quoted, end bound is $char $cursor++; $value_begin = $cursor; $cursor = strpos($string, $char, $cursor); $value_end = $cursor; } else { // it's not quoted, end bound is whitespace $value_begin = $cursor; $cursor += strcspn($string, $this->_whitespace, $cursor); $value_end = $cursor; } // we reached a premature end if ($cursor === false) { $cursor = $size; $value_end = $cursor; } $value = substr($string, $value_begin, $value_end - $value_begin); if ($value === false) { $value = ''; } $array[$key] = $this->parseData($value); $cursor++; } else { // boolattr if ($key !== '') { $array[$key] = $key; } else { // purely theoretical if ($e) { $e->send(E_ERROR, 'Lexer: Missing attribute key'); } } } } return $array; } } /** * Concrete comment node class. */ class HTMLPurifier_Node_Comment extends HTMLPurifier_Node { /** * Character data within comment. * @type string */ public $data; /** * @type bool */ public $is_whitespace = true; /** * Transparent constructor. * * @param string $data String comment data. * @param int $line * @param int $col */ public function __construct($data, $line = null, $col = null) { $this->data = $data; $this->line = $line; $this->col = $col; } public function toTokenPair() { return array(new HTMLPurifier_Token_Comment($this->data, $this->line, $this->col), null); } } /** * Concrete element node class. */ class HTMLPurifier_Node_Element extends HTMLPurifier_Node { /** * The lower-case name of the tag, like 'a', 'b' or 'blockquote'. * * @note Strictly speaking, XML tags are case sensitive, so we shouldn't * be lower-casing them, but these tokens cater to HTML tags, which are * insensitive. * @type string */ public $name; /** * Associative array of the node's attributes. * @type array */ public $attr = array(); /** * List of child elements. * @type array */ public $children = array(); /** * Does this use the <a></a> form or the </a> form, i.e. * is it a pair of start/end tokens or an empty token. * @bool */ public $empty = false; public $endCol = null, $endLine = null, $endArmor = array(); public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) { $this->name = $name; $this->attr = $attr; $this->line = $line; $this->col = $col; $this->armor = $armor; } public function toTokenPair() { // XXX inefficiency here, normalization is not necessary if ($this->empty) { return array(new HTMLPurifier_Token_Empty($this->name, $this->attr, $this->line, $this->col, $this->armor), null); } else { $start = new HTMLPurifier_Token_Start($this->name, $this->attr, $this->line, $this->col, $this->armor); $end = new HTMLPurifier_Token_End($this->name, array(), $this->endLine, $this->endCol, $this->endArmor); //$end->start = $start; return array($start, $end); } } } /** * Concrete text token class. * * Text tokens comprise of regular parsed character data (PCDATA) and raw * character data (from the CDATA sections). Internally, their * data is parsed with all entities expanded. Surprisingly, the text token * does have a "tag name" called #PCDATA, which is how the DTD represents it * in permissible child nodes. */ class HTMLPurifier_Node_Text extends HTMLPurifier_Node { /** * PCDATA tag name compatible with DTD, see * HTMLPurifier_ChildDef_Custom for details. * @type string */ public $name = '#PCDATA'; /** * @type string */ public $data; /**< Parsed character data of text. */ /** * @type bool */ public $is_whitespace; /**< Bool indicating if node is whitespace. */ /** * Constructor, accepts data and determines if it is whitespace. * @param string $data String parsed character data. * @param int $line * @param int $col */ public function __construct($data, $is_whitespace, $line = null, $col = null) { $this->data = $data; $this->is_whitespace = $is_whitespace; $this->line = $line; $this->col = $col; } public function toTokenPair() { return array(new HTMLPurifier_Token_Text($this->data, $this->line, $this->col), null); } } /** * Composite strategy that runs multiple strategies on tokens. */ abstract class HTMLPurifier_Strategy_Composite extends HTMLPurifier_Strategy { /** * List of strategies to run tokens through. * @type HTMLPurifier_Strategy[] */ protected $strategies = array(); /** * @param HTMLPurifier_Token[] $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token[] */ public function execute($tokens, $config, $context) { foreach ($this->strategies as $strategy) { $tokens = $strategy->execute($tokens, $config, $context); } return $tokens; } } /** * Core strategy composed of the big four strategies. */ class HTMLPurifier_Strategy_Core extends HTMLPurifier_Strategy_Composite { public function __construct() { $this->strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements(); $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed(); $this->strategies[] = new HTMLPurifier_Strategy_FixNesting(); $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes(); } } /** * Takes a well formed list of tokens and fixes their nesting. * * HTML elements dictate which elements are allowed to be their children, * for example, you can't have a p tag in a span tag. Other elements have * much more rigorous definitions: tables, for instance, require a specific * order for their elements. There are also constraints not expressible by * document type definitions, such as the chameleon nature of ins/del * tags and global child exclusions. * * The first major objective of this strategy is to iterate through all * the nodes and determine whether or not their children conform to the * element's definition. If they do not, the child definition may * optionally supply an amended list of elements that is valid or * require that the entire node be deleted (and the previous node * rescanned). * * The second objective is to ensure that explicitly excluded elements of * an element do not appear in its children. Code that accomplishes this * task is pervasive through the strategy, though the two are distinct tasks * and could, theoretically, be seperated (although it's not recommended). * * @note Whether or not unrecognized children are silently dropped or * translated into text depends on the child definitions. * * @todo Enable nodes to be bubbled out of the structure. This is * easier with our new algorithm. */ class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy { /** * @param HTMLPurifier_Token[] $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array|HTMLPurifier_Token[] */ public function execute($tokens, $config, $context) { //####################################################################// // Pre-processing // O(n) pass to convert to a tree, so that we can efficiently // refer to substrings $top_node = HTMLPurifier_Arborize::arborize($tokens, $config, $context); // get a copy of the HTML definition $definition = $config->getHTMLDefinition(); $excludes_enabled = !$config->get('Core.DisableExcludes'); // setup the context variable 'IsInline', for chameleon processing // is 'false' when we are not inline, 'true' when it must always // be inline, and an integer when it is inline for a certain // branch of the document tree $is_inline = $definition->info_parent_def->descendants_are_inline; $context->register('IsInline', $is_inline); // setup error collector $e =& $context->get('ErrorCollector', true); //####################################################################// // Loop initialization // stack that contains all elements that are excluded // it is organized by parent elements, similar to $stack, // but it is only populated when an element with exclusions is // processed, i.e. there won't be empty exclusions. $exclude_stack = array($definition->info_parent_def->excludes); // variable that contains the start token while we are processing // nodes. This enables error reporting to do its job $node = $top_node; // dummy token list($token, $d) = $node->toTokenPair(); $context->register('CurrentNode', $node); $context->register('CurrentToken', $token); //####################################################################// // Loop // We need to implement a post-order traversal iteratively, to // avoid running into stack space limits. This is pretty tricky // to reason about, so we just manually stack-ify the recursive // variant: // // function f($node) { // foreach ($node->children as $child) { // f($child); // } // validate($node); // } // // Thus, we will represent a stack frame as array($node, // $is_inline, stack of children) // e.g. array_reverse($node->children) - already processed // children. $parent_def = $definition->info_parent_def; $stack = array( array($top_node, $parent_def->descendants_are_inline, $parent_def->excludes, // exclusions 0) ); while (!empty($stack)) { list($node, $is_inline, $excludes, $ix) = array_pop($stack); // recursive call $go = false; $def = empty($stack) ? $definition->info_parent_def : $definition->info[$node->name]; while (isset($node->children[$ix])) { $child = $node->children[$ix++]; if ($child instanceof HTMLPurifier_Node_Element) { $go = true; $stack[] = array($node, $is_inline, $excludes, $ix); $stack[] = array($child, // ToDo: I don't think it matters if it's def or // child_def, but double check this... $is_inline || $def->descendants_are_inline, empty($def->excludes) ? $excludes : array_merge($excludes, $def->excludes), 0); break; } }; if ($go) continue; list($token, $d) = $node->toTokenPair(); // base case if ($excludes_enabled && isset($excludes[$node->name])) { $node->dead = true; if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node excluded'); } else { // XXX I suppose it would be slightly more efficient to // avoid the allocation here and have children // strategies handle it $children = array(); foreach ($node->children as $child) { if (!$child->dead) $children[] = $child; } $result = $def->child->validateChildren($children, $config, $context); if ($result === true) { // nop $node->children = $children; } elseif ($result === false) { $node->dead = true; if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node removed'); } else { $node->children = $result; if ($e) { // XXX This will miss mutations of internal nodes. Perhaps defer to the child validators if (empty($result) && !empty($children)) { $e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed'); } else if ($result != $children) { $e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized'); } } } } } //####################################################################// // Post-processing // remove context variables $context->destroy('IsInline'); $context->destroy('CurrentNode'); $context->destroy('CurrentToken'); //####################################################################// // Return return HTMLPurifier_Arborize::flatten($node, $config, $context); } } /** * Takes tokens makes them well-formed (balance end tags, etc.) * * Specification of the armor attributes this strategy uses: * * - MakeWellFormed_TagClosedError: This armor field is used to * suppress tag closed errors for certain tokens [TagClosedSuppress], * in particular, if a tag was generated automatically by HTML * Purifier, we may rely on our infrastructure to close it for us * and shouldn't report an error to the user [TagClosedAuto]. */ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy { /** * Array stream of tokens being processed. * @type HTMLPurifier_Token[] */ protected $tokens; /** * Current token. * @type HTMLPurifier_Token */ protected $token; /** * Zipper managing the true state. * @type HTMLPurifier_Zipper */ protected $zipper; /** * Current nesting of elements. * @type array */ protected $stack; /** * Injectors active in this stream processing. * @type HTMLPurifier_Injector[] */ protected $injectors; /** * Current instance of HTMLPurifier_Config. * @type HTMLPurifier_Config */ protected $config; /** * Current instance of HTMLPurifier_Context. * @type HTMLPurifier_Context */ protected $context; /** * @param HTMLPurifier_Token[] $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token[] * @throws HTMLPurifier_Exception */ public function execute($tokens, $config, $context) { $definition = $config->getHTMLDefinition(); // local variables $generator = new HTMLPurifier_Generator($config, $context); $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); // used for autoclose early abortion $global_parent_allowed_elements = $definition->info_parent_def->child->getAllowedElements($config); $e = $context->get('ErrorCollector', true); $i = false; // injector index list($zipper, $token) = HTMLPurifier_Zipper::fromArray($tokens); if ($token === NULL) { return array(); } $reprocess = false; // whether or not to reprocess the same token $stack = array(); // member variables $this->stack =& $stack; $this->tokens =& $tokens; $this->token =& $token; $this->zipper =& $zipper; $this->config = $config; $this->context = $context; // context variables $context->register('CurrentNesting', $stack); $context->register('InputZipper', $zipper); $context->register('CurrentToken', $token); // -- begin INJECTOR -- $this->injectors = array(); $injectors = $config->getBatch('AutoFormat'); $def_injectors = $definition->info_injector; $custom_injectors = $injectors['Custom']; unset($injectors['Custom']); // special case foreach ($injectors as $injector => $b) { // XXX: Fix with a legitimate lookup table of enabled filters if (strpos($injector, '.') !== false) { continue; } $injector = "HTMLPurifier_Injector_$injector"; if (!$b) { continue; } $this->injectors[] = new $injector; } foreach ($def_injectors as $injector) { // assumed to be objects $this->injectors[] = $injector; } foreach ($custom_injectors as $injector) { if (!$injector) { continue; } if (is_string($injector)) { $injector = "HTMLPurifier_Injector_$injector"; $injector = new $injector; } $this->injectors[] = $injector; } // give the injectors references to the definition and context // variables for performance reasons foreach ($this->injectors as $ix => $injector) { $error = $injector->prepare($config, $context); if (!$error) { continue; } array_splice($this->injectors, $ix, 1); // rm the injector trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING); } // -- end INJECTOR -- // a note on reprocessing: // In order to reduce code duplication, whenever some code needs // to make HTML changes in order to make things "correct", the // new HTML gets sent through the purifier, regardless of its // status. This means that if we add a start token, because it // was totally necessary, we don't have to update nesting; we just // punt ($reprocess = true; continue;) and it does that for us. // isset is in loop because $tokens size changes during loop exec for (;; // only increment if we don't need to reprocess $reprocess ? $reprocess = false : $token = $zipper->next($token)) { // check for a rewind if (is_int($i)) { // possibility: disable rewinding if the current token has a // rewind set on it already. This would offer protection from // infinite loop, but might hinder some advanced rewinding. $rewind_offset = $this->injectors[$i]->getRewindOffset(); if (is_int($rewind_offset)) { for ($j = 0; $j < $rewind_offset; $j++) { if (empty($zipper->front)) break; $token = $zipper->prev($token); // indicate that other injectors should not process this token, // but we need to reprocess it unset($token->skip[$i]); $token->rewind = $i; if ($token instanceof HTMLPurifier_Token_Start) { array_pop($this->stack); } elseif ($token instanceof HTMLPurifier_Token_End) { $this->stack[] = $token->start; } } } $i = false; } // handle case of document end if ($token === NULL) { // kill processing if stack is empty if (empty($this->stack)) { break; } // peek $top_nesting = array_pop($this->stack); $this->stack[] = $top_nesting; // send error [TagClosedSuppress] if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) { $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting); } // append, don't splice, since this is the end $token = new HTMLPurifier_Token_End($top_nesting->name); // punt! $reprocess = true; continue; } //echo '<br>'; printZipper($zipper, $token);//printTokens($this->stack); //flush(); // quick-check: if it's not a tag, no need to process if (empty($token->is_tag)) { if ($token instanceof HTMLPurifier_Token_Text) { foreach ($this->injectors as $i => $injector) { if (isset($token->skip[$i])) { continue; } if ($token->rewind !== null && $token->rewind !== $i) { continue; } // XXX fuckup $r = $token; $injector->handleText($r); $token = $this->processToken($r, $i); $reprocess = true; break; } } // another possibility is a comment continue; } if (isset($definition->info[$token->name])) { $type = $definition->info[$token->name]->child->type; } else { $type = false; // Type is unknown, treat accordingly } // quick tag checks: anything that's *not* an end tag $ok = false; if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) { // claims to be a start tag but is empty $token = new HTMLPurifier_Token_Empty( $token->name, $token->attr, $token->line, $token->col, $token->armor ); $ok = true; } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) { // claims to be empty but really is a start tag // NB: this assignment is required $old_token = $token; $token = new HTMLPurifier_Token_End($token->name); $token = $this->insertBefore( new HTMLPurifier_Token_Start($old_token->name, $old_token->attr, $old_token->line, $old_token->col, $old_token->armor) ); // punt (since we had to modify the input stream in a non-trivial way) $reprocess = true; continue; } elseif ($token instanceof HTMLPurifier_Token_Empty) { // real empty token $ok = true; } elseif ($token instanceof HTMLPurifier_Token_Start) { // start tag // ...unless they also have to close their parent if (!empty($this->stack)) { // Performance note: you might think that it's rather // inefficient, recalculating the autoclose information // for every tag that a token closes (since when we // do an autoclose, we push a new token into the // stream and then /process/ that, before // re-processing this token.) But this is // necessary, because an injector can make an // arbitrary transformations to the autoclosing // tokens we introduce, so things may have changed // in the meantime. Also, doing the inefficient thing is // "easy" to reason about (for certain perverse definitions // of "easy") $parent = array_pop($this->stack); $this->stack[] = $parent; $parent_def = null; $parent_elements = null; $autoclose = false; if (isset($definition->info[$parent->name])) { $parent_def = $definition->info[$parent->name]; $parent_elements = $parent_def->child->getAllowedElements($config); $autoclose = !isset($parent_elements[$token->name]); } if ($autoclose && $definition->info[$token->name]->wrap) { // Check if an element can be wrapped by another // element to make it valid in a context (for // example, <ul><ul> needs a <li> in between) $wrapname = $definition->info[$token->name]->wrap; $wrapdef = $definition->info[$wrapname]; $elements = $wrapdef->child->getAllowedElements($config); if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) { $newtoken = new HTMLPurifier_Token_Start($wrapname); $token = $this->insertBefore($newtoken); $reprocess = true; continue; } } $carryover = false; if ($autoclose && $parent_def->formatting) { $carryover = true; } if ($autoclose) { // check if this autoclose is doomed to fail // (this rechecks $parent, which his harmless) $autoclose_ok = isset($global_parent_allowed_elements[$token->name]); if (!$autoclose_ok) { foreach ($this->stack as $ancestor) { $elements = $definition->info[$ancestor->name]->child->getAllowedElements($config); if (isset($elements[$token->name])) { $autoclose_ok = true; break; } if ($definition->info[$token->name]->wrap) { $wrapname = $definition->info[$token->name]->wrap; $wrapdef = $definition->info[$wrapname]; $wrap_elements = $wrapdef->child->getAllowedElements($config); if (isset($wrap_elements[$token->name]) && isset($elements[$wrapname])) { $autoclose_ok = true; break; } } } } if ($autoclose_ok) { // errors need to be updated $new_token = new HTMLPurifier_Token_End($parent->name); $new_token->start = $parent; // [TagClosedSuppress] if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) { if (!$carryover) { $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent); } else { $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent); } } if ($carryover) { $element = clone $parent; // [TagClosedAuto] $element->armor['MakeWellFormed_TagClosedError'] = true; $element->carryover = true; $token = $this->processToken(array($new_token, $token, $element)); } else { $token = $this->insertBefore($new_token); } } else { $token = $this->remove(); } $reprocess = true; continue; } } $ok = true; } if ($ok) { foreach ($this->injectors as $i => $injector) { if (isset($token->skip[$i])) { continue; } if ($token->rewind !== null && $token->rewind !== $i) { continue; } $r = $token; $injector->handleElement($r); $token = $this->processToken($r, $i); $reprocess = true; break; } if (!$reprocess) { // ah, nothing interesting happened; do normal processing if ($token instanceof HTMLPurifier_Token_Start) { $this->stack[] = $token; } elseif ($token instanceof HTMLPurifier_Token_End) { throw new HTMLPurifier_Exception( 'Improper handling of end tag in start code; possible error in MakeWellFormed' ); } } continue; } // sanity check: we should be dealing with a closing tag if (!$token instanceof HTMLPurifier_Token_End) { throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier'); } // make sure that we have something open if (empty($this->stack)) { if ($escape_invalid_tags) { if ($e) { $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text'); } $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token)); } else { if ($e) { $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed'); } $token = $this->remove(); } $reprocess = true; continue; } // first, check for the simplest case: everything closes neatly. // Eventually, everything passes through here; if there are problems // we modify the input stream accordingly and then punt, so that // the tokens get processed again. $current_parent = array_pop($this->stack); if ($current_parent->name == $token->name) { $token->start = $current_parent; foreach ($this->injectors as $i => $injector) { if (isset($token->skip[$i])) { continue; } if ($token->rewind !== null && $token->rewind !== $i) { continue; } $r = $token; $injector->handleEnd($r); $token = $this->processToken($r, $i); $this->stack[] = $current_parent; $reprocess = true; break; } continue; } // okay, so we're trying to close the wrong tag // undo the pop previous pop $this->stack[] = $current_parent; // scroll back the entire nest, trying to find our tag. // (feature could be to specify how far you'd like to go) $size = count($this->stack); // -2 because -1 is the last element, but we already checked that $skipped_tags = false; for ($j = $size - 2; $j >= 0; $j--) { if ($this->stack[$j]->name == $token->name) { $skipped_tags = array_slice($this->stack, $j); break; } } // we didn't find the tag, so remove if ($skipped_tags === false) { if ($escape_invalid_tags) { if ($e) { $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text'); } $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token)); } else { if ($e) { $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed'); } $token = $this->remove(); } $reprocess = true; continue; } // do errors, in REVERSE $j order: a,b,c with </a></b></c> $c = count($skipped_tags); if ($e) { for ($j = $c - 1; $j > 0; $j--) { // notice we exclude $j == 0, i.e. the current ending tag, from // the errors... [TagClosedSuppress] if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) { $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]); } } } // insert tags, in FORWARD $j order: c,b,a with </a></b></c> $replace = array($token); for ($j = 1; $j < $c; $j++) { // ...as well as from the insertions $new_token = new HTMLPurifier_Token_End($skipped_tags[$j]->name); $new_token->start = $skipped_tags[$j]; array_unshift($replace, $new_token); if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) { // [TagClosedAuto] $element = clone $skipped_tags[$j]; $element->carryover = true; $element->armor['MakeWellFormed_TagClosedError'] = true; $replace[] = $element; } } $token = $this->processToken($replace); $reprocess = true; continue; } $context->destroy('CurrentToken'); $context->destroy('CurrentNesting'); $context->destroy('InputZipper'); unset($this->injectors, $this->stack, $this->tokens); return $zipper->toArray($token); } /** * Processes arbitrary token values for complicated substitution patterns. * In general: * * If $token is an array, it is a list of tokens to substitute for the * current token. These tokens then get individually processed. If there * is a leading integer in the list, that integer determines how many * tokens from the stream should be removed. * * If $token is a regular token, it is swapped with the current token. * * If $token is false, the current token is deleted. * * If $token is an integer, that number of tokens (with the first token * being the current one) will be deleted. * * @param HTMLPurifier_Token|array|int|bool $token Token substitution value * @param HTMLPurifier_Injector|int $injector Injector that performed the substitution; default is if * this is not an injector related operation. * @throws HTMLPurifier_Exception */ protected function processToken($token, $injector = -1) { // normalize forms of token if (is_object($token)) { $token = array(1, $token); } if (is_int($token)) { $token = array($token); } if ($token === false) { $token = array(1); } if (!is_array($token)) { throw new HTMLPurifier_Exception('Invalid token type from injector'); } if (!is_int($token[0])) { array_unshift($token, 1); } if ($token[0] === 0) { throw new HTMLPurifier_Exception('Deleting zero tokens is not valid'); } // $token is now an array with the following form: // array(number nodes to delete, new node 1, new node 2, ...) $delete = array_shift($token); list($old, $r) = $this->zipper->splice($this->token, $delete, $token); if ($injector > -1) { // determine appropriate skips $oldskip = isset($old[0]) ? $old[0]->skip : array(); foreach ($token as $object) { $object->skip = $oldskip; $object->skip[$injector] = true; } } return $r; } /** * Inserts a token before the current token. Cursor now points to * this token. You must reprocess after this. * @param HTMLPurifier_Token $token */ private function insertBefore($token) { // NB not $this->zipper->insertBefore(), due to positioning // differences $splice = $this->zipper->splice($this->token, 0, array($token)); return $splice[1]; } /** * Removes current token. Cursor now points to new token occupying previously * occupied space. You must reprocess after this. */ private function remove() { return $this->zipper->delete(); } } /** * Removes all unrecognized tags from the list of tokens. * * This strategy iterates through all the tokens and removes unrecognized * tokens. If a token is not recognized but a TagTransform is defined for * that element, the element will be transformed accordingly. */ class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy { /** * @param HTMLPurifier_Token[] $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return array|HTMLPurifier_Token[] */ public function execute($tokens, $config, $context) { $definition = $config->getHTMLDefinition(); $generator = new HTMLPurifier_Generator($config, $context); $result = array(); $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); $remove_invalid_img = $config->get('Core.RemoveInvalidImg'); // currently only used to determine if comments should be kept $trusted = $config->get('HTML.Trusted'); $comment_lookup = $config->get('HTML.AllowedComments'); $comment_regexp = $config->get('HTML.AllowedCommentsRegexp'); $check_comments = $comment_lookup !== array() || $comment_regexp !== null; $remove_script_contents = $config->get('Core.RemoveScriptContents'); $hidden_elements = $config->get('Core.HiddenElements'); // remove script contents compatibility if ($remove_script_contents === true) { $hidden_elements['script'] = true; } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) { unset($hidden_elements['script']); } $attr_validator = new HTMLPurifier_AttrValidator(); // removes tokens until it reaches a closing tag with its value $remove_until = false; // converts comments into text tokens when this is equal to a tag name $textify_comments = false; $token = false; $context->register('CurrentToken', $token); $e = false; if ($config->get('Core.CollectErrors')) { $e =& $context->get('ErrorCollector'); } foreach ($tokens as $token) { if ($remove_until) { if (empty($token->is_tag) || $token->name !== $remove_until) { continue; } } if (!empty($token->is_tag)) { // DEFINITION CALL // before any processing, try to transform the element if (isset($definition->info_tag_transform[$token->name])) { $original_name = $token->name; // there is a transformation for this tag // DEFINITION CALL $token = $definition-> info_tag_transform[$token->name]->transform($token, $config, $context); if ($e) { $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name); } } if (isset($definition->info[$token->name])) { // mostly everything's good, but // we need to make sure required attributes are in order if (($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) && $definition->info[$token->name]->required_attr && ($token->name != 'img' || $remove_invalid_img) // ensure config option still works ) { $attr_validator->validateToken($token, $config, $context); $ok = true; foreach ($definition->info[$token->name]->required_attr as $name) { if (!isset($token->attr[$name])) { $ok = false; break; } } if (!$ok) { if ($e) { $e->send( E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name ); } continue; } $token->armor['ValidateAttributes'] = true; } if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) { $textify_comments = $token->name; } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) { $textify_comments = false; } } elseif ($escape_invalid_tags) { // invalid tag, generate HTML representation and insert in if ($e) { $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text'); } $token = new HTMLPurifier_Token_Text( $generator->generateFromToken($token) ); } else { // check if we need to destroy all of the tag's children // CAN BE GENERICIZED if (isset($hidden_elements[$token->name])) { if ($token instanceof HTMLPurifier_Token_Start) { $remove_until = $token->name; } elseif ($token instanceof HTMLPurifier_Token_Empty) { // do nothing: we're still looking } else { $remove_until = false; } if ($e) { $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed'); } } else { if ($e) { $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed'); } } continue; } } elseif ($token instanceof HTMLPurifier_Token_Comment) { // textify comments in script tags when they are allowed if ($textify_comments !== false) { $data = $token->data; $token = new HTMLPurifier_Token_Text($data); } elseif ($trusted || $check_comments) { // always cleanup comments $trailing_hyphen = false; if ($e) { // perform check whether or not there's a trailing hyphen if (substr($token->data, -1) == '-') { $trailing_hyphen = true; } } $token->data = rtrim($token->data, '-'); $found_double_hyphen = false; while (strpos($token->data, '--') !== false) { $found_double_hyphen = true; $token->data = str_replace('--', '-', $token->data); } if ($trusted || !empty($comment_lookup[trim($token->data)]) || ($comment_regexp !== null && preg_match($comment_regexp, trim($token->data)))) { // OK good if ($e) { if ($trailing_hyphen) { $e->send( E_NOTICE, 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' ); } if ($found_double_hyphen) { $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed'); } } } else { if ($e) { $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); } continue; } } else { // strip comments if ($e) { $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); } continue; } } elseif ($token instanceof HTMLPurifier_Token_Text) { } else { continue; } $result[] = $token; } if ($remove_until && $e) { // we removed tokens until the end, throw error $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until); } $context->destroy('CurrentToken'); return $result; } } /** * Validate all attributes in the tokens. */ class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy { /** * @param HTMLPurifier_Token[] $tokens * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token[] */ public function execute($tokens, $config, $context) { // setup validator $validator = new HTMLPurifier_AttrValidator(); $token = false; $context->register('CurrentToken', $token); foreach ($tokens as $key => $token) { // only process tokens that have attributes, // namely start and empty tags if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) { continue; } // skip tokens that are armored if (!empty($token->armor['ValidateAttributes'])) { continue; } // note that we have no facilities here for removing tokens $validator->validateToken($token, $config, $context); } $context->destroy('CurrentToken'); return $tokens; } } /** * Transforms FONT tags to the proper form (SPAN with CSS styling) * * This transformation takes the three proprietary attributes of FONT and * transforms them into their corresponding CSS attributes. These are color, * face, and size. * * @note Size is an interesting case because it doesn't map cleanly to CSS. * Thanks to * http://style.cleverchimp.com/font_size_intervals/altintervals.html * for reasonable mappings. * @warning This doesn't work completely correctly; specifically, this * TagTransform operates before well-formedness is enforced, so * the "active formatting elements" algorithm doesn't get applied. */ class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform { /** * @type string */ public $transform_to = 'span'; /** * @type array */ protected $_size_lookup = array( '0' => 'xx-small', '1' => 'xx-small', '2' => 'small', '3' => 'medium', '4' => 'large', '5' => 'x-large', '6' => 'xx-large', '7' => '300%', '-1' => 'smaller', '-2' => '60%', '+1' => 'larger', '+2' => '150%', '+3' => '200%', '+4' => '300%' ); /** * @param HTMLPurifier_Token_Tag $tag * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return HTMLPurifier_Token_End|string */ public function transform($tag, $config, $context) { if ($tag instanceof HTMLPurifier_Token_End) { $new_tag = clone $tag; $new_tag->name = $this->transform_to; return $new_tag; } $attr = $tag->attr; $prepend_style = ''; // handle color transform if (isset($attr['color'])) { $prepend_style .= 'color:' . $attr['color'] . ';'; unset($attr['color']); } // handle face transform if (isset($attr['face'])) { $prepend_style .= 'font-family:' . $attr['face'] . ';'; unset($attr['face']); } // handle size transform if (isset($attr['size'])) { // normalize large numbers if ($attr['size'] !== '') { if ($attr['size']{0} == '+' || $attr['size']{0} == '-') { $size = (int)$attr['size']; if ($size < -2) { $attr['size'] = '-2'; } if ($size > 4) { $attr['size'] = '+4'; } } else { $size = (int)$attr['size']; if ($size > 7) { $attr['size'] = '7'; } } } if (isset($this->_size_lookup[$attr['size']])) { $prepend_style .= 'font-size:' . $this->_size_lookup[$attr['size']] . ';'; } unset($attr['size']); } if ($prepend_style) { $attr['style'] = isset($attr['style']) ? $prepend_style . $attr['style'] : $prepend_style; } $new_tag = clone $tag; $new_tag->name = $this->transform_to; $new_tag->attr = $attr; return $new_tag; } } /** * Simple transformation, just change tag name to something else, * and possibly add some styling. This will cover most of the deprecated * tag cases. */ class HTMLPurifier_TagTransform_Simple extends HTMLPurifier_TagTransform { /** * @type string */ protected $style; /** * @param string $transform_to Tag name to transform to. * @param string $style CSS style to add to the tag */ public function __construct($transform_to, $style = null) { $this->transform_to = $transform_to; $this->style = $style; } /** * @param HTMLPurifier_Token_Tag $tag * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return string */ public function transform($tag, $config, $context) { $new_tag = clone $tag; $new_tag->name = $this->transform_to; if (!is_null($this->style) && ($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty) ) { $this->prependCSS($new_tag->attr, $this->style); } return $new_tag; } } /** * Concrete comment token class. Generally will be ignored. */ class HTMLPurifier_Token_Comment extends HTMLPurifier_Token { /** * Character data within comment. * @type string */ public $data; /** * @type bool */ public $is_whitespace = true; /** * Transparent constructor. * * @param string $data String comment data. * @param int $line * @param int $col */ public function __construct($data, $line = null, $col = null) { $this->data = $data; $this->line = $line; $this->col = $col; } public function toNode() { return new HTMLPurifier_Node_Comment($this->data, $this->line, $this->col); } } /** * Abstract class of a tag token (start, end or empty), and its behavior. */ abstract class HTMLPurifier_Token_Tag extends HTMLPurifier_Token { /** * Static bool marker that indicates the class is a tag. * * This allows us to check objects with <tt>!empty($obj->is_tag)</tt> * without having to use a function call <tt>is_a()</tt>. * @type bool */ public $is_tag = true; /** * The lower-case name of the tag, like 'a', 'b' or 'blockquote'. * * @note Strictly speaking, XML tags are case sensitive, so we shouldn't * be lower-casing them, but these tokens cater to HTML tags, which are * insensitive. * @type string */ public $name; /** * Associative array of the tag's attributes. * @type array */ public $attr = array(); /** * Non-overloaded constructor, which lower-cases passed tag name. * * @param string $name String name. * @param array $attr Associative array of attributes. * @param int $line * @param int $col * @param array $armor */ public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) { $this->name = ctype_lower($name) ? $name : strtolower($name); foreach ($attr as $key => $value) { // normalization only necessary when key is not lowercase if (!ctype_lower($key)) { $new_key = strtolower($key); if (!isset($attr[$new_key])) { $attr[$new_key] = $attr[$key]; } if ($new_key !== $key) { unset($attr[$key]); } } } $this->attr = $attr; $this->line = $line; $this->col = $col; $this->armor = $armor; } public function toNode() { return new HTMLPurifier_Node_Element($this->name, $this->attr, $this->line, $this->col, $this->armor); } } /** * Concrete empty token class. */ class HTMLPurifier_Token_Empty extends HTMLPurifier_Token_Tag { public function toNode() { $n = parent::toNode(); $n->empty = true; return $n; } } /** * Concrete end token class. * * @warning This class accepts attributes even though end tags cannot. This * is for optimization reasons, as under normal circumstances, the Lexers * do not pass attributes. */ class HTMLPurifier_Token_End extends HTMLPurifier_Token_Tag { /** * Token that started this node. * Added by MakeWellFormed. Please do not edit this! * @type HTMLPurifier_Token */ public $start; public function toNode() { throw new Exception("HTMLPurifier_Token_End->toNode not supported!"); } } /** * Concrete start token class. */ class HTMLPurifier_Token_Start extends HTMLPurifier_Token_Tag { } /** * Concrete text token class. * * Text tokens comprise of regular parsed character data (PCDATA) and raw * character data (from the CDATA sections). Internally, their * data is parsed with all entities expanded. Surprisingly, the text token * does have a "tag name" called #PCDATA, which is how the DTD represents it * in permissible child nodes. */ class HTMLPurifier_Token_Text extends HTMLPurifier_Token { /** * @type string */ public $name = '#PCDATA'; /**< PCDATA tag name compatible with DTD. */ /** * @type string */ public $data; /**< Parsed character data of text. */ /** * @type bool */ public $is_whitespace; /**< Bool indicating if node is whitespace. */ /** * Constructor, accepts data and determines if it is whitespace. * @param string $data String parsed character data. * @param int $line * @param int $col */ public function __construct($data, $line = null, $col = null) { $this->data = $data; $this->is_whitespace = ctype_space($data); $this->line = $line; $this->col = $col; } public function toNode() { return new HTMLPurifier_Node_Text($this->data, $this->is_whitespace, $this->line, $this->col); } } class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter { /** * @type string */ public $name = 'DisableExternal'; /** * @type array */ protected $ourHostParts = false; /** * @param HTMLPurifier_Config $config * @return void */ public function prepare($config) { $our_host = $config->getDefinition('URI')->host; if ($our_host !== null) { $this->ourHostParts = array_reverse(explode('.', $our_host)); } } /** * @param HTMLPurifier_URI $uri Reference * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { if (is_null($uri->host)) { return true; } if ($this->ourHostParts === false) { return false; } $host_parts = array_reverse(explode('.', $uri->host)); foreach ($this->ourHostParts as $i => $x) { if (!isset($host_parts[$i])) { return false; } if ($host_parts[$i] != $this->ourHostParts[$i]) { return false; } } return true; } } class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal { /** * @type string */ public $name = 'DisableExternalResources'; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { if (!$context->get('EmbeddedURI', true)) { return true; } return parent::filter($uri, $config, $context); } } class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter { /** * @type string */ public $name = 'DisableResources'; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { return !$context->get('EmbeddedURI', true); } } // It's not clear to me whether or not Punycode means that hostnames // do not have canonical forms anymore. As far as I can tell, it's // not a problem (punycoding should be identity when no Unicode // points are involved), but I'm not 100% sure class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter { /** * @type string */ public $name = 'HostBlacklist'; /** * @type array */ protected $blacklist = array(); /** * @param HTMLPurifier_Config $config * @return bool */ public function prepare($config) { $this->blacklist = $config->get('URI.HostBlacklist'); return true; } /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { foreach ($this->blacklist as $blacklisted_host_fragment) { if (strpos($uri->host, $blacklisted_host_fragment) !== false) { return false; } } return true; } } // does not support network paths class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter { /** * @type string */ public $name = 'MakeAbsolute'; /** * @type */ protected $base; /** * @type array */ protected $basePathStack = array(); /** * @param HTMLPurifier_Config $config * @return bool */ public function prepare($config) { $def = $config->getDefinition('URI'); $this->base = $def->base; if (is_null($this->base)) { trigger_error( 'URI.MakeAbsolute is being ignored due to lack of ' . 'value for URI.Base configuration', E_USER_WARNING ); return false; } $this->base->fragment = null; // fragment is invalid for base URI $stack = explode('/', $this->base->path); array_pop($stack); // discard last segment $stack = $this->_collapseStack($stack); // do pre-parsing $this->basePathStack = $stack; return true; } /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { if (is_null($this->base)) { return true; } // abort early if ($uri->path === '' && is_null($uri->scheme) && is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) { // reference to current document $uri = clone $this->base; return true; } if (!is_null($uri->scheme)) { // absolute URI already: don't change if (!is_null($uri->host)) { return true; } $scheme_obj = $uri->getSchemeObj($config, $context); if (!$scheme_obj) { // scheme not recognized return false; } if (!$scheme_obj->hierarchical) { // non-hierarchal URI with explicit scheme, don't change return true; } // special case: had a scheme but always is hierarchical and had no authority } if (!is_null($uri->host)) { // network path, don't bother return true; } if ($uri->path === '') { $uri->path = $this->base->path; } elseif ($uri->path[0] !== '/') { // relative path, needs more complicated processing $stack = explode('/', $uri->path); $new_stack = array_merge($this->basePathStack, $stack); if ($new_stack[0] !== '' && !is_null($this->base->host)) { array_unshift($new_stack, ''); } $new_stack = $this->_collapseStack($new_stack); $uri->path = implode('/', $new_stack); } else { // absolute path, but still we should collapse $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); } // re-combine $uri->scheme = $this->base->scheme; if (is_null($uri->userinfo)) { $uri->userinfo = $this->base->userinfo; } if (is_null($uri->host)) { $uri->host = $this->base->host; } if (is_null($uri->port)) { $uri->port = $this->base->port; } return true; } /** * Resolve dots and double-dots in a path stack * @param array $stack * @return array */ private function _collapseStack($stack) { $result = array(); $is_folder = false; for ($i = 0; isset($stack[$i]); $i++) { $is_folder = false; // absorb an internally duplicated slash if ($stack[$i] == '' && $i && isset($stack[$i + 1])) { continue; } if ($stack[$i] == '..') { if (!empty($result)) { $segment = array_pop($result); if ($segment === '' && empty($result)) { // error case: attempted to back out too far: // restore the leading slash $result[] = ''; } elseif ($segment === '..') { $result[] = '..'; // cannot remove .. with .. } } else { // relative path, preserve the double-dots $result[] = '..'; } $is_folder = true; continue; } if ($stack[$i] == '.') { // silently absorb $is_folder = true; continue; } $result[] = $stack[$i]; } if ($is_folder) { $result[] = ''; } return $result; } } class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter { /** * @type string */ public $name = 'Munge'; /** * @type bool */ public $post = true; /** * @type string */ private $target; /** * @type HTMLPurifier_URIParser */ private $parser; /** * @type bool */ private $doEmbed; /** * @type string */ private $secretKey; /** * @type array */ protected $replace = array(); /** * @param HTMLPurifier_Config $config * @return bool */ public function prepare($config) { $this->target = $config->get('URI.' . $this->name); $this->parser = new HTMLPurifier_URIParser(); $this->doEmbed = $config->get('URI.MungeResources'); $this->secretKey = $config->get('URI.MungeSecretKey'); if ($this->secretKey && !function_exists('hash_hmac')) { throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support."); } return true; } /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { if ($context->get('EmbeddedURI', true) && !$this->doEmbed) { return true; } $scheme_obj = $uri->getSchemeObj($config, $context); if (!$scheme_obj) { return true; } // ignore unknown schemes, maybe another postfilter did it if (!$scheme_obj->browsable) { return true; } // ignore non-browseable schemes, since we can't munge those in a reasonable way if ($uri->isBenign($config, $context)) { return true; } // don't redirect if a benign URL $this->makeReplace($uri, $config, $context); $this->replace = array_map('rawurlencode', $this->replace); $new_uri = strtr($this->target, $this->replace); $new_uri = $this->parser->parse($new_uri); // don't redirect if the target host is the same as the // starting host if ($uri->host === $new_uri->host) { return true; } $uri = $new_uri; // overwrite return true; } /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context */ protected function makeReplace($uri, $config, $context) { $string = $uri->toString(); // always available $this->replace['%s'] = $string; $this->replace['%r'] = $context->get('EmbeddedURI', true); $token = $context->get('CurrentToken', true); $this->replace['%n'] = $token ? $token->name : null; $this->replace['%m'] = $context->get('CurrentAttr', true); $this->replace['%p'] = $context->get('CurrentCSSProperty', true); // not always available if ($this->secretKey) { $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); } } } /** * Implements safety checks for safe iframes. * * @warning This filter is *critical* for ensuring that %HTML.SafeIframe * works safely. */ class HTMLPurifier_URIFilter_SafeIframe extends HTMLPurifier_URIFilter { /** * @type string */ public $name = 'SafeIframe'; /** * @type bool */ public $always_load = true; /** * @type string */ protected $regexp = null; // XXX: The not so good bit about how this is all set up now is we // can't check HTML.SafeIframe in the 'prepare' step: we have to // defer till the actual filtering. /** * @param HTMLPurifier_Config $config * @return bool */ public function prepare($config) { $this->regexp = $config->get('URI.SafeIframeRegexp'); return true; } /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function filter(&$uri, $config, $context) { // check if filter not applicable if (!$config->get('HTML.SafeIframe')) { return true; } // check if the filter should actually trigger if (!$context->get('EmbeddedURI', true)) { return true; } $token = $context->get('CurrentToken', true); if (!($token && $token->name == 'iframe')) { return true; } // check if we actually have some whitelists enabled if ($this->regexp === null) { return false; } // actually check the whitelists return preg_match($this->regexp, $uri->toString()); } } /** * Implements data: URI for base64 encoded images supported by GD. */ class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme { /** * @type bool */ public $browsable = true; /** * @type array */ public $allowed_types = array( // you better write validation code for other types if you // decide to allow them 'image/jpeg' => true, 'image/gif' => true, 'image/png' => true, ); // this is actually irrelevant since we only write out the path // component /** * @type bool */ public $may_omit_host = true; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { $result = explode(',', $uri->path, 2); $is_base64 = false; $charset = null; $content_type = null; if (count($result) == 2) { list($metadata, $data) = $result; // do some legwork on the metadata $metas = explode(';', $metadata); while (!empty($metas)) { $cur = array_shift($metas); if ($cur == 'base64') { $is_base64 = true; break; } if (substr($cur, 0, 8) == 'charset=') { // doesn't match if there are arbitrary spaces, but // whatever dude if ($charset !== null) { continue; } // garbage $charset = substr($cur, 8); // not used } else { if ($content_type !== null) { continue; } // garbage $content_type = $cur; } } } else { $data = $result[0]; } if ($content_type !== null && empty($this->allowed_types[$content_type])) { return false; } if ($charset !== null) { // error; we don't allow plaintext stuff $charset = null; } $data = rawurldecode($data); if ($is_base64) { $raw_data = base64_decode($data); } else { $raw_data = $data; } // XXX probably want to refactor this into a general mechanism // for filtering arbitrary content types $file = tempnam("/tmp", ""); file_put_contents($file, $raw_data); if (function_exists('exif_imagetype')) { $image_code = exif_imagetype($file); unlink($file); } elseif (function_exists('getimagesize')) { set_error_handler(array($this, 'muteErrorHandler')); $info = getimagesize($file); restore_error_handler(); unlink($file); if ($info == false) { return false; } $image_code = $info[2]; } else { trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR); } $real_content_type = image_type_to_mime_type($image_code); if ($real_content_type != $content_type) { // we're nice guys; if the content type is something else we // support, change it over if (empty($this->allowed_types[$real_content_type])) { return false; } $content_type = $real_content_type; } // ok, it's kosher, rewrite what we need $uri->userinfo = null; $uri->host = null; $uri->port = null; $uri->fragment = null; $uri->query = null; $uri->path = "$content_type;base64," . base64_encode($raw_data); return true; } /** * @param int $errno * @param string $errstr */ public function muteErrorHandler($errno, $errstr) { } } /** * Validates file as defined by RFC 1630 and RFC 1738. */ class HTMLPurifier_URIScheme_file extends HTMLPurifier_URIScheme { /** * Generally file:// URLs are not accessible from most * machines, so placing them as an img src is incorrect. * @type bool */ public $browsable = false; /** * Basically the *only* URI scheme for which this is true, since * accessing files on the local machine is very common. In fact, * browsers on some operating systems don't understand the * authority, though I hear it is used on Windows to refer to * network shares. * @type bool */ public $may_omit_host = true; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { // Authentication method is not supported $uri->userinfo = null; // file:// makes no provisions for accessing the resource $uri->port = null; // While it seems to work on Firefox, the querystring has // no possible effect and is thus stripped. $uri->query = null; return true; } } /** * Validates ftp (File Transfer Protocol) URIs as defined by generic RFC 1738. */ class HTMLPurifier_URIScheme_ftp extends HTMLPurifier_URIScheme { /** * @type int */ public $default_port = 21; /** * @type bool */ public $browsable = true; // usually /** * @type bool */ public $hierarchical = true; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { $uri->query = null; // typecode check $semicolon_pos = strrpos($uri->path, ';'); // reverse if ($semicolon_pos !== false) { $type = substr($uri->path, $semicolon_pos + 1); // no semicolon $uri->path = substr($uri->path, 0, $semicolon_pos); $type_ret = ''; if (strpos($type, '=') !== false) { // figure out whether or not the declaration is correct list($key, $typecode) = explode('=', $type, 2); if ($key !== 'type') { // invalid key, tack it back on encoded $uri->path .= '%3B' . $type; } elseif ($typecode === 'a' || $typecode === 'i' || $typecode === 'd') { $type_ret = ";type=$typecode"; } } else { $uri->path .= '%3B' . $type; } $uri->path = str_replace(';', '%3B', $uri->path); $uri->path .= $type_ret; } return true; } } /** * Validates http (HyperText Transfer Protocol) as defined by RFC 2616 */ class HTMLPurifier_URIScheme_http extends HTMLPurifier_URIScheme { /** * @type int */ public $default_port = 80; /** * @type bool */ public $browsable = true; /** * @type bool */ public $hierarchical = true; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { $uri->userinfo = null; return true; } } /** * Validates https (Secure HTTP) according to http scheme. */ class HTMLPurifier_URIScheme_https extends HTMLPurifier_URIScheme_http { /** * @type int */ public $default_port = 443; /** * @type bool */ public $secure = true; } // VERY RELAXED! Shouldn't cause problems, not even Firefox checks if the // email is valid, but be careful! /** * Validates mailto (for E-mail) according to RFC 2368 * @todo Validate the email address * @todo Filter allowed query parameters */ class HTMLPurifier_URIScheme_mailto extends HTMLPurifier_URIScheme { /** * @type bool */ public $browsable = false; /** * @type bool */ public $may_omit_host = true; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { $uri->userinfo = null; $uri->host = null; $uri->port = null; // we need to validate path against RFC 2368's addr-spec return true; } } /** * Validates news (Usenet) as defined by generic RFC 1738 */ class HTMLPurifier_URIScheme_news extends HTMLPurifier_URIScheme { /** * @type bool */ public $browsable = false; /** * @type bool */ public $may_omit_host = true; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { $uri->userinfo = null; $uri->host = null; $uri->port = null; $uri->query = null; // typecode check needed on path return true; } } /** * Validates nntp (Network News Transfer Protocol) as defined by generic RFC 1738 */ class HTMLPurifier_URIScheme_nntp extends HTMLPurifier_URIScheme { /** * @type int */ public $default_port = 119; /** * @type bool */ public $browsable = false; /** * @param HTMLPurifier_URI $uri * @param HTMLPurifier_Config $config * @param HTMLPurifier_Context $context * @return bool */ public function doValidate(&$uri, $config, $context) { $uri->userinfo = null; $uri->query = null; return true; } } /** * Performs safe variable parsing based on types which can be used by * users. This may not be able to represent all possible data inputs, * however. */ class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser { /** * @param mixed $var * @param int $type * @param bool $allow_null * @return array|bool|float|int|mixed|null|string * @throws HTMLPurifier_VarParserException */ protected function parseImplementation($var, $type, $allow_null) { if ($allow_null && $var === null) { return null; } switch ($type) { // Note: if code "breaks" from the switch, it triggers a generic // exception to be thrown. Specific errors can be specifically // done here. case self::MIXED: case self::ISTRING: case self::STRING: case self::TEXT: case self::ITEXT: return $var; case self::INT: if (is_string($var) && ctype_digit($var)) { $var = (int)$var; } return $var; case self::FLOAT: if ((is_string($var) && is_numeric($var)) || is_int($var)) { $var = (float)$var; } return $var; case self::BOOL: if (is_int($var) && ($var === 0 || $var === 1)) { $var = (bool)$var; } elseif (is_string($var)) { if ($var == 'on' || $var == 'true' || $var == '1') { $var = true; } elseif ($var == 'off' || $var == 'false' || $var == '0') { $var = false; } else { throw new HTMLPurifier_VarParserException("Unrecognized value '$var' for $type"); } } return $var; case self::ALIST: case self::HASH: case self::LOOKUP: if (is_string($var)) { // special case: technically, this is an array with // a single empty string item, but having an empty // array is more intuitive if ($var == '') { return array(); } if (strpos($var, "\n") === false && strpos($var, "\r") === false) { // simplistic string to array method that only works // for simple lists of tag names or alphanumeric characters $var = explode(',', $var); } else { $var = preg_split('/(,|[\n\r]+)/', $var); } // remove spaces foreach ($var as $i => $j) { $var[$i] = trim($j); } if ($type === self::HASH) { // key:value,key2:value2 $nvar = array(); foreach ($var as $keypair) { $c = explode(':', $keypair, 2); if (!isset($c[1])) { continue; } $nvar[trim($c[0])] = trim($c[1]); } $var = $nvar; } } if (!is_array($var)) { break; } $keys = array_keys($var); if ($keys === array_keys($keys)) { if ($type == self::ALIST) { return $var; } elseif ($type == self::LOOKUP) { $new = array(); foreach ($var as $key) { $new[$key] = true; } return $new; } else { break; } } if ($type === self::ALIST) { trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING); return array_values($var); } if ($type === self::LOOKUP) { foreach ($var as $key => $value) { if ($value !== true) { trigger_error( "Lookup array has non-true value at key '$key'; " . "maybe your input array was not indexed numerically", E_USER_WARNING ); } $var[$key] = true; } } return $var; default: $this->errorInconsistent(__CLASS__, $type); } $this->errorGeneric($var, $type); } } /** * This variable parser uses PHP's internal code engine. Because it does * this, it can represent all inputs; however, it is dangerous and cannot * be used by users. */ class HTMLPurifier_VarParser_Native extends HTMLPurifier_VarParser { /** * @param mixed $var * @param int $type * @param bool $allow_null * @return null|string */ protected function parseImplementation($var, $type, $allow_null) { return $this->evalExpression($var); } /** * @param string $expr * @return mixed * @throws HTMLPurifier_VarParserException */ protected function evalExpression($expr) { $var = null; $result = eval("\$var = $expr;"); if ($result === false) { throw new HTMLPurifier_VarParserException("Fatal error in evaluated code"); } return $var; } } �����������������������Collabtive-2.0/include/SmartyPaginate.class.php�����������������������������������������������������0000664�0000000�0000000�00000031425�12372520637�0021643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php /** * Project: SmartyPaginate: Pagination for the Smarty Template Engine * File: SmartyPaginate.class.php * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://www.phpinsider.com/php/code/SmartyPaginate/ * @copyright 2001-2005 New Digital Group, Inc. * @author Monte Ohrt <monte at newdigitalgroup dot com> * @package SmartyPaginate * @version 1.6 */ class SmartyPaginate { /** * Class Constructor */ function SmartyPaginate() { } /** * initialize the session data * * @param string $id the pagination id * @param string $formvar the variable containing submitted pagination information */ static function connect($id = 'default', $formvar = null) { if (!isset($_SESSION['SmartyPaginate'][$id])) { SmartyPaginate::reset($id); } // use $_GET by default unless otherwise specified $_formvar = isset($formvar) ? $formvar : $_GET; // set the current page $_total = SmartyPaginate::getTotal($id); if (isset($_formvar[SmartyPaginate::getUrlVar($id)]) && $_formvar[SmartyPaginate::getUrlVar($id)] > 0 && (!isset($_total) || $_formvar[SmartyPaginate::getUrlVar($id)] <= $_total)) $_SESSION['SmartyPaginate'][$id]['current_item'] = $_formvar[$_SESSION['SmartyPaginate'][$id]['urlvar']]; } /** * see if session has been initialized * * @param string $id the pagination id */ function isConnected($id = 'default') { return isset($_SESSION['SmartyPaginate'][$id]); } /** * reset/init the session data * * @param string $id the pagination id */ static function reset($id = 'default') { $_SESSION['SmartyPaginate'][$id] = array('item_limit' => 10, 'item_total' => null, 'current_item' => 1, 'urlvar' => 'next', 'url' => full_url(), 'prev_text' => 'prev', 'next_text' => 'next', 'first_text' => 'first', 'last_text' => 'last' ); } /** * clear the SmartyPaginate session data * * @param string $id the pagination id */ static function disconnect($id = null) { if (isset($id)) unset($_SESSION['SmartyPaginate'][$id]); else unset($_SESSION['SmartyPaginate']); } /** * set maximum number of items per page * * @param string $id the pagination id */ static function setLimit($limit, $id = 'default') { if (!preg_match('!^\d+$!', $limit)) { trigger_error('SmartyPaginate setLimit: limit must be an integer.'); return false; } settype($limit, 'integer'); if ($limit < 1) { trigger_error('SmartyPaginate setLimit: limit must be greater than zero.'); return false; } $_SESSION['SmartyPaginate'][$id]['item_limit'] = $limit; } /** * get maximum number of items per page * * @param string $id the pagination id */ static function getLimit($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['item_limit']; } /** * set the total number of items * * @param int $total the total number of items * @param string $id the pagination id */ static function setTotal($total, $id = 'default') { if (!preg_match('!^\d+$!', $total)) { trigger_error('SmartyPaginate setTotal: total must be an integer.'); return false; } settype($total, 'integer'); if ($total < 0) { trigger_error('SmartyPaginate setTotal: total must be positive.'); return false; } $_SESSION['SmartyPaginate'][$id]['item_total'] = $total; } /** * get the total number of items * * @param string $id the pagination id */ static function getTotal($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['item_total']; } /** * set the url used in the links, default is $PHP_SELF * * @param string $url the pagination url * @param string $id the pagination id */ static function setUrl($url, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['url'] = $url; } /** * get the url variable * * @param string $id the pagination id */ static function getUrl($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['url']; } /** * set the url variable ie. ?next=10 * ^^^^ * * @param string $url url pagination varname * @param string $id the pagination id */ static function setUrlVar($urlvar, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['urlvar'] = $urlvar; } /** * get the url variable * * @param string $id the pagination id */ static function getUrlVar($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['urlvar']; } /** * set the current item (usually done automatically by next/prev links) * * @param int $item index of the current item * @param string $id the pagination id */ static function setCurrentItem($item, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['current_item'] = $item; } /** * get the current item * * @param string $id the pagination id */ static function getCurrentItem($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['current_item']; } /** * get the current item index * * @param string $id the pagination id */ static function getCurrentIndex($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['current_item'] - 1; } /** * get the last displayed item * * @param string $id the pagination id */ static function getLastItem($id = 'default') { $_total = SmartyPaginate::getTotal($id); $_limit = SmartyPaginate::getLimit($id); $_last = SmartyPaginate::getCurrentItem($id) + $_limit - 1; return ($_last <= $_total) ? $_last : $_total; } /** * assign $paginate var values * * @param obj $ &$smarty the smarty object reference * @param string $var the name of the assigned var * @param string $id the pagination id */ static function assign(&$smarty, $var = 'paginate', $id = 'default') { if (is_object($smarty) && (strtolower(get_class($smarty)) == 'smarty' || is_subclass_of($smarty, 'smarty'))) { $_paginate['total'] = SmartyPaginate::getTotal($id); $_paginate['first'] = SmartyPaginate::getCurrentItem($id); $_paginate['last'] = SmartyPaginate::getLastItem($id); $_paginate['page_current'] = ceil(SmartyPaginate::getLastItem($id) / SmartyPaginate::getLimit($id)); $_paginate['page_total'] = ceil(SmartyPaginate::getTotal($id) / SmartyPaginate::getLimit($id)); $_paginate['size'] = $_paginate['last'] - $_paginate['first']; $_paginate['url'] = SmartyPaginate::getUrl($id); $_paginate['urlvar'] = SmartyPaginate::getUrlVar($id); $_paginate['current_item'] = SmartyPaginate::getCurrentItem($id); // $_paginate['prev_text'] = SmartyPaginate::getPrevText($id); // $_paginate['next_text'] = SmartyPaginate::getNextText($id); $_paginate['prev_text'] = "<<"; $_paginate['next_text'] = ">>"; $_paginate['limit'] = SmartyPaginate::getLimit($id); $_item = 1; $_page = 1; while ($_item <= $_paginate['total']) { $_paginate['page'][$_page]['number'] = $_page; $_paginate['page'][$_page]['item_start'] = $_item; $_paginate['page'][$_page]['item_end'] = ($_item + $_paginate['limit'] - 1 <= $_paginate['total']) ? $_item + $_paginate['limit'] - 1 : $_paginate['total']; $_paginate['page'][$_page]['is_current'] = ($_item == $_paginate['current_item']); $_item += $_paginate['limit']; $_page++; } $smarty->assign($var, $_paginate); } else { trigger_error("SmartyPaginate: [assign] I need a valid Smarty object."); return false; } } /** * set the default text for the "previous" page link * * @param string $text index of the current item * @param string $id the pagination id */ static function setPrevText($text, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['prev_text'] = $text; } /** * get the default text for the "previous" page link * * @param string $id the pagination id */ static function getPrevText($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['prev_text']; } /** * set the text for the "next" page link * * @param string $text index of the current item * @param string $id the pagination id */ static function setNextText($text, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['next_text'] = $text; } /** * get the default text for the "next" page link * * @param string $id the pagination id */ static function getNextText($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['next_text']; } /** * set the text for the "first" page link * * @param string $text index of the current item * @param string $id the pagination id */ static function setFirstText($text, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['first_text'] = $text; } /** * get the default text for the "first" page link * * @param string $id the pagination id */ static function getFirstText($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['first_text']; } /** * set the text for the "last" page link * * @param string $text index of the current item * @param string $id the pagination id */ static function setLastText($text, $id = 'default') { $_SESSION['SmartyPaginate'][$id]['last_text'] = $text; } /** * get the default text for the "last" page link * * @param string $id the pagination id */ static function getLastText($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['last_text']; } /** * set default number of page groupings in {paginate_middle} * * @param string $id the pagination id */ static function setPageLimit($limit, $id = 'default') { if (!preg_match('!^\d+$!', $limit)) { trigger_error('SmartyPaginate setPageLimit: limit must be an integer.'); return false; } settype($limit, 'integer'); if ($limit < 1) { trigger_error('SmartyPaginate setPageLimit: limit must be greater than zero.'); return false; } $_SESSION['SmartyPaginate'][$id]['page_limit'] = $limit; } /** * get default number of page groupings in {paginate_middle} * * @param string $id the pagination id */ static function getPageLimit($id = 'default') { return $_SESSION['SmartyPaginate'][$id]['page_limit']; } /** * get the previous page of items * * @param string $id the pagination id */ static function _getPrevPageItem($id = 'default') { $_prev_item = $_SESSION['SmartyPaginate'][$id]['current_item'] - $_SESSION['SmartyPaginate'][$id]['item_limit']; return ($_prev_item > 0) ? $_prev_item : false; } /** * get the previous page of items * * @param string $id the pagination id */ static function _getNextPageItem($id = 'default') { $_next_item = $_SESSION['SmartyPaginate'][$id]['current_item'] + $_SESSION['SmartyPaginate'][$id]['item_limit']; return ($_next_item <= $_SESSION['SmartyPaginate'][$id]['item_total']) ? $_next_item : false; } } ?> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/include/class.MYPDF.php��������������������������������������������������������������0000664�0000000�0000000�00000006046�12372520637�0017573�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php /* * Implements PDF exports * * @author Philipp Kiszka <info@o-dyn.de> * @name MYPDF * @version 1.0 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class MYPDF extends TCPDF { // String for the header private $headerName; // cellFill is expected to be an array containing a RGB triplet. private $cellFill; private $headerMargin = 20; public function setup($headerName = "", array $cellFill = array()) { // TCPDF boilerplate setup $this->SetMargins(15, $this->headerMargin, 15); $this->SetFooterMargin(PDF_MARGIN_FOOTER); $this->SetFont(PDF_FONT_NAME_DATA, "", 11); $this->SetAutoPageBreak(true, PDF_MARGIN_FOOTER); $this->getAliasNbPages(); $this->AddPage(); // Set string for display above table $this->headerName = $headerName; // Set colored fill value for rows. cellFill is expected to be an array containing a RGB triplet. Default alternate is white. $this->cellFill = $cellFill; $this->Header(); } public function Header() { // If header name is set print it out if ($this->headerName) { // make it big and bold $this->setFontSize(22); $this->SetFont('', 'B'); $this->Cell(0, 0, $this->headerName, 0, 1, "L", 0); $this->headerMargin = $this->GetY() + 10; // $this->Cell(0, 0, "", 0, 1, "L", 0); } } public function table($header, $data) { // font restoration $this->setFontSize(12); $this->SetFillColor(255, 255, 255); $this->SetTextColor(0); $this->SetLineWidth(0.3); $this->SetFont('', 'B'); // Calculate Headers $num_headers = count($header); $awidth = floor(180 / $num_headers); for($i = 0; $i < $num_headers; $i++) { if ($i > 0) { $this->Cell($awidth, 7, $header[$i], 1, 0, 'C', 1, "", 1); } else { $this->Cell($awidth + 5, 7, $header[$i], 1, 0, 'C', 1, "", 1); } } $this->Ln(); // Color and font restoration if (!empty($this->cellFill)) { $this->SetFillColor($this->cellFill[0], $this->cellFill[1], $this->cellFill[2]); } else { $this->SetFillColor(224, 235, 255); } $this->SetFont(''); $doFill = false; // Loop through data array and for each line, draw cells according to the header count foreach($data as $row) { for($i = 0;$i < $num_headers;$i++) { if ($i > 0) { $this->Cell($awidth, 6, $row[$i], 1, 0, 'LR', $doFill, "", 1); } else { $this->Cell($awidth + 5, 6, $row[$i], 1, 0, 'LR', $doFill, "", 1); } } // Reverse the value of dofill $doFill = !$doFill; $this->Ln(); } $this->Cell(180, 0, '', 'T'); } } ?>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/include/class.PHPmailer.php����������������������������������������������������������0000664�0000000�0000000�00000155770�12372520637�0020546�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php /*~ class.phpmailer.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | | Version: 2.1 | | Contact: via sourceforge.net support pages (also www.codeworxtech.com) | | Info: http://phpmailer.sourceforge.net | | Support: http://sourceforge.net/projects/phpmailer/ | | ------------------------------------------------------------------------- | | Author: Andy Prevost (project admininistrator) | | Author: Brent R. Matzelle (original founder) | | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. | | Copyright (c) 2001-2003, Brent R. Matzelle | | ------------------------------------------------------------------------- | | License: Distributed under the Lesser General Public License (LGPL) | | http://www.gnu.org/copyleft/lesser.html | | This program is distributed in the hope that it will be useful - WITHOUT | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | | FITNESS FOR A PARTICULAR PURPOSE. | | ------------------------------------------------------------------------- | | We offer a number of paid services (www.codeworxtech.com): | | - Web Hosting on highly optimized fast and secure servers | | - Technology Consulting | | - Oursourcing (highly qualified programmers and graphic designers) | '---------------------------------------------------------------------------' /** * PHPMailer - PHP email transport class * NOTE: Designed for use with PHP version 5 and up * @package PHPMailer * @author Andy Prevost * @copyright 2004 - 2008 Andy Prevost */ class PHPMailer { ///////////////////////////////////////////////// // PROPERTIES, PUBLIC ///////////////////////////////////////////////// /** * Email priority (1 = High, 3 = Normal, 5 = low). * @var int */ public $Priority = 3; /** * Sets the CharSet of the message. * @var string */ public $CharSet = 'utf-8'; /** * Sets the Content-type of the message. * @var string */ public $ContentType = 'text/plain'; /** * Sets the Encoding of the message. Options for this are "8bit", * "7bit", "binary", "base64", and "quoted-printable". * @var string */ public $Encoding = '8bit'; /** * Holds the most recent mailer error message. * @var string */ public $ErrorInfo = ''; /** * Sets the From email address for the message. * @var string */ public $From = 'root@localhost'; /** * Sets the From name of the message. * @var string */ public $FromName = 'Root User'; /** * Sets the Sender email (Return-Path) of the message. If not empty, * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. * @var string */ public $Sender = ''; /** * Sets the Subject of the message. * @var string */ public $Subject = ''; /** * Sets the Body of the message. This can be either an HTML or text body. * If HTML then run IsHTML(true). * @var string */ public $Body = ''; /** * Sets the text-only body of the message. This automatically sets the * email to multipart/alternative. This body can be read by mail * clients that do not have HTML email capability such as mutt. Clients * that can read HTML will view the normal Body. * @var string */ public $AltBody = ''; /** * Sets word wrapping on the body of the message to a given number of * characters. * @var int */ public $WordWrap = 0; /** * Method to send mail: ("mail", "sendmail", or "smtp"). * @var string */ public $Mailer = 'mail'; /** * Sets the path of the sendmail program. * @var string */ public $Sendmail = '/usr/sbin/sendmail'; /** * Path to PHPMailer plugins. This is now only useful if the SMTP class * is in a different directory than the PHP include path. * @var string */ public $PluginDir = ''; /** * Holds PHPMailer version. * @var string */ public $Version = "2.1"; /** * Sets the email address that a reading confirmation will be sent. * @var string */ public $ConfirmReadingTo = ''; /** * Sets the hostname to use in Message-Id and Received headers * and as default HELO string. If empty, the value returned * by SERVER_NAME is used or 'localhost.localdomain'. * @var string */ public $Hostname = ''; /** * Sets the message ID to be used in the Message-Id header. * If empty, a unique id will be generated. * @var string */ public $MessageID = ''; ///////////////////////////////////////////////// // PROPERTIES FOR SMTP ///////////////////////////////////////////////// /** * Sets the SMTP hosts. All hosts must be separated by a * semicolon. You can also specify a different port * for each host by using this format: [hostname:port] * (e.g. "smtp1.example.com:25;smtp2.example.com"). * Hosts will be tried in order. * @var string */ public $Host = 'localhost'; /** * Sets the default SMTP server port. * @var int */ public $Port = 25; /** * Sets the SMTP HELO of the message (Default is $Hostname). * @var string */ public $Helo = ''; /** * Sets connection prefix. * Options are "", "ssl" or "tls" * @var string */ public $SMTPSecure = ""; /** * Sets SMTP authentication. Utilizes the Username and Password variables. * @var bool */ public $SMTPAuth = false; /** * Sets SMTP username. * @var string */ public $Username = ''; /** * Sets SMTP password. * @var string */ public $Password = ''; /** * Sets the SMTP server timeout in seconds. This function will not * work with the win32 version. * @var int */ public $Timeout = 10; /** * Sets SMTP class debugging on or off. * @var bool */ public $SMTPDebug = false; /** * Prevents the SMTP connection from being closed after each mail * sending. If this is set to true then to close the connection * requires an explicit call to SmtpClose(). * @var bool */ public $SMTPKeepAlive = false; /** * Provides the ability to have the TO field process individual * emails, instead of sending to entire TO addresses * @var bool */ public $SingleTo = false; ///////////////////////////////////////////////// // PROPERTIES, PRIVATE ///////////////////////////////////////////////// private $smtp = NULL; private $to = array(); private $cc = array(); private $bcc = array(); private $ReplyTo = array(); private $attachment = array(); private $CustomHeader = array(); private $message_type = ''; private $boundary = array(); private $language = array(); private $error_count = 0; private $LE = "\n"; private $sign_key_file = ""; private $sign_key_pass = ""; ///////////////////////////////////////////////// // METHODS, VARIABLES ///////////////////////////////////////////////// /** * Sets message type to HTML. * @param bool $bool * @return void */ public function IsHTML($bool) { if($bool == true) { $this->ContentType = 'text/html'; } else { $this->ContentType = 'text/plain'; } } /** * Sets Mailer to send message using SMTP. * @return void */ public function IsSMTP() { $this->Mailer = 'smtp'; } /** * Sets Mailer to send message using PHP mail() function. * @return void */ public function IsMail() { $this->Mailer = 'mail'; } /** * Sets Mailer to send message using the $Sendmail program. * @return void */ public function IsSendmail() { $this->Mailer = 'sendmail'; } /** * Sets Mailer to send message using the qmail MTA. * @return void */ public function IsQmail() { $this->Sendmail = '/var/qmail/bin/sendmail'; $this->Mailer = 'sendmail'; } ///////////////////////////////////////////////// // METHODS, RECIPIENTS ///////////////////////////////////////////////// /** * Adds a "To" address. * @param string $address * @param string $name * @return void */ public function AddAddress($address, $name = '') { $cur = count($this->to); $this->to[$cur][0] = trim($address); $this->to[$cur][1] = $name; } /** * Adds a "Cc" address. Note: this function works * with the SMTP mailer on win32, not with the "mail" * mailer. * @param string $address * @param string $name * @return void */ public function AddCC($address, $name = '') { $cur = count($this->cc); $this->cc[$cur][0] = trim($address); $this->cc[$cur][1] = $name; } /** * Adds a "Bcc" address. Note: this function works * with the SMTP mailer on win32, not with the "mail" * mailer. * @param string $address * @param string $name * @return void */ public function AddBCC($address, $name = '') { $cur = count($this->bcc); $this->bcc[$cur][0] = trim($address); $this->bcc[$cur][1] = $name; } /** * Adds a "Reply-to" address. * @param string $address * @param string $name * @return void */ public function AddReplyTo($address, $name = '') { $cur = count($this->ReplyTo); $this->ReplyTo[$cur][0] = trim($address); $this->ReplyTo[$cur][1] = $name; } ///////////////////////////////////////////////// // METHODS, MAIL SENDING ///////////////////////////////////////////////// /** * Creates message and assigns Mailer. If the message is * not sent successfully then it returns false. Use the ErrorInfo * variable to view description of the error. * @return bool */ public function Send() { $header = ''; $body = ''; $result = true; if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { $this->SetError($this->Lang('provide_address')); return false; } /* Set whether the message is multipart/alternative */ if(!empty($this->AltBody)) { $this->ContentType = 'multipart/alternative'; } $this->error_count = 0; // reset errors $this->SetMessageType(); $header .= $this->CreateHeader(); $body = $this->CreateBody(); if($body == '') { return false; } /* Choose the mailer */ switch($this->Mailer) { case 'sendmail': $result = $this->SendmailSend($header, $body); break; case 'smtp': $result = $this->SmtpSend($header, $body); break; case 'mail': $result = $this->MailSend($header, $body); break; default: $result = $this->MailSend($header, $body); break; //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); //$result = false; //break; } return $result; } /** * Sends mail using the $Sendmail program. * @access public * @return bool */ public function SendmailSend($header, $body) { if ($this->Sender != '') { $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); } else { $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); } if(!@$mail = popen($sendmail, 'w')) { $this->SetError($this->Lang('execute') . $this->Sendmail); return false; } fputs($mail, $header); fputs($mail, $body); $result = pclose($mail); if (version_compare(phpversion(), '4.2.3') == -1) { $result = $result >> 8 & 0xFF; } if($result != 0) { $this->SetError($this->Lang('execute') . $this->Sendmail); return false; } return true; } /** * Sends mail using the PHP mail() function. * @access public * @return bool */ public function MailSend($header, $body) { $to = ''; for($i = 0; $i < count($this->to); $i++) { if($i != 0) { $to .= ', '; } $to .= $this->AddrFormat($this->to[$i]); } $toArr = explode(',', $to); $params = sprintf("-oi -f %s", $this->Sender); if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) { $old_from = ini_get('sendmail_from'); ini_set('sendmail_from', $this->Sender); if ($this->SingleTo === true && count($toArr) > 1) { foreach ($toArr as $key => $val) { $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); } } else { $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); } } else { if ($this->SingleTo === true && count($toArr) > 1) { foreach ($toArr as $key => $val) { $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); } } else { $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); } } if (isset($old_from)) { ini_set('sendmail_from', $old_from); } if(!$rt) { $this->SetError($this->Lang('instantiate')); return false; } return true; } /** * Sends mail via SMTP using PhpSMTP (Author: * Chris Ryan). Returns bool. Returns false if there is a * bad MAIL FROM, RCPT, or DATA input. * @access public * @return bool */ public function SmtpSend($header, $body) { include_once($this->PluginDir . 'class.smtp.php'); $error = ''; $bad_rcpt = array(); if(!$this->SmtpConnect()) { return false; } $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; if(!$this->smtp->Mail($smtp_from)) { $error = $this->Lang('from_failed') . $smtp_from; $this->SetError($error); $this->smtp->Reset(); return false; } /* Attempt to send attach all recipients */ for($i = 0; $i < count($this->to); $i++) { if(!$this->smtp->Recipient($this->to[$i][0])) { $bad_rcpt[] = $this->to[$i][0]; } } for($i = 0; $i < count($this->cc); $i++) { if(!$this->smtp->Recipient($this->cc[$i][0])) { $bad_rcpt[] = $this->cc[$i][0]; } } for($i = 0; $i < count($this->bcc); $i++) { if(!$this->smtp->Recipient($this->bcc[$i][0])) { $bad_rcpt[] = $this->bcc[$i][0]; } } if(count($bad_rcpt) > 0) { // Create error message for($i = 0; $i < count($bad_rcpt); $i++) { if($i != 0) { $error .= ', '; } $error .= $bad_rcpt[$i]; } $error = $this->Lang('recipients_failed') . $error; $this->SetError($error); $this->smtp->Reset(); return false; } if(!$this->smtp->Data($header . $body)) { $this->SetError($this->Lang('data_not_accepted')); $this->smtp->Reset(); return false; } if($this->SMTPKeepAlive == true) { $this->smtp->Reset(); } else { $this->SmtpClose(); } return true; } /** * Initiates a connection to an SMTP server. Returns false if the * operation failed. * @access public * @return bool */ public function SmtpConnect() { if($this->smtp == NULL) { $this->smtp = new SMTP(); } $this->smtp->do_debug = $this->SMTPDebug; $hosts = explode(';', $this->Host); $index = 0; $connection = ($this->smtp->Connected()); /* Retry while there is no connection */ while($index < count($hosts) && $connection == false) { $hostinfo = array(); if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) { $host = $hostinfo[1]; $port = $hostinfo[2]; } else { $host = $hosts[$index]; $port = $this->Port; } $tls = ($this->SMTPSecure == 'tls'); $ssl = ($this->SMTPSecure == 'ssl'); if($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { $hello = ($this->Helo != '' ? $this->Hello : $this->ServerHostname()); $this->smtp->Hello($hello); if($tls) { if(!$this->smtp->StartTLS()) { $this->SetError($this->Lang("tls")); $this->smtp->Reset(); $connection = false; } //We must resend HELLO after tls negociation $this->smtp->Hello($hello); } $connection = true; if($this->SMTPAuth) { if(!$this->smtp->Authenticate($this->Username, $this->Password)) { $this->SetError($this->Lang('authenticate')); $this->smtp->Reset(); $connection = false; } } } $index++; } if(!$connection) { $this->SetError($this->Lang('connect_host')); } return $connection; } /** * Closes the active SMTP session if one exists. * @return void */ public function SmtpClose() { if($this->smtp != NULL) { if($this->smtp->Connected()) { $this->smtp->Quit(); $this->smtp->Close(); } } } /** * Sets the language for all class error messages. Returns false * if it cannot load the language file. The default language type * is English. * @param string $lang_type Type of language (e.g. Portuguese: "br") * @param string $lang_path Path to the language file directory * @access public * @return bool */ function SetLanguage($lang_type = 'en', $lang_path = 'language/') { if( !(@include $lang_path.'phpmailer.lang-'.$lang_type.'.php') ) { $this->SetError('Could not load language file'); return false; } $this->language = $PHPMAILER_LANG; return true; } ///////////////////////////////////////////////// // METHODS, MESSAGE CREATION ///////////////////////////////////////////////// /** * Creates recipient headers. * @access public * @return string */ public function AddrAppend($type, $addr) { $addr_str = $type . ': '; $addr_str .= $this->AddrFormat($addr[0]); if(count($addr) > 1) { for($i = 1; $i < count($addr); $i++) { $addr_str .= ', ' . $this->AddrFormat($addr[$i]); } } $addr_str .= $this->LE; return $addr_str; } /** * Formats an address correctly. * @access public * @return string */ public function AddrFormat($addr) { if(empty($addr[1])) { $formatted = $this->SecureHeader($addr[0]); } else { $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; } return $formatted; } /** * Wraps message for use with mailers that do not * automatically perform wrapping and for quoted-printable. * Original written by philippe. * @access public * @return string */ public function WrapText($message, $length, $qp_mode = false) { $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; // If utf-8 encoding is used, we will need to make sure we don't // split multibyte characters when we wrap $is_utf8 = (strtolower($this->CharSet) == "utf-8"); $message = $this->FixEOL($message); if (substr($message, -1) == $this->LE) { $message = substr($message, 0, -1); } $line = explode($this->LE, $message); $message = ''; for ($i=0 ;$i < count($line); $i++) { $line_part = explode(' ', $line[$i]); $buf = ''; for ($e = 0; $e<count($line_part); $e++) { $word = $line_part[$e]; if ($qp_mode and (strlen($word) > $length)) { $space_left = $length - strlen($buf) - 1; if ($e != 0) { if ($space_left > 20) { $len = $space_left; if ($is_utf8) { $len = $this->UTF8CharBoundary($word, $len); } elseif (substr($word, $len - 1, 1) == "=") { $len--; } elseif (substr($word, $len - 2, 1) == "=") { $len -= 2; } $part = substr($word, 0, $len); $word = substr($word, $len); $buf .= ' ' . $part; $message .= $buf . sprintf("=%s", $this->LE); } else { $message .= $buf . $soft_break; } $buf = ''; } while (strlen($word) > 0) { $len = $length; if ($is_utf8) { $len = $this->UTF8CharBoundary($word, $len); } elseif (substr($word, $len - 1, 1) == "=") { $len--; } elseif (substr($word, $len - 2, 1) == "=") { $len -= 2; } $part = substr($word, 0, $len); $word = substr($word, $len); if (strlen($word) > 0) { $message .= $part . sprintf("=%s", $this->LE); } else { $buf = $part; } } } else { $buf_o = $buf; $buf .= ($e == 0) ? $word : (' ' . $word); if (strlen($buf) > $length and $buf_o != '') { $message .= $buf_o . $soft_break; $buf = $word; } } } $message .= $buf . $this->LE; } return $message; } /** * Finds last character boundary prior to maxLength in a utf-8 * quoted (printable) encoded string. * Original written by Colin Brown. * @access public * @param string $encodedText utf-8 QP text * @param int $maxLength find last character boundary prior to this length * @return int */ public function UTF8CharBoundary($encodedText, $maxLength) { $foundSplitPos = false; $lookBack = 3; while (!$foundSplitPos) { $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); $encodedCharPos = strpos($lastChunk, "="); if ($encodedCharPos !== false) { // Found start of encoded character byte within $lookBack block. // Check the encoded byte value (the 2 chars after the '=') $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); $dec = hexdec($hex); if ($dec < 128) { // Single byte character. // If the encoded char was found at pos 0, it will fit // otherwise reduce maxLength to start of the encoded char $maxLength = ($encodedCharPos == 0) ? $maxLength : $maxLength - ($lookBack - $encodedCharPos); $foundSplitPos = true; } elseif ($dec >= 192) { // First byte of a multi byte character // Reduce maxLength to split at start of character $maxLength = $maxLength - ($lookBack - $encodedCharPos); $foundSplitPos = true; } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back $lookBack += 3; } } else { // No encoded character found $foundSplitPos = true; } } return $maxLength; } /** * Set the body wrapping. * @access public * @return void */ public function SetWordWrap() { if($this->WordWrap < 1) { return; } switch($this->message_type) { case 'alt': /* fall through */ case 'alt_attachments': $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); break; default: $this->Body = $this->WrapText($this->Body, $this->WordWrap); break; } } /** * Assembles message header. * @access public * @return string */ public function CreateHeader() { $result = ''; /* Set the boundaries */ $uniq_id = md5(uniqid(time())); $this->boundary[1] = 'b1_' . $uniq_id; $this->boundary[2] = 'b2_' . $uniq_id; $result .= $this->HeaderLine('Date', $this->RFCDate()); if($this->Sender == '') { $result .= $this->HeaderLine('Return-Path', trim($this->From)); } else { $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); } /* To be created automatically by mail() */ if($this->Mailer != 'mail') { if(count($this->to) > 0) { $result .= $this->AddrAppend('To', $this->to); } elseif (count($this->cc) == 0) { $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); } if(count($this->cc) > 0) { $result .= $this->AddrAppend('Cc', $this->cc); } } $from = array(); $from[0][0] = trim($this->From); $from[0][1] = $this->FromName; $result .= $this->AddrAppend('From', $from); /* sendmail and mail() extract Cc from the header before sending */ if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) { $result .= $this->AddrAppend('Cc', $this->cc); } /* sendmail and mail() extract Bcc from the header before sending */ if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { $result .= $this->AddrAppend('Bcc', $this->bcc); } if(count($this->ReplyTo) > 0) { $result .= $this->AddrAppend('Reply-to', $this->ReplyTo); } /* mail() sets the subject itself */ if($this->Mailer != 'mail') { $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); } if($this->MessageID != '') { $result .= $this->HeaderLine('Message-ID',$this->MessageID); } else { $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); } $result .= $this->HeaderLine('X-Priority', $this->Priority); $result .= $this->HeaderLine('X-Mailer', 'Collabtive Groupware'); if($this->ConfirmReadingTo != '') { $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); } // Add custom headers for($index = 0; $index < count($this->CustomHeader); $index++) { $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); } //$result .= $this->HeaderLine('MIME-Version', '1.0'); if (!$this->sign_key_file) { $result .= $this->HeaderLine('MIME-Version', '1.0'); $result .= $this->GetMailMIME(); } return $result; } /** * Returns the message MIME. * @access public * @return string */ public function GetMailMIME() { $result = ''; switch($this->message_type) { case 'plain': $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); break; case 'attachments': /* fall through */ case 'alt_attachments': if($this->InlineImageExists()){ $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); } else { $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); } break; case 'alt': $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); break; } if($this->Mailer != 'mail') { $result .= $this->LE.$this->LE; } return $result; } /** * Assembles the message body. Returns an empty string on failure. * @access public * @return string */ public function CreateBody() { $result = ''; if ($this->sign_key_file) { $result .= $this->GetMailMIME(); } $this->SetWordWrap(); switch($this->message_type) { case 'alt': $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); $result .= $this->EncodeString($this->AltBody, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); $result .= $this->EncodeString($this->Body, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->EndBoundary($this->boundary[1]); break; case 'plain': $result .= $this->EncodeString($this->Body, $this->Encoding); break; case 'attachments': $result .= $this->GetBoundary($this->boundary[1], '', '', ''); $result .= $this->EncodeString($this->Body, $this->Encoding); $result .= $this->LE; $result .= $this->AttachAll(); break; case 'alt_attachments': $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body $result .= $this->EncodeString($this->AltBody, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body $result .= $this->EncodeString($this->Body, $this->Encoding); $result .= $this->LE.$this->LE; $result .= $this->EndBoundary($this->boundary[2]); $result .= $this->AttachAll(); break; } if($this->IsError()) { $result = ''; } else if ($this->sign_key_file) { $file = tempnam("", "mail"); $fp = fopen($file, "w"); fwrite($fp, $result); fclose($fp); $signed = tempnam("", "signed"); if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_key_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) { $fp = fopen($signed, "r"); $result = fread($fp, filesize($this->sign_key_file)); fclose($fp); } else { $this->SetError($this->Lang("signing").openssl_error_string()); $result = ''; } unlink($file); unlink($signed); } return $result; } /** * Returns the start of a message boundary. * @access public */ public function GetBoundary($boundary, $charSet, $contentType, $encoding) { $result = ''; if($charSet == '') { $charSet = $this->CharSet; } if($contentType == '') { $contentType = $this->ContentType; } if($encoding == '') { $encoding = $this->Encoding; } $result .= $this->TextLine('--' . $boundary); $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet); $result .= $this->LE; $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); $result .= $this->LE; return $result; } /** * Returns the end of a message boundary. * @access public */ public function EndBoundary($boundary) { return $this->LE . '--' . $boundary . '--' . $this->LE; } /** * Sets the message type. * @access public * @return void */ public function SetMessageType() { if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { $this->message_type = 'plain'; } else { if(count($this->attachment) > 0) { $this->message_type = 'attachments'; } if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) { $this->message_type = 'alt'; } if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) { $this->message_type = 'alt_attachments'; } } } /* Returns a formatted header line. * @access public * @return string */ public function HeaderLine($name, $value) { return $name . ': ' . $value . $this->LE; } /** * Returns a formatted mail line. * @access public * @return string */ public function TextLine($value) { return $value . $this->LE; } ///////////////////////////////////////////////// // CLASS METHODS, ATTACHMENTS ///////////////////////////////////////////////// /** * Adds an attachment from a path on the filesystem. * Returns false if the file could not be found * or accessed. * @param string $path Path to the attachment. * @param string $name Overrides the attachment name. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return bool */ public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { if(!@is_file($path)) { $this->SetError($this->Lang('file_access') . $path); return false; } $filename = basename($path); if($name == '') { $name = $filename; } $cur = count($this->attachment); $this->attachment[$cur][0] = $path; $this->attachment[$cur][1] = $filename; $this->attachment[$cur][2] = $name; $this->attachment[$cur][3] = $encoding; $this->attachment[$cur][4] = $type; $this->attachment[$cur][5] = false; // isStringAttachment $this->attachment[$cur][6] = 'attachment'; $this->attachment[$cur][7] = 0; return true; } /** * Attaches all fs, string, and binary attachments to the message. * Returns an empty string on failure. * @access public * @return string */ public function AttachAll() { /* Return text of body */ $mime = array(); /* Add all attachments */ for($i = 0; $i < count($this->attachment); $i++) { /* Check for string attachment */ $bString = $this->attachment[$i][5]; if ($bString) { $string = $this->attachment[$i][0]; } else { $path = $this->attachment[$i][0]; } $filename = $this->attachment[$i][1]; $name = $this->attachment[$i][2]; $encoding = $this->attachment[$i][3]; $type = $this->attachment[$i][4]; $disposition = $this->attachment[$i][6]; $cid = $this->attachment[$i][7]; $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); if($disposition == 'inline') { $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); } $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); /* Encode as string attachment */ if($bString) { $mime[] = $this->EncodeString($string, $encoding); if($this->IsError()) { return ''; } $mime[] = $this->LE.$this->LE; } else { $mime[] = $this->EncodeFile($path, $encoding); if($this->IsError()) { return ''; } $mime[] = $this->LE.$this->LE; } } $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); return join('', $mime); } /** * Encodes attachment in requested format. Returns an * empty string on failure. * @access public * @return string */ public function EncodeFile ($path, $encoding = 'base64') { if(!@$fd = fopen($path, 'rb')) { $this->SetError($this->Lang('file_open') . $path); return ''; } $magic_quotes = get_magic_quotes_runtime(); set_magic_quotes_runtime(0); $file_buffer = file_get_contents($path); $file_buffer = $this->EncodeString($file_buffer, $encoding); fclose($fd); set_magic_quotes_runtime($magic_quotes); return $file_buffer; } /** * Encodes string to requested format. Returns an * empty string on failure. * @access public * @return string */ public function EncodeString ($str, $encoding = 'base64') { $encoded = ''; switch(strtolower($encoding)) { case 'base64': $encoded = chunk_split(base64_encode($str), 76, $this->LE); break; case '7bit': case '8bit': $encoded = $this->FixEOL($str); if (substr($encoded, -(strlen($this->LE))) != $this->LE) $encoded .= $this->LE; break; case 'binary': $encoded = $str; break; case 'quoted-printable': $encoded = $this->EncodeQP($str); break; default: $this->SetError($this->Lang('encoding') . $encoding); break; } return $encoded; } /** * Encode a header string to best of Q, B, quoted or none. * @access public * @return string */ public function EncodeHeader ($str, $position = 'text') { $x = 0; switch (strtolower($position)) { case 'phrase': if (!preg_match('/[\200-\377]/', $str)) { /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */ $encoded = addcslashes($str, "\0..\37\177\\\""); if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { return ($encoded); } else { return ("\"$encoded\""); } } $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); break; case 'comment': $x = preg_match_all('/[()"]/', $str, $matches); /* Fall-through */ case 'text': default: $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); break; } if ($x == 0) { return ($str); } $maxlen = 75 - 7 - strlen($this->CharSet); /* Try to select the encoding which should produce the shortest output */ if (strlen($str)/3 < $x) { $encoding = 'B'; if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { // Use a custom function which correctly encodes and wraps long // multibyte strings without breaking lines within a character $encoded = $this->Base64EncodeWrapMB($str); } else { $encoded = base64_encode($str); $maxlen -= $maxlen % 4; $encoded = trim(chunk_split($encoded, $maxlen, "\n")); } } else { $encoding = 'Q'; $encoded = $this->EncodeQ($str, $position); $encoded = $this->WrapText($encoded, $maxlen, true); $encoded = str_replace('='.$this->LE, "\n", trim($encoded)); } $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); $encoded = trim(str_replace("\n", $this->LE, $encoded)); return $encoded; } /** * Checks if a string contains multibyte characters. * @access public * @param string $str multi-byte text to wrap encode * @return bool */ public function HasMultiBytes($str) { if (function_exists('mb_strlen')) { return (strlen($str) > mb_strlen($str, $this->CharSet)); } else { // Assume no multibytes (we can't handle without mbstring functions anyway) return False; } } /** * Correctly encodes and wraps long multibyte strings for mail headers * without breaking lines within a character. * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php * @access public * @param string $str multi-byte text to wrap encode * @return string */ public function Base64EncodeWrapMB($str) { $start = "=?".$this->CharSet."?B?"; $end = "?="; $encoded = ""; $mb_length = mb_strlen($str, $this->CharSet); // Each line must have length <= 75, including $start and $end $length = 75 - strlen($start) - strlen($end); // Average multi-byte ratio $ratio = $mb_length / strlen($str); // Base64 has a 4:3 ratio $offset = $avgLength = floor($length * $ratio * .75); for ($i = 0; $i < $mb_length; $i += $offset) { $lookBack = 0; do { $offset = $avgLength - $lookBack; $chunk = mb_substr($str, $i, $offset, $this->CharSet); $chunk = base64_encode($chunk); $lookBack++; } while (strlen($chunk) > $length); $encoded .= $chunk . $this->LE; } // Chomp the last linefeed $encoded = substr($encoded, 0, -strlen($this->LE)); return $encoded; } /** * Encode string to quoted-printable. * @access public * @param string $string the text to encode * @param integer $line_max Number of chars allowed on a line before wrapping * @return string */ public function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) { $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); $lines = preg_split('/(?:\r\n|\r|\n)/', $input); $eol = "\r\n"; $escape = '='; $output = ''; while( list(, $line) = each($lines) ) { $linlen = strlen($line); $newline = ''; for($i = 0; $i < $linlen; $i++) { $c = substr( $line, $i, 1 ); $dec = ord( $c ); if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E $c = '=2E'; } if ( $dec == 32 ) { if ( $i == ( $linlen - 1 ) ) { // convert space at eol only $c = '=20'; } else if ( $space_conv ) { $c = '=20'; } } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required $h2 = floor($dec/16); $h1 = floor($dec%16); $c = $escape.$hex[$h2].$hex[$h1]; } if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay $newline = ''; // check if newline first character will be point or not if ( $dec == 46 ) { $c = '=2E'; } } $newline .= $c; } // end of for $output .= $newline.$eol; } // end of while return trim($output); } /** * Encode string to q encoding. * @access public * @return string */ public function EncodeQ ($str, $position = 'text') { /* There should not be any EOL in the string */ $encoded = preg_replace("[\r\n]", '', $str); switch (strtolower($position)) { case 'phrase': $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); break; case 'comment': $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); case 'text': default: /* Replace every high ascii, control =, ? and _ characters */ $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded); break; } /* Replace every spaces to _ (more readable than =20) */ $encoded = str_replace(' ', '_', $encoded); return $encoded; } /** * Adds a string or binary attachment (non-filesystem) to the list. * This method can be used to attach ascii or binary data, * such as a BLOB record from a database. * @param string $string String attachment data. * @param string $filename Name of the attachment. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return void */ public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { /* Append to $attachment array */ $cur = count($this->attachment); $this->attachment[$cur][0] = $string; $this->attachment[$cur][1] = $filename; $this->attachment[$cur][2] = $filename; $this->attachment[$cur][3] = $encoding; $this->attachment[$cur][4] = $type; $this->attachment[$cur][5] = true; // isString $this->attachment[$cur][6] = 'attachment'; $this->attachment[$cur][7] = 0; } /** * Adds an embedded attachment. This can include images, sounds, and * just about any other document. Make sure to set the $type to an * image type. For JPEG images use "image/jpeg" and for GIF images * use "image/gif". * @param string $path Path to the attachment. * @param string $cid Content ID of the attachment. Use this to identify * the Id for accessing the image in an HTML form. * @param string $name Overrides the attachment name. * @param string $encoding File encoding (see $Encoding). * @param string $type File extension (MIME) type. * @return bool */ public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { if(!@is_file($path)) { $this->SetError($this->Lang('file_access') . $path); return false; } $filename = basename($path); if($name == '') { $name = $filename; } /* Append to $attachment array */ $cur = count($this->attachment); $this->attachment[$cur][0] = $path; $this->attachment[$cur][1] = $filename; $this->attachment[$cur][2] = $name; $this->attachment[$cur][3] = $encoding; $this->attachment[$cur][4] = $type; $this->attachment[$cur][5] = false; $this->attachment[$cur][6] = 'inline'; $this->attachment[$cur][7] = $cid; return true; } /** * Returns true if an inline attachment is present. * @access public * @return bool */ public function InlineImageExists() { $result = false; for($i = 0; $i < count($this->attachment); $i++) { if($this->attachment[$i][6] == 'inline') { $result = true; break; } } return $result; } ///////////////////////////////////////////////// // CLASS METHODS, MESSAGE RESET ///////////////////////////////////////////////// /** * Clears all recipients assigned in the TO array. Returns void. * @return void */ public function ClearAddresses() { $this->to = array(); } /** * Clears all recipients assigned in the CC array. Returns void. * @return void */ public function ClearCCs() { $this->cc = array(); } /** * Clears all recipients assigned in the BCC array. Returns void. * @return void */ public function ClearBCCs() { $this->bcc = array(); } /** * Clears all recipients assigned in the ReplyTo array. Returns void. * @return void */ public function ClearReplyTos() { $this->ReplyTo = array(); } /** * Clears all recipients assigned in the TO, CC and BCC * array. Returns void. * @return void */ public function ClearAllRecipients() { $this->to = array(); $this->cc = array(); $this->bcc = array(); } /** * Clears all previously set filesystem, string, and binary * attachments. Returns void. * @return void */ public function ClearAttachments() { $this->attachment = array(); } /** * Clears all custom headers. Returns void. * @return void */ public function ClearCustomHeaders() { $this->CustomHeader = array(); } ///////////////////////////////////////////////// // CLASS METHODS, MISCELLANEOUS ///////////////////////////////////////////////// /** * Adds the error message to the error container. * Returns void. * @access private * @return void */ private function SetError($msg) { $this->error_count++; $this->ErrorInfo = $msg; } /** * Returns the proper RFC 822 formatted date. * @access private * @return string */ private static function RFCDate() { $tz = date('Z'); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int)($tz/3600)*100 + ($tz%3600)/60; $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); return $result; } /** * Returns the server hostname or 'localhost.localdomain' if unknown. * @access private * @return string */ private function ServerHostname() { if (!empty($this->Hostname)) { $result = $this->Hostname; } elseif (isset($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } else { $result = "localhost.localdomain"; } return $result; } /** * Returns a message in the appropriate language. * @access private * @return string */ private function Lang($key) { if(count($this->language) < 1) { $this->SetLanguage('en'); // set the default language } if(isset($this->language[$key])) { return $this->language[$key]; } else { return 'Language string failed to load: ' . $key; } } /** * Returns true if an error occurred. * @access public * @return bool */ public function IsError() { return ($this->error_count > 0); } /** * Changes every end of line from CR or LF to CRLF. * @access private * @return string */ private function FixEOL($str) { $str = str_replace("\r\n", "\n", $str); $str = str_replace("\r", "\n", $str); $str = str_replace("\n", $this->LE, $str); return $str; } /** * Adds a custom header. * @access public * @return void */ public function AddCustomHeader($custom_header) { $this->CustomHeader[] = explode(':', $custom_header, 2); } /** * Evaluates the message and returns modifications for inline images and backgrounds * @access public * @return $message */ public function MsgHTML($message,$basedir='') { preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); if(isset($images[2])) { foreach($images[2] as $i => $url) { // do not change urls for absolute images (thanks to corvuscorax) if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) { $filename = basename($url); $directory = dirname($url); ($directory == '.')?$directory='':''; $cid = 'cid:' . md5($filename); $fileParts = split("\.", $filename); $ext = $fileParts[1]; $mimeType = $this->_mime_types($ext); if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } if ( strlen($directory) > 1 && substr($basedir,-1) != '/') { $directory .= '/'; } $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType); if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) { $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message); } } } } $this->IsHTML(true); $this->Body = $message; $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); if ( !empty($textMsg) && empty($this->AltBody) ) { $this->AltBody = $textMsg; } if ( empty($this->AltBody) ) { $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n"; } } /** * Gets the mime type of the embedded or inline image * @access public * @return mime type of ext */ public function _mime_types($ext = '') { $mimes = array( 'hqx' => 'application/mac-binhex40', 'cpt' => 'application/mac-compactpro', 'doc' => 'application/msword', 'bin' => 'application/macbinary', 'dms' => 'application/octet-stream', 'lha' => 'application/octet-stream', 'lzh' => 'application/octet-stream', 'exe' => 'application/octet-stream', 'class' => 'application/octet-stream', 'psd' => 'application/octet-stream', 'so' => 'application/octet-stream', 'sea' => 'application/octet-stream', 'dll' => 'application/octet-stream', 'oda' => 'application/oda', 'pdf' => 'application/pdf', 'ai' => 'application/postscript', 'eps' => 'application/postscript', 'ps' => 'application/postscript', 'smi' => 'application/smil', 'smil' => 'application/smil', 'mif' => 'application/vnd.mif', 'xls' => 'application/vnd.ms-excel', 'ppt' => 'application/vnd.ms-powerpoint', 'wbxml' => 'application/vnd.wap.wbxml', 'wmlc' => 'application/vnd.wap.wmlc', 'dcr' => 'application/x-director', 'dir' => 'application/x-director', 'dxr' => 'application/x-director', 'dvi' => 'application/x-dvi', 'gtar' => 'application/x-gtar', 'php' => 'application/x-httpd-php', 'php4' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php', 'phtml' => 'application/x-httpd-php', 'phps' => 'application/x-httpd-php-source', 'js' => 'application/x-javascript', 'swf' => 'application/x-shockwave-flash', 'sit' => 'application/x-stuffit', 'tar' => 'application/x-tar', 'tgz' => 'application/x-tar', 'xhtml' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml', 'zip' => 'application/zip', 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mpga' => 'audio/mpeg', 'mp2' => 'audio/mpeg', 'mp3' => 'audio/mpeg', 'aif' => 'audio/x-aiff', 'aiff' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', 'ram' => 'audio/x-pn-realaudio', 'rm' => 'audio/x-pn-realaudio', 'rpm' => 'audio/x-pn-realaudio-plugin', 'ra' => 'audio/x-realaudio', 'rv' => 'video/vnd.rn-realvideo', 'wav' => 'audio/x-wav', 'bmp' => 'image/bmp', 'gif' => 'image/gif', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'jpe' => 'image/jpeg', 'png' => 'image/png', 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'css' => 'text/css', 'html' => 'text/html', 'htm' => 'text/html', 'shtml' => 'text/html', 'txt' => 'text/plain', 'text' => 'text/plain', 'log' => 'text/plain', 'rtx' => 'text/richtext', 'rtf' => 'text/rtf', 'xml' => 'text/xml', 'xsl' => 'text/xml', 'mpeg' => 'video/mpeg', 'mpg' => 'video/mpeg', 'mpe' => 'video/mpeg', 'qt' => 'video/quicktime', 'mov' => 'video/quicktime', 'avi' => 'video/x-msvideo', 'movie' => 'video/x-sgi-movie', 'doc' => 'application/msword', 'word' => 'application/msword', 'xl' => 'application/excel', 'eml' => 'message/rfc822' ); return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; } /** * Set (or reset) Class Objects (variables) * * Usage Example: * $page->set('X-Priority', '3'); * * @access public * @param string $name Parameter Name * @param mixed $value Parameter Value * NOTE: will not work with arrays, there are no arrays to set/reset */ public function set ( $name, $value = '' ) { if ( isset($this->$name) ) { $this->$name = $value; } else { $this->SetError('Cannot set or reset variable ' . $name); return false; } } /** * Read a file from a supplied filename and return it. * * @access public * @param string $filename Parameter File Name */ public function getFile($filename) { $return = ''; if ($fp = fopen($filename, 'rb')) { while (!feof($fp)) { $return .= fread($fp, 1024); } fclose($fp); return $return; } else { return false; } } /** * Strips newlines to prevent header injection. * @access public * @param string $str String * @return string */ public function SecureHeader($str) { $str = trim($str); $str = str_replace("\r", "", $str); $str = str_replace("\n", "", $str); return $str; } /** * Set the private key file and password to sign the message. * * @access public * @param string $key_filename Parameter File Name * @param string $key_pass Password for private key */ public function Sign($key_filename, $key_pass) { $this->sign_key_file = $key_filename; $this->sign_key_pass = $key_pass; } } ?> ��������Collabtive-2.0/include/class.PclZip.php�������������������������������������������������������������0000664�0000000�0000000�00000742421�12372520637�0020121�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php // -------------------------------------------------------------------------------- // Zip Module 2.6 // -------------------------------------------------------------------------------- // License GNU/LGPL - Vincent Blavet - March 2006 // -------------------------------------------------------------------------------- // ----- Constants if (!defined('PCLZIP_READ_BLOCK_SIZE')) { define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); } // ----- File list separator // In version 1.x of PclZip, the separator for file list is a space // (which is not a very smart choice, specifically for windows paths !). // A better separator should be a comma (,). This constant gives you the // abilty to change that. // However notice that changing this value, may have impact on existing // scripts, using space separated filenames. // Recommanded values for compatibility with older versions : //define( 'PCLZIP_SEPARATOR', ' ' ); // Recommanded values for smart separation of filenames. if (!defined('PCLZIP_SEPARATOR')) { define( 'PCLZIP_SEPARATOR', ',' ); } // ----- Error configuration // 0 : PclZip Class integrated error handling // 1 : PclError external library error handling. By enabling this // you must ensure that you have included PclError library. // [2,...] : reserved for futur use if (!defined('PCLZIP_ERROR_EXTERNAL')) { define( 'PCLZIP_ERROR_EXTERNAL', 0 ); } // ----- Optional static temporary directory // By default temporary files are generated in the script current // path. // If defined : // - MUST BE terminated by a '/'. // - MUST be a valid, already created directory // Samples : // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); if (!defined('PCLZIP_TEMPORARY_DIR')) { define( 'PCLZIP_TEMPORARY_DIR', '' ); } // -------------------------------------------------------------------------------- // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** // -------------------------------------------------------------------------------- // ----- Global variables $g_pclzip_version = "2.6"; // ----- Error codes // -1 : Unable to open file in binary write mode // -2 : Unable to open file in binary read mode // -3 : Invalid parameters // -4 : File does not exist // -5 : Filename is too long (max. 255) // -6 : Not a valid zip file // -7 : Invalid extracted file size // -8 : Unable to create directory // -9 : Invalid archive extension // -10 : Invalid archive format // -11 : Unable to delete file (unlink) // -12 : Unable to rename file (rename) // -13 : Invalid header checksum // -14 : Invalid archive size define( 'PCLZIP_ERR_USER_ABORTED', 2 ); define( 'PCLZIP_ERR_NO_ERROR', 0 ); define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); define( 'PCLZIP_ERR_MISSING_FILE', -4 ); define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); // ----- Options values define( 'PCLZIP_OPT_PATH', 77001 ); define( 'PCLZIP_OPT_ADD_PATH', 77002 ); define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); define( 'PCLZIP_OPT_BY_NAME', 77008 ); define( 'PCLZIP_OPT_BY_INDEX', 77009 ); define( 'PCLZIP_OPT_BY_EREG', 77010 ); define( 'PCLZIP_OPT_BY_PREG', 77011 ); define( 'PCLZIP_OPT_COMMENT', 77012 ); define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); // Having big trouble with crypt. Need to multiply 2 long int // which is not correctly supported by PHP ... //define( 'PCLZIP_OPT_CRYPT', 77018 ); define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); // ----- File description attributes define( 'PCLZIP_ATT_FILE_NAME', 79001 ); define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); // ----- Call backs values define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); define( 'PCLZIP_CB_PRE_ADD', 78003 ); define( 'PCLZIP_CB_POST_ADD', 78004 ); /* For futur use define( 'PCLZIP_CB_PRE_LIST', 78005 ); define( 'PCLZIP_CB_POST_LIST', 78006 ); define( 'PCLZIP_CB_PRE_DELETE', 78007 ); define( 'PCLZIP_CB_POST_DELETE', 78008 ); */ // -------------------------------------------------------------------------------- // Class : PclZip // Description : // PclZip is the class that represent a Zip archive. // The public methods allow the manipulation of the archive. // Attributes : // Attributes must not be accessed directly. // Methods : // PclZip() : Object creator // create() : Creates the Zip archive // listContent() : List the content of the Zip archive // extract() : Extract the content of the archive // properties() : List the properties of the archive // -------------------------------------------------------------------------------- class PclZip { // ----- Filename of the zip file var $zipname = ''; // ----- File descriptor of the zip file var $zip_fd = 0; // ----- Internal error handling var $error_code = 1; var $error_string = ''; // ----- Current status of the magic_quotes_runtime // This value store the php configuration for magic_quotes // The class can then disable the magic_quotes and reset it after var $magic_quotes_status; // -------------------------------------------------------------------------------- // Function : PclZip() // Description : // Creates a PclZip object and set the name of the associated Zip archive // filename. // Note that no real action is taken, if the archive does not exist it is not // created. Use create() for that. // -------------------------------------------------------------------------------- function PclZip($p_zipname) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname"); // ----- Tests the zlib if (!function_exists('gzopen')) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing"); die('Abort '.basename(__FILE__).' : Missing zlib extensions'); } // ----- Set the attributes $this->zipname = $p_zipname; $this->zip_fd = 0; $this->magic_quotes_status = -1; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1); return; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // create($p_filelist, $p_add_dir="", $p_remove_dir="") // create($p_filelist, $p_option, $p_option_value, ...) // Description : // This method supports two different synopsis. The first one is historical. // This method creates a Zip Archive. The Zip file is created in the // filesystem. The files and directories indicated in $p_filelist // are added in the archive. See the parameters description for the // supported format of $p_filelist. // When a directory is in the list, the directory and its content is added // in the archive. // In this synopsis, the function takes an optional variable list of // options. See bellow the supported options. // Parameters : // $p_filelist : An array containing file or directory names, or // a string containing one filename or one directory name, or // a string containing a list of filenames and/or directory // names separated by spaces. // $p_add_dir : A path to add before the real path of the archived file, // in order to have it memorized in the archive. // $p_remove_dir : A path to remove from the real path of the file to archive, // in order to have a shorter path memorized in the archive. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir // is removed first, before $p_add_dir is added. // Options : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_OPT_COMMENT : // PCLZIP_CB_PRE_ADD : // PCLZIP_CB_POST_ADD : // Return Values : // 0 on failure, // The list of the added files, with a status of the add action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function create($p_filelist) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ..."); $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Set default values $v_options = array(); $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; // ----- Look for variable options arguments $v_size = func_num_args(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); // ----- Look for arguments if ($v_size > 1) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Remove from the options list the first argument array_shift($v_arg_list); $v_size--; // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected"); // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_ADD => 'optional', PCLZIP_CB_POST_ADD => 'optional', PCLZIP_OPT_NO_COMPRESSION => 'optional', PCLZIP_OPT_COMMENT => 'optional' //, PCLZIP_OPT_CRYPT => 'optional' )); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); // ----- Get the first argument $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } else if ($v_size > 2) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return 0; } } } // ----- Init $v_string_list = array(); $v_att_list = array(); $v_filedescr_list = array(); $p_result_list = array(); // ----- Look if the $p_filelist is really an array if (is_array($p_filelist)) { // ----- Look if the first element is also an array // This will mean that this is a file description entry if (isset($p_filelist[0]) && is_array($p_filelist[0])) { $v_att_list = $p_filelist; } // ----- The list is a list of string names else { $v_string_list = $p_filelist; } } // ----- Look if the $p_filelist is a string else if (is_string($p_filelist)) { // ----- Create a list from the string $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); } // ----- Invalid variable type for $p_filelist else { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Reformat the string list if (sizeof($v_string_list) != 0) { foreach ($v_string_list as $v_string) { if ($v_string != '') { $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename"); } } } // ----- For each file in the list check the attributes $v_supported_attributes = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' ,PCLZIP_ATT_FILE_MTIME => 'optional' ,PCLZIP_ATT_FILE_CONTENT => 'optional' ,PCLZIP_ATT_FILE_COMMENT => 'optional' ); foreach ($v_att_list as $v_entry) { $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } } // ----- Expand the filelist (expand directories) $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Call the create fct $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list); return $p_result_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // add($p_filelist, $p_add_dir="", $p_remove_dir="") // add($p_filelist, $p_option, $p_option_value, ...) // Description : // This method supports two synopsis. The first one is historical. // This methods add the list of files in an existing archive. // If a file with the same name already exists, it is added at the end of the // archive, the first one is still present. // If the archive does not exist, it is created. // Parameters : // $p_filelist : An array containing file or directory names, or // a string containing one filename or one directory name, or // a string containing a list of filenames and/or directory // names separated by spaces. // $p_add_dir : A path to add before the real path of the archived file, // in order to have it memorized in the archive. // $p_remove_dir : A path to remove from the real path of the file to archive, // in order to have a shorter path memorized in the archive. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir // is removed first, before $p_add_dir is added. // Options : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_OPT_COMMENT : // PCLZIP_OPT_ADD_COMMENT : // PCLZIP_OPT_PREPEND_COMMENT : // PCLZIP_CB_PRE_ADD : // PCLZIP_CB_POST_ADD : // Return Values : // 0 on failure, // The list of the added files, with a status of the add action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function add($p_filelist) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ..."); $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Set default values $v_options = array(); $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; // ----- Look for variable options arguments $v_size = func_num_args(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); // ----- Look for arguments if ($v_size > 1) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Remove form the options list the first argument array_shift($v_arg_list); $v_size--; // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected"); // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_ADD => 'optional', PCLZIP_CB_POST_ADD => 'optional', PCLZIP_OPT_NO_COMPRESSION => 'optional', PCLZIP_OPT_COMMENT => 'optional', PCLZIP_OPT_ADD_COMMENT => 'optional', PCLZIP_OPT_PREPEND_COMMENT => 'optional' //, PCLZIP_OPT_CRYPT => 'optional' )); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); // ----- Get the first argument $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } else if ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return 0; } } } // ----- Init $v_string_list = array(); $v_att_list = array(); $v_filedescr_list = array(); $p_result_list = array(); // ----- Look if the $p_filelist is really an array if (is_array($p_filelist)) { // ----- Look if the first element is also an array // This will mean that this is a file description entry if (isset($p_filelist[0]) && is_array($p_filelist[0])) { $v_att_list = $p_filelist; } // ----- The list is a list of string names else { $v_string_list = $p_filelist; } } // ----- Look if the $p_filelist is a string else if (is_string($p_filelist)) { // ----- Create a list from the string $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); } // ----- Invalid variable type for $p_filelist else { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Reformat the string list if (sizeof($v_string_list) != 0) { foreach ($v_string_list as $v_string) { $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; } } // ----- For each file in the list check the attributes $v_supported_attributes = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' ,PCLZIP_ATT_FILE_MTIME => 'optional' ,PCLZIP_ATT_FILE_CONTENT => 'optional' ,PCLZIP_ATT_FILE_COMMENT => 'optional' ); foreach ($v_att_list as $v_entry) { $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } } // ----- Expand the filelist (expand directories) $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Call the create fct $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list); return $p_result_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : listContent() // Description : // This public method, gives the list of the files and directories, with their // properties. // The properties of each entries in the list are (used also in other functions) : // filename : Name of the file. For a create or add action it is the filename // given by the user. For an extract function it is the filename // of the extracted file. // stored_filename : Name of the file / directory stored in the archive. // size : Size of the stored file. // compressed_size : Size of the file's data compressed in the archive // (without the headers overhead) // mtime : Last known modification date of the file (UNIX timestamp) // comment : Comment associated with the file // folder : true | false // index : index of the file in the archive // status : status of the action (depending of the action) : // Values are : // ok : OK ! // filtered : the file / dir is not extracted (filtered by user) // already_a_directory : the file can not be extracted because a // directory with the same name already exists // write_protected : the file can not be extracted because a file // with the same name already exists and is // write protected // newer_exist : the file was not extracted because a newer file exists // path_creation_fail : the file is not extracted because the folder // does not exists and can not be created // write_error : the file was not extracted because there was a // error while writing the file // read_error : the file was not extracted because there was a error // while reading the file // invalid_header : the file was not extracted because of an archive // format error (bad file header) // Note that each time a method can continue operating when there // is an action error on a file, the error is only logged in the file status. // Return Values : // 0 on an unrecoverable failure, // The list of the files in the archive. // -------------------------------------------------------------------------------- function listContent() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', ""); $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return(0); } // ----- Call the extracting fct $p_list = array(); if (($v_result = $this->privList($p_list)) != 1) { unset($p_list); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); return(0); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // extract($p_path="./", $p_remove_path="") // extract([$p_option, $p_option_value, ...]) // Description : // This method supports two synopsis. The first one is historical. // This method extract all the files / directories from the archive to the // folder indicated in $p_path. // If you want to ignore the 'root' part of path of the memorized files // you can indicate this in the optional $p_remove_path parameter. // By default, if a newer file with the same name already exists, the // file is not extracted. // // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append // at the end of the path value of PCLZIP_OPT_PATH. // Parameters : // $p_path : Path where the files and directories are to be extracted // $p_remove_path : First part ('root' part) of the memorized path // (if any similar) to remove while extracting. // Options : // PCLZIP_OPT_PATH : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_CB_PRE_EXTRACT : // PCLZIP_CB_POST_EXTRACT : // Return Values : // 0 or a negative value on failure, // The list of the extracted files, with a status of the action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function extract() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", ""); $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return(0); } // ----- Set default values $v_options = array(); // $v_path = "./"; $v_path = ''; $v_remove_path = ""; $v_remove_all_path = false; // ----- Look for variable options arguments $v_size = func_num_args(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); // ----- Default values for option $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; // ----- Look for arguments if ($v_size > 0) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options"); // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_PATH => 'optional', PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_EXTRACT => 'optional', PCLZIP_CB_POST_EXTRACT => 'optional', PCLZIP_OPT_SET_CHMOD => 'optional', PCLZIP_OPT_BY_NAME => 'optional', PCLZIP_OPT_BY_EREG => 'optional', PCLZIP_OPT_BY_PREG => 'optional', PCLZIP_OPT_BY_INDEX => 'optional', PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', PCLZIP_OPT_REPLACE_NEWER => 'optional' ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional' )); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Set the arguments if (isset($v_options[PCLZIP_OPT_PATH])) { $v_path = $v_options[PCLZIP_OPT_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { // ----- Check for '/' in last path char if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { $v_path .= '/'; } $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); // ----- Get the first argument $v_path = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_remove_path = $v_arg_list[1]; } else if ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); return 0; } } } // ----- Trace //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'"); // ----- Call the extracting fct $p_list = array(); $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options); if ($v_result < 1) { unset($p_list); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); return(0); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // extractByIndex($p_index, $p_path="./", $p_remove_path="") // extractByIndex($p_index, [$p_option, $p_option_value, ...]) // Description : // This method supports two synopsis. The first one is historical. // This method is doing a partial extract of the archive. // The extracted files or folders are identified by their index in the // archive (from 0 to n). // Note that if the index identify a folder, only the folder entry is // extracted, not all the files included in the archive. // Parameters : // $p_index : A single index (integer) or a string of indexes of files to // extract. The form of the string is "0,4-6,8-12" with only numbers // and '-' for range or ',' to separate ranges. No spaces or ';' // are allowed. // $p_path : Path where the files and directories are to be extracted // $p_remove_path : First part ('root' part) of the memorized path // (if any similar) to remove while extracting. // Options : // PCLZIP_OPT_PATH : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and // not as files. // The resulting content is in a new field 'content' in the file // structure. // This option must be used alone (any other options are ignored). // PCLZIP_CB_PRE_EXTRACT : // PCLZIP_CB_POST_EXTRACT : // Return Values : // 0 on failure, // The list of the extracted files, with a status of the action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- //function extractByIndex($p_index, options...) function extractByIndex($p_index) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ..."); $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return(0); } // ----- Set default values $v_options = array(); // $v_path = "./"; $v_path = ''; $v_remove_path = ""; $v_remove_all_path = false; // ----- Look for variable options arguments $v_size = func_num_args(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); // ----- Default values for option $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; // ----- Look for arguments if ($v_size > 1) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Remove form the options list the first argument array_shift($v_arg_list); $v_size--; // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options"); // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_PATH => 'optional', PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_EXTRACT => 'optional', PCLZIP_CB_POST_EXTRACT => 'optional', PCLZIP_OPT_SET_CHMOD => 'optional', PCLZIP_OPT_REPLACE_NEWER => 'optional' ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional' )); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Set the arguments if (isset($v_options[PCLZIP_OPT_PATH])) { $v_path = $v_options[PCLZIP_OPT_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { // ----- Check for '/' in last path char if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { $v_path .= '/'; } $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; } if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set."); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set."); } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); // ----- Get the first argument $v_path = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_remove_path = $v_arg_list[1]; } else if ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return 0; } } } // ----- Trace //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'"); // ----- Trick // Here I want to reuse extractByRule(), so I need to parse the $p_index // with privParseOptions() $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); $v_options_trick = array(); $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array (PCLZIP_OPT_BY_INDEX => 'optional' )); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; // ----- Call the extracting fct if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); return(0); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // delete([$p_option, $p_option_value, ...]) // Description : // This method removes files from the archive. // If no parameters are given, then all the archive is emptied. // Parameters : // None or optional arguments. // Options : // PCLZIP_OPT_BY_INDEX : // PCLZIP_OPT_BY_NAME : // PCLZIP_OPT_BY_EREG : // PCLZIP_OPT_BY_PREG : // Return Values : // 0 on failure, // The list of the files which are still present in the archive. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function delete() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", ""); $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return(0); } // ----- Set default values $v_options = array(); // ----- Look for variable options arguments $v_size = func_num_args(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); // ----- Look for arguments if ($v_size > 0) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_BY_NAME => 'optional', PCLZIP_OPT_BY_EREG => 'optional', PCLZIP_OPT_BY_PREG => 'optional', PCLZIP_OPT_BY_INDEX => 'optional' )); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } } // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Call the delete fct $v_list = array(); if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { $this->privSwapBackMagicQuotes(); unset($v_list); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); return(0); } // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list); return $v_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : deleteByIndex() // Description : // ***** Deprecated ***** // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. // -------------------------------------------------------------------------------- function deleteByIndex($p_index) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'"); $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : properties() // Description : // This method gives the properties of the archive. // The properties are : // nb : Number of files in the archive // comment : Comment associated with the archive file // status : not_exist, ok // Parameters : // None // Return Values : // 0 on failure, // An array with the archive properties. // -------------------------------------------------------------------------------- function properties() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", ""); // ----- Reset the error handler $this->privErrorReset(); // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Check archive if (!$this->privCheckFormat()) { $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return(0); } // ----- Default properties $v_prop = array(); $v_prop['comment'] = ''; $v_prop['nb'] = 0; $v_prop['status'] = 'not_exist'; // ----- Look if file exists if (@is_file($this->zipname)) { // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0); return 0; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return 0; } // ----- Close the zip file $this->privCloseFd(); // ----- Set the user attributes $v_prop['comment'] = $v_central_dir['comment']; $v_prop['nb'] = $v_central_dir['entries']; $v_prop['status'] = 'ok'; } // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop); return $v_prop; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : duplicate() // Description : // This method creates an archive by copying the content of an other one. If // the archive already exist, it is replaced by the new one without any warning. // Parameters : // $p_archive : The filename of a valid archive, or // a valid PclZip object. // Return Values : // 1 on success. // 0 or a negative value on error (error code). // -------------------------------------------------------------------------------- function duplicate($p_archive) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", ""); $v_result = 1; // ----- Reset the error handler $this->privErrorReset(); // ----- Look if the $p_archive is a PclZip object if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'"); // ----- Duplicate the archive $v_result = $this->privDuplicate($p_archive->zipname); } // ----- Look if the $p_archive is a string (so a filename) else if (is_string($p_archive)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'"); // ----- Check that $p_archive is a valid zip file // TBC : Should also check the archive format if (!is_file($p_archive)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); $v_result = PCLZIP_ERR_MISSING_FILE; } else { // ----- Duplicate the archive $v_result = $this->privDuplicate($p_archive); } } // ----- Invalid variable else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); $v_result = PCLZIP_ERR_INVALID_PARAMETER; } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : merge() // Description : // This method merge the $p_archive_to_add archive at the end of the current // one ($this). // If the archive ($this) does not exist, the merge becomes a duplicate. // If the $p_archive_to_add archive does not exist, the merge is a success. // Parameters : // $p_archive_to_add : It can be directly the filename of a valid zip archive, // or a PclZip object archive. // Return Values : // 1 on success, // 0 or negative values on error (see below). // -------------------------------------------------------------------------------- function merge($p_archive_to_add) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", ""); $v_result = 1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); return(0); } // ----- Look if the $p_archive_to_add is a PclZip object if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object"); // ----- Merge the archive $v_result = $this->privMerge($p_archive_to_add); } // ----- Look if the $p_archive_to_add is a string (so a filename) else if (is_string($p_archive_to_add)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename"); // ----- Create a temporary archive $v_object_archive = new PclZip($p_archive_to_add); // ----- Merge the archive $v_result = $this->privMerge($v_object_archive); } // ----- Invalid variable else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); $v_result = PCLZIP_ERR_INVALID_PARAMETER; } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : errorCode() // Description : // Parameters : // -------------------------------------------------------------------------------- function errorCode() { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorCode()); } else { return($this->error_code); } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : errorName() // Description : // Parameters : // -------------------------------------------------------------------------------- function errorName($p_with_code=false) { $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' ); if (isset($v_name[$this->error_code])) { $v_value = $v_name[$this->error_code]; } else { $v_value = 'NoName'; } if ($p_with_code) { return($v_value.' ('.$this->error_code.')'); } else { return($v_value); } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : errorInfo() // Description : // Parameters : // -------------------------------------------------------------------------------- function errorInfo($p_full=false) { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorString()); } else { if ($p_full) { return($this->errorName(true)." : ".$this->error_string); } else { return($this->error_string." [code ".$this->error_code."]"); } } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** // ***** ***** // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCheckFormat() // Description : // This method check that the archive exists and is a valid zip archive. // Several level of check exists. (futur) // Parameters : // $p_level : Level of check. Default 0. // 0 : Check the first bytes (magic codes) (default value)) // 1 : 0 + Check the central directory (futur) // 2 : 1 + Check each file header (futur) // Return Values : // true on success, // false on error, the error code is set. // -------------------------------------------------------------------------------- function privCheckFormat($p_level=0) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", ""); $v_result = true; // ----- Reset the file system cache clearstatcache(); // ----- Reset the error handler $this->privErrorReset(); // ----- Look if the file exits if (!is_file($this->zipname)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo()); return(false); } // ----- Check that the file is readeable if (!is_readable($this->zipname)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo()); return(false); } // ----- Check the magic code // TBC // ----- Check the central header // TBC // ----- Check each file header // TBC // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privParseOptions() // Description : // This internal methods reads the variable list of arguments ($p_options_list, // $p_size) and generate an array with the options and values ($v_result_list). // $v_requested_options contains the options that can be present and those that // must be present. // $v_requested_options is an array, with the option value as key, and 'optional', // or 'mandatory' as value. // Parameters : // See above. // Return Values : // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", ""); $v_result=1; // ----- Read the options $i=0; while ($i<$p_size) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'"); // ----- Check if the option is supported if (!isset($v_requested_options[$p_options_list[$i]])) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Look for next option switch ($p_options_list[$i]) { // ----- Look for options that request a path value case PCLZIP_OPT_PATH : case PCLZIP_OPT_REMOVE_PATH : case PCLZIP_OPT_ADD_PATH : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); $i++; break; case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value if ( is_string($p_options_list[$i+1]) && ($p_options_list[$i+1] != '')) { $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); $i++; } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored."); } break; // ----- Look for options that request an array of string for value case PCLZIP_OPT_BY_NAME : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; } else if (is_array($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); $i++; break; // ----- Look for options that request an EREG or PREG expression case PCLZIP_OPT_BY_EREG : case PCLZIP_OPT_BY_PREG : //case PCLZIP_OPT_CRYPT : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); $i++; break; // ----- Look for options that takes a string case PCLZIP_OPT_COMMENT : case PCLZIP_OPT_ADD_COMMENT : case PCLZIP_OPT_PREPEND_COMMENT : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" .PclZipUtilOptionText($p_options_list[$i]) ."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" .PclZipUtilOptionText($p_options_list[$i]) ."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); $i++; break; // ----- Look for options that request an array of index case PCLZIP_OPT_BY_INDEX : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value $v_work_list = array(); if (is_string($p_options_list[$i+1])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'"); // ----- Remove spaces $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); // ----- Parse items $v_work_list = explode(",", $p_options_list[$i+1]); } else if (is_integer($p_options_list[$i+1])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'"); $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; } else if (is_array($p_options_list[$i+1])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array"); $v_work_list = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Reduce the index list // each index item in the list must be a couple with a start and // an end value : [0,3], [5-5], [8-10], ... // ----- Check the format of each item $v_sort_flag=false; $v_sort_value=0; for ($j=0; $j<sizeof($v_work_list); $j++) { // ----- Explode the item $v_item_list = explode("-", $v_work_list[$j]); $v_size_item_list = sizeof($v_item_list); // ----- TBC : Here we might check that each item is a // real integer ... // ----- Look for single value if ($v_size_item_list == 1) { // ----- Set the option value $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; } elseif ($v_size_item_list == 2) { // ----- Set the option value $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]"); // ----- Look for list sort if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ..."); $v_sort_flag=true; // ----- TBC : An automatic sort should be writen ... // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; } // ----- Sort the items if ($v_sort_flag) { // TBC : To Be Completed //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ..."); } // ----- Next option $i++; break; // ----- Look for options that request no value case PCLZIP_OPT_REMOVE_ALL_PATH : case PCLZIP_OPT_EXTRACT_AS_STRING : case PCLZIP_OPT_NO_COMPRESSION : case PCLZIP_OPT_EXTRACT_IN_OUTPUT : case PCLZIP_OPT_REPLACE_NEWER : case PCLZIP_OPT_STOP_ON_ERROR : $v_result_list[$p_options_list[$i]] = true; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); break; // ----- Look for options that request an octal value case PCLZIP_OPT_SET_CHMOD : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); $i++; break; // ----- Look for options that request a call-back case PCLZIP_CB_PRE_EXTRACT : case PCLZIP_CB_POST_EXTRACT : case PCLZIP_CB_PRE_ADD : case PCLZIP_CB_POST_ADD : /* for futur use case PCLZIP_CB_PRE_DELETE : case PCLZIP_CB_POST_DELETE : case PCLZIP_CB_PRE_LIST : case PCLZIP_CB_POST_LIST : */ // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Get the value $v_function_name = $p_options_list[$i+1]; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'"); // ----- Check that the value is a valid existing function if (!function_exists($v_function_name)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Set the attribute $v_result_list[$p_options_list[$i]] = $v_function_name; $i++; break; default : // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" .$p_options_list[$i]."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Next options $i++; } // ----- Look for mandatory options if ($v_requested_options !== false) { for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { // ----- Look for mandatory option if ($v_requested_options[$key] == 'mandatory') { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")"); // ----- Look if present if (!isset($v_result_list[$key])) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privFileDescrParseAtt() // Description : // Parameters : // Return Values : // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", ""); $v_result=1; // ----- For each file in the list check the attributes foreach ($p_file_list as $v_key => $v_value) { // ----- Check if the option is supported if (!isset($v_requested_options[$v_key])) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Look for attribute switch ($v_key) { case PCLZIP_ATT_FILE_NAME : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); if ($p_filedescr['filename'] == '') { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } break; case PCLZIP_ATT_FILE_NEW_SHORT_NAME : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); if ($p_filedescr['new_short_name'] == '') { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } break; case PCLZIP_ATT_FILE_NEW_FULL_NAME : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); if ($p_filedescr['new_full_name'] == '') { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } break; // ----- Look for options that takes a string case PCLZIP_ATT_FILE_COMMENT : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } $p_filedescr['comment'] = $v_value; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); break; case PCLZIP_ATT_FILE_MTIME : if (!is_integer($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } $p_filedescr['mtime'] = $v_value; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); break; case PCLZIP_ATT_FILE_CONTENT : $p_filedescr['content'] = $v_value; ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); break; default : // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '".$v_key."'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Look for mandatory options if ($v_requested_options !== false) { for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { // ----- Look for mandatory option if ($v_requested_options[$key] == 'mandatory') { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")"); // ----- Look if present if (!isset($p_file_list[$key])) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } } } // end foreach } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privFileDescrExpand() // Description : // Parameters : // Return Values : // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- function privFileDescrExpand(&$p_filedescr_list, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", ""); $v_result=1; // ----- Create a result list $v_result_list = array(); // ----- Look each entry for ($i=0; $i<sizeof($p_filedescr_list); $i++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for file ".$i."."); // ----- Get filedescr $v_descr = $p_filedescr_list[$i]; // ----- Reduce the filename //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'"); $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']); $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'"); // ----- Look for real file or folder if (file_exists($v_descr['filename'])) { if (@is_file($v_descr['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file"); $v_descr['type'] = 'file'; } else if (@is_dir($v_descr['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder"); $v_descr['type'] = 'folder'; } else if (@is_link($v_descr['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link"); // skip continue; } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type"); // skip continue; } } // ----- Look for string added as file else if (isset($v_descr['content'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a string added as a file"); $v_descr['type'] = 'virtual_file'; } // ----- Missing file else { // ----- Error log //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists"); PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Calculate the stored filename $this->privCalculateStoredFilename($v_descr, $p_options); // ----- Add the descriptor in result list $v_result_list[sizeof($v_result_list)] = $v_descr; // ----- Look for folder if ($v_descr['type'] == 'folder') { // ----- List of items in folder $v_dirlist_descr = array(); $v_dirlist_nb = 0; if ($v_folder_handler = @opendir($v_descr['filename'])) { while (($v_item_handler = @readdir($v_folder_handler)) !== false) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory"); // ----- Skip '.' and '..' if (($v_item_handler == '.') || ($v_item_handler == '..')) { continue; } // ----- Compose the full filename $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; // ----- Look for different stored filename // Because the name of the folder was changed, the name of the // files/sub-folders also change if ($v_descr['stored_filename'] != $v_descr['filename']) { if ($v_descr['stored_filename'] != '') { $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; } else { $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; } } $v_dirlist_nb++; } @closedir($v_folder_handler); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped."); // TBC : unable to open folder in read mode } // ----- Expand each element of the list if ($v_dirlist_nb != 0) { // ----- Expand if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Concat the resulting list //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')"); $v_result_list = array_merge($v_result_list, $v_dirlist_descr); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'"); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand."); } // ----- Free local array unset($v_dirlist_descr); } } // ----- Get the result list $p_filedescr_list = $v_result_list; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCreate() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privCreate($p_filedescr_list, &$p_result_list, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list"); $v_result=1; $v_list_detail = array(); // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Open the file in write mode if (($v_result = $this->privOpenFd('wb')) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Add the list of files $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); // ----- Close $this->privCloseFd(); // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAdd() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privAdd($p_filedescr_list, &$p_result_list, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list"); $v_result=1; $v_list_detail = array(); // ----- Look if the archive exists or is empty if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it."); // ----- Do a create $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_result=$this->privOpenFd('rb')) != 1) { // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Go to beginning of File //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); // ----- Creates a temporay file $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; // ----- Open the temporary file in write mode //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Copy the files from the archive to the temporary file // TBC : Here I should better append the file and go back to erase the central dir $v_size = $v_central_dir['offset']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = fread($this->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Swap the file descriptor // Here is a trick : I swap the temporary fd with the zip fd, in order to use // the following methods on the temporary fil and not the real archive $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Add the files $v_header_list = array(); if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { fclose($v_zip_temp_fd); $this->privCloseFd(); @unlink($v_zip_temp_name); $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Store the offset of the central dir $v_offset = @ftell($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset"); // ----- Copy the block of file headers from the old archive $v_size = $v_central_dir['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @fread($v_zip_temp_fd, $v_read_size); @fwrite($this->zip_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Create the Central Dir files header for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) { // ----- Create the file header if ($v_header_list[$i]['status'] == 'ok') { if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { fclose($v_zip_temp_fd); $this->privCloseFd(); @unlink($v_zip_temp_name); $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $v_count++; } // ----- Transform the header to a 'usable' info $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } // ----- Zip file comment $v_comment = $v_central_dir['comment']; if (isset($p_options[PCLZIP_OPT_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; } if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; } // ----- Calculate the size of the central header $v_size = @ftell($this->zip_fd)-$v_offset; // ----- Create the central dir footer if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) { // ----- Reset the file list unset($v_header_list); $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Swap back the file descriptor $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Close $this->privCloseFd(); // ----- Close the temporary file @fclose($v_zip_temp_fd); // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Delete the zip file // TBC : I should test the result ... @unlink($this->zipname); // ----- Rename the temporary file // TBC : I should test the result ... //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privOpenFd() // Description : // Parameters : // -------------------------------------------------------------------------------- function privOpenFd($p_mode) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode); $v_result=1; // ----- Look if already open if ($this->zip_fd != 0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode'); if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCloseFd() // Description : // Parameters : // -------------------------------------------------------------------------------- function privCloseFd() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", ""); $v_result=1; if ($this->zip_fd != 0) @fclose($this->zip_fd); $this->zip_fd = 0; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddList() // Description : // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is // different from the real path of the file. This is usefull if you want to have PclTar // running in any directory, and memorize relative path from an other directory. // Parameters : // $p_list : An array containing the file or directory names to add in the tar // $p_result_list : list of added files with their properties (specially the status field) // $p_add_dir : Path to add in the filename path archived // $p_remove_dir : Path to remove in the filename path archived // Return Values : // -------------------------------------------------------------------------------- // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) function privAddList($p_filedescr_list, &$p_result_list, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list"); $v_result=1; // ----- Add the files $v_header_list = array(); if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Store the offset of the central dir $v_offset = @ftell($this->zip_fd); // ----- Create the Central Dir files header for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++) { // ----- Create the file header if ($v_header_list[$i]['status'] == 'ok') { if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $v_count++; } // ----- Transform the header to a 'usable' info $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } // ----- Zip file comment $v_comment = ''; if (isset($p_options[PCLZIP_OPT_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } // ----- Calculate the size of the central header $v_size = @ftell($this->zip_fd)-$v_offset; // ----- Create the central dir footer if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) { // ----- Reset the file list unset($v_header_list); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddFileList() // Description : // Parameters : // $p_filedescr_list : An array containing the file description // or directory names to add in the zip // $p_result_list : list of added files with their properties (specially the status field) // Return Values : // -------------------------------------------------------------------------------- function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "filedescr_list"); $v_result=1; $v_header = array(); // ----- Recuperate the current number of elt in list $v_nb = sizeof($p_result_list); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have ".$v_nb." elements"); // ----- Loop on the files for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { // ----- Format the filename $p_filedescr_list[$j]['filename'] = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file '".$p_filedescr_list[$j]['filename']."'"); // ----- Skip empty file names // TBC : Can this be possible ? not checked in DescrParseAtt ? if ($p_filedescr_list[$j]['filename'] == "") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename"); continue; } // ----- Check the filename if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') && (!file_exists($p_filedescr_list[$j]['filename']))) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_filedescr_list[$j]['filename']."' does not exists"); PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Look if it is a file or a dir with no all path remove option // or a dir with all its path removed // if ( (is_file($p_filedescr_list[$j]['filename'])) // || ( is_dir($p_filedescr_list[$j]['filename']) if ( ($p_filedescr_list[$j]['type'] == 'file') || ($p_filedescr_list[$j]['type'] == 'virtual_file') || ( ($p_filedescr_list[$j]['type'] == 'folder') && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) ) { // ----- Add the file $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, $p_options); if ($v_result != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Store the file infos $p_result_list[$v_nb++] = $v_header; } } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have ".$v_nb." elements"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddFile() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privAddFile($p_filedescr, &$p_header, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'"); $v_result=1; // ----- Working variable $p_filename = $p_filedescr['filename']; // TBC : Already done in the fileAtt check ... ? if ($p_filename == "") { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Look for a stored different filename /* TBC : Removed if (isset($p_filedescr['stored_filename'])) { $v_stored_filename = $p_filedescr['stored_filename']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"'); } else { $v_stored_filename = $p_filedescr['stored_filename']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same'); } */ // ----- Set the file properties clearstatcache(); $p_header['version'] = 20; $p_header['version_extracted'] = 10; $p_header['flag'] = 0; $p_header['compression'] = 0; $p_header['crc'] = 0; $p_header['compressed_size'] = 0; $p_header['filename_len'] = strlen($p_filename); $p_header['extra_len'] = 0; $p_header['disk'] = 0; $p_header['internal'] = 0; $p_header['offset'] = 0; $p_header['filename'] = $p_filename; // TBC : Removed $p_header['stored_filename'] = $v_stored_filename; $p_header['stored_filename'] = $p_filedescr['stored_filename']; $p_header['extra'] = ''; $p_header['status'] = 'ok'; $p_header['index'] = -1; // ----- Look for regular file if ($p_filedescr['type']=='file') { $p_header['external'] = 0x00000000; $p_header['size'] = filesize($p_filename); } // ----- Look for regular folder else if ($p_filedescr['type']=='folder') { $p_header['external'] = 0x00000010; $p_header['mtime'] = filemtime($p_filename); $p_header['size'] = filesize($p_filename); } // ----- Look for virtual file else if ($p_filedescr['type'] == 'virtual_file') { $p_header['external'] = 0x00000000; $p_header['size'] = strlen($p_filedescr['content']); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'"); // ----- Look for filetime if (isset($p_filedescr['mtime'])) { $p_header['mtime'] = $p_filedescr['mtime']; } else if ($p_filedescr['type'] == 'virtual_file') { $p_header['mtime'] = mktime(); } else { $p_header['mtime'] = filemtime($p_filename); } // ------ Look for file comment if (isset($p_filedescr['comment'])) { $p_header['comment_len'] = strlen($p_filedescr['comment']); $p_header['comment'] = $p_filedescr['comment']; } else { $p_header['comment_len'] = 0; $p_header['comment'] = ''; } // ----- Look for pre-add callback if (isset($p_options[PCLZIP_CB_PRE_ADD])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_header, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); if ($v_result == 0) { // ----- Change the file status $p_header['status'] = "skipped"; $v_result = 1; } // ----- Update the informations // Only some fields can be modified if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'"); } } // ----- Look for empty stored filename if ($p_header['stored_filename'] == "") { $p_header['status'] = "filtered"; } // ----- Check the path length if (strlen($p_header['stored_filename']) > 0xFF) { $p_header['status'] = 'filename_too_long'; } // ----- Look if no error, or file not skipped if ($p_header['status'] == 'ok') { // ----- Look for a file // if (is_file($p_filename)) if ( ($p_filedescr['type'] == 'file') || ($p_filedescr['type'] == 'virtual_file')) { // ----- Get content from real file if ($p_filedescr['type'] == 'file') { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file"); // ----- Open the source file if (($v_file = @fopen($p_filename, "rb")) == 0) { PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Read the file content $v_content = @fread($v_file, $p_header['size']); // ----- Close the file @fclose($v_file); } else if ($p_filedescr['type'] == 'virtual_file') { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Add by string"); $v_content = $p_filedescr['content']; } // ----- Calculate the CRC $p_header['crc'] = @crc32($v_content); // ----- Look for no compression if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed"); // ----- Set header parameters $p_header['compressed_size'] = $p_header['size']; $p_header['compression'] = 0; } // ----- Look for normal compression else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed"); // ----- Compress the content $v_content = @gzdeflate($v_content); // ----- Set header parameters $p_header['compressed_size'] = strlen($v_content); $p_header['compression'] = 8; } // ----- Look for encryption /* if ((isset($p_options[PCLZIP_OPT_CRYPT])) && ($p_options[PCLZIP_OPT_CRYPT] != "")) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ...."); // Should be a random header $v_header = 'xxxxxxxxxxxx'; $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed, $p_header['compressed_size'], $v_header, $p_header['crc'], "test"); $p_header['compressed_size'] += 12; $p_header['flag'] = 1; // ----- Add the header to the data $v_content_compressed = $v_header.$v_content_compressed; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed).""); } */ // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { @fclose($v_file); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Write the compressed (or not) content @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); } // ----- Look for a directory else if ($p_filedescr['type'] == 'folder') { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder"); // ----- Look for directory last '/' if (@substr($p_header['stored_filename'], -1) != '/') { $p_header['stored_filename'] .= '/'; } // ----- Set the file properties $p_header['size'] = 0; //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked $p_header['external'] = 0x00000010; // Value for a folder : to be checked // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } } } // ----- Look for post-add callback if (isset($p_options[PCLZIP_CB_POST_ADD])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_header, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); if ($v_result == 0) { // ----- Ignored $v_result = 1; } // ----- Update the informations // Nothing can be modified } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCalculateStoredFilename() // Description : // Based on file descriptor properties and global options, this method // calculate the filename that will be stored in the archive. // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privCalculateStoredFilename(&$p_filedescr, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCalculateStoredFilename", "filename='".$p_filedescr['filename']."'"); $v_result=1; // ----- Working variables $p_filename = $p_filedescr['filename']; if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; } else { $p_add_dir = ''; } if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; } else { $p_remove_dir = ''; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Remove path ='".$p_remove_dir."'"); if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } else { $p_remove_all_dir = 0; } // ----- Look for full name change if (isset($p_filedescr['new_full_name'])) { $v_stored_filename = $p_filedescr['new_full_name']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing full name of '".$p_filename."' for '".$v_stored_filename."'"); } // ----- Look for path and/or short name change else { // ----- Look for short name change if (isset($p_filedescr['new_short_name'])) { $v_path_info = pathinfo($p_filename); $v_dir = ''; if ($v_path_info['dirname'] != '') { $v_dir = $v_path_info['dirname'].'/'; } $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing short name of '".$p_filename."' for '".$v_stored_filename."'"); } else { // ----- Calculate the stored filename $v_stored_filename = $p_filename; } // ----- Look for all path to remove if ($p_remove_all_dir) { $v_stored_filename = basename($p_filename); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove all path selected change '".$p_filename."' for '".$v_stored_filename."'"); } // ----- Look for partial path remove else if ($p_remove_dir != "") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Partial path to remove"); if (substr($p_remove_dir, -1) != '/') $p_remove_dir .= "/"; if ( (substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) { if ( (substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) { $p_remove_dir = "./".$p_remove_dir; } if ( (substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) { $p_remove_dir = substr($p_remove_dir, 2); } } $v_compare = PclZipUtilPathInclusion($p_remove_dir, $v_stored_filename); if ($v_compare > 0) { if ($v_compare == 2) { $v_stored_filename = ""; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder"); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$v_stored_filename'"); $v_stored_filename = substr($v_stored_filename, strlen($p_remove_dir)); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Result is '$v_stored_filename'"); } } } // ----- Look for path to add if ($p_add_dir != "") { if (substr($p_add_dir, -1) == "/") $v_stored_filename = $p_add_dir.$v_stored_filename; else $v_stored_filename = $p_add_dir."/".$v_stored_filename; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'"); } } // ----- Filename (reduce the path of stored name) $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); $p_filedescr['stored_filename'] = $v_stored_filename; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename'])); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privWriteFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privWriteFileHeader(&$p_header) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"'); $v_result=1; // ----- Store the offset position of the file $p_header['offset'] = ftell($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']); // ----- Transform UNIX mtime to DOS format mdate/mtime //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); $v_date = getdate($p_header['mtime']); $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; // ----- Packed data $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len']); // ----- Write the first 148 bytes of the header in the archive fputs($this->zip_fd, $v_binary_data, 30); // ----- Write the variable fields if (strlen($p_header['stored_filename']) != 0) { fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); } if ($p_header['extra_len'] != 0) { fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privWriteCentralFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privWriteCentralFileHeader(&$p_header) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"'); $v_result=1; // TBC //for(reset($p_header); $key = key($p_header); next($p_header)) { // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]); //} // ----- Transform UNIX mtime to DOS format mdate/mtime //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); $v_date = getdate($p_header['mtime']); $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment size : \''.$p_header['comment_len'].'\''); // ----- Packed data $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']); // ----- Write the 42 bytes of the header in the zip file fputs($this->zip_fd, $v_binary_data, 46); // ----- Write the variable fields if (strlen($p_header['stored_filename']) != 0) { fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); } if ($p_header['extra_len'] != 0) { fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); } if ($p_header['comment_len'] != 0) { fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privWriteCentralHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"'); $v_result=1; // ----- Packed data $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment)); // ----- Write the 22 bytes of the header in the zip file fputs($this->zip_fd, $v_binary_data, 22); // ----- Write the variable fields if (strlen($p_comment) != 0) { fputs($this->zip_fd, $p_comment, strlen($p_comment)); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privList() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privList(&$p_list) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list"); $v_result=1; // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Go to beginning of Central Dir //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'"); if (@fseek($this->zip_fd, $v_central_dir['offset'])) { $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'"); // ----- Read each entry for ($i=0; $i<$v_central_dir['entries']; $i++) { // ----- Read the file header if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $v_header['index'] = $i; // ----- Get the only interesting attributes $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); unset($v_header); } // ----- Close the zip file $this->privCloseFd(); // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privConvertHeader2FileInfo() // Description : // This function takes the file informations from the central directory // entries and extract the interesting parameters that will be given back. // The resulting file infos are set in the array $p_info // $p_info['filename'] : Filename with full path. Given by user (add), // extracted in the filesystem (extract). // $p_info['stored_filename'] : Stored filename in the archive. // $p_info['size'] = Size of the file. // $p_info['compressed_size'] = Compressed size of the file. // $p_info['mtime'] = Last modification date of the file. // $p_info['comment'] = Comment associated with the file. // $p_info['folder'] = true/false : indicates if the entry is a folder or not. // $p_info['status'] = status of the action on the file. // $p_info['crc'] = CRC of the file content. // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privConvertHeader2FileInfo($p_header, &$p_info) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'"); $v_result=1; // ----- Get the interesting attributes $p_info['filename'] = $p_header['filename']; $p_info['stored_filename'] = $p_header['stored_filename']; $p_info['size'] = $p_header['size']; $p_info['compressed_size'] = $p_header['compressed_size']; $p_info['mtime'] = $p_header['mtime']; $p_info['comment'] = $p_header['comment']; $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); $p_info['index'] = $p_header['index']; $p_info['status'] = $p_header['status']; $p_info['crc'] = $p_header['crc']; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractByRule() // Description : // Extract a file or directory depending of rules (by index, by name, ...) // Parameters : // $p_file_list : An array where will be placed the properties of each // extracted file // $p_path : Path to add while writing the extracted files // $p_remove_path : Path to remove (from the file memorized path) while writing the // extracted files. If the path does not match the file path, // the file is extracted with its memorized path. // $p_remove_path does not apply to 'list' mode. // $p_path and $p_remove_path are commulative. // Return Values : // 1 on success,0 or less on error (see error code list) // -------------------------------------------------------------------------------- function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'"); $v_result=1; // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Check the path if ( ($p_path == "") || ( (substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) $p_path = "./".$p_path; // ----- Reduce the path last (and duplicated) '/' if (($p_path != "./") && ($p_path != "/")) { // ----- Look for the path end '/' while (substr($p_path, -1) == "/") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'"); $p_path = substr($p_path, 0, strlen($p_path)-1); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]"); } } // ----- Look for path to remove format (should end by /) if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_result = $this->privOpenFd('rb')) != 1) { $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Start at beginning of Central Dir $v_pos_entry = $v_central_dir['offset']; // ----- Read each entry $j_start = 0; for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'"); // ----- Read next Central dir entry //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'"); if (@fseek($this->zip_fd, $v_pos_entry)) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'"); // ----- Read the file header $v_header = array(); if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Store the index $v_header['index'] = $i; // ----- Store the file position $v_pos_entry = ftell($this->zip_fd); // ----- Look for the specific extract rules $v_extract = false; // ----- Look for extract by name rule if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'"); // ----- Look if the filename is in the list for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'"); // ----- Look for a directory if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory"); // ----- Look if the directory is in the filename path if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path"); $v_extract = true; } } // ----- Look for a filename elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one."); $v_extract = true; } } } // ----- Look for extract by ereg rule else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'"); if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); $v_extract = true; } } // ----- Look for extract by preg rule else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'"); if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); $v_extract = true; } } // ----- Look for extract by index rule else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'"); // ----- Look if the index is in the list for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]"); if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range"); $v_extract = true; } if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop"); $j_start = $j+1; } if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop"); break; } } } // ----- Look for no rule, which means extract all the archive else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)"); $v_extract = true; } // ----- Check compression method if ( ($v_extract) && ( ($v_header['compression'] != 8) && ($v_header['compression'] != 0))) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")"); $v_header['status'] = 'unsupported_compression'; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '".$v_header['stored_filename']."' is " ."compressed by an unsupported compression " ."method (".$v_header['compression'].") "); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Check encrypted files if (($v_extract) && (($v_header['flag'] & 1) == 1)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption"); $v_header['status'] = 'unsupported_encryption'; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, "Unsupported encryption for " ." filename '".$v_header['stored_filename'] ."'"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Look for real extraction if (($v_extract) && ($v_header['status'] != 'ok')) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract"); $v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++]); if ($v_result != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $v_extract = false; } // ----- Look for real extraction if ($v_extract) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'"); // ----- Go to the file position //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'"); if (@fseek($this->zip_fd, $v_header['offset'])) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'"); // ----- Look for extraction as string if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { // ----- Extracting the file $v_result1 = $this->privExtractFileAsString($v_header, $v_string); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1); return $v_result1; } // ----- Get the only interesting attributes if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Set the file content $p_file_list[$v_nb_extracted]['content'] = $v_string; // ----- Next extracted file $v_nb_extracted++; // ----- Look for user callback abort if ($v_result1 == 2) { break; } } // ----- Look for extraction in standard output elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { // ----- Extracting the file in standard output $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1); return $v_result1; } // ----- Get the only interesting attributes if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look for user callback abort if ($v_result1 == 2) { break; } } // ----- Look for normal extraction else { // ----- Extracting the file $v_result1 = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1); return $v_result1; } // ----- Get the only interesting attributes if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look for user callback abort if ($v_result1 == 2) { break; } } } } // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFile() // Description : // Parameters : // Return Values : // // 1 : ... ? // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback // -------------------------------------------------------------------------------- function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'"); $v_result=1; // ----- Read the file header if (($v_result = $this->privReadFileHeader($v_header)) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } // ----- Look for all path to remove if ($p_remove_all_path == true) { // ----- Look for folder entry that not need to be extracted if (($p_entry['external']&0x00000010)==0x00000010) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered"); $p_entry['status'] = "filtered"; //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed"); // ----- Get the basename of the path $p_entry['filename'] = basename($p_entry['filename']); } // ----- Look for path to remove else if ($p_remove_path != "") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove"); if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'"); // ----- Change the file status $p_entry['status'] = "filtered"; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $p_remove_path_size = strlen($p_remove_path); if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'"); // ----- Remove the path $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'"); } } // ----- Add the path if ($p_path != '') { $p_entry['filename'] = $p_path."/".$p_entry['filename']; } // ----- Check a base_dir_restriction if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Check the extract directory restriction"); $v_inclusion = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], $p_entry['filename']); if ($v_inclusion == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_EXTRACT_DIR_RESTRICTION is selected, file is outside restriction"); PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, "Filename '".$p_entry['filename']."' is " ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Look for pre-extract callback if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); if ($v_result == 0) { // ----- Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // ----- Look for abort result if ($v_result == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'"); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'"); // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Look for specific actions while the file exist if (file_exists($p_entry['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists"); // ----- Look if file is a directory if (is_dir($p_entry['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory"); // ----- Change the file status $p_entry['status'] = "already_a_directory"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '".$p_entry['filename']."' is " ."already used by an existing directory"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Look if file is write protected else if (!is_writeable($p_entry['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected"); // ----- Change the file status $p_entry['status'] = "write_protected"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '".$p_entry['filename']."' exists " ."and is write protected"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Look if the extracted file is older else if (filemtime($p_entry['filename']) > $p_entry['mtime']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")"); // ----- Change the file status if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced"); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced"); $p_entry['status'] = "newer_exist"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '".$p_entry['filename']."' exists " ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is older than the extrated one - will be replaced by the extracted one (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")"); } } // ----- Check the directory availability and create it if necessary else { if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) $v_dir_to_check = $p_entry['filename']; else if (!strstr($p_entry['filename'], "/")) $v_dir_to_check = ""; else $v_dir_to_check = dirname($p_entry['filename']); if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'"); // ----- Change the file status $p_entry['status'] = "path_creation_fail"; // ----- Return ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); //return $v_result; $v_result = 1; } } } // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Do the extraction (if not a folder) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file if ($p_entry['compression'] == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode"); // ----- Change the file status $p_entry['status'] = "write_error"; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes"); // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks $v_size = $p_entry['compressed_size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes"); $v_buffer = @fread($this->zip_fd, $v_read_size); /* Try to speed up the code $v_binary_data = pack('a'.$v_read_size, $v_buffer); @fwrite($v_dest_file, $v_binary_data, $v_read_size); */ @fwrite($v_dest_file, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Closing the destination file fclose($v_dest_file); // ----- Change the file mtime touch($p_entry['filename'], $p_entry['mtime']); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")"); // ----- TBC // Need to be finished if (($p_entry['flag'] & 1) == 1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted"); /* // ----- Read the encryption header //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes"); $v_encryption_header = @fread($this->zip_fd, 12); // ----- Read the encrypted & compressed file in a buffer //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes"); $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12); // ----- Decrypt the buffer $this->privDecrypt($v_encryption_header, $v_buffer, $p_entry['compressed_size']-12, $p_entry['crc']); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'"); */ } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes"); // ----- Read the compressed file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); } // ----- Decompress the file $v_file_content = @gzinflate($v_buffer); unset($v_buffer); if ($v_file_content === FALSE) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file"); // ----- Change the file status // TBC $p_entry['status'] = "error"; //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode"); // ----- Change the file status $p_entry['status'] = "write_error"; //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Write the uncompressed data @fwrite($v_dest_file, $v_file_content, $p_entry['size']); unset($v_file_content); // ----- Closing the destination file @fclose($v_dest_file); // ----- Change the file mtime @touch($p_entry['filename'], $p_entry['mtime']); } // ----- Look for chmod option if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'"); // ----- Change the mode of the file @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); } } // ----- Change abort status if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; } // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); // ----- Look for abort result if ($v_result == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); $v_result = PCLZIP_ERR_USER_ABORTED; } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFileInOutput() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privExtractFileInOutput(&$p_entry, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', ""); $v_result=1; // ----- Read the file header if (($v_result = $this->privReadFileHeader($v_header)) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } // ----- Look for pre-extract callback if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); if ($v_result == 0) { // ----- Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // ----- Look for abort result if ($v_result == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'"); } // ----- Trace //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'"); // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Do the extraction (if not a folder) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file if ($p_entry['compressed_size'] == $p_entry['size']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes"); // ----- Read the file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Send the file to the output echo $v_buffer; unset($v_buffer); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes"); // ----- Read the compressed file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file $v_file_content = gzinflate($v_buffer); unset($v_buffer); // ----- Send the file to the output echo $v_file_content; unset($v_file_content); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); } } // ----- Change abort status if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; } // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); // ----- Look for abort result if ($v_result == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); $v_result = PCLZIP_ERR_USER_ABORTED; } } //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFileAsString() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privExtractFileAsString(&$p_entry, &$p_string) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'"); $v_result=1; // ----- Read the file header $v_header = array(); if (($v_result = $this->privReadFileHeader($v_header)) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'"); // ----- Do the extraction (if not a folder) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file // if ($p_entry['compressed_size'] == $p_entry['size']) if ($p_entry['compression'] == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes"); // ----- Reading the file $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')"); // ----- Reading the file $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file if (($p_string = @gzinflate($v_data)) === FALSE) { // TBC } } // ----- Trace //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); } else { // TBC : error : can not extract a folder in a string } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privReadFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privReadFileHeader(&$p_header) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", ""); $v_result=1; // ----- Read the 4 bytes signature $v_binary_data = @fread($this->zip_fd, 4); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'"); $v_data = unpack('Vid', $v_binary_data); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'"); // ----- Check signature if ($v_data['id'] != 0x04034b50) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header"); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Read the first 42 bytes of the header $v_binary_data = fread($this->zip_fd, 26); // ----- Look for invalid block size if (strlen($v_binary_data) != 26) { $p_header['filename'] = ""; $p_header['status'] = "invalid_header"; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data)); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Extract the values //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'"); $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); // ----- Get filename //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']); $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\''); // ----- Get extra_fields //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']); if ($v_data['extra_len'] != 0) { $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); } else { $p_header['extra'] = ''; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\''); // ----- Extract properties $p_header['version_extracted'] = $v_data['version']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\''); $p_header['compression'] = $v_data['compression']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.$p_header['compression'].'\''); $p_header['size'] = $v_data['size']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\''); $p_header['compressed_size'] = $v_data['compressed_size']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\''); $p_header['crc'] = $v_data['crc']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\''); $p_header['flag'] = $v_data['flag']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\''); $p_header['filename_len'] = $v_data['filename_len']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : \''.$p_header['filename_len'].'\''); // ----- Recuperate date in UNIX format $p_header['mdate'] = $v_data['mdate']; $p_header['mtime'] = $v_data['mtime']; if ($p_header['mdate'] && $p_header['mtime']) { // ----- Extract time $v_hour = ($p_header['mtime'] & 0xF800) >> 11; $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; $v_seconde = ($p_header['mtime'] & 0x001F)*2; // ----- Extract date $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; $v_month = ($p_header['mdate'] & 0x01E0) >> 5; $v_day = $p_header['mdate'] & 0x001F; // ----- Get UNIX date format $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); } else { $p_header['mtime'] = time(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); } // TBC //for(reset($v_data); $key = key($v_data); next($v_data)) { // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]); //} // ----- Set the stored filename $p_header['stored_filename'] = $p_header['filename']; // ----- Set the status field $p_header['status'] = "ok"; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privReadCentralFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privReadCentralFileHeader(&$p_header) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", ""); $v_result=1; // ----- Read the 4 bytes signature $v_binary_data = @fread($this->zip_fd, 4); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'"); $v_data = unpack('Vid', $v_binary_data); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'"); // ----- Check signature if ($v_data['id'] != 0x02014b50) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature"); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Read the first 42 bytes of the header $v_binary_data = fread($this->zip_fd, 42); // ----- Look for invalid block size if (strlen($v_binary_data) != 42) { $p_header['filename'] = ""; $p_header['status'] = "invalid_header"; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data)); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Extract the values //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'"); $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); // ----- Get filename //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']); if ($p_header['filename_len'] != 0) $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); else $p_header['filename'] = ''; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\''); // ----- Get extra //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']); if ($p_header['extra_len'] != 0) $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); else $p_header['extra'] = ''; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\''); // ----- Get comment //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']); if ($p_header['comment_len'] != 0) $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); else $p_header['comment'] = ''; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\''); // ----- Extract properties //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\''); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\''); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\''); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\''); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\''); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\''); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\''); // ----- Recuperate date in UNIX format //if ($p_header['mdate'] && $p_header['mtime']) // TBC : bug : this was ignoring time with 0/0/0 if (1) { // ----- Extract time $v_hour = ($p_header['mtime'] & 0xF800) >> 11; $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; $v_seconde = ($p_header['mtime'] & 0x001F)*2; // ----- Extract date $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; $v_month = ($p_header['mdate'] & 0x01E0) >> 5; $v_day = $p_header['mdate'] & 0x001F; // ----- Get UNIX date format $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); } else { $p_header['mtime'] = time(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); } // ----- Set the stored filename $p_header['stored_filename'] = $p_header['filename']; // ----- Set default status to ok $p_header['status'] = 'ok'; // ----- Look if it is a directory //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')'); if (substr($p_header['filename'], -1) == '/') { //$p_header['external'] = 0x41FF0010; $p_header['external'] = 0x00000010; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.sprintf("Ox%04X", $p_header['external']).'\''); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\''); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCheckFileHeaders() // Description : // Parameters : // Return Values : // 1 on success, // 0 on error; // -------------------------------------------------------------------------------- function privCheckFileHeaders(&$p_local_header, &$p_central_header) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", ""); $v_result=1; // ----- Check the static values // TBC if ($p_local_header['filename'] != $p_central_header['filename']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed'); } if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed'); } if ($p_local_header['flag'] != $p_central_header['flag']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed'); } if ($p_local_header['compression'] != $p_central_header['compression']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed'); } if ($p_local_header['mtime'] != $p_central_header['mtime']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed'); } if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed'); } // ----- Look for flag bit 3 if (($p_local_header['flag'] & 8) == 8) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !'); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header'); $p_local_header['size'] = $p_central_header['size']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_local_header['size'].'\''); $p_local_header['compressed_size'] = $p_central_header['compressed_size']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_local_header['compressed_size'].'\''); $p_local_header['crc'] = $p_central_header['crc']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_local_header['crc']).'\''); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privReadEndCentralDir() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privReadEndCentralDir(&$p_central_dir) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", ""); $v_result=1; // ----- Go to the end of the zip file $v_size = filesize($this->zipname); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size"); @fseek($this->zip_fd, $v_size); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\''); if (@ftell($this->zip_fd) != $v_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- First try : look if this is an archive with no commentaries (most of the time) // in this case the end of central dir is at 22 bytes of the file end $v_found = 0; if ($v_size > 26) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment'); @fseek($this->zip_fd, $v_size-22); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\''); if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Read for bytes $v_binary_data = @fread($this->zip_fd, 4); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'"); $v_data = @unpack('Vid', $v_binary_data); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'"); // ----- Check signature if ($v_data['id'] == 0x06054b50) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position."); $v_found = 1; } $v_pos = ftell($this->zip_fd); } // ----- Go back to the maximum possible size of the Central Dir End Record if (!$v_found) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir'); $v_maximum_size = 65557; // 0xFFFF + 22; if ($v_maximum_size > $v_size) $v_maximum_size = $v_size; @fseek($this->zip_fd, $v_size-$v_maximum_size); if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\''); // ----- Read byte per byte in order to find the signature $v_pos = ftell($this->zip_fd); $v_bytes = 0x00000000; while ($v_pos < $v_size) { // ----- Read a byte $v_byte = @fread($this->zip_fd, 1); // ----- Add the byte $v_bytes = ($v_bytes << 8) | Ord($v_byte); // ----- Compare the bytes if ($v_bytes == 0x504b0506) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\''); $v_pos++; break; } $v_pos++; } // ----- Look if not found end of central dir if ($v_pos == $v_size) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature"); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Read the first 18 bytes of the header $v_binary_data = fread($this->zip_fd, 18); // ----- Look for invalid block size if (strlen($v_binary_data) != 18) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Extract the values ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'"); ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'"); $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); // ----- Check the global size //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']); if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive."); // ----- Removed in release 2.2 see readme file // The check of the file size is a little too strict. // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. // While decrypted, zip has training 0 bytes if (0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive.' .' Some trailing bytes exists after the archive.'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } // ----- Get comment //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment size : \''.$v_data['comment_size'].'\''); if ($v_data['comment_size'] != 0) { $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); } else $p_central_dir['comment'] = ''; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\''); $p_central_dir['entries'] = $v_data['entries']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\''); $p_central_dir['disk_entries'] = $v_data['disk_entries']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\''); $p_central_dir['offset'] = $v_data['offset']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\''); $p_central_dir['size'] = $v_data['size']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\''); $p_central_dir['disk'] = $v_data['disk']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\''); $p_central_dir['disk_start'] = $v_data['disk_start']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\''); // TBC //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]); //} // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDeleteByRule() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDeleteByRule(&$p_result_list, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", ""); $v_result=1; $v_list_detail = array(); // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_result=$this->privOpenFd('rb')) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Go to beginning of File //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); // ----- Scan all the files // ----- Start at beginning of Central Dir $v_pos_entry = $v_central_dir['offset']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'"); if (@fseek($this->zip_fd, $v_pos_entry)) { // ----- Close the zip file $this->privCloseFd(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'"); // ----- Read each entry $v_header_list = array(); $j_start = 0; for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')"); // ----- Read the file header $v_header_list[$v_nb_extracted] = array(); if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) { // ----- Close the zip file $this->privCloseFd(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'"); // ----- Store the index $v_header_list[$v_nb_extracted]['index'] = $i; // ----- Look for the specific extract rules $v_found = false; // ----- Look for extract by name rule if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'"); // ----- Look if the filename is in the list for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'"); // ----- Look for a directory if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory"); // ----- Look if the directory is in the filename path if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path"); $v_found = true; } elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory"); $v_found = true; } } // ----- Look for a filename elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one."); $v_found = true; } } } // ----- Look for extract by ereg rule else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'"); if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); $v_found = true; } } // ----- Look for extract by preg rule else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'"); if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); $v_found = true; } } // ----- Look for extract by index rule else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'"); // ----- Look if the index is in the list for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]"); if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range"); $v_found = true; } if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop"); $j_start = $j+1; } if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop"); break; } } } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file"); $v_found = true; } // ----- Look for deletion if ($v_found) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted"); unset($v_header_list[$v_nb_extracted]); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted"); $v_nb_extracted++; } } // ----- Look if something need to be deleted if ($v_nb_extracted > 0) { // ----- Creates a temporay file $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; // ----- Creates a temporary zip archive $v_temp_zip = new PclZip($v_zip_temp_name); // ----- Open the temporary zip file in write mode //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode"); if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { $this->privCloseFd(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look which file need to be kept for ($i=0; $i<sizeof($v_header_list); $i++) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'"); // ----- Calculate the position of the header //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'"); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'"); if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'"); // ----- Read the file header $v_local_header = array(); if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Check that local file header is same as central file header if ($this->privCheckFileHeaders($v_local_header, $v_header_list[$i]) != 1) { // TBC } unset($v_local_header); // ----- Write the file header if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'"); // ----- Read/write the data block if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } } // ----- Store the offset of the central dir $v_offset = @ftell($v_temp_zip->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset"); // ----- Re-Create the Central Dir files header //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory"); for ($i=0; $i<sizeof($v_header_list); $i++) { // ----- Create the file header //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']); if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { $v_temp_zip->privCloseFd(); $this->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Transform the header to a 'usable' info $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer"); // ----- Zip file comment $v_comment = ''; if (isset($p_options[PCLZIP_OPT_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } // ----- Calculate the size of the central header $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; // ----- Create the central dir footer if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { // ----- Reset the file list unset($v_header_list); $v_temp_zip->privCloseFd(); $this->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Close $v_temp_zip->privCloseFd(); $this->privCloseFd(); // ----- Delete the zip file // TBC : I should test the result ... @unlink($this->zipname); // ----- Rename the temporary file // TBC : I should test the result ... //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); // ----- Destroy the temporary archive unset($v_temp_zip); } // ----- Remove every files : reset the file else if ($v_central_dir['entries'] != 0) { $this->privCloseFd(); if (($v_result = $this->privOpenFd('wb')) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $this->privCloseFd(); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDirCheck() // Description : // Check if a directory exists, if not it creates it and all the parents directory // which may be useful. // Parameters : // $p_dir : Directory path to check. // Return Values : // 1 : OK // -1 : Unable to create directory // -------------------------------------------------------------------------------- function privDirCheck($p_dir, $p_is_dir=false) { $v_result = 1; //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'"); // ----- Remove the final '/' if (($p_is_dir) && (substr($p_dir, -1)=='/')) { $p_dir = substr($p_dir, 0, strlen($p_dir)-1); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'"); // ----- Check the directory availability if ((is_dir($p_dir)) || ($p_dir == "")) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory"); return 1; } // ----- Extract parent directory $p_parent_dir = dirname($p_dir); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'"); // ----- Just a check if ($p_parent_dir != $p_dir) { // ----- Look for parent directory if ($p_parent_dir != "") { if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } } } // ----- Create the directory //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'"); if (!@mkdir($p_dir, 0777)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created"); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privMerge() // Description : // If $p_archive_to_add does not exist, the function exit with a success result. // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privMerge(&$p_archive_to_add) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'"); $v_result=1; // ----- Look if the archive_to_add exists if (!is_file($p_archive_to_add->zipname)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge."); // ----- Nothing to merge, so merge is a success $v_result = 1; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look if the archive exists if (!is_file($this->zipname)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add."); // ----- Do a duplicate $v_result = $this->privDuplicate($p_archive_to_add->zipname); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_result=$this->privOpenFd('rb')) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Go to beginning of File //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'"); @rewind($this->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'"); // ----- Open the archive_to_add file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode"); if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) { $this->privCloseFd(); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Read the central directory informations $v_central_dir_to_add = array(); if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) { $this->privCloseFd(); $p_archive_to_add->privCloseFd(); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Go to beginning of File //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'"); @rewind($p_archive_to_add->zip_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'"); // ----- Creates a temporay file $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; // ----- Open the temporary file in write mode //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { $this->privCloseFd(); $p_archive_to_add->privCloseFd(); PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Copy the files from the archive to the temporary file // TBC : Here I should better append the file and go back to erase the central dir $v_size = $v_central_dir['offset']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = fread($this->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Copy the files from the archive_to_add into the temporary file $v_size = $v_central_dir_to_add['offset']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Store the offset of the central dir $v_offset = @ftell($v_zip_temp_fd); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset"); // ----- Copy the block of file headers from the old archive $v_size = $v_central_dir['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @fread($this->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Copy the block of file headers from the archive_to_add $v_size = $v_central_dir_to_add['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Merge the file comments $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; // ----- Calculate the size of the (new) central header $v_size = @ftell($v_zip_temp_fd)-$v_offset; // ----- Swap the file descriptor // Here is a trick : I swap the temporary fd with the zip fd, in order to use // the following methods on the temporary fil and not the real archive fd $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Create the central dir footer if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) { $this->privCloseFd(); $p_archive_to_add->privCloseFd(); @fclose($v_zip_temp_fd); $this->zip_fd = null; // ----- Reset the file list unset($v_header_list); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Swap back the file descriptor $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Close $this->privCloseFd(); $p_archive_to_add->privCloseFd(); // ----- Close the temporary file @fclose($v_zip_temp_fd); // ----- Delete the zip file // TBC : I should test the result ... @unlink($this->zipname); // ----- Rename the temporary file // TBC : I should test the result ... //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDuplicate() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDuplicate($p_archive_filename) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'"); $v_result=1; // ----- Look if the $p_archive_filename exists if (!is_file($p_archive_filename)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate."); // ----- Nothing to duplicate, so duplicate is a success. $v_result = 1; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Open the zip file //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_result=$this->privOpenFd('wb')) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Open the temporary file in write mode //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) { $this->privCloseFd(); PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } // ----- Copy the files from the archive to the temporary file // TBC : Here I should better append the file and go back to erase the central dir $v_size = filesize($p_archive_filename); while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes"); $v_buffer = fread($v_zip_temp_fd, $v_read_size); @fwrite($this->zip_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Close $this->privCloseFd(); // ----- Close the temporary file @fclose($v_zip_temp_fd); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privErrorLog() // Description : // Parameters : // -------------------------------------------------------------------------------- function privErrorLog($p_error_code=0, $p_error_string='') { if (PCLZIP_ERROR_EXTERNAL == 1) { PclError($p_error_code, $p_error_string); } else { $this->error_code = $p_error_code; $this->error_string = $p_error_string; } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privErrorReset() // Description : // Parameters : // -------------------------------------------------------------------------------- function privErrorReset() { if (PCLZIP_ERROR_EXTERNAL == 1) { PclErrorReset(); } else { $this->error_code = 0; $this->error_string = ''; } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDecrypt() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size.""); $v_result=1; // ----- To Be Modified ;-) $v_pwd = "test"; $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header, $p_crc, $v_pwd); // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDisableMagicQuotes() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDisableMagicQuotes() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', ""); $v_result=1; // ----- Look if function exists if ( (!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look if already done if ($this->magic_quotes_status != -1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Get and memorize the magic_quote value $this->magic_quotes_status = @get_magic_quotes_runtime(); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'"); // ----- Disable magic_quotes if ($this->magic_quotes_status == 1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes"); @set_magic_quotes_runtime(0); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privSwapBackMagicQuotes() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privSwapBackMagicQuotes() { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', ""); $v_result=1; // ----- Look if function exists if ( (!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look if something to do if ($this->magic_quotes_status != -1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Swap back magic_quotes if ($this->magic_quotes_status == 1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes"); @set_magic_quotes_runtime($this->magic_quotes_status); } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- } // End of class // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilPathReduction() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function PclZipUtilPathReduction($p_dir) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'"); $v_result = ""; // ----- Look for not empty path if ($p_dir != "") { // ----- Explode path by directory names $v_list = explode("/", $p_dir); // ----- Study directories from last to first $v_skip = 0; for ($i=sizeof($v_list)-1; $i>=0; $i--) { // ----- Look for current path if ($v_list[$i] == ".") { // ----- Ignore this directory // Should be the first $i=0, but no check is done } else if ($v_list[$i] == "..") { $v_skip++; } else if ($v_list[$i] == "") { // ----- First '/' i.e. root slash if ($i == 0) { $v_result = "/".$v_result; if ($v_skip > 0) { // ----- It is an invalid path, so the path is not modified // TBC $v_result = $p_dir; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged"); $v_skip = 0; } } // ----- Last '/' i.e. indicates a directory else if ($i == (sizeof($v_list)-1)) { $v_result = $v_list[$i]; } // ----- Double '/' inside the path else { // ----- Ignore only the double '//' in path, // but not the first and last '/' } } else { // ----- Look for item to skip if ($v_skip > 0) { $v_skip--; } else { $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); } } } // ----- Look for skip if ($v_skip > 0) { while ($v_skip > 0) { $v_result = '../'.$v_result; $v_skip--; } } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilPathInclusion() // Description : // This function indicates if the path $p_path is under the $p_dir tree. Or, // said in an other way, if the file or sub-dir $p_path is inside the dir // $p_dir. // The function indicates also if the path is exactly the same as the dir. // This function supports path with duplicated '/' like '//', but does not // support '.' or '..' statements. // Parameters : // Return Values : // 0 if $p_path is not inside directory $p_dir // 1 if $p_path is inside directory $p_dir // 2 if $p_path is exactly the same as $p_dir // -------------------------------------------------------------------------------- function PclZipUtilPathInclusion($p_dir, $p_path) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'"); $v_result = 1; // ----- Look for path beginning by ./ if ( ($p_dir == '.') || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_dir '".$p_dir."'"); } if ( ($p_path == '.') || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_path '".$p_path."'"); } // ----- Explode dir and path by directory separator $v_list_dir = explode("/", $p_dir); $v_list_dir_size = sizeof($v_list_dir); $v_list_path = explode("/", $p_path); $v_list_path_size = sizeof($v_list_path); // ----- Study directories paths $i = 0; $j = 0; while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'"); // ----- Look for empty dir (path reduction) if ($v_list_dir[$i] == '') { $i++; continue; } if ($v_list_path[$j] == '') { $j++; continue; } // ----- Compare the items if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different"); $v_result = 0; } // ----- Next items $i++; $j++; } // ----- Look if everything seems to be the same if ($v_result) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break"); // ----- Skip all the empty items while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'"); if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { // ----- There are exactly the same $v_result = 2; } else if ($i < $v_list_dir_size) { // ----- The path is shorter than the dir $v_result = 0; } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilCopyBlock() // Description : // Parameters : // $p_mode : read/write compression mode // 0 : src & dest normal // 1 : src gzip, dest normal // 2 : src normal, dest gzip // 3 : src & dest gzip // Return Values : // -------------------------------------------------------------------------------- function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode"); $v_result = 1; if ($p_mode==0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src))); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest))); while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @fread($p_src, $v_read_size); @fwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src))); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest))); } else if ($p_mode==1) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @gzread($p_src, $v_read_size); @fwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } else if ($p_mode==2) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @fread($p_src, $v_read_size); @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } else if ($p_mode==3) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); $v_buffer = @gzread($p_src, $v_read_size); @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilRename() // Description : // This function tries to do a simple rename() function. If it fails, it // tries to copy the $p_src file in a new $p_dest file and then unlink the // first one. // Parameters : // $p_src : Old filename // $p_dest : New filename // Return Values : // 1 on success, 0 on failure. // -------------------------------------------------------------------------------- function PclZipUtilRename($p_src, $p_dest) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest"); $v_result = 1; // ----- Try to rename the files if (!@rename($p_src, $p_dest)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink"); // ----- Try to copy & unlink the src if (!@copy($p_src, $p_dest)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file"); $v_result = 0; } else if (!@unlink($p_src)) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename"); $v_result = 0; } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilOptionText() // Description : // Translate option value in text. Mainly for debug purpose. // Parameters : // $p_option : the option value. // Return Values : // The option text value. // -------------------------------------------------------------------------------- function PclZipUtilOptionText($p_option) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'"); $v_list = get_defined_constants(); for (reset($v_list); $v_key = key($v_list); next($v_list)) { $v_prefix = substr($v_key, 0, 10); if (( ($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_') || ($v_prefix == 'PCLZIP_ATT')) && ($v_list[$v_key] == $p_option)) { //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key); return $v_key; } } $v_result = 'Unknown'; //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilTranslateWinPath() // Description : // Translate windows path by replacing '\' by '/' and optionally removing // drive letter. // Parameters : // $p_path : path to translate. // $p_remove_disk_letter : true | false // Return Values : // The path translated. // -------------------------------------------------------------------------------- function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) { if (stristr(php_uname(), 'windows')) { // ----- Look for potential disk letter if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { $p_path = substr($p_path, $v_position+1); } // ----- Change potential windows directory separator if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { $p_path = strtr($p_path, '\\', '/'); } } return $p_path; } // -------------------------------------------------------------------------------- ?> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/include/class.Smarty.php�������������������������������������������������������������0000664�0000000�0000000�00000131277�12372520637�0020200�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php /** * Project: Smarty: the PHP compiling template engine * File: Smarty.class.php * SVN: $Id: Smarty.class.php 4694 2013-01-13 21:13:14Z uwe.tews@googlemail.com $ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For questions, help, comments, discussion, etc., please join the * Smarty mailing list. Send a blank e-mail to * smarty-discussion-subscribe@googlegroups.com * * @link http://www.smarty.net/ * @copyright 2008 New Digital Group, Inc. * @author Monte Ohrt <monte at ohrt dot com> * @author Uwe Tews * @author Rodney Rehm * @package Smarty * @version 3.1.13 */ /** * define shorthand directory separator constant */ if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); } /** * set SMARTY_DIR to absolute path to Smarty library files. * Sets SMARTY_DIR only if user application has not already defined it. */ if (!defined('SMARTY_DIR')) { define('SMARTY_DIR', dirname(__FILE__) . DS); } /** * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. */ if (!defined('SMARTY_SYSPLUGINS_DIR')) { define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS); } if (!defined('SMARTY_PLUGINS_DIR')) { define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); } if (!defined('SMARTY_MBSTRING')) { define('SMARTY_MBSTRING', function_exists('mb_split')); } if (!defined('SMARTY_RESOURCE_CHAR_SET')) { // UTF-8 can only be done properly when mbstring is available! /** * @deprecated in favor of Smarty::$_CHARSET */ define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); } if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { /** * @deprecated in favor of Smarty::$_DATE_FORMAT */ define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y'); } /** * register the class autoloader */ if (!defined('SMARTY_SPL_AUTOLOAD')) { define('SMARTY_SPL_AUTOLOAD', 0); } if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) { $registeredAutoLoadFunctions = spl_autoload_functions(); if (!isset($registeredAutoLoadFunctions['spl_autoload'])) { spl_autoload_register(); } } else { spl_autoload_register('smartyAutoload'); } /** * Load always needed external class files */ include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php'; include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php'; include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php'; include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php'; include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php'; include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php'; include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php'; /** * This is the main Smarty class * @package Smarty */ class Smarty extends Smarty_Internal_TemplateBase { /**#@+ * constant definitions */ /** * smarty version */ const SMARTY_VERSION = 'Smarty-3.1.13'; /** * define variable scopes */ const SCOPE_LOCAL = 0; const SCOPE_PARENT = 1; const SCOPE_ROOT = 2; const SCOPE_GLOBAL = 3; /** * define caching modes */ const CACHING_OFF = 0; const CACHING_LIFETIME_CURRENT = 1; const CACHING_LIFETIME_SAVED = 2; /** * define compile check modes */ const COMPILECHECK_OFF = 0; const COMPILECHECK_ON = 1; const COMPILECHECK_CACHEMISS = 2; /** * modes for handling of "<?php ... ?>" tags in templates. */ const PHP_PASSTHRU = 0; //-> print tags as plain text const PHP_QUOTE = 1; //-> escape tags as entities const PHP_REMOVE = 2; //-> escape tags as entities const PHP_ALLOW = 3; //-> escape tags as entities /** * filter types */ const FILTER_POST = 'post'; const FILTER_PRE = 'pre'; const FILTER_OUTPUT = 'output'; const FILTER_VARIABLE = 'variable'; /** * plugin types */ const PLUGIN_FUNCTION = 'function'; const PLUGIN_BLOCK = 'block'; const PLUGIN_COMPILER = 'compiler'; const PLUGIN_MODIFIER = 'modifier'; const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler'; /**#@-*/ /** * assigned global tpl vars */ public static $global_tpl_vars = array(); /** * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors() */ public static $_previous_error_handler = null; /** * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors() */ public static $_muted_directories = array(); /** * Flag denoting if Multibyte String functions are available */ public static $_MBSTRING = SMARTY_MBSTRING; /** * The character set to adhere to (e.g. "UTF-8") */ public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET; /** * The date format to be used internally * (accepts date() and strftime()) */ public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT; /** * Flag denoting if PCRE should run in UTF-8 mode */ public static $_UTF8_MODIFIER = 'u'; /** * Flag denoting if operating system is windows */ public static $_IS_WINDOWS = false; /**#@+ * variables */ /** * auto literal on delimiters with whitspace * @var boolean */ public $auto_literal = true; /** * display error on not assigned variables * @var boolean */ public $error_unassigned = false; /** * look up relative filepaths in include_path * @var boolean */ public $use_include_path = false; /** * template directory * @var array */ private $template_dir = array(); /** * joined template directory string used in cache keys * @var string */ public $joined_template_dir = null; /** * joined config directory string used in cache keys * @var string */ public $joined_config_dir = null; /** * default template handler * @var callable */ public $default_template_handler_func = null; /** * default config handler * @var callable */ public $default_config_handler_func = null; /** * default plugin handler * @var callable */ public $default_plugin_handler_func = null; /** * compile directory * @var string */ private $compile_dir = null; /** * plugins directory * @var array */ private $plugins_dir = array(); /** * cache directory * @var string */ private $cache_dir = null; /** * config directory * @var array */ private $config_dir = array(); /** * force template compiling? * @var boolean */ public $force_compile = false; /** * check template for modifications? * @var boolean */ public $compile_check = true; /** * use sub dirs for compiled/cached files? * @var boolean */ public $use_sub_dirs = false; /** * allow ambiguous resources (that are made unique by the resource handler) * @var boolean */ public $allow_ambiguous_resources = false; /** * caching enabled * @var boolean */ public $caching = false; /** * merge compiled includes * @var boolean */ public $merge_compiled_includes = false; /** * cache lifetime in seconds * @var integer */ public $cache_lifetime = 3600; /** * force cache file creation * @var boolean */ public $force_cache = false; /** * Set this if you want different sets of cache files for the same * templates. * * @var string */ public $cache_id = null; /** * Set this if you want different sets of compiled files for the same * templates. * * @var string */ public $compile_id = null; /** * template left-delimiter * @var string */ public $left_delimiter = "{"; /** * template right-delimiter * @var string */ public $right_delimiter = "}"; /**#@+ * security */ /** * class name * * This should be instance of Smarty_Security. * * @var string * @see Smarty_Security */ public $security_class = 'Smarty_Security'; /** * implementation of security class * * @var Smarty_Security */ public $security_policy = null; /** * controls handling of PHP-blocks * * @var integer */ public $php_handling = self::PHP_PASSTHRU; /** * controls if the php template file resource is allowed * * @var bool */ public $allow_php_templates = false; /** * Should compiled-templates be prevented from being called directly? * * {@internal * Currently used by Smarty_Internal_Template only. * }} * * @var boolean */ public $direct_access_security = true; /**#@-*/ /** * debug mode * * Setting this to true enables the debug-console. * * @var boolean */ public $debugging = false; /** * This determines if debugging is enable-able from the browser. * <ul> * <li>NONE => no debugging control allowed</li> * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> * </ul> * @var string */ public $debugging_ctrl = 'NONE'; /** * Name of debugging URL-param. * * Only used when $debugging_ctrl is set to 'URL'. * The name of the URL-parameter that activates debugging. * * @var type */ public $smarty_debug_id = 'SMARTY_DEBUG'; /** * Path of debug template. * @var string */ public $debug_tpl = null; /** * When set, smarty uses this value as error_reporting-level. * @var int */ public $error_reporting = null; /** * Internal flag for getTags() * @var boolean */ public $get_used_tags = false; /**#@+ * config var settings */ /** * Controls whether variables with the same name overwrite each other. * @var boolean */ public $config_overwrite = true; /** * Controls whether config values of on/true/yes and off/false/no get converted to boolean. * @var boolean */ public $config_booleanize = true; /** * Controls whether hidden config sections/vars are read from the file. * @var boolean */ public $config_read_hidden = false; /**#@-*/ /**#@+ * resource locking */ /** * locking concurrent compiles * @var boolean */ public $compile_locking = true; /** * Controls whether cache resources should emply locking mechanism * @var boolean */ public $cache_locking = false; /** * seconds to wait for acquiring a lock before ignoring the write lock * @var float */ public $locking_timeout = 10; /**#@-*/ /** * global template functions * @var array */ public $template_functions = array(); /** * resource type used if none given * * Must be an valid key of $registered_resources. * @var string */ public $default_resource_type = 'file'; /** * caching type * * Must be an element of $cache_resource_types. * * @var string */ public $caching_type = 'file'; /** * internal config properties * @var array */ public $properties = array(); /** * config type * @var string */ public $default_config_type = 'file'; /** * cached template objects * @var array */ public $template_objects = array(); /** * check If-Modified-Since headers * @var boolean */ public $cache_modified_check = false; /** * registered plugins * @var array */ public $registered_plugins = array(); /** * plugin search order * @var array */ public $plugin_search_order = array('function', 'block', 'compiler', 'class'); /** * registered objects * @var array */ public $registered_objects = array(); /** * registered classes * @var array */ public $registered_classes = array(); /** * registered filters * @var array */ public $registered_filters = array(); /** * registered resources * @var array */ public $registered_resources = array(); /** * resource handler cache * @var array */ public $_resource_handlers = array(); /** * registered cache resources * @var array */ public $registered_cache_resources = array(); /** * cache resource handler cache * @var array */ public $_cacheresource_handlers = array(); /** * autoload filter * @var array */ public $autoload_filters = array(); /** * default modifier * @var array */ public $default_modifiers = array(); /** * autoescape variable output * @var boolean */ public $escape_html = false; /** * global internal smarty vars * @var array */ public static $_smarty_vars = array(); /** * start time for execution time calculation * @var int */ public $start_time = 0; /** * default file permissions * @var int */ public $_file_perms = 0644; /** * default dir permissions * @var int */ public $_dir_perms = 0771; /** * block tag hierarchy * @var array */ public $_tag_stack = array(); /** * self pointer to Smarty object * @var Smarty */ public $smarty; /** * required by the compiler for BC * @var string */ public $_current_file = null; /** * internal flag to enable parser debugging * @var bool */ public $_parserdebug = false; /** * Saved parameter of merged templates during compilation * * @var array */ public $merged_templates_func = array(); /**#@-*/ /** * Initialize new Smarty object * */ public function __construct() { // selfpointer needed by some other class methods $this->smarty = $this; if (is_callable('mb_internal_encoding')) { mb_internal_encoding(Smarty::$_CHARSET); } $this->start_time = microtime(true); // set default dirs $this->setTemplateDir('.' . DS . 'templates' . DS) ->setCompileDir('.' . DS . 'templates_c' . DS) ->setPluginsDir(SMARTY_PLUGINS_DIR) ->setCacheDir('.' . DS . 'cache' . DS) ->setConfigDir('.' . DS . 'configs' . DS); $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl'; if (isset($_SERVER['SCRIPT_NAME'])) { $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']); } } /** * Class destructor */ public function __destruct() { // intentionally left blank } /** * <<magic>> set selfpointer on cloned object */ public function __clone() { $this->smarty = $this; } /** * <<magic>> Generic getter. * * Calls the appropriate getter function. * Issues an E_USER_NOTICE if no valid getter is found. * * @param string $name property name * @return mixed */ public function __get($name) { $allowed = array( 'template_dir' => 'getTemplateDir', 'config_dir' => 'getConfigDir', 'plugins_dir' => 'getPluginsDir', 'compile_dir' => 'getCompileDir', 'cache_dir' => 'getCacheDir', ); if (isset($allowed[$name])) { return $this->{$allowed[$name]}(); } else { trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE); } } /** * <<magic>> Generic setter. * * Calls the appropriate setter function. * Issues an E_USER_NOTICE if no valid setter is found. * * @param string $name property name * @param mixed $value parameter passed to setter */ public function __set($name, $value) { $allowed = array( 'template_dir' => 'setTemplateDir', 'config_dir' => 'setConfigDir', 'plugins_dir' => 'setPluginsDir', 'compile_dir' => 'setCompileDir', 'cache_dir' => 'setCacheDir', ); if (isset($allowed[$name])) { $this->{$allowed[$name]}($value); } else { trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); } } /** * Check if a template resource exists * * @param string $resource_name template name * @return boolean status */ public function templateExists($resource_name) { // create template object $save = $this->template_objects; $tpl = new $this->template_class($resource_name, $this); // check if it does exists $result = $tpl->source->exists; $this->template_objects = $save; return $result; } /** * Returns a single or all global variables * * @param object $smarty * @param string $varname variable name or null * @return string variable value or or array of variables */ public function getGlobal($varname = null) { if (isset($varname)) { if (isset(self::$global_tpl_vars[$varname])) { return self::$global_tpl_vars[$varname]->value; } else { return ''; } } else { $_result = array(); foreach (self::$global_tpl_vars AS $key => $var) { $_result[$key] = $var->value; } return $_result; } } /** * Empty cache folder * * @param integer $exp_time expiration time * @param string $type resource type * @return integer number of cache files deleted */ function clearAllCache($exp_time = null, $type = null) { // load cache resource and call clearAll $_cache_resource = Smarty_CacheResource::load($this, $type); Smarty_CacheResource::invalidLoadedCache($this); return $_cache_resource->clearAll($this, $exp_time); } /** * Empty cache for a specific template * * @param string $template_name template name * @param string $cache_id cache id * @param string $compile_id compile id * @param integer $exp_time expiration time * @param string $type resource type * @return integer number of cache files deleted */ public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) { // load cache resource and call clear $_cache_resource = Smarty_CacheResource::load($this, $type); Smarty_CacheResource::invalidLoadedCache($this); return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); } /** * Loads security class and enables security * * @param string|Smarty_Security $security_class if a string is used, it must be class-name * @return Smarty current Smarty instance for chaining * @throws SmartyException when an invalid class name is provided */ public function enableSecurity($security_class = null) { if ($security_class instanceof Smarty_Security) { $this->security_policy = $security_class; return $this; } elseif (is_object($security_class)) { throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security."); } if ($security_class == null) { $security_class = $this->security_class; } if (!class_exists($security_class)) { throw new SmartyException("Security class '$security_class' is not defined"); } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) { throw new SmartyException("Class '$security_class' must extend Smarty_Security."); } else { $this->security_policy = new $security_class($this); } return $this; } /** * Disable security * @return Smarty current Smarty instance for chaining */ public function disableSecurity() { $this->security_policy = null; return $this; } /** * Set template directory * * @param string|array $template_dir directory(s) of template sources * @return Smarty current Smarty instance for chaining */ public function setTemplateDir($template_dir) { $this->template_dir = array(); foreach ((array) $template_dir as $k => $v) { $this->template_dir[$k] = rtrim($v, '/\\') . DS; } $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); return $this; } /** * Add template directory(s) * * @param string|array $template_dir directory(s) of template sources * @param string $key of the array element to assign the template dir to * @return Smarty current Smarty instance for chaining * @throws SmartyException when the given template directory is not valid */ public function addTemplateDir($template_dir, $key=null) { // make sure we're dealing with an array $this->template_dir = (array) $this->template_dir; if (is_array($template_dir)) { foreach ($template_dir as $k => $v) { if (is_int($k)) { // indexes are not merged but appended $this->template_dir[] = rtrim($v, '/\\') . DS; } else { // string indexes are overridden $this->template_dir[$k] = rtrim($v, '/\\') . DS; } } } elseif ($key !== null) { // override directory at specified index $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS; } else { // append new directory $this->template_dir[] = rtrim($template_dir, '/\\') . DS; } $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); return $this; } /** * Get template directories * * @param mixed index of directory to get, null to get all * @return array|string list of template directories, or directory of $index */ public function getTemplateDir($index=null) { if ($index !== null) { return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; } return (array)$this->template_dir; } /** * Set config directory * * @param string|array $template_dir directory(s) of configuration sources * @return Smarty current Smarty instance for chaining */ public function setConfigDir($config_dir) { $this->config_dir = array(); foreach ((array) $config_dir as $k => $v) { $this->config_dir[$k] = rtrim($v, '/\\') . DS; } $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); return $this; } /** * Add config directory(s) * * @param string|array $config_dir directory(s) of config sources * @param string key of the array element to assign the config dir to * @return Smarty current Smarty instance for chaining */ public function addConfigDir($config_dir, $key=null) { // make sure we're dealing with an array $this->config_dir = (array) $this->config_dir; if (is_array($config_dir)) { foreach ($config_dir as $k => $v) { if (is_int($k)) { // indexes are not merged but appended $this->config_dir[] = rtrim($v, '/\\') . DS; } else { // string indexes are overridden $this->config_dir[$k] = rtrim($v, '/\\') . DS; } } } elseif( $key !== null ) { // override directory at specified index $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS; } else { // append new directory $this->config_dir[] = rtrim($config_dir, '/\\') . DS; } $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); return $this; } /** * Get config directory * * @param mixed index of directory to get, null to get all * @return array|string configuration directory */ public function getConfigDir($index=null) { if ($index !== null) { return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null; } return (array)$this->config_dir; } /** * Set plugins directory * * @param string|array $plugins_dir directory(s) of plugins * @return Smarty current Smarty instance for chaining */ public function setPluginsDir($plugins_dir) { $this->plugins_dir = array(); foreach ((array)$plugins_dir as $k => $v) { $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; } return $this; } /** * Adds directory of plugin files * * @param object $smarty * @param string $ |array $ plugins folder * @return Smarty current Smarty instance for chaining */ public function addPluginsDir($plugins_dir) { // make sure we're dealing with an array $this->plugins_dir = (array) $this->plugins_dir; if (is_array($plugins_dir)) { foreach ($plugins_dir as $k => $v) { if (is_int($k)) { // indexes are not merged but appended $this->plugins_dir[] = rtrim($v, '/\\') . DS; } else { // string indexes are overridden $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; } } } else { // append new directory $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS; } $this->plugins_dir = array_unique($this->plugins_dir); return $this; } /** * Get plugin directories * * @return array list of plugin directories */ public function getPluginsDir() { return (array)$this->plugins_dir; } /** * Set compile directory * * @param string $compile_dir directory to store compiled templates in * @return Smarty current Smarty instance for chaining */ public function setCompileDir($compile_dir) { $this->compile_dir = rtrim($compile_dir, '/\\') . DS; if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { Smarty::$_muted_directories[$this->compile_dir] = null; } return $this; } /** * Get compiled directory * * @return string path to compiled templates */ public function getCompileDir() { return $this->compile_dir; } /** * Set cache directory * * @param string $cache_dir directory to store cached templates in * @return Smarty current Smarty instance for chaining */ public function setCacheDir($cache_dir) { $this->cache_dir = rtrim($cache_dir, '/\\') . DS; if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { Smarty::$_muted_directories[$this->cache_dir] = null; } return $this; } /** * Get cache directory * * @return string path of cache directory */ public function getCacheDir() { return $this->cache_dir; } /** * Set default modifiers * * @param array|string $modifiers modifier or list of modifiers to set * @return Smarty current Smarty instance for chaining */ public function setDefaultModifiers($modifiers) { $this->default_modifiers = (array) $modifiers; return $this; } /** * Add default modifiers * * @param array|string $modifiers modifier or list of modifiers to add * @return Smarty current Smarty instance for chaining */ public function addDefaultModifiers($modifiers) { if (is_array($modifiers)) { $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); } else { $this->default_modifiers[] = $modifiers; } return $this; } /** * Get default modifiers * * @return array list of default modifiers */ public function getDefaultModifiers() { return $this->default_modifiers; } /** * Set autoload filters * * @param array $filters filters to load automatically * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types * @return Smarty current Smarty instance for chaining */ public function setAutoloadFilters($filters, $type=null) { if ($type !== null) { $this->autoload_filters[$type] = (array) $filters; } else { $this->autoload_filters = (array) $filters; } return $this; } /** * Add autoload filters * * @param array $filters filters to load automatically * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types * @return Smarty current Smarty instance for chaining */ public function addAutoloadFilters($filters, $type=null) { if ($type !== null) { if (!empty($this->autoload_filters[$type])) { $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters); } else { $this->autoload_filters[$type] = (array) $filters; } } else { foreach ((array) $filters as $key => $value) { if (!empty($this->autoload_filters[$key])) { $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value); } else { $this->autoload_filters[$key] = (array) $value; } } } return $this; } /** * Get autoload filters * * @param string $type type of filter to get autoloads for. Defaults to all autoload filters * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified */ public function getAutoloadFilters($type=null) { if ($type !== null) { return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); } return $this->autoload_filters; } /** * return name of debugging template * * @return string */ public function getDebugTemplate() { return $this->debug_tpl; } /** * set the debug template * * @param string $tpl_name * @return Smarty current Smarty instance for chaining * @throws SmartyException if file is not readable */ public function setDebugTemplate($tpl_name) { if (!is_readable($tpl_name)) { throw new SmartyException("Unknown file '{$tpl_name}'"); } $this->debug_tpl = $tpl_name; return $this; } /** * creates a template object * * @param string $template the resource handle of the template file * @param mixed $cache_id cache id to be used with this template * @param mixed $compile_id compile id to be used with this template * @param object $parent next higher level of Smarty variables * @param boolean $do_clone flag is Smarty object shall be cloned * @return object template object */ public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) { if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) { $parent = $cache_id; $cache_id = null; } if (!empty($parent) && is_array($parent)) { $data = $parent; $parent = null; } else { $data = null; } // default to cache_id and compile_id of Smarty object $cache_id = $cache_id === null ? $this->cache_id : $cache_id; $compile_id = $compile_id === null ? $this->compile_id : $compile_id; // already in template cache? if ($this->allow_ambiguous_resources) { $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id; } else { $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id; } if (isset($_templateId[150])) { $_templateId = sha1($_templateId); } if ($do_clone) { if (isset($this->template_objects[$_templateId])) { // return cached template object $tpl = clone $this->template_objects[$_templateId]; $tpl->smarty = clone $tpl->smarty; $tpl->parent = $parent; $tpl->tpl_vars = array(); $tpl->config_vars = array(); } else { $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id); } } else { if (isset($this->template_objects[$_templateId])) { // return cached template object $tpl = $this->template_objects[$_templateId]; $tpl->parent = $parent; $tpl->tpl_vars = array(); $tpl->config_vars = array(); } else { $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id); } } // fill data if present if (!empty($data) && is_array($data)) { // set up variable values foreach ($data as $_key => $_val) { $tpl->tpl_vars[$_key] = new Smarty_variable($_val); } } return $tpl; } /** * Takes unknown classes and loads plugin files for them * class name format: Smarty_PluginType_PluginName * plugin filename format: plugintype.pluginname.php * * @param string $plugin_name class plugin name to load * @param bool $check check if already loaded * @return string |boolean filepath of loaded file or false */ public function loadPlugin($plugin_name, $check = true) { // if function or class exists, exit silently (already loaded) if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { return true; } // Plugin name is expected to be: Smarty_[Type]_[Name] $_name_parts = explode('_', $plugin_name, 3); // class name must have three parts to be valid plugin // count($_name_parts) < 3 === !isset($_name_parts[2]) if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') { throw new SmartyException("plugin {$plugin_name} is not a valid name format"); return false; } // if type is "internal", get plugin from sysplugins if (strtolower($_name_parts[1]) == 'internal') { $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php'; if (file_exists($file)) { require_once($file); return $file; } else { return false; } } // plugin filename is expected to be: [type].[name].php $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); // loop through plugin dirs and find the plugin foreach($this->getPluginsDir() as $_plugin_dir) { $names = array( $_plugin_dir . $_plugin_filename, $_plugin_dir . strtolower($_plugin_filename), ); foreach ($names as $file) { if (file_exists($file)) { require_once($file); return $file; } if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { // try PHP include_path if ($_stream_resolve_include_path) { $file = stream_resolve_include_path($file); } else { $file = Smarty_Internal_Get_Include_Path::getIncludePath($file); } if ($file !== false) { require_once($file); return $file; } } } } // no plugin loaded return false; } /** * Compile all template files * * @param string $extension file extension * @param bool $force_compile force all to recompile * @param int $time_limit * @param int $max_errors * @return integer number of template files recompiled */ public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) { return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this); } /** * Compile all config files * * @param string $extension file extension * @param bool $force_compile force all to recompile * @param int $time_limit * @param int $max_errors * @return integer number of template files recompiled */ public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) { return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this); } /** * Delete compiled template file * * @param string $resource_name template name * @param string $compile_id compile id * @param integer $exp_time expiration time * @return integer number of template files deleted */ public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) { return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this); } /** * Return array of tag/attributes of all tags used by an template * * @param object $templae template object * @return array of tag/attributes */ public function getTags(Smarty_Internal_Template $template) { return Smarty_Internal_Utility::getTags($template); } /** * Run installation test * * @param array $errors Array to write errors into, rather than outputting them * @return boolean true if setup is fine, false if something is wrong */ public function testInstall(&$errors=null) { return Smarty_Internal_Utility::testInstall($this, $errors); } /** * Error Handler to mute expected messages * * @link http://php.net/set_error_handler * @param integer $errno Error level * @return boolean */ public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) { $_is_muted_directory = false; // add the SMARTY_DIR to the list of muted directories if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { $smarty_dir = realpath(SMARTY_DIR); if ($smarty_dir !== false) { Smarty::$_muted_directories[SMARTY_DIR] = array( 'file' => $smarty_dir, 'length' => strlen($smarty_dir), ); } } // walk the muted directories and test against $errfile foreach (Smarty::$_muted_directories as $key => &$dir) { if (!$dir) { // resolve directory and length for speedy comparisons $file = realpath($key); if ($file === false) { // this directory does not exist, remove and skip it unset(Smarty::$_muted_directories[$key]); continue; } $dir = array( 'file' => $file, 'length' => strlen($file), ); } if (!strncmp($errfile, $dir['file'], $dir['length'])) { $_is_muted_directory = true; break; } } // pass to next error handler if this error did not occur inside SMARTY_DIR // or the error was within smarty but masked to be ignored if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { if (Smarty::$_previous_error_handler) { return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext); } else { return false; } } } /** * Enable error handler to mute expected messages * * @return void */ public static function muteExpectedErrors() { /* error muting is done because some people implemented custom error_handlers using http://php.net/set_error_handler and for some reason did not understand the following paragraph: It is important to remember that the standard PHP error handler is completely bypassed for the error types specified by error_types unless the callback function returns FALSE. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator. Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include - @filemtime() is almost twice as fast as using an additional file_exists() - between file_exists() and filemtime() a possible race condition is opened, which does not exist using the simple @filemtime() approach. */ $error_handler = array('Smarty', 'mutingErrorHandler'); $previous = set_error_handler($error_handler); // avoid dead loops if ($previous !== $error_handler) { Smarty::$_previous_error_handler = $previous; } } /** * Disable error handler muting expected messages * * @return void */ public static function unmuteExpectedErrors() { restore_error_handler(); } } // Check if we're running on windows Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 if (Smarty::$_CHARSET !== 'UTF-8') { Smarty::$_UTF8_MODIFIER = ''; } /** * Smarty exception class * @package Smarty */ class SmartyException extends Exception { public static $escape = true; public function __construct($message) { $this->message = self::$escape ? htmlentities($message) : $message; } } /** * Smarty compiler exception class * @package Smarty */ class SmartyCompilerException extends SmartyException { } /** * Autoloader */ function smartyAutoload($class) { $_class = strtolower($class); $_classes = array( 'smarty_config_source' => true, 'smarty_config_compiled' => true, 'smarty_security' => true, 'smarty_cacheresource' => true, 'smarty_cacheresource_custom' => true, 'smarty_cacheresource_keyvaluestore' => true, 'smarty_resource' => true, 'smarty_resource_custom' => true, 'smarty_resource_uncompiled' => true, 'smarty_resource_recompiled' => true, ); if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; } } ?> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Collabtive-2.0/include/class.TCPDF.php��������������������������������������������������������������0000664�0000000�0000000�00003303711�12372520637�0017556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php //============================================================+ // File name : tcpdf.php // Version : 6.0.011 // Begin : 2002-08-03 // Last Update : 2013-04-03 // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com // License : http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT GNU-LGPLv3 // ------------------------------------------------------------------- // Copyright (C) 2002-2013 Nicola Asuni - Tecnick.com LTD // // This file is part of TCPDF software library. // // TCPDF is free software: you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // TCPDF is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the License // along with TCPDF. If not, see // <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : // This is a PHP class for generating PDF documents without requiring external extensions. // // NOTE: // This class was originally derived in 2002 from the Public // Domain FPDF class by Olivier Plathey (http://www.fpdf.org), // but now is almost entirely rewritten and contains thousands of // new lines of code and hundreds new features. // // Main features: // * no external libraries are required for the basic functions; // * all standard page formats, custom page formats, custom margins and units of measure; // * UTF-8 Unicode and Right-To-Left languages; // * TrueTypeUnicode, TrueType, Type1 and CID-0 fonts; // * font subsetting; // * methods to publish some XHTML + CSS code, Javascript and Forms; // * images, graphic (geometric figures) and transformation methods; // * supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/www/formats.html) // * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417; // * JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies; // * automatic page header and footer management; // * document encryption up to 256 bit and digital signature certifications; // * transactions to UNDO commands; // * PDF annotations, including links, text and file attachments; // * text rendering modes (fill, stroke and clipping); // * multiple columns mode; // * no-write page regions; // * bookmarks, named destinations and table of content; // * text hyphenation; // * text stretching and spacing (tracking); // * automatic page break, line break and text alignments including justification; // * automatic page numbering and page groups; // * move and delete pages; // * page compression (requires php-zlib extension); // * XOBject Templates; // * Layers and object visibility. // * PDF/A-1b support. // // ----------------------------------------------------------- // THANKS TO: // // Olivier Plathey (http://www.fpdf.org) for original FPDF. // Efthimios Mavrogeorgiadis (emavro@yahoo.com) for suggestions on RTL language support. // Klemen Vodopivec (http://www.fpdf.de/downloads/addons/37/) for Encryption algorithm. // Warren Sherliker (wsherliker@gmail.com) for better image handling. // dullus for text Justification. // Bob Vincent (pillarsdotnet@users.sourceforge.net) for <li> value attribute. // Patrick Benny for text stretch suggestion on Cell(). // Johannes Gntert for JavaScript support. // Denis Van Nuffelen for Dynamic Form. // Jacek Czekaj for multibyte justification // Anthony Ferrara for the reintroduction of legacy image methods. // Sourceforge user 1707880 (hucste) for line-trough mode. // Larry Stanbery for page groups. // Martin Hall-May for transparency. // Aaron C. Spike for Polycurve method. // Mohamad Ali Golkar, Saleh AlMatrafe, Charles Abbott for Arabic and Persian support. // Moritz Wagner and Andreas Wurmser for graphic functions. // Andrew Whitehead for core fonts support. // Esteban Jol Marn for OpenType font conversion. // Teus Hagen for several suggestions and fixes. // Yukihiro Nakadaira for CID-0 CJK fonts fixes. // Kosmas Papachristos for some CSS improvements. // Marcel Partap for some fixes. // Won Kyu Park for several suggestions, fixes and patches. // Dominik Dzienia for QR-code support. // Laurent Minguet for some suggestions. // Christian Deligant for some suggestions and fixes. // Travis Harris for crop mark suggestion. // Aleksey Kuznetsov for some suggestions and text shadows. // Jim Hanlon for several suggestions and patches. // Anyone else that has reported a bug or sent a suggestion. //============================================================+ /** * @file * This is a PHP class for generating PDF documents without requiring external extensions.<br> * TCPDF project (http://www.tcpdf.org) was originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br> * <h3>TCPDF main features are:</h3> * <ul> * <li>no external libraries are required for the basic functions;</li> * <li>all standard page formats, custom page formats, custom margins and units of measure;</li> * <li>UTF-8 Unicode and Right-To-Left languages;</li> * <li>TrueTypeUnicode, TrueType, Type1 and CID-0 fonts;</li> * <li>font subsetting;</li> * <li>methods to publish some XHTML + CSS code, Javascript and Forms;</li> * <li>images, graphic (geometric figures) and transformation methods; * <li>supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/www/formats.html)</li> * <li>1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;</li> * <li>JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;</li> * <li>automatic page header and footer management;</li> * <li>document encryption up to 256 bit and digital signature certifications;</li> * <li>transactions to UNDO commands;</li> * <li>PDF annotations, including links, text and file attachments;</li> * <li>text rendering modes (fill, stroke and clipping);</li> * <li>multiple columns mode;</li> * <li>no-write page regions;</li> * <li>bookmarks, named destinations and table of content;</li> * <li>text hyphenation;</li> * <li>text stretching and spacing (tracking);</li> * <li>automatic page break, line break and text alignments including justification;</li> * <li>automatic page numbering and page groups;</li> * <li>move and delete pages;</li> * <li>page compression (requires php-zlib extension);</li> * <li>XOBject Templates;</li> * <li>Layers and object visibility;</li> * <li>PDF/A-1b support.</li> * </ul> * Tools to encode your unicode fonts are on fonts/utils directory.</p> * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 6.0.011 */ if (!defined('K_TCPDF_EXTERNAL_CONFIG')) { // DOCUMENT_ROOT fix for IIS Webserver if ((!isset($_SERVER['DOCUMENT_ROOT'])) OR (empty($_SERVER['DOCUMENT_ROOT']))) { if(isset($_SERVER['SCRIPT_FILENAME'])) { $_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF']))); } elseif(isset($_SERVER['PATH_TRANSLATED'])) { $_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr(str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']), 0, 0-strlen($_SERVER['PHP_SELF']))); } else { // define here your DOCUMENT_ROOT path if the previous fails (e.g. '/var/www') $_SERVER['DOCUMENT_ROOT'] = '/var/www'; } } // be sure that the end slash is present $_SERVER['DOCUMENT_ROOT'] = str_replace('//', '/', $_SERVER['DOCUMENT_ROOT'].'/'); // Automatic calculation for the following K_PATH_MAIN constant $k_path_main = realpath(dirname(__FILE__))."/"; /** * Installation path (/var/www/tcpdf/). * By default it is automatically calculated but you can also set it as a fixed string to improve performances. */ define ('K_PATH_MAIN', $k_path_main); // Automatic calculation for the following K_PATH_URL constant $k_path_url = $k_path_main; // default value for console mode if (isset($_SERVER['HTTP_HOST']) AND (!empty($_SERVER['HTTP_HOST']))) { if(isset($_SERVER['HTTPS']) AND (!empty($_SERVER['HTTPS'])) AND strtolower($_SERVER['HTTPS'])!='off') { $k_path_url = 'https://'; } else { $k_path_url = 'http://'; } $k_path_url .= $_SERVER['HTTP_HOST']; $k_path_url .= str_replace( '\\', '/', substr($_SERVER['PHP_SELF'], 0, -24)); } /** * URL path to tcpdf installation folder (http://localhost/tcpdf/). * By default it is automatically calculated but you can also set it as a fixed string to improve performances. */ define ('K_PATH_URL', $k_path_url); /** * path for PDF fonts * use K_PATH_MAIN.'fonts/old/' for old non-UTF8 fonts */ define ('K_PATH_FONTS', K_PATH_MAIN.'font/'); /** * cache directory for temporary files (full path) */ define ('K_PATH_CACHE', K_PATH_MAIN.'cache/'); /** * cache directory for temporary files (url path) */ define ('K_PATH_URL_CACHE', K_PATH_URL.'cache/'); /** *images directory */ define ('K_PATH_IMAGES', K_PATH_MAIN.'images/'); /** * blank image */ define ('K_BLANK_IMAGE', K_PATH_IMAGES.'_blank.png'); /** * page format */ define ('PDF_PAGE_FORMAT', 'A4'); /** * page orientation (P=portrait, L=landscape) */ define ('PDF_PAGE_ORIENTATION', 'P'); /** * document creator */ define ('PDF_CREATOR', 'Collabtive'); /** * document author */ define ('PDF_AUTHOR', ''); /** * header title */ define ('PDF_HEADER_TITLE', ' '); /** * header description string */ define ('PDF_HEADER_STRING', ""); /** * image logo */ define ('PDF_HEADER_LOGO', ''); /** * header logo image width [mm] */ define ('PDF_HEADER_LOGO_WIDTH', 30); /** * document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch] */ define ('PDF_UNIT', 'mm'); /** * header margin */ define ('PDF_MARGIN_HEADER', 5); /** * footer margin */ define ('PDF_MARGIN_FOOTER', 10); /** * top margin */ define ('PDF_MARGIN_TOP', 25); /** * bottom margin */ define ('PDF_MARGIN_BOTTOM', 17); /** * left margin */ define ('PDF_MARGIN_LEFT', 15); /** * right margin */ define ('PDF_MARGIN_RIGHT', 15); /** * default main font name */ define ('PDF_FONT_NAME_MAIN', 'helvetica'); /** * default main font size */ define ('PDF_FONT_SIZE_MAIN', 10); /** * default data font name */ define ('PDF_FONT_NAME_DATA', 'freeserif'); /** * default data font size */ define ('PDF_FONT_SIZE_DATA', 8); /** * default monospaced font name */ define ('PDF_FONT_MONOSPACED', 'courier'); /** * ratio used to adjust the conversion of pixels to user units */ define ('PDF_IMAGE_SCALE_RATIO', 4); /** * magnification factor for titles */ define('HEAD_MAGNIFICATION', 0); /** * height of cell respect font height */ define('K_CELL_HEIGHT_RATIO', 1.25); /** * title magnification respect main font size */ define('K_TITLE_MAGNIFICATION', 1.3); /** * reduction factor for small font */ define('K_SMALL_RATIO', 2/3); /** * set to true to enable the special procedure used to avoid the overlappind of symbols on Thai language */ define('K_THAI_TOPCHARS', true); /** * if true allows to call TCPDF methods using HTML syntax * IMPORTANT: For security reason, disable this feature if you are printing user HTML content. */ define('K_TCPDF_CALLS_IN_HTML', true); /** * if true adn PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution. */ define('K_TCPDF_THROW_EXCEPTION_ERROR', false); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // TCPDF static font methods and data require_once(dirname(__FILE__).'/include/tcpdf_font_data.php'); // TCPDF static font methods and data require_once(dirname(__FILE__).'/include/tcpdf_fonts.php'); // TCPDF static color methods and data require(dirname(__FILE__).'/include/tcpdf_colors.php'); // TCPDF static image methods and data require(dirname(__FILE__).'/include/tcpdf_images.php'); // TCPDF static methods and data require_once(dirname(__FILE__).'/include/tcpdf_static.php'); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * @class TCPDF * PHP class for generating PDF documents without requiring external extensions. * TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br> * @package com.tecnick.tcpdf * @brief PHP class for generating PDF documents without requiring external extensions. * @version 6.0.011 * @author Nicola Asuni - info@tecnick.com */ class TCPDF { // Protected properties /** * Current page number. * @protected */ protected $page; /** * Current object number. * @protected */ protected $n; /** * Array of object offsets. * @protected */ protected $offsets = array(); /** * Array of object IDs for each page. * @protected */ protected $pageobjects = array(); /** * Buffer holding in-memory PDF. * @protected */ protected $buffer; /** * Array containing pages. * @protected */ protected $pages = array(); /** * Current document state. * @protected */ protected $state; /** * Compression flag. * @protected */ protected $compress; /** * Current page orientation (P = Portrait, L = Landscape). * @protected */ protected $CurOrientation; /** * Page dimensions. * @protected */ protected $pagedim = array(); /** * Scale factor (number of points in user unit). * @protected */ protected $k; /** * Width of page format in points. * @protected */ protected $fwPt; /** * Height of page format in points. * @protected */ protected $fhPt; /** * Current width of page in points. * @protected */ protected $wPt; /** * Current height of page in points. * @protected */ protected $hPt; /** * Current width of page in user unit. * @protected */ protected $w; /** * Current height of page in user unit. * @protected */ protected $h; /** * Left margin. * @protected */ protected $lMargin; /** * Right margin. * @protected */ protected $rMargin; /** * Cell left margin (used by regions). * @protected */ protected $clMargin; /** * Cell right margin (used by regions). * @protected */ protected $crMargin; /** * Top margin. * @protected */ protected $tMargin; /** * Page break margin. * @protected */ protected $bMargin; /** * Array of cell internal paddings ('T' => top, 'R' => right, 'B' => bottom, 'L' => left). * @since 5.9.000 (2010-10-03) * @protected */ protected $cell_padding = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0); /** * Array of cell margins ('T' => top, 'R' => right, 'B' => bottom, 'L' => left). * @since 5.9.000 (2010-10-04) * @protected */ protected $cell_margin = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0); /** * Current horizontal position in user unit for cell positioning. * @protected */ protected $x; /** * Current vertical position in user unit for cell positioning. * @protected */ protected $y; /** * Height of last cell printed. * @protected */ protected $lasth; /** * Line width in user unit. * @protected */ protected $LineWidth; /** * Array of standard font names. * @protected */ protected $CoreFonts; /** * Array of used fonts. * @protected */ protected $fonts = array(); /** * Array of font files. * @protected */ protected $FontFiles = array(); /** * Array of encoding differences. * @protected */ protected $diffs = array(); /** * Array of used images. * @protected */ protected $images = array(); /** * Array of cached files. * @protected */ protected $cached_files = array(); /** * Array of Annotations in pages. * @protected */ protected $PageAnnots = array(); /** * Array of internal links. * @protected */ protected $links = array(); /** * Current font family. * @protected */ protected $FontFamily; /** * Current font style. * @protected */ protected $FontStyle; /** * Current font ascent (distance between font top and baseline). * @protected * @since 2.8.000 (2007-03-29) */ protected $FontAscent; /** * Current font descent (distance between font bottom and baseline). * @protected * @since 2.8.000 (2007-03-29) */ protected $FontDescent; /** * Underlining flag. * @protected */ protected $underline; /** * Overlining flag. * @protected */ protected $overline; /** * Current font info. * @protected */ protected $CurrentFont; /** * Current font size in points. * @protected */ protected $FontSizePt; /** * Current font size in user unit. * @protected */ protected $FontSize; /** * Commands for drawing color. * @protected */ protected $DrawColor; /** * Commands for filling color. * @protected */ protected $FillColor; /** * Commands for text color. * @protected */ protected $TextColor; /** * Indicates whether fill and text colors are different. * @protected */ protected $ColorFlag; /** * Automatic page breaking. * @protected */ protected $AutoPageBreak; /** * Threshold used to trigger page breaks. * @protected */ protected $PageBreakTrigger; /** * Flag set when processing page header. * @protected */ protected $InHeader = false; /** * Flag set when processing page footer. * @protected */ protected $InFooter = false; /** * Zoom display mode. * @protected */ protected $ZoomMode; /** * Layout display mode. * @protected */ protected $LayoutMode; /** * If true set the document information dictionary in Unicode. * @protected */ protected $docinfounicode = true; /** * Document title. * @protected */ protected $title = ''; /** * Document subject. * @protected */ protected $subject = ''; /** * Document author. * @protected */ protected $author = ''; /** * Document keywords. * @protected */ protected $keywords = ''; /** * Document creator. * @protected */ protected $creator = ''; /** * Starting page number. * @protected */ protected $starting_page_number = 1; /** * The right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image. * @since 2002-07-31 * @author Nicola Asuni * @protected */ protected $img_rb_x; /** * The right-bottom corner Y coordinate of last inserted image. * @since 2002-07-31 * @author Nicola Asuni * @protected */ protected $img_rb_y; /** * Adjusting factor to convert pixels to user units. * @since 2004-06-14 * @author Nicola Asuni * @protected */ protected $imgscale = 1; /** * Boolean flag set to true when the input text is unicode (require unicode fonts). * @since 2005-01-02 * @author Nicola Asuni * @protected */ protected $isunicode = false; /** * PDF version. * @since 1.5.3 * @protected */ protected $PDFVersion = '1.7'; /** * ID of the stored default header template (-1 = not set). * @protected */ protected $header_xobjid = -1; /** * If true reset the Header Xobject template at each page * @protected */ protected $header_xobj_autoreset = false; /** * Minimum distance between header and top page margin. * @protected */ protected $header_margin; /** * Minimum distance between footer and bottom page margin. * @protected */ protected $footer_margin; /** * Original left margin value. * @protected * @since 1.53.0.TC013 */ protected $original_lMargin; /** * Original right margin value. * @protected * @since 1.53.0.TC013 */ protected $original_rMargin; /** * Default font used on page header. * @protected */ protected $header_font; /** * Default font used on page footer. * @protected */ protected $footer_font; /** * Language templates. * @protected */ protected $l; /** * Barcode to print on page footer (only if set). * @protected */ protected $barcode = false; /** * Boolean flag to print/hide page header. * @protected */ protected $print_header = true; /** * Boolean flag to print/hide page footer. * @protected */ protected $print_footer = true; /** * Header image logo. * @protected */ protected $header_logo = ''; /** * Width of header image logo in user units. * @protected */ protected $header_logo_width = 30; /** * Title to be printed on default page header. * @protected */ protected $header_title = ''; /** * String to pring on page header after title. * @protected */ protected $header_string = ''; /** * Color for header text (RGB array). * @since 5.9.174 (2012-07-25) * @protected */ protected $header_text_color = array(0,0,0); /** * Color for header line (RGB array). * @since 5.9.174 (2012-07-25) * @protected */ protected $header_line_color = array(0,0,0); /** * Color for footer text (RGB array). * @since 5.9.174 (2012-07-25) * @protected */ protected $footer_text_color = array(0,0,0); /** * Color for footer line (RGB array). * @since 5.9.174 (2012-07-25) * @protected */ protected $footer_line_color = array(0,0,0); /** * Text shadow data array. * @since 5.9.174 (2012-07-25) * @protected */ protected $txtshadow = array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal'); /** * Default number of columns for html table. * @protected */ protected $default_table_columns = 4; // variables for html parser /** * HTML PARSER: array to store current link and rendering styles. * @protected */ protected $HREF = array(); /** * List of available fonts on filesystem. * @protected */ protected $fontlist = array(); /** * Current foreground color. * @protected */ protected $fgcolor; /** * HTML PARSER: array of boolean values, true in case of ordered list (OL), false otherwise. * @protected */ protected $listordered = array(); /** * HTML PARSER: array count list items on nested lists. * @protected */ protected $listcount = array(); /** * HTML PARSER: current list nesting level. * @protected */ protected $listnum = 0; /** * HTML PARSER: indent amount for lists. * @protected */ protected $listindent = 0; /** * HTML PARSER: current list indententation level. * @protected */ protected $listindentlevel = 0; /** * Current background color. * @protected */ protected $bgcolor; /** * Temporary font size in points. * @protected */ protected $tempfontsize = 10; /** * Spacer string for LI tags. * @protected */ protected $lispacer = ''; /** * Default encoding. * @protected * @since 1.53.0.TC010 */ protected $encoding = 'UTF-8'; /** * PHP internal encoding. * @protected * @since 1.53.0.TC016 */ protected $internal_encoding; /** * Boolean flag to indicate if the document language is Right-To-Left. * @protected * @since 2.0.000 */ protected $rtl = false; /** * Boolean flag used to force RTL or LTR string direction. * @protected * @since 2.0.000 */ protected $tmprtl = false; // --- Variables used for document encryption: /** * IBoolean flag indicating whether document is protected. * @protected * @since 2.0.000 (2008-01-02) */ protected $encrypted; /** * Array containing encryption settings. * @protected * @since 5.0.005 (2010-05-11) */ protected $encryptdata = array(); /** * Last RC4 key encrypted (cached for optimisation). * @protected * @since 2.0.000 (2008-01-02) */ protected $last_enc_key; /** * Last RC4 computed key. * @protected * @since 2.0.000 (2008-01-02) */ protected $last_enc_key_c; /** * File ID (used on document trailer). * @protected * @since 5.0.005 (2010-05-12) */ protected $file_id; // --- bookmark --- /** * Outlines for bookmark. * @protected * @since 2.1.002 (2008-02-12) */ protected $outlines = array(); /** * Outline root for bookmark. * @protected * @since 2.1.002 (2008-02-12) */ protected $OutlineRoot; // --- javascript and form --- /** * Javascript code. * @protected * @since 2.1.002 (2008-02-12) */ protected $javascript = ''; /** * Javascript counter. * @protected * @since 2.1.002 (2008-02-12) */ protected $n_js; /** * line trough state * @protected * @since 2.8.000 (2008-03-19) */ protected $linethrough; /** * Array with additional document-wide usage rights for the document. * @protected * @since 5.8.014 (2010-08-23) */ protected $ur = array(); /** * DPI (Dot Per Inch) Document Resolution (do not change). * @protected * @since 3.0.000 (2008-03-27) */ protected $dpi = 72; /** * Array of page numbers were a new page group was started (the page numbers are the keys of the array). * @protected * @since 3.0.000 (2008-03-27) */ protected $newpagegroup = array(); /** * Array that contains the number of pages in each page group. * @protected * @since 3.0.000 (2008-03-27) */ protected $pagegroups = array(); /** * Current page group number. * @protected * @since 3.0.000 (2008-03-27) */ protected $currpagegroup = 0; /** * Array of transparency objects and parameters. * @protected * @since 3.0.000 (2008-03-27) */ protected $extgstates; /** * Set the default JPEG compression quality (1-100). * @protected * @since 3.0.000 (2008-03-27) */ protected $jpeg_quality; /** * Default cell height ratio. * @protected * @since 3.0.014 (2008-05-23) */ protected $cell_height_ratio = K_CELL_HEIGHT_RATIO; /** * PDF viewer preferences. * @protected * @since 3.1.000 (2008-06-09) */ protected $viewer_preferences; /** * A name object specifying how the document should be displayed when opened. * @protected * @since 3.1.000 (2008-06-09) */ protected $PageMode; /** * Array for storing gradient information. * @protected * @since 3.1.000 (2008-06-09) */ protected $gradients = array(); /** * Array used to store positions inside the pages buffer (keys are the page numbers). * @protected * @since 3.2.000 (2008-06-26) */ protected $intmrk = array(); /** * Array used to store positions inside the pages buffer (keys are the page numbers). * @protected * @since 5.7.000 (2010-08-03) */ protected $bordermrk = array(); /** * Array used to store page positions to track empty pages (keys are the page numbers). * @protected * @since 5.8.007 (2010-08-18) */ protected $emptypagemrk = array(); /** * Array used to store content positions inside the pages buffer (keys are the page numbers). * @protected * @since 4.6.021 (2009-07-20) */ protected $cntmrk = array(); /** * Array used to store footer positions of each page. * @protected * @since 3.2.000 (2008-07-01) */ protected $footerpos = array(); /** * Array used to store footer length of each page. * @protected * @since 4.0.014 (2008-07-29) */ protected $footerlen = array(); /** * Boolean flag to indicate if a new line is created. * @protected * @since 3.2.000 (2008-07-01) */ protected $newline = true; /** * End position of the latest inserted line. * @protected * @since 3.2.000 (2008-07-01) */ protected $endlinex = 0; /** * PDF string for width value of the last line. * @protected * @since 4.0.006 (2008-07-16) */ protected $linestyleWidth = ''; /** * PDF string for CAP value of the last line. * @protected * @since 4.0.006 (2008-07-16) */ protected $linestyleCap = '0 J'; /** * PDF string for join value of the last line. * @protected * @since 4.0.006 (2008-07-16) */ protected $linestyleJoin = '0 j'; /** * PDF string for dash value of the last line. * @protected * @since 4.0.006 (2008-07-16) */ protected $linestyleDash = '[] 0 d'; /** * Boolean flag to indicate if marked-content sequence is open. * @protected * @since 4.0.013 (2008-07-28) */ protected $openMarkedContent = false; /** * Count the latest inserted vertical spaces on HTML. * @protected * @since 4.0.021 (2008-08-24) */ protected $htmlvspace = 0; /** * Array of Spot colors. * @protected * @since 4.0.024 (2008-09-12) */ protected $spot_colors = array(); /** * Symbol used for HTML unordered list items. * @protected * @since 4.0.028 (2008-09-26) */ protected $lisymbol = ''; /** * String used to mark the beginning and end of EPS image blocks. * @protected * @since 4.1.000 (2008-10-18) */ protected $epsmarker = 'x#!#EPS#!#x'; /** * Array of transformation matrix. * @protected * @since 4.2.000 (2008-10-29) */ protected $transfmatrix = array(); /** * Current key for transformation matrix. * @protected * @since 4.8.005 (2009-09-17) */ protected $transfmatrix_key = 0; /** * Booklet mode for double-sided pages. * @protected * @since 4.2.000 (2008-10-29) */ protected $booklet = false; /** * Epsilon value used for float calculations. * @protected * @since 4.2.000 (2008-10-29) */ protected $feps = 0.005; /** * Array used for custom vertical spaces for HTML tags. * @protected * @since 4.2.001 (2008-10-30) */ protected $tagvspaces = array(); /** * HTML PARSER: custom indent amount for lists. Negative value means disabled. * @protected * @since 4.2.007 (2008-11-12) */ protected $customlistindent = -1; /** * Boolean flag to indicate if the border of the cell sides that cross the page should be removed. * @protected * @since 4.2.010 (2008-11-14) */ protected $opencell = true; /** * Array of files to embedd. * @protected * @since 4.4.000 (2008-12-07) */ protected $embeddedfiles = array(); /** * Boolean flag to indicate if we are inside a PRE tag. * @protected * @since 4.4.001 (2008-12-08) */ protected $premode = false; /** * Array used to store positions of graphics transformation blocks inside the page buffer. * keys are the page numbers * @protected * @since 4.4.002 (2008-12-09) */ protected $transfmrk = array(); /** * Default color for html links. * @protected * @since 4.4.003 (2008-12-09) */ protected $htmlLinkColorArray = array(0, 0, 255); /** * Default font style to add to html links. * @protected * @since 4.4.003 (2008-12-09) */ protected $htmlLinkFontStyle = 'U'; /** * Counts the number of pages. * @protected * @since 4.5.000 (2008-12-31) */ protected $numpages = 0; /** * Array containing page lengths in bytes. * @protected * @since 4.5.000 (2008-12-31) */ protected $pagelen = array(); /** * Counts the number of pages. * @protected * @since 4.5.000 (2008-12-31) */ protected $numimages = 0; /** * Store the image keys. * @protected * @since 4.5.000 (2008-12-31) */ protected $imagekeys = array(); /** * Length of the buffer in bytes. * @protected * @since 4.5.000 (2008-12-31) */ protected $bufferlen = 0; /** * If true enables disk caching. * @protected * @since 4.5.000 (2008-12-31) */ protected $diskcache = false; /** * Counts the number of fonts. * @protected * @since 4.5.000 (2009-01-02) */ protected $numfonts = 0; /** * Store the font keys. * @protected * @since 4.5.000 (2009-01-02) */ protected $fontkeys = array(); /** * Store the font object IDs. * @protected * @since 4.8.001 (2009-09-09) */ protected $font_obj_ids = array(); /** * Store the fage status (true when opened, false when closed). * @protected * @since 4.5.000 (2009-01-02) */ protected $pageopen = array(); /** * Default monospace font. * @protected * @since 4.5.025 (2009-03-10) */ protected $default_monospaced_font = 'courier'; /** * Cloned copy of the current class object. * @protected * @since 4.5.029 (2009-03-19) */ protected $objcopy; /** * Array used to store the lengths of cache files. * @protected * @since 4.5.029 (2009-03-19) */ protected $cache_file_length = array(); /** * Table header content to be repeated on each new page. * @protected * @since 4.5.030 (2009-03-20) */ protected $thead = ''; /** * Margins used for table header. * @protected * @since 4.5.030 (2009-03-20) */ protected $theadMargins = array(); /** * Boolean flag to enable document digital signature. * @protected * @since 4.6.005 (2009-04-24) */ protected $sign = false; /** * Digital signature data. * @protected * @since 4.6.005 (2009-04-24) */ protected $signature_data = array(); /** * Digital signature max length. * @protected * @since 4.6.005 (2009-04-24) */ protected $signature_max_length = 11742; /** * Data for digital signature appearance. * @protected * @since 5.3.011 (2010-06-16) */ protected $signature_appearance = array('page' => 1, 'rect' => '0 0 0 0'); /** * Array of empty digital signature appearances. * @protected * @since 5.9.101 (2011-07-06) */ protected $empty_signature_appearance = array(); /** * Regular expression used to find blank characters (required for word-wrapping). * @protected * @since 4.6.006 (2009-04-28) */ protected $re_spaces = '/[^\S\xa0]/'; /** * Array of $re_spaces parts. * @protected * @since 5.5.011 (2010-07-09) */ protected $re_space = array('p' => '[^\S\xa0]', 'm' => ''); /** * Digital signature object ID. * @protected * @since 4.6.022 (2009-06-23) */ protected $sig_obj_id = 0; /** * ID of page objects. * @protected * @since 4.7.000 (2009-08-29) */ protected $page_obj_id = array(); /** * List of form annotations IDs. * @protected * @since 4.8.000 (2009-09-07) */ protected $form_obj_id = array(); /** * Deafult Javascript field properties. Possible values are described on official Javascript for Acrobat API reference. Annotation options can be directly specified using the 'aopt' entry. * @protected * @since 4.8.000 (2009-09-07) */ protected $default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128)); /** * Javascript objects array. * @protected * @since 4.8.000 (2009-09-07) */ protected $js_objects = array(); /** * Current form action (used during XHTML rendering). * @protected * @since 4.8.000 (2009-09-07) */ protected $form_action = ''; /** * Current form encryption type (used during XHTML rendering). * @protected * @since 4.8.000 (2009-09-07) */ protected $form_enctype = 'application/x-www-form-urlencoded'; /** * Current method to submit forms. * @protected * @since 4.8.000 (2009-09-07) */ protected $form_mode = 'post'; /** * List of fonts used on form fields (fontname => fontkey). * @protected * @since 4.8.001 (2009-09-09) */ protected $annotation_fonts = array(); /** * List of radio buttons parent objects. * @protected * @since 4.8.001 (2009-09-09) */ protected $radiobutton_groups = array(); /** * List of radio group objects IDs. * @protected * @since 4.8.001 (2009-09-09) */ protected $radio_groups = array(); /** * Text indentation value (used for text-indent CSS attribute). * @protected * @since 4.8.006 (2009-09-23) */ protected $textindent = 0; /** * Store page number when startTransaction() is called. * @protected * @since 4.8.006 (2009-09-23) */ protected $start_transaction_page = 0; /** * Store Y position when startTransaction() is called. * @protected * @since 4.9.001 (2010-03-28) */ protected $start_transaction_y = 0; /** * True when we are printing the thead section on a new page. * @protected * @since 4.8.027 (2010-01-25) */ protected $inthead = false; /** * Array of column measures (width, space, starting Y position). * @protected * @since 4.9.001 (2010-03-28) */ protected $columns = array(); /** * Number of colums. * @protected * @since 4.9.001 (2010-03-28) */ protected $num_columns = 1; /** * Current column number. * @protected * @since 4.9.001 (2010-03-28) */ protected $current_column = 0; /** * Starting page for columns. * @protected * @since 4.9.001 (2010-03-28) */ protected $column_start_page = 0; /** * Maximum page and column selected. * @protected * @since 5.8.000 (2010-08-11) */ protected $maxselcol = array('page' => 0, 'column' => 0); /** * Array of: X difference between table cell x start and starting page margin, cellspacing, cellpadding. * @protected * @since 5.8.000 (2010-08-11) */ protected $colxshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0)); /** * Text rendering mode: 0 = Fill text; 1 = Stroke text; 2 = Fill, then stroke text; 3 = Neither fill nor stroke text (invisible); 4 = Fill text and add to path for clipping; 5 = Stroke text and add to path for clipping; 6 = Fill, then stroke text and add to path for clipping; 7 = Add text to path for clipping. * @protected * @since 4.9.008 (2010-04-03) */ protected $textrendermode = 0; /** * Text stroke width in doc units. * @protected * @since 4.9.008 (2010-04-03) */ protected $textstrokewidth = 0; /** * Current stroke color. * @protected * @since 4.9.008 (2010-04-03) */ protected $strokecolor; /** * Default unit of measure for document. * @protected * @since 5.0.000 (2010-04-22) */ protected $pdfunit = 'mm'; /** * Boolean flag true when we are on TOC (Table Of Content) page. * @protected */ protected $tocpage = false; /** * Boolean flag: if true convert vector images (SVG, EPS) to raster image using GD or ImageMagick library. * @protected * @since 5.0.000 (2010-04-26) */ protected $rasterize_vector_images = false; /** * Boolean flag: if true enables font subsetting by default. * @protected * @since 5.3.002 (2010-06-07) */ protected $font_subsetting = true; /** * Array of default graphic settings. * @protected * @since 5.5.008 (2010-07-02) */ protected $default_graphic_vars = array(); /** * Array of XObjects. * @protected * @since 5.8.014 (2010-08-23) */ protected $xobjects = array(); /** * Boolean value true when we are inside an XObject. * @protected * @since 5.8.017 (2010-08-24) */ protected $inxobj = false; /** * Current XObject ID. * @protected * @since 5.8.017 (2010-08-24) */ protected $xobjid = ''; /** * Percentage of character stretching. * @protected * @since 5.9.000 (2010-09-29) */ protected $font_stretching = 100; /** * Increases or decreases the space between characters in a text by the specified amount (tracking). * @protected * @since 5.9.000 (2010-09-29) */ protected $font_spacing = 0; /** * Array of no-write regions. * ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right) * @protected * @since 5.9.003 (2010-10-14) */ protected $page_regions = array(); /** * Boolean value true when page region check is active. * @protected */ protected $check_page_regions = true; /** * Array of PDF layers data. * @protected * @since 5.9.102 (2011-07-13) */ protected $pdflayers = array(); /** * A dictionary of names and corresponding destinations (Dests key on document Catalog). * @protected * @since 5.9.097 (2011-06-23) */ protected $dests = array(); /** * Object ID for Named Destinations * @protected * @since 5.9.097 (2011-06-23) */ protected $n_dests; /** * Embedded Files Names * @protected * @since 5.9.204 (2013-01-23) */ protected $efnames = array(); /** * Directory used for the last SVG image. * @protected * @since 5.0.000 (2010-05-05) */ protected $svgdir = ''; /** * Deafult unit of measure for SVG. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgunit = 'px'; /** * Array of SVG gradients. * @protected * @since 5.0.000 (2010-05-02) */ protected $svggradients = array(); /** * ID of last SVG gradient. * @protected * @since 5.0.000 (2010-05-02) */ protected $svggradientid = 0; /** * Boolean value true when in SVG defs group. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgdefsmode = false; /** * Array of SVG defs. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgdefs = array(); /** * Boolean value true when in SVG clipPath tag. * @protected * @since 5.0.000 (2010-04-26) */ protected $svgclipmode = false; /** * Array of SVG clipPath commands. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgclippaths = array(); /** * Array of SVG clipPath tranformation matrix. * @protected * @since 5.8.022 (2010-08-31) */ protected $svgcliptm = array(); /** * ID of last SVG clipPath. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgclipid = 0; /** * SVG text. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgtext = ''; /** * SVG text properties. * @protected * @since 5.8.013 (2010-08-23) */ protected $svgtextmode = array(); /** * Array of SVG properties. * @protected * @since 5.0.000 (2010-05-02) */ protected $svgstyles = array(array( 'alignment-baseline' => 'auto', 'baseline-shift' => 'baseline', 'clip' => 'auto', 'clip-path' => 'none', 'clip-rule' => 'nonzero', 'color' => 'black', 'color-interpolation' => 'sRGB', 'color-interpolation-filters' => 'linearRGB', 'color-profile' => 'auto', 'color-rendering' => 'auto', 'cursor' => 'auto', 'direction' => 'ltr', 'display' => 'inline', 'dominant-baseline' => 'auto', 'enable-background' => 'accumulate', 'fill' => 'black', 'fill-opacity' => 1, 'fill-rule' => 'nonzero', 'filter' => 'none', 'flood-color' => 'black', 'flood-opacity' => 1, 'font' => '', 'font-family' => 'helvetica', 'font-size' => 'medium', 'font-size-adjust' => 'none', 'font-stretch' => 'normal', 'font-style' => 'normal', 'font-variant' => 'normal', 'font-weight' => 'normal', 'glyph-orientation-horizontal' => '0deg', 'glyph-orientation-vertical' => 'auto', 'image-rendering' => 'auto', 'kerning' => 'auto', 'letter-spacing' => 'normal', 'lighting-color' => 'white', 'marker' => '', 'marker-end' => 'none', 'marker-mid' => 'none', 'marker-start' => 'none', 'mask' => 'none', 'opacity' => 1, 'overflow' => 'auto', 'pointer-events' => 'visiblePainted', 'shape-rendering' => 'auto', 'stop-color' => 'black', 'stop-opacity' => 1, 'stroke' => 'none', 'stroke-dasharray' => 'none', 'stroke-dashoffset' => 0, 'stroke-linecap' => 'butt', 'stroke-linejoin' => 'miter', 'stroke-miterlimit' => 4, 'stroke-opacity' => 1, 'stroke-width' => 1, 'text-anchor' => 'start', 'text-decoration' => 'none', 'text-rendering' => 'auto', 'unicode-bidi' => 'normal', 'visibility' => 'visible', 'word-spacing' => 'normal', 'writing-mode' => 'lr-tb', 'text-color' => 'black', 'transfmatrix' => array(1, 0, 0, 1, 0, 0) )); /** * If true force sRGB color profile for all document. * @protected * @since 5.9.121 (2011-09-28) */ protected $force_srgb = false; /** * If true set the document to PDF/A mode. * @protected * @since 5.9.121 (2011-09-27) */ protected $pdfa_mode = false; /** * Document creation date-time * @protected * @since 5.9.152 (2012-03-22) */ protected $doc_creation_timestamp; /** * Document modification date-time * @protected * @since 5.9.152 (2012-03-22) */ protected $doc_modification_timestamp; /** * Custom XMP data. * @protected * @since 5.9.128 (2011-10-06) */ protected $custom_xmp = ''; /** * Overprint mode array. * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008). * @protected * @since 5.9.152 (2012-03-23) */ protected $overprint = array('OP' => false, 'op' => false, 'OPM' => 0); /** * Alpha mode array. * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008). * @protected * @since 5.9.152 (2012-03-23) */ protected $alpha = array('CA' => 1, 'ca' => 1, 'BM' => '/Normal', 'AIS' => false); /** * Define the page boundaries boxes to be set on document. * @protected * @since 5.9.152 (2012-03-23) */ protected $page_boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'); /** * If true print TCPDF meta link. * @protected * @since 5.9.152 (2012-03-23) */ protected $tcpdflink = true; /** * Cache array for computed GD gamma values. * @protected * @since 5.9.1632 (2012-06-05) */ protected $gdgammacache = array(); //------------------------------------------------------------ // METHODS //------------------------------------------------------------ /** * This is the class constructor. * It allows to set up the page format, the orientation and the measure unit used in all the methods (except for the font sizes). * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li><li>'' (empty string) for automatic orientation</li></ul> * @param $unit (string) User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit. * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat(). * @param $unicode (boolean) TRUE means that the input text is unicode (default = true) * @param $encoding (string) Charset encoding (used only when converting back html entities); default is UTF-8. * @param $diskcache (boolean) If TRUE reduce the RAM memory usage by caching temporary data on filesystem (slower). * @param $pdfa (boolean) If TRUE set the document to PDF/A mode. * @public * @see getPageSizeFromFormat(), setPageFormat() */ public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) { /* Set internal character encoding to ASCII */ if (function_exists('mb_internal_encoding') AND mb_internal_encoding()) { $this->internal_encoding = mb_internal_encoding(); mb_internal_encoding('ASCII'); } $this->font_obj_ids = array(); $this->page_obj_id = array(); $this->form_obj_id = array(); // set pdf/a mode $this->pdfa_mode = $pdfa; $this->force_srgb = false; // set disk caching $this->diskcache = $diskcache ? true : false; // set language direction $this->rtl = false; $this->tmprtl = false; // some checks $this->_dochecks(); // initialization of properties $this->isunicode = $unicode; $this->page = 0; $this->transfmrk[0] = array(); $this->pagedim = array(); $this->n = 2; $this->buffer = ''; $this->pages = array(); $this->state = 0; $this->fonts = array(); $this->FontFiles = array(); $this->diffs = array(); $this->images = array(); $this->links = array(); $this->gradients = array(); $this->InFooter = false; $this->lasth = 0; $this->FontFamily = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica'; $this->FontStyle = ''; $this->FontSizePt = 12; $this->underline = false; $this->overline = false; $this->linethrough = false; $this->DrawColor = '0 G'; $this->FillColor = '0 g'; $this->TextColor = '0 g'; $this->ColorFlag = false; $this->pdflayers = array(); // encryption values $this->encrypted = false; $this->last_enc_key = ''; // standard Unicode fonts $this->CoreFonts = array( 'courier'=>'Courier', 'courierB'=>'Courier-Bold', 'courierI'=>'Courier-Oblique', 'courierBI'=>'Courier-BoldOblique', 'helvetica'=>'Helvetica', 'helveticaB'=>'Helvetica-Bold', 'helveticaI'=>'Helvetica-Oblique', 'helveticaBI'=>'Helvetica-BoldOblique', 'times'=>'Times-Roman', 'timesB'=>'Times-Bold', 'timesI'=>'Times-Italic', 'timesBI'=>'Times-BoldItalic', 'symbol'=>'Symbol', 'zapfdingbats'=>'ZapfDingbats' ); // set scale factor $this->setPageUnit($unit); // set page format and orientation $this->setPageFormat($format, $orientation); // page margins (1 cm) $margin = 28.35 / $this->k; $this->SetMargins($margin, $margin); $this->clMargin = $this->lMargin; $this->crMargin = $this->rMargin; // internal cell padding $cpadding = $margin / 10; $this->setCellPaddings($cpadding, 0, $cpadding, 0); // cell margins $this->setCellMargins(0, 0, 0, 0); // line width (0.2 mm) $this->LineWidth = 0.57 / $this->k; $this->linestyleWidth = sprintf('%F w', ($this->LineWidth * $this->k)); $this->linestyleCap = '0 J'; $this->linestyleJoin = '0 j'; $this->linestyleDash = '[] 0 d'; // automatic page break $this->SetAutoPageBreak(true, (2 * $margin)); // full width display mode $this->SetDisplayMode('fullwidth'); // compression $this->SetCompression(); // set default PDF version number $this->setPDFVersion(); $this->tcpdflink = true; $this->encoding = $encoding; $this->HREF = array(); $this->getFontsList(); $this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0); $this->strokecolor = array('R' => 0, 'G' => 0, 'B' => 0); $this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255); $this->extgstates = array(); $this->setTextShadow(); // user's rights $this->sign = false; $this->ur['enabled'] = false; $this->ur['document'] = '/FullSave'; $this->ur['annots'] = '/Create/Delete/Modify/Copy/Import/Export'; $this->ur['form'] = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate'; $this->ur['signature'] = '/Modify'; $this->ur['ef'] = '/Create/Delete/Modify/Import'; $this->ur['formex'] = ''; $this->signature_appearance = array('page' => 1, 'rect' => '0 0 0 0'); $this->empty_signature_appearance = array(); // set default JPEG quality $this->jpeg_quality = 75; // initialize some settings TCPDF_FONTS::utf8Bidi(array(''), '', false, $this->isunicode, $this->CurrentFont); // set default font $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt); // check if PCRE Unicode support is enabled if ($this->isunicode AND (@preg_match('/\pL/u', 'a') == 1)) { // PCRE unicode support is turned ON // \p{Z} or \p{Separator}: any kind of Unicode whitespace or invisible separator. // \p{Lo} or \p{Other_Letter}: a Unicode letter or ideograph that does not have lowercase and uppercase variants. // \p{Lo} is needed because Chinese characters are packed next to each other without spaces in between. //$this->setSpacesRE('/[^\S\P{Z}\P{Lo}\xa0]/u'); $this->setSpacesRE('/[^\S\P{Z}\xa0]/u'); } else { // PCRE unicode support is turned OFF $this->setSpacesRE('/[^\S\xa0]/'); } $this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128)); // set file ID for trailer $serformat = (is_array($format) ? serialize($format) : $format); $this->file_id = md5(TCPDF_STATIC::getRandomSeed('TCPDF'.$orientation.$unit.$serformat.$encoding)); // set document creation and modification timestamp $this->doc_creation_timestamp = time(); $this->doc_modification_timestamp = $this->doc_creation_timestamp; // get default graphic vars $this->default_graphic_vars = $this->getGraphicVars(); $this->header_xobj_autoreset = false; $this->custom_xmp = ''; } /** * Default destructor. * @public * @since 1.53.0.TC016 */ public function __destruct() { // restore internal encoding if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) { mb_internal_encoding($this->internal_encoding); } // unset all class variables $this->_destroy(true); } /** * Set the units of measure for the document. * @param $unit (string) User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit. * @public * @since 3.0.015 (2008-06-06) */ public function setPageUnit($unit) { $unit = strtolower($unit); //Set scale factor switch ($unit) { // points case 'px': case 'pt': { $this->k = 1; break; } // millimeters case 'mm': { $this->k = $this->dpi / 25.4; break; } // centimeters case 'cm': { $this->k = $this->dpi / 2.54; break; } // inches case 'in': { $this->k = $this->dpi; break; } // unsupported unit default : { $this->Error('Incorrect unit: '.$unit); break; } } $this->pdfunit = $unit; if (isset($this->CurOrientation)) { $this->setPageOrientation($this->CurOrientation); } } /** * Change the format of the current page * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() documentation or an array of two numners (width, height) or an array containing the following measures and options:<ul> * <li>['format'] = page format name (one of the above);</li> * <li>['Rotate'] : The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.</li> * <li>['PZ'] : The page's preferred zoom (magnification) factor.</li> * <li>['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed:</li> * <li>['MediaBox']['llx'] : lower-left x coordinate in points</li> * <li>['MediaBox']['lly'] : lower-left y coordinate in points</li> * <li>['MediaBox']['urx'] : upper-right x coordinate in points</li> * <li>['MediaBox']['ury'] : upper-right y coordinate in points</li> * <li>['CropBox'] : the visible region of default user space:</li> * <li>['CropBox']['llx'] : lower-left x coordinate in points</li> * <li>['CropBox']['lly'] : lower-left y coordinate in points</li> * <li>['CropBox']['urx'] : upper-right x coordinate in points</li> * <li>['CropBox']['ury'] : upper-right y coordinate in points</li> * <li>['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment:</li> * <li>['BleedBox']['llx'] : lower-left x coordinate in points</li> * <li>['BleedBox']['lly'] : lower-left y coordinate in points</li> * <li>['BleedBox']['urx'] : upper-right x coordinate in points</li> * <li>['BleedBox']['ury'] : upper-right y coordinate in points</li> * <li>['TrimBox'] : the intended dimensions of the finished page after trimming:</li> * <li>['TrimBox']['llx'] : lower-left x coordinate in points</li> * <li>['TrimBox']['lly'] : lower-left y coordinate in points</li> * <li>['TrimBox']['urx'] : upper-right x coordinate in points</li> * <li>['TrimBox']['ury'] : upper-right y coordinate in points</li> * <li>['ArtBox'] : the extent of the page's meaningful content:</li> * <li>['ArtBox']['llx'] : lower-left x coordinate in points</li> * <li>['ArtBox']['lly'] : lower-left y coordinate in points</li> * <li>['ArtBox']['urx'] : upper-right x coordinate in points</li> * <li>['ArtBox']['ury'] : upper-right y coordinate in points</li> * <li>['BoxColorInfo'] :specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for each of the possible page boundaries other than the MediaBox:</li> * <li>['BoxColorInfo'][BOXTYPE]['C'] : an array of three numbers in the range 0-255, representing the components in the DeviceRGB colour space.</li> * <li>['BoxColorInfo'][BOXTYPE]['W'] : the guideline width in default user units</li> * <li>['BoxColorInfo'][BOXTYPE]['S'] : the guideline style: S = Solid; D = Dashed</li> * <li>['BoxColorInfo'][BOXTYPE]['D'] : dash array defining a pattern of dashes and gaps to be used in drawing dashed guidelines</li> * <li>['trans'] : the style and duration of the visual transition to use when moving from another page to the given page during a presentation</li> * <li>['trans']['Dur'] : The page's display duration (also called its advance timing): the maximum length of time, in seconds, that the page shall be displayed during presentations before the viewer application shall automatically advance to the next page.</li> * <li>['trans']['S'] : transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade</li> * <li>['trans']['D'] : The duration of the transition effect, in seconds.</li> * <li>['trans']['Dm'] : (Split and Blinds transition styles only) The dimension in which the specified transition effect shall occur: H = Horizontal, V = Vertical. Default value: H.</li> * <li>['trans']['M'] : (Split, Box and Fly transition styles only) The direction of motion for the specified transition effect: I = Inward from the edges of the page, O = Outward from the center of the pageDefault value: I.</li> * <li>['trans']['Di'] : (Wipe, Glitter, Fly, Cover, Uncover and Push transition styles only) The direction in which the specified transition effect shall moves, expressed in degrees counterclockwise starting from a left-to-right direction. If the value is a number, it shall be one of: 0 = Left to right, 90 = Bottom to top (Wipe only), 180 = Right to left (Wipe only), 270 = Top to bottom, 315 = Top-left to bottom-right (Glitter only). If the value is a name, it shall be None, which is relevant only for the Fly transition when the value of SS is not 1.0. Default value: 0.</li> * <li>['trans']['SS'] : (Fly transition style only) The starting or ending scale at which the changes shall be drawn. If M specifies an inward transition, the scale of the changes drawn shall progress from SS to 1.0 over the course of the transition. If M specifies an outward transition, the scale of the changes drawn shall progress from 1.0 to SS over the course of the transition. Default: 1.0.</li> * <li>['trans']['B'] : (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.</li> * </ul> * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul> * <li>P or Portrait (default)</li> * <li>L or Landscape</li> * <li>'' (empty string) for automatic orientation</li> * </ul> * @protected * @since 3.0.015 (2008-06-06) * @see getPageSizeFromFormat() */ protected function setPageFormat($format, $orientation='P') { if (!empty($format) AND isset($this->pagedim[$this->page])) { // remove inherited values unset($this->pagedim[$this->page]); } if (is_string($format)) { // get page measures from format name $pf = TCPDF_STATIC::getPageSizeFromFormat($format); $this->fwPt = $pf[0]; $this->fhPt = $pf[1]; } else { // the boundaries of the physical medium on which the page shall be displayed or printed if (isset($format['MediaBox'])) { $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', $format['MediaBox']['llx'], $format['MediaBox']['lly'], $format['MediaBox']['urx'], $format['MediaBox']['ury'], false, $this->k, $this->pagedim); $this->fwPt = (($format['MediaBox']['urx'] - $format['MediaBox']['llx']) * $this->k); $this->fhPt = (($format['MediaBox']['ury'] - $format['MediaBox']['lly']) * $this->k); } else { if (isset($format[0]) AND is_numeric($format[0]) AND isset($format[1]) AND is_numeric($format[1])) { $pf = array(($format[0] * $this->k), ($format[1] * $this->k)); } else { if (!isset($format['format'])) { // default value $format['format'] = 'A4'; } $pf = TCPDF_STATIC::getPageSizeFromFormat($format['format']); } $this->fwPt = $pf[0]; $this->fhPt = $pf[1]; $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true, $this->k, $this->pagedim); } // the visible region of default user space if (isset($format['CropBox'])) { $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'CropBox', $format['CropBox']['llx'], $format['CropBox']['lly'], $format['CropBox']['urx'], $format['CropBox']['ury'], false, $this->k, $this->pagedim); } // the region to which the contents of the page shall be clipped when output in a production environment if (isset($format['BleedBox'])) { $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'BleedBox', $format['BleedBox']['llx'], $format['BleedBox']['lly'], $format['BleedBox']['urx'], $format['BleedBox']['ury'], false, $this->k, $this->pagedim); } // the intended dimensions of the finished page after trimming if (isset($format['TrimBox'])) { $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'TrimBox', $format['TrimBox']['llx'], $format['TrimBox']['lly'], $format['TrimBox']['urx'], $format['TrimBox']['ury'], false, $this->k, $this->pagedim); } // the page's meaningful content (including potential white space) if (isset($format['ArtBox'])) { $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'ArtBox', $format['ArtBox']['llx'], $format['ArtBox']['lly'], $format['ArtBox']['urx'], $format['ArtBox']['ury'], false, $this->k, $this->pagedim); } // specify the colours and other visual characteristics that should be used in displaying guidelines on the screen for the various page boundaries if (isset($format['BoxColorInfo'])) { $this->pagedim[$this->page]['BoxColorInfo'] = $format['BoxColorInfo']; } if (isset($format['Rotate']) AND (($format['Rotate'] % 90) == 0)) { // The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90. $this->pagedim[$this->page]['Rotate'] = intval($format['Rotate']); } if (isset($format['PZ'])) { // The page's preferred zoom (magnification) factor $this->pagedim[$this->page]['PZ'] = floatval($format['PZ']); } if (isset($format['trans'])) { // The style and duration of the visual transition to use when moving from another page to the given page during a presentation if (isset($format['trans']['Dur'])) { // The page's display duration $this->pagedim[$this->page]['trans']['Dur'] = floatval($format['trans']['Dur']); } $stansition_styles = array('Split', 'Blinds', 'Box', 'Wipe', 'Dissolve', 'Glitter', 'R', 'Fly', 'Push', 'Cover', 'Uncover', 'Fade'); if (isset($format['trans']['S']) AND in_array($format['trans']['S'], $stansition_styles)) { // The transition style that shall be used when moving to this page from another during a presentation $this->pagedim[$this->page]['trans']['S'] = $format['trans']['S']; $valid_effect = array('Split', 'Blinds'); $valid_vals = array('H', 'V'); if (isset($format['trans']['Dm']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['Dm'], $valid_vals)) { $this->pagedim[$this->page]['trans']['Dm'] = $format['trans']['Dm']; } $valid_effect = array('Split', 'Box', 'Fly'); $valid_vals = array('I', 'O'); if (isset($format['trans']['M']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['M'], $valid_vals)) { $this->pagedim[$this->page]['trans']['M'] = $format['trans']['M']; } $valid_effect = array('Wipe', 'Glitter', 'Fly', 'Cover', 'Uncover', 'Push'); if (isset($format['trans']['Di']) AND in_array($format['trans']['S'], $valid_effect)) { if (((($format['trans']['Di'] == 90) OR ($format['trans']['Di'] == 180)) AND ($format['trans']['S'] == 'Wipe')) OR (($format['trans']['Di'] == 315) AND ($format['trans']['S'] == 'Glitter')) OR (($format['trans']['Di'] == 0) OR ($format['trans']['Di'] == 270))) { $this->pagedim[$this->page]['trans']['Di'] = intval($format['trans']['Di']); } } if (isset($format['trans']['SS']) AND ($format['trans']['S'] == 'Fly')) { $this->pagedim[$this->page]['trans']['SS'] = floatval($format['trans']['SS']); } if (isset($format['trans']['B']) AND ($format['trans']['B'] === true) AND ($format['trans']['S'] == 'Fly')) { $this->pagedim[$this->page]['trans']['B'] = 'true'; } } else { $this->pagedim[$this->page]['trans']['S'] = 'R'; } if (isset($format['trans']['D'])) { // The duration of the transition effect, in seconds $this->pagedim[$this->page]['trans']['D'] = floatval($format['trans']['D']); } else { $this->pagedim[$this->page]['trans']['D'] = 1; } } } $this->setPageOrientation($orientation); } /** * Set page orientation. * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li><li>'' (empty string) for automatic orientation</li></ul> * @param $autopagebreak (boolean) Boolean indicating if auto-page-break mode should be on or off. * @param $bottommargin (float) bottom margin of the page. * @public * @since 3.0.015 (2008-06-06) */ public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') { if (!isset($this->pagedim[$this->page]['MediaBox'])) { // the boundaries of the physical medium on which the page shall be displayed or printed $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true, $this->k, $this->pagedim); } if (!isset($this->pagedim[$this->page]['CropBox'])) { // the visible region of default user space $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'CropBox', $this->pagedim[$this->page]['MediaBox']['llx'], $this->pagedim[$this->page]['MediaBox']['lly'], $this->pagedim[$this->page]['MediaBox']['urx'], $this->pagedim[$this->page]['MediaBox']['ury'], true, $this->k, $this->pagedim); } if (!isset($this->pagedim[$this->page]['BleedBox'])) { // the region to which the contents of the page shall be clipped when output in a production environment $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'BleedBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true, $this->k, $this->pagedim); } if (!isset($this->pagedim[$this->page]['TrimBox'])) { // the intended dimensions of the finished page after trimming $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'TrimBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true, $this->k, $this->pagedim); } if (!isset($this->pagedim[$this->page]['ArtBox'])) { // the page's meaningful content (including potential white space) $this->pagedim = TCPDF_STATIC::setPageBoxes($this->page, 'ArtBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true, $this->k, $this->pagedim); } if (!isset($this->pagedim[$this->page]['Rotate'])) { // The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90. $this->pagedim[$this->page]['Rotate'] = 0; } if (!isset($this->pagedim[$this->page]['PZ'])) { // The page's preferred zoom (magnification) factor $this->pagedim[$this->page]['PZ'] = 1; } if ($this->fwPt > $this->fhPt) { // landscape $default_orientation = 'L'; } else { // portrait $default_orientation = 'P'; } $valid_orientations = array('P', 'L'); if (empty($orientation)) { $orientation = $default_orientation; } else { $orientation = strtoupper($orientation{0}); } if (in_array($orientation, $valid_orientations) AND ($orientation != $default_orientation)) { $this->CurOrientation = $orientation; $this->wPt = $this->fhPt; $this->hPt = $this->fwPt; } else { $this->CurOrientation = $default_orientation; $this->wPt = $this->fwPt; $this->hPt = $this->fhPt; } if ((abs($this->pagedim[$this->page]['MediaBox']['urx'] - $this->hPt) < $this->feps) AND (abs($this->pagedim[$this->page]['MediaBox']['ury'] - $this->wPt) < $this->feps)){ // swap X and Y coordinates (change page orientation) $this->pagedim = TCPDF_STATIC::swapPageBoxCoordinates($this->page, $this->pagedim); } $this->w = ($this->wPt / $this->k); $this->h = ($this->hPt / $this->k); if (TCPDF_STATIC::empty_string($autopagebreak)) { if (isset($this->AutoPageBreak)) { $autopagebreak = $this->AutoPageBreak; } else { $autopagebreak = true; } } if (TCPDF_STATIC::empty_string($bottommargin)) { if (isset($this->bMargin)) { $bottommargin = $this->bMargin; } else { // default value = 2 cm $bottommargin = 2 * 28.35 / $this->k; } } $this->SetAutoPageBreak($autopagebreak, $bottommargin); // store page dimensions $this->pagedim[$this->page]['w'] = $this->wPt; $this->pagedim[$this->page]['h'] = $this->hPt; $this->pagedim[$this->page]['wk'] = $this->w; $this->pagedim[$this->page]['hk'] = $this->h; $this->pagedim[$this->page]['tm'] = $this->tMargin; $this->pagedim[$this->page]['bm'] = $bottommargin; $this->pagedim[$this->page]['lm'] = $this->lMargin; $this->pagedim[$this->page]['rm'] = $this->rMargin; $this->pagedim[$this->page]['pb'] = $autopagebreak; $this->pagedim[$this->page]['or'] = $this->CurOrientation; $this->pagedim[$this->page]['olm'] = $this->original_lMargin; $this->pagedim[$this->page]['orm'] = $this->original_rMargin; } /** * Set regular expression to detect withespaces or word separators. * The pattern delimiter must be the forward-slash character "/". * Some example patterns are: * <pre> * Non-Unicode or missing PCRE unicode support: "/[^\S\xa0]/" * Unicode and PCRE unicode support: "/[^\S\P{Z}\xa0]/u" * Unicode and PCRE unicode support in Chinese mode: "/[^\S\P{Z}\P{Lo}\xa0]/u" * if PCRE unicode support is turned ON ("\P" is the negate class of "\p"): * "\p{Z}" or "\p{Separator}": any kind of Unicode whitespace or invisible separator. * "\p{Lo}" or "\p{Other_Letter}": a Unicode letter or ideograph that does not have lowercase and uppercase variants. * "\p{Lo}" is needed for Chinese characters because are packed next to each other without spaces in between. * </pre> * @param $re (string) regular expression (leave empty for default). * @public * @since 4.6.016 (2009-06-15) */ public function setSpacesRE($re='/[^\S\xa0]/') { $this->re_spaces = $re; $re_parts = explode('/', $re); // get pattern parts $this->re_space = array(); if (isset($re_parts[1]) AND !empty($re_parts[1])) { $this->re_space['p'] = $re_parts[1]; } else { $this->re_space['p'] = '[\s]'; } // set pattern modifiers if (isset($re_parts[2]) AND !empty($re_parts[2])) { $this->re_space['m'] = $re_parts[2]; } else { $this->re_space['m'] = ''; } } /** * Enable or disable Right-To-Left language mode * @param $enable (Boolean) if true enable Right-To-Left language mode. * @param $resetx (Boolean) if true reset the X position on direction change. * @public * @since 2.0.000 (2008-01-03) */ public function setRTL($enable, $resetx=true) { $enable = $enable ? true : false; $resetx = ($resetx AND ($enable != $this->rtl)); $this->rtl = $enable; $this->tmprtl = false; if ($resetx) { $this->Ln(0); } } /** * Return the RTL status * @return boolean * @public * @since 4.0.012 (2008-07-24) */ public function getRTL() { return $this->rtl; } /** * Force temporary RTL language direction * @param $mode (mixed) can be false, 'L' for LTR or 'R' for RTL * @public * @since 2.1.000 (2008-01-09) */ public function setTempRTL($mode) { $newmode = false; switch (strtoupper($mode)) { case 'LTR': case 'L': { if ($this->rtl) { $newmode = 'L'; } break; } case 'RTL': case 'R': { if (!$this->rtl) { $newmode = 'R'; } break; } case false: default: { $newmode = false; break; } } $this->tmprtl = $newmode; } /** * Return the current temporary RTL status * @return boolean * @public * @since 4.8.014 (2009-11-04) */ public function isRTLTextDir() { return ($this->rtl OR ($this->tmprtl == 'R')); } /** * Set the last cell height. * @param $h (float) cell height. * @author Nicola Asuni * @public * @since 1.53.0.TC034 */ public function setLastH($h) { $this->lasth = $h; } /** * Reset the last cell height. * @public * @since 5.9.000 (2010-10-03) */ public function resetLastH() { $this->lasth = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B']; } /** * Get the last cell height. * @return last cell height * @public * @since 4.0.017 (2008-08-05) */ public function getLastH() { return $this->lasth; } /** * Set the adjusting factor to convert pixels to user units. * @param $scale (float) adjusting factor to convert pixels to user units. * @author Nicola Asuni * @public * @since 1.5.2 */ public function setImageScale($scale) { $this->imgscale = $scale; } /** * Returns the adjusting factor to convert pixels to user units. * @return float adjusting factor to convert pixels to user units. * @author Nicola Asuni * @public * @since 1.5.2 */ public function getImageScale() { return $this->imgscale; } /** * Returns an array of page dimensions: * <ul><li>$this->pagedim[$this->page]['w'] = page width in points</li><li>$this->pagedim[$this->page]['h'] = height in points</li><li>$this->pagedim[$this->page]['wk'] = page width in user units</li><li>$this->pagedim[$this->page]['hk'] = page height in user units</li><li>$this->pagedim[$this->page]['tm'] = top margin</li><li>$this->pagedim[$this->page]['bm'] = bottom margin</li><li>$this->pagedim[$this->page]['lm'] = left margin</li><li>$this->pagedim[$this->page]['rm'] = right margin</li><li>$this->pagedim[$this->page]['pb'] = auto page break</li><li>$this->pagedim[$this->page]['or'] = page orientation</li><li>$this->pagedim[$this->page]['olm'] = original left margin</li><li>$this->pagedim[$this->page]['orm'] = original right margin</li><li>$this->pagedim[$this->page]['Rotate'] = The number of degrees by which the page shall be rotated clockwise when displayed or printed. The value shall be a multiple of 90.</li><li>$this->pagedim[$this->page]['PZ'] = The page's preferred zoom (magnification) factor.</li><li>$this->pagedim[$this->page]['trans'] : the style and duration of the visual transition to use when moving from another page to the given page during a presentation<ul><li>$this->pagedim[$this->page]['trans']['Dur'] = The page's display duration (also called its advance timing): the maximum length of time, in seconds, that the page shall be displayed during presentations before the viewer application shall automatically advance to the next page.</li><li>$this->pagedim[$this->page]['trans']['S'] = transition style : Split, Blinds, Box, Wipe, Dissolve, Glitter, R, Fly, Push, Cover, Uncover, Fade</li><li>$this->pagedim[$this->page]['trans']['D'] = The duration of the transition effect, in seconds.</li><li>$this->pagedim[$this->page]['trans']['Dm'] = (Split and Blinds transition styles only) The dimension in which the specified transition effect shall occur: H = Horizontal, V = Vertical. Default value: H.</li><li>$this->pagedim[$this->page]['trans']['M'] = (Split, Box and Fly transition styles only) The direction of motion for the specified transition effect: I = Inward from the edges of the page, O = Outward from the center of the pageDefault value: I.</li><li>$this->pagedim[$this->page]['trans']['Di'] = (Wipe, Glitter, Fly, Cover, Uncover and Push transition styles only) The direction in which the specified transition effect shall moves, expressed in degrees counterclockwise starting from a left-to-right direction. If the value is a number, it shall be one of: 0 = Left to right, 90 = Bottom to top (Wipe only), 180 = Right to left (Wipe only), 270 = Top to bottom, 315 = Top-left to bottom-right (Glitter only). If the value is a name, it shall be None, which is relevant only for the Fly transition when the value of SS is not 1.0. Default value: 0.</li><li>$this->pagedim[$this->page]['trans']['SS'] = (Fly transition style only) The starting or ending scale at which the changes shall be drawn. If M specifies an inward transition, the scale of the changes drawn shall progress from SS to 1.0 over the course of the transition. If M specifies an outward transition, the scale of the changes drawn shall progress from 1.0 to SS over the course of the transition. Default: 1.0. </li><li>$this->pagedim[$this->page]['trans']['B'] = (Fly transition style only) If true, the area that shall be flown in is rectangular and opaque. Default: false.</li></ul></li><li>$this->pagedim[$this->page]['MediaBox'] : the boundaries of the physical medium on which the page shall be displayed or printed<ul><li>$this->pagedim[$this->page]['MediaBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['MediaBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['MediaBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['MediaBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['CropBox'] : the visible region of default user space<ul><li>$this->pagedim[$this->page]['CropBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['CropBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['CropBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['CropBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['BleedBox'] : the region to which the contents of the page shall be clipped when output in a production environment<ul><li>$this->pagedim[$this->page]['BleedBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['BleedBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['BleedBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['BleedBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['TrimBox'] : the intended dimensions of the finished page after trimming<ul><li>$this->pagedim[$this->page]['TrimBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['TrimBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['TrimBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['TrimBox']['ury'] = upper-right y coordinate in points</li></ul></li><li>$this->pagedim[$this->page]['ArtBox'] : the extent of the page's meaningful content<ul><li>$this->pagedim[$this->page]['ArtBox']['llx'] = lower-left x coordinate in points</li><li>$this->pagedim[$this->page]['ArtBox']['lly'] = lower-left y coordinate in points</li><li>$this->pagedim[$this->page]['ArtBox']['urx'] = upper-right x coordinate in points</li><li>$this->pagedim[$this->page]['ArtBox']['ury'] = upper-right y coordinate in points</li></ul></li></ul> * @param $pagenum (int) page number (empty = current page) * @return array of page dimensions. * @author Nicola Asuni * @public * @since 4.5.027 (2009-03-16) */ public function getPageDimensions($pagenum='') { if (empty($pagenum)) { $pagenum = $this->page; } return $this->pagedim[$pagenum]; } /** * Returns the page width in units. * @param $pagenum (int) page number (empty = current page) * @return int page width. * @author Nicola Asuni * @public * @since 1.5.2 * @see getPageDimensions() */ public function getPageWidth($pagenum='') { if (empty($pagenum)) { return $this->w; } return $this->pagedim[$pagenum]['w']; } /** * Returns the page height in units. * @param $pagenum (int) page number (empty = current page) * @return int page height. * @author Nicola Asuni * @public * @since 1.5.2 * @see getPageDimensions() */ public function getPageHeight($pagenum='') { if (empty($pagenum)) { return $this->h; } return $this->pagedim[$pagenum]['h']; } /** * Returns the page break margin. * @param $pagenum (int) page number (empty = current page) * @return int page break margin. * @author Nicola Asuni * @public * @since 1.5.2 * @see getPageDimensions() */ public function getBreakMargin($pagenum='') { if (empty($pagenum)) { return $this->bMargin; } return $this->pagedim[$pagenum]['bm']; } /** * Returns the scale factor (number of points in user unit). * @return int scale factor. * @author Nicola Asuni * @public * @since 1.5.2 */ public function getScaleFactor() { return $this->k; } /** * Defines the left, top and right margins. * @param $left (float) Left margin. * @param $top (float) Top margin. * @param $right (float) Right margin. Default value is the left one. * @param $keepmargins (boolean) if true overwrites the default page margins * @public * @since 1.0 * @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak() */ public function SetMargins($left, $top, $right=-1, $keepmargins=false) { //Set left, top and right margins $this->lMargin = $left; $this->tMargin = $top; if ($right == -1) { $right = $left; } $this->rMargin = $right; if ($keepmargins) { // overwrite original values $this->original_lMargin = $this->lMargin; $this->original_rMargin = $this->rMargin; } } /** * Defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin. * @param $margin (float) The margin. * @public * @since 1.4 * @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins() */ public function SetLeftMargin($margin) { //Set left margin $this->lMargin = $margin; if (($this->page > 0) AND ($this->x < $margin)) { $this->x = $margin; } } /** * Defines the top margin. The method can be called before creating the first page. * @param $margin (float) The margin. * @public * @since 1.5 * @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins() */ public function SetTopMargin($margin) { //Set top margin $this->tMargin = $margin; if (($this->page > 0) AND ($this->y < $margin)) { $this->y = $margin; } } /** * Defines the right margin. The method can be called before creating the first page. * @param $margin (float) The margin. * @public * @since 1.5 * @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins() */ public function SetRightMargin($margin) { $this->rMargin = $margin; if (($this->page > 0) AND ($this->x > ($this->w - $margin))) { $this->x = $this->w - $margin; } } /** * Set the same internal Cell padding for top, right, bottom, left- * @param $pad (float) internal padding. * @public * @since 2.1.000 (2008-01-09) * @see getCellPaddings(), setCellPaddings() */ public function SetCellPadding($pad) { if ($pad >= 0) { $this->cell_padding['L'] = $pad; $this->cell_padding['T'] = $pad; $this->cell_padding['R'] = $pad; $this->cell_padding['B'] = $pad; } } /** * Set the internal Cell paddings. * @param $left (float) left padding * @param $top (float) top padding * @param $right (float) right padding * @param $bottom (float) bottom padding * @public * @since 5.9.000 (2010-10-03) * @see getCellPaddings(), SetCellPadding() */ public function setCellPaddings($left='', $top='', $right='', $bottom='') { if (($left !== '') AND ($left >= 0)) { $this->cell_padding['L'] = $left; } if (($top !== '') AND ($top >= 0)) { $this->cell_padding['T'] = $top; } if (($right !== '') AND ($right >= 0)) { $this->cell_padding['R'] = $right; } if (($bottom !== '') AND ($bottom >= 0)) { $this->cell_padding['B'] = $bottom; } } /** * Get the internal Cell padding array. * @return array of padding values * @public * @since 5.9.000 (2010-10-03) * @see setCellPaddings(), SetCellPadding() */ public function getCellPaddings() { return $this->cell_padding; } /** * Set the internal Cell margins. * @param $left (float) left margin * @param $top (float) top margin * @param $right (float) right margin * @param $bottom (float) bottom margin * @public * @since 5.9.000 (2010-10-03) * @see getCellMargins() */ public function setCellMargins($left='', $top='', $right='', $bottom='') { if (($left !== '') AND ($left >= 0)) { $this->cell_margin['L'] = $left; } if (($top !== '') AND ($top >= 0)) { $this->cell_margin['T'] = $top; } if (($right !== '') AND ($right >= 0)) { $this->cell_margin['R'] = $right; } if (($bottom !== '') AND ($bottom >= 0)) { $this->cell_margin['B'] = $bottom; } } /** * Get the internal Cell margin array. * @return array of margin values * @public * @since 5.9.000 (2010-10-03) * @see setCellMargins() */ public function getCellMargins() { return $this->cell_margin; } /** * Adjust the internal Cell padding array to take account of the line width. * @param $brd (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @return array of adjustments * @public * @since 5.9.000 (2010-10-03) */ protected function adjustCellPadding($brd=0) { if (empty($brd)) { return; } if (is_string($brd)) { // convert string to array $slen = strlen($brd); $newbrd = array(); for ($i = 0; $i < $slen; ++$i) { $newbrd[$brd[$i]] = true; } $brd = $newbrd; } elseif (($brd === 1) OR ($brd === true) OR (is_numeric($brd) AND (intval($brd) > 0))) { $brd = array('LRTB' => true); } if (!is_array($brd)) { return; } // store current cell padding $cp = $this->cell_padding; // select border mode if (isset($brd['mode'])) { $mode = $brd['mode']; unset($brd['mode']); } else { $mode = 'normal'; } // process borders foreach ($brd as $border => $style) { $line_width = $this->LineWidth; if (is_array($style) AND isset($style['width'])) { // get border width $line_width = $style['width']; } $adj = 0; // line width inside the cell switch ($mode) { case 'ext': { $adj = 0; break; } case 'int': { $adj = $line_width; break; } case 'normal': default: { $adj = ($line_width / 2); break; } } // correct internal cell padding if required to avoid overlap between text and lines if ((strpos($border,'T') !== false) AND ($this->cell_padding['T'] < $adj)) { $this->cell_padding['T'] = $adj; } if ((strpos($border,'R') !== false) AND ($this->cell_padding['R'] < $adj)) { $this->cell_padding['R'] = $adj; } if ((strpos($border,'B') !== false) AND ($this->cell_padding['B'] < $adj)) { $this->cell_padding['B'] = $adj; } if ((strpos($border,'L') !== false) AND ($this->cell_padding['L'] < $adj)) { $this->cell_padding['L'] = $adj; } } return array('T' => ($this->cell_padding['T'] - $cp['T']), 'R' => ($this->cell_padding['R'] - $cp['R']), 'B' => ($this->cell_padding['B'] - $cp['B']), 'L' => ($this->cell_padding['L'] - $cp['L'])); } /** * Enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm. * @param $auto (boolean) Boolean indicating if mode should be on or off. * @param $margin (float) Distance from the bottom of the page. * @public * @since 1.0 * @see Cell(), MultiCell(), AcceptPageBreak() */ public function SetAutoPageBreak($auto, $margin=0) { $this->AutoPageBreak = $auto ? true : false; $this->bMargin = $margin; $this->PageBreakTrigger = $this->h - $margin; } /** * Return the auto-page-break mode (true or false). * @return boolean auto-page-break mode * @public * @since 5.9.088 */ public function getAutoPageBreak() { return $this->AutoPageBreak; } /** * Defines the way the document is to be displayed by the viewer. * @param $zoom (mixed) The zoom to use. It can be one of the following string values or a number indicating the zooming factor to use. <ul><li>fullpage: displays the entire page on screen </li><li>fullwidth: uses maximum width of window</li><li>real: uses real size (equivalent to 100% zoom)</li><li>default: uses viewer default mode</li></ul> * @param $layout (string) The page layout. Possible values are:<ul><li>SinglePage Display one page at a time</li><li>OneColumn Display the pages in one column</li><li>TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left</li><li>TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right</li><li>TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left</li><li>TwoPageRight (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right</li></ul> * @param $mode (string) A name object specifying how the document should be displayed when opened:<ul><li>UseNone Neither document outline nor thumbnail images visible</li><li>UseOutlines Document outline visible</li><li>UseThumbs Thumbnail images visible</li><li>FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible</li><li>UseOC (PDF 1.5) Optional content group panel visible</li><li>UseAttachments (PDF 1.6) Attachments panel visible</li></ul> * @public * @since 1.2 */ public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') { if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) { $this->ZoomMode = $zoom; } else { $this->Error('Incorrect zoom display mode: '.$zoom); } $this->LayoutMode = TCPDF_STATIC::getPageLayoutMode($layout); $this->PageMode = TCPDF_STATIC::getPageMode($mode); } /** * Activates or deactivates page compression. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default. * Note: the Zlib extension is required for this feature. If not present, compression will be turned off. * @param $compress (boolean) Boolean indicating if compression must be enabled. * @public * @since 1.4 */ public function SetCompression($compress=true) { if (function_exists('gzcompress')) { $this->compress = $compress ? true : false; } else { $this->compress = false; } } /** * Set flag to force sRGB_IEC61966-2.1 black scaled ICC color profile for the whole document. * @param $mode (boolean) If true force sRGB output intent. * @public * @since 5.9.121 (2011-09-28) */ public function setSRGBmode($mode=false) { $this->force_srgb = $mode ? true : false; } /** * Turn on/off Unicode mode for document information dictionary (meta tags). * This has effect only when unicode mode is set to false. * @param $unicode (boolean) if true set the meta information in Unicode * @since 5.9.027 (2010-12-01) * @public */ public function SetDocInfoUnicode($unicode=true) { $this->docinfounicode = $unicode ? true : false; } /** * Defines the title of the document. * @param $title (string) The title. * @public * @since 1.2 * @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject() */ public function SetTitle($title) { $this->title = $title; } /** * Defines the subject of the document. * @param $subject (string) The subject. * @public * @since 1.2 * @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle() */ public function SetSubject($subject) { $this->subject = $subject; } /** * Defines the author of the document. * @param $author (string) The name of the author. * @public * @since 1.2 * @see SetCreator(), SetKeywords(), SetSubject(), SetTitle() */ public function SetAuthor($author) { $this->author = $author; } /** * Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'. * @param $keywords (string) The list of keywords. * @public * @since 1.2 * @see SetAuthor(), SetCreator(), SetSubject(), SetTitle() */ public function SetKeywords($keywords) { $this->keywords = $keywords; } /** * Defines the creator of the document. This is typically the name of the application that generates the PDF. * @param $creator (string) The name of the creator. * @public * @since 1.2 * @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle() */ public function SetCreator($creator) { $this->creator = $creator; } /** * This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. An inherited class may override it to customize the error handling but should always halt the script, or the resulting document would probably be invalid. * 2004-06-11 :: Nicola Asuni : changed bold tag with strong * @param $msg (string) The error message * @public * @since 1.0 */ public function Error($msg) { // unset all class variables $this->_destroy(true); $phpmainver = PHP_VERSION; // exit program and print error if ((intval($phpmainver[0]) < 5) OR !defined('K_TCPDF_THROW_EXCEPTION_ERROR') OR !K_TCPDF_THROW_EXCEPTION_ERROR) { die('<strong>TCPDF ERROR: </strong>'.$msg); } else { throw new Exception('TCPDF ERROR: '.$msg); } } /** * This method begins the generation of the PDF document. * It is not necessary to call it explicitly because AddPage() does it automatically. * Note: no page is created by this method * @public * @since 1.0 * @see AddPage(), Close() */ public function Open() { $this->state = 1; } /** * Terminates the PDF document. * It is not necessary to call this method explicitly because Output() does it automatically. * If the document contains no page, AddPage() is called to prevent from getting an invalid document. * @public * @since 1.0 * @see Open(), Output() */ public function Close() { if ($this->state == 3) { return; } if ($this->page == 0) { $this->AddPage(); } $this->endLayer(); if ($this->tcpdflink) { // save current graphic settings $gvars = $this->getGraphicVars(); $this->setEqualColumns(); $this->lastpage(true); $this->SetAutoPageBreak(false); $this->x = 0; $this->y = $this->h - (1 / $this->k); $this->lMargin = 0; $this->_out('q'); $font = defined('PDF_FONT_NAME_MAIN')?PDF_FONT_NAME_MAIN:'helvetica'; $this->SetFont($font, '', 1); $this->setTextRenderingMode(0, false, false); $msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29"; $lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67"; $this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B'); $this->_out('Q'); // restore graphic settings $this->setGraphicVars($gvars); } // close page $this->endPage(); // close document $this->_enddoc(); // unset all class variables (except critical ones) $this->_destroy(false); } /** * Move pointer at the specified document page and update page dimensions. * @param $pnum (int) page number (1 ... numpages) * @param $resetmargins (boolean) if true reset left, right, top margins and Y position. * @public * @since 2.1.000 (2008-01-07) * @see getPage(), lastpage(), getNumPages() */ public function setPage($pnum, $resetmargins=false) { if (($pnum == $this->page) AND ($this->state == 2)) { return; } if (($pnum > 0) AND ($pnum <= $this->numpages)) { $this->state = 2; // save current graphic settings //$gvars = $this->getGraphicVars(); $oldpage = $this->page; $this->page = $pnum; $this->wPt = $this->pagedim[$this->page]['w']; $this->hPt = $this->pagedim[$this->page]['h']; $this->w = $this->pagedim[$this->page]['wk']; $this->h = $this->pagedim[$this->page]['hk']; $this->tMargin = $this->pagedim[$this->page]['tm']; $this->bMargin = $this->pagedim[$this->page]['bm']; $this->original_lMargin = $this->pagedim[$this->page]['olm']; $this->original_rMargin = $this->pagedim[$this->page]['orm']; $this->AutoPageBreak = $this->pagedim[$this->page]['pb']; $this->CurOrientation = $this->pagedim[$this->page]['or']; $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin); // restore graphic settings //$this->setGraphicVars($gvars); if ($resetmargins) { $this->lMargin = $this->pagedim[$this->page]['olm']; $this->rMargin = $this->pagedim[$this->page]['orm']; $this->SetY($this->tMargin); } else { // account for booklet mode if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) { $deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm']; $this->lMargin += $deltam; $this->rMargin -= $deltam; } } } else { $this->Error('Wrong page number on setPage() function: '.$pnum); } } /** * Reset pointer to the last document page. * @param $resetmargins (boolean) if true reset left, right, top margins and Y position. * @public * @since 2.0.000 (2008-01-04) * @see setPage(), getPage(), getNumPages() */ public function lastPage($resetmargins=false) { $this->setPage($this->getNumPages(), $resetmargins); } /** * Get current document page number. * @return int page number * @public * @since 2.1.000 (2008-01-07) * @see setPage(), lastpage(), getNumPages() */ public function getPage() { return $this->page; } /** * Get the total number of insered pages. * @return int number of pages * @public * @since 2.1.000 (2008-01-07) * @see setPage(), getPage(), lastpage() */ public function getNumPages() { return $this->numpages; } /** * Adds a new TOC (Table Of Content) page to the document. * @param $orientation (string) page orientation. * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat(). * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins * @public * @since 5.0.001 (2010-05-06) * @see AddPage(), startPage(), endPage(), endTOCPage() */ public function addTOCPage($orientation='', $format='', $keepmargins=false) { $this->AddPage($orientation, $format, $keepmargins, true); } /** * Terminate the current TOC (Table Of Content) page * @public * @since 5.0.001 (2010-05-06) * @see AddPage(), startPage(), endPage(), addTOCPage() */ public function endTOCPage() { $this->endPage(true); } /** * Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer (if enabled). Then the page is added, the current position set to the top-left corner according to the left and top margins (or top-right if in RTL mode), and Header() is called to display the header (if enabled). * The origin of the coordinate system is at the top-left corner (or top-right for RTL) and increasing ordinates go downwards. * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul> * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat(). * @param $keepmargins (boolean) if true overwrites the default page margins with the current margins * @param $tocpage (boolean) if true set the tocpage state to true (the added page will be used to display Table Of Content). * @public * @since 1.0 * @see startPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat() */ public function AddPage($orientation='', $format='', $keepmargins=false, $tocpage=false) { if ($this->inxobj) { // we are inside an XObject template return; } if (!isset($this->original_lMargin) OR $keepmargins) { $this->original_lMargin = $this->lMargin; } if (!isset($this->original_rMargin) OR $keepmargins) { $this->original_rMargin = $this->rMargin; } // terminate previous page $this->endPage(); // start new page $this->startPage($orientation, $format, $tocpage); } /** * Terminate the current page * @param $tocpage (boolean) if true set the tocpage state to false (end the page used to display Table Of Content). * @public * @since 4.2.010 (2008-11-14) * @see AddPage(), startPage(), addTOCPage(), endTOCPage() */ public function endPage($tocpage=false) { // check if page is already closed if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) { return; } // print page footer $this->setFooter(); // close page $this->_endpage(); // mark page as closed $this->pageopen[$this->page] = false; if ($tocpage) { $this->tocpage = false; } } /** * Starts a new page to the document. The page must be closed using the endPage() function. * The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards. * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul> * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat(). * @param $tocpage (boolean) if true the page is designated to contain the Table-Of-Content. * @since 4.2.010 (2008-11-14) * @see AddPage(), endPage(), addTOCPage(), endTOCPage(), getPageSizeFromFormat(), setPageFormat() * @public */ public function startPage($orientation='', $format='', $tocpage=false) { if ($tocpage) { $this->tocpage = true; } // move page numbers of documents to be attached if ($this->tocpage) { // move reference to unexistent pages (used for page attachments) // adjust outlines $tmpoutlines = $this->outlines; foreach ($tmpoutlines as $key => $outline) { if ($outline['p'] > $this->numpages) { $this->outlines[$key]['p'] = ($outline['p'] + 1); } } // adjust dests $tmpdests = $this->dests; foreach ($tmpdests as $key => $dest) { if ($dest['p'] > $this->numpages) { $this->dests[$key]['p'] = ($dest['p'] + 1); } } // adjust links $tmplinks = $this->links; foreach ($tmplinks as $key => $link) { if ($link[0] > $this->numpages) { $this->links[$key][0] = ($link[0] + 1); } } } if ($this->numpages > $this->page) { // this page has been already added $this->setPage($this->page + 1); $this->SetY($this->tMargin); return; } // start a new page if ($this->state == 0) { $this->Open(); } ++$this->numpages; $this->swapMargins($this->booklet); // save current graphic settings $gvars = $this->getGraphicVars(); // start new page $this->_beginpage($orientation, $format); // mark page as open $this->pageopen[$this->page] = true; // restore graphic settings $this->setGraphicVars($gvars); // mark this point $this->setPageMark(); // print page header $this->setHeader(); // restore graphic settings $this->setGraphicVars($gvars); // mark this point $this->setPageMark(); // print table header (if any) $this->setTableHeader(); // set mark for empty page check $this->emptypagemrk[$this->page]= $this->pagelen[$this->page]; } /** * Set start-writing mark on current page stream used to put borders and fills. * Borders and fills are always created after content and inserted on the position marked by this method. * This function must be called after calling Image() function for a background image. * Background images must be always inserted before calling Multicell() or WriteHTMLCell() or WriteHTML() functions. * @public * @since 4.0.016 (2008-07-30) */ public function setPageMark() { $this->intmrk[$this->page] = $this->pagelen[$this->page]; $this->bordermrk[$this->page] = $this->intmrk[$this->page]; $this->setContentMark(); } /** * Set start-writing mark on selected page. * Borders and fills are always created after content and inserted on the position marked by this method. * @param $page (int) page number (default is the current page) * @protected * @since 4.6.021 (2009-07-20) */ protected function setContentMark($page=0) { if ($page <= 0) { $page = $this->page; } if (isset($this->footerlen[$page])) { $this->cntmrk[$page] = $this->pagelen[$page] - $this->footerlen[$page]; } else { $this->cntmrk[$page] = $this->pagelen[$page]; } } /** * Set header data. * @param $ln (string) header image logo * @param $lw (string) header image logo width in mm * @param $ht (string) string to print as title on document header * @param $hs (string) string to print on document header * @param $tc (array) RGB array color for text. * @param $lc (array) RGB array color for line. * @public */ public function setHeaderData($ln='', $lw=0, $ht='', $hs='', $tc=array(0,0,0), $lc=array(0,0,0)) { $this->header_logo = $ln; $this->header_logo_width = $lw; $this->header_title = $ht; $this->header_string = $hs; $this->header_text_color = $tc; $this->header_line_color = $lc; } /** * Set footer data. * @param $tc (array) RGB array color for text. * @param $lc (array) RGB array color for line. * @public */ public function setFooterData($tc=array(0,0,0), $lc=array(0,0,0)) { $this->footer_text_color = $tc; $this->footer_line_color = $lc; } /** * Returns header data: * <ul><li>$ret['logo'] = logo image</li><li>$ret['logo_width'] = width of the image logo in user units</li><li>$ret['title'] = header title</li><li>$ret['string'] = header description string</li></ul> * @return array() * @public * @since 4.0.012 (2008-07-24) */ public function getHeaderData() { $ret = array(); $ret['logo'] = $this->header_logo; $ret['logo_width'] = $this->header_logo_width; $ret['title'] = $this->header_title; $ret['string'] = $this->header_string; $ret['text_color'] = $this->header_text_color; $ret['line_color'] = $this->header_line_color; return $ret; } /** * Set header margin. * (minimum distance between header and top page margin) * @param $hm (int) distance in user units * @public */ public function setHeaderMargin($hm=10) { $this->header_margin = $hm; } /** * Returns header margin in user units. * @return float * @since 4.0.012 (2008-07-24) * @public */ public function getHeaderMargin() { return $this->header_margin; } /** * Set footer margin. * (minimum distance between footer and bottom page margin) * @param $fm (int) distance in user units * @public */ public function setFooterMargin($fm=10) { $this->footer_margin = $fm; } /** * Returns footer margin in user units. * @return float * @since 4.0.012 (2008-07-24) * @public */ public function getFooterMargin() { return $this->footer_margin; } /** * Set a flag to print page header. * @param $val (boolean) set to true to print the page header (default), false otherwise. * @public */ public function setPrintHeader($val=true) { $this->print_header = $val ? true : false; } /** * Set a flag to print page footer. * @param $val (boolean) set to true to print the page footer (default), false otherwise. * @public */ public function setPrintFooter($val=true) { $this->print_footer = $val ? true : false; } /** * Return the right-bottom (or left-bottom for RTL) corner X coordinate of last inserted image * @return float * @public */ public function getImageRBX() { return $this->img_rb_x; } /** * Return the right-bottom (or left-bottom for RTL) corner Y coordinate of last inserted image * @return float * @public */ public function getImageRBY() { return $this->img_rb_y; } /** * Reset the xobject template used by Header() method. * @public */ public function resetHeaderTemplate() { $this->header_xobjid = -1; } /** * Set a flag to automatically reset the xobject template used by Header() method at each page. * @param $val (boolean) set to true to reset Header xobject template at each page, false otherwise. * @public */ public function setHeaderTemplateAutoreset($val=true) { $this->header_xobj_autoreset = $val ? true : false; } /** * This method is used to render the page header. * It is automatically called by AddPage() and could be overwritten in your own inherited class. * @public */ public function Header() { if ($this->header_xobjid < 0) { // start a new XObject Template $this->header_xobjid = $this->startTemplate($this->w, $this->tMargin); $headerfont = $this->getHeaderFont(); $headerdata = $this->getHeaderData(); $this->y = $this->header_margin; if ($this->rtl) { $this->x = $this->w - $this->original_rMargin; } else { $this->x = $this->original_lMargin; } if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) { $imgtype = TCPDF_IMAGES::getImageFileType(K_PATH_IMAGES.$headerdata['logo']); if (($imgtype == 'eps') OR ($imgtype == 'ai')) { $this->ImageEps(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']); } elseif ($imgtype == 'svg') { $this->ImageSVG(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']); } else { $this->Image(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']); } $imgy = $this->getImageRBY(); } else { $imgy = $this->y; } $cell_height = round(($this->cell_height_ratio * $headerfont[2]) / $this->k, 2); // set starting margin for text data cell if ($this->getRTL()) { $header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1); } else { $header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1); } $cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1); $this->SetTextColorArray($this->header_text_color); // header title $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1); $this->SetX($header_x); $this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0); // header string $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]); $this->SetX($header_x); $this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false, true, 0, 'T', false); // print an ending header line $this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $headerdata['line_color'])); $this->SetY((2.835 / $this->k) + max($imgy, $this->y)); if ($this->rtl) { $this->SetX($this->original_rMargin); } else { $this->SetX($this->original_lMargin); } $this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C'); $this->endTemplate(); } // print header template $x = 0; $dx = 0; if (!$this->header_xobj_autoreset AND $this->booklet AND (($this->page % 2) == 0)) { // adjust margins for booklet mode $dx = ($this->original_lMargin - $this->original_rMargin); } if ($this->rtl) { $x = $this->w + $dx; } else { $x = 0 + $dx; } $this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false); if ($this->header_xobj_autoreset) { // reset header xobject template at each page $this->header_xobjid = -1; } } /** * This method is used to render the page footer. * It is automatically called by AddPage() and could be overwritten in your own inherited class. * @public */ public function Footer() { $cur_y = $this->y; $this->SetTextColorArray($this->footer_text_color); //set style for cell border $line_width = (0.85 / $this->k); $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $this->footer_line_color)); //print document barcode $barcode = $this->getBarcode(); if (!empty($barcode)) { $this->Ln($line_width); $barcode_width = round(($this->w - $this->original_lMargin - $this->original_rMargin) / 3); $style = array( 'position' => $this->rtl?'R':'L', 'align' => $this->rtl?'R':'L', 'stretch' => false, 'fitwidth' => true, 'cellfitalign' => '', 'border' => false, 'padding' => 0, 'fgcolor' => array(0,0,0), 'bgcolor' => false, 'text' => false ); $this->write1DBarcode($barcode, 'C128', '', $cur_y + $line_width, '', (($this->footer_margin / 3) - $line_width), 0.3, $style, ''); } $w_page = isset($this->l['w_page']) ? $this->l['w_page'].' ' : ''; if (empty($this->pagegroups)) { $pagenumtxt = $w_page.$this->getAliasNumPage().' / '.$this->getAliasNbPages(); } else { $pagenumtxt = $w_page.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias(); } $this->SetY($cur_y); //Print page number if ($this->getRTL()) { $this->SetX($this->original_rMargin); $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L'); } else { $this->SetX($this->original_lMargin); $this->Cell(0, 0, $this->getAliasRightShift().$pagenumtxt, 'T', 0, 'R'); } } /** * This method is used to render the page header. * @protected * @since 4.0.012 (2008-07-24) */ protected function setHeader() { if (!$this->print_header OR ($this->state != 2)) { return; } $this->InHeader = true; $this->setGraphicVars($this->default_graphic_vars); $temp_thead = $this->thead; $temp_theadMargins = $this->theadMargins; $lasth = $this->lasth; $this->_out('q'); $this->rMargin = $this->original_rMargin; $this->lMargin = $this->original_lMargin; $this->SetCellPadding(0); //set current position if ($this->rtl) { $this->SetXY($this->original_rMargin, $this->header_margin); } else { $this->SetXY($this->original_lMargin, $this->header_margin); } $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]); $this->Header(); //restore position if ($this->rtl) { $this->SetXY($this->original_rMargin, $this->tMargin); } else { $this->SetXY($this->original_lMargin, $this->tMargin); } $this->_out('Q'); $this->lasth = $lasth; $this->thead = $temp_thead; $this->theadMargins = $temp_theadMargins; $this->newline = false; $this->InHeader = false; } /** * This method is used to render the page footer. * @protected * @since 4.0.012 (2008-07-24) */ protected function setFooter() { if ($this->state != 2) { return; } $this->InFooter = true; // save current graphic settings $gvars = $this->getGraphicVars(); // mark this point $this->footerpos[$this->page] = $this->pagelen[$this->page]; $this->_out("\n"); if ($this->print_footer) { $this->setGraphicVars($this->default_graphic_vars); $this->current_column = 0; $this->num_columns = 1; $temp_thead = $this->thead; $temp_theadMargins = $this->theadMargins; $lasth = $this->lasth; $this->_out('q'); $this->rMargin = $this->original_rMargin; $this->lMargin = $this->original_lMargin; $this->SetCellPadding(0); //set current position $footer_y = $this->h - $this->footer_margin; if ($this->rtl) { $this->SetXY($this->original_rMargin, $footer_y); } else { $this->SetXY($this->original_lMargin, $footer_y); } $this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]); $this->Footer(); //restore position if ($this->rtl) { $this->SetXY($this->original_rMargin, $this->tMargin); } else { $this->SetXY($this->original_lMargin, $this->tMargin); } $this->_out('Q'); $this->lasth = $lasth; $this->thead = $temp_thead; $this->theadMargins = $temp_theadMargins; } // restore graphic settings $this->setGraphicVars($gvars); $this->current_column = $gvars['current_column']; $this->num_columns = $gvars['num_columns']; // calculate footer length $this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1; $this->InFooter = false; } /** * Check if we are on the page body (excluding page header and footer). * @return true if we are not in page header nor in page footer, false otherwise. * @protected * @since 5.9.091 (2011-06-15) */ protected function inPageBody() { return (($this->InHeader === false) AND ($this->InFooter === false)); } /** * This method is used to render the table header on new page (if any). * @protected * @since 4.5.030 (2009-03-25) */ protected function setTableHeader() { if ($this->num_columns > 1) { // multi column mode return; } if (isset($this->theadMargins['top'])) { // restore the original top-margin $this->tMargin = $this->theadMargins['top']; $this->pagedim[$this->page]['tm'] = $this->tMargin; $this->y = $this->tMargin; } if (!TCPDF_STATIC::empty_string($this->thead) AND (!$this->inthead)) { // set margins $prev_lMargin = $this->lMargin; $prev_rMargin = $this->rMargin; $prev_cell_padding = $this->cell_padding; $this->lMargin = $this->theadMargins['lmargin'] + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$this->theadMargins['page']]['olm']); $this->rMargin = $this->theadMargins['rmargin'] + ($this->pagedim[$this->page]['orm'] - $this->pagedim[$this->theadMargins['page']]['orm']); $this->cell_padding = $this->theadMargins['cell_padding']; if ($this->rtl) { $this->x = $this->w - $this->rMargin; } else { $this->x = $this->lMargin; } // account for special "cell" mode if ($this->theadMargins['cell']) { if ($this->rtl) { $this->x -= $this->cell_padding['R']; } else { $this->x += $this->cell_padding['L']; } } // print table header $this->writeHTML($this->thead, false, false, false, false, ''); // set new top margin to skip the table headers if (!isset($this->theadMargins['top'])) { $this->theadMargins['top'] = $this->tMargin; } // store end of header position if (!isset($this->columns[0]['th'])) { $this->columns[0]['th'] = array(); } $this->columns[0]['th']['\''.$this->page.'\''] = $this->y; $this->tMargin = $this->y; $this->pagedim[$this->page]['tm'] = $this->tMargin; $this->lasth = 0; $this->lMargin = $prev_lMargin; $this->rMargin = $prev_rMargin; $this->cell_padding = $prev_cell_padding; } } /** * Returns the current page number. * @return int page number * @public * @since 1.0 * @see getAliasNbPages() */ public function PageNo() { return $this->page; } /** * Defines a new spot color. * It can be expressed in RGB components or gray scale. * The method can be called before the first page is created and the value is retained from page to page. * @param $name (string) Full name of the spot color. * @param $c (float) Cyan color for CMYK. Value between 0 and 100. * @param $m (float) Magenta color for CMYK. Value between 0 and 100. * @param $y (float) Yellow color for CMYK. Value between 0 and 100. * @param $k (float) Key (Black) color for CMYK. Value between 0 and 100. * @public * @since 4.0.024 (2008-09-12) * @see SetDrawSpotColor(), SetFillSpotColor(), SetTextSpotColor() */ public function AddSpotColor($name, $c, $m, $y, $k) { if (!isset($this->spot_colors[$name])) { $i = (1 + count($this->spot_colors)); $this->spot_colors[$name] = array('C' => $c, 'M' => $m, 'Y' => $y, 'K' => $k, 'name' => $name, 'i' => $i); } } /** * Set the spot color for the specified type ('draw', 'fill', 'text'). * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text'). * @param $name (string) Name of the spot color. * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default). * @return (string) PDF color command. * @public * @since 5.9.125 (2011-10-03) */ public function setSpotColor($type, $name, $tint=100) { $spotcolor = TCPDF_COLORS::getSpotColor($name, $this->spot_colors); if ($spotcolor === false) { $this->Error('Undefined spot color: '.$name.', you must add it on the spotcolors.php file.'); } $tint = (max(0, min(100, $tint)) / 100); $pdfcolor = sprintf('/CS%d ', $this->spot_colors[$name]['i']); switch ($type) { case 'draw': { $pdfcolor .= sprintf('CS %F SCN', $tint); $this->DrawColor = $pdfcolor; $this->strokecolor = $spotcolor; break; } case 'fill': { $pdfcolor .= sprintf('cs %F scn', $tint); $this->FillColor = $pdfcolor; $this->bgcolor = $spotcolor; break; } case 'text': { $pdfcolor .= sprintf('cs %F scn', $tint); $this->TextColor = $pdfcolor; $this->fgcolor = $spotcolor; break; } } $this->ColorFlag = ($this->FillColor != $this->TextColor); if ($this->state == 2) { $this->_out($pdfcolor); } if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['spot_colors'][$name] = $this->spot_colors[$name]; } return $pdfcolor; } /** * Defines the spot color used for all drawing operations (lines, rectangles and cell borders). * @param $name (string) Name of the spot color. * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default). * @public * @since 4.0.024 (2008-09-12) * @see AddSpotColor(), SetFillSpotColor(), SetTextSpotColor() */ public function SetDrawSpotColor($name, $tint=100) { $this->setSpotColor('draw', $name, $tint); } /** * Defines the spot color used for all filling operations (filled rectangles and cell backgrounds). * @param $name (string) Name of the spot color. * @param $tint (float) Intensity of the color (from 0 to 100 ; 100 = full intensity by default). * @public * @since 4.0.024 (2008-09-12) * @see AddSpotColor(), SetDrawSpotColor(), SetTextSpotColor() */ public function SetFillSpotColor($name, $tint=100) { $this->setSpotColor('fill', $name, $tint); } /** * Defines the spot color used for text. * @param $name (string) Name of the spot color. * @param $tint (int) Intensity of the color (from 0 to 100 ; 100 = full intensity by default). * @public * @since 4.0.024 (2008-09-12) * @see AddSpotColor(), SetDrawSpotColor(), SetFillSpotColor() */ public function SetTextSpotColor($name, $tint=100) { $this->setSpotColor('text', $name, $tint); } /** * Set the color array for the specified type ('draw', 'fill', 'text'). * It can be expressed in RGB, CMYK or GRAY SCALE components. * The method can be called before the first page is created and the value is retained from page to page. * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text'). * @param $color (array) Array of colors (1=gray, 3=RGB, 4=CMYK or 5=spotcolor=CMYK+name values). * @param $ret (boolean) If true do not send the PDF command. * @return (string) The PDF command or empty string. * @public * @since 3.1.000 (2008-06-11) */ public function setColorArray($type, $color, $ret=false) { if (is_array($color)) { $color = array_values($color); // component: grey, RGB red or CMYK cyan $c = isset($color[0]) ? $color[0] : -1; // component: RGB green or CMYK magenta $m = isset($color[1]) ? $color[1] : -1; // component: RGB blue or CMYK yellow $y = isset($color[2]) ? $color[2] : -1; // component: CMYK black $k = isset($color[3]) ? $color[3] : -1; // color name $name = isset($color[4]) ? $color[4] : ''; if ($c >= 0) { return $this->setColor($type, $c, $m, $y, $k, $ret, $name); } } return ''; } /** * Defines the color used for all drawing operations (lines, rectangles and cell borders). * It can be expressed in RGB, CMYK or GRAY SCALE components. * The method can be called before the first page is created and the value is retained from page to page. * @param $color (array) Array of colors (1, 3 or 4 values). * @param $ret (boolean) If true do not send the PDF command. * @return string the PDF command * @public * @since 3.1.000 (2008-06-11) * @see SetDrawColor() */ public function SetDrawColorArray($color, $ret=false) { return $this->setColorArray('draw', $color, $ret); } /** * Defines the color used for all filling operations (filled rectangles and cell backgrounds). * It can be expressed in RGB, CMYK or GRAY SCALE components. * The method can be called before the first page is created and the value is retained from page to page. * @param $color (array) Array of colors (1, 3 or 4 values). * @param $ret (boolean) If true do not send the PDF command. * @public * @since 3.1.000 (2008-6-11) * @see SetFillColor() */ public function SetFillColorArray($color, $ret=false) { return $this->setColorArray('fill', $color, $ret); } /** * Defines the color used for text. It can be expressed in RGB components or gray scale. * The method can be called before the first page is created and the value is retained from page to page. * @param $color (array) Array of colors (1, 3 or 4 values). * @param $ret (boolean) If true do not send the PDF command. * @public * @since 3.1.000 (2008-6-11) * @see SetFillColor() */ public function SetTextColorArray($color, $ret=false) { return $this->setColorArray('text', $color, $ret); } /** * Defines the color used by the specified type ('draw', 'fill', 'text'). * @param $type (string) Type of object affected by this color: ('draw', 'fill', 'text'). * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100). * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100). * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100). * @param $col4 (float) KEY (BLACK) color for CMYK (0-100). * @param $ret (boolean) If true do not send the command. * @param $name (string) spot color name (if any) * @return (string) The PDF command or empty string. * @public * @since 5.9.125 (2011-10-03) */ public function setColor($type, $col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') { // set default values if (!is_numeric($col1)) { $col1 = 0; } if (!is_numeric($col2)) { $col2 = -1; } if (!is_numeric($col3)) { $col3 = -1; } if (!is_numeric($col4)) { $col4 = -1; } // set color by case $suffix = ''; if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) { // Grey scale $col1 = max(0, min(255, $col1)); $intcolor = array('G' => $col1); $pdfcolor = sprintf('%F ', ($col1 / 255)); $suffix = 'g'; } elseif ($col4 == -1) { // RGB $col1 = max(0, min(255, $col1)); $col2 = max(0, min(255, $col2)); $col3 = max(0, min(255, $col3)); $intcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3); $pdfcolor = sprintf('%F %F %F ', ($col1 / 255), ($col2 / 255), ($col3 / 255)); $suffix = 'rg'; } else { $col1 = max(0, min(100, $col1)); $col2 = max(0, min(100, $col2)); $col3 = max(0, min(100, $col3)); $col4 = max(0, min(100, $col4)); if (empty($name)) { // CMYK $intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4); $pdfcolor = sprintf('%F %F %F %F ', ($col1 / 100), ($col2 / 100), ($col3 / 100), ($col4 / 100)); $suffix = 'k'; } else { // SPOT COLOR $intcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4, 'name' => $name); $this->AddSpotColor($name, $col1, $col2, $col3, $col4); $pdfcolor = $this->setSpotColor($type, $name, 100); } } switch ($type) { case 'draw': { $pdfcolor .= strtoupper($suffix); $this->DrawColor = $pdfcolor; $this->strokecolor = $intcolor; break; } case 'fill': { $pdfcolor .= $suffix; $this->FillColor = $pdfcolor; $this->bgcolor = $intcolor; break; } case 'text': { $pdfcolor .= $suffix; $this->TextColor = $pdfcolor; $this->fgcolor = $intcolor; break; } } $this->ColorFlag = ($this->FillColor != $this->TextColor); if (($type != 'text') AND ($this->state == 2)) { if (!$ret) { $this->_out($pdfcolor); } return $pdfcolor; } return ''; } /** * Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page. * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100). * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100). * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100). * @param $col4 (float) KEY (BLACK) color for CMYK (0-100). * @param $ret (boolean) If true do not send the command. * @param $name (string) spot color name (if any) * @return string the PDF command * @public * @since 1.3 * @see SetDrawColorArray(), SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell() */ public function SetDrawColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') { return $this->setColor('draw', $col1, $col2, $col3, $col4, $ret, $name); } /** * Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page. * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100). * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100). * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100). * @param $col4 (float) KEY (BLACK) color for CMYK (0-100). * @param $ret (boolean) If true do not send the command. * @param $name (string) Spot color name (if any). * @return (string) The PDF command. * @public * @since 1.3 * @see SetFillColorArray(), SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell() */ public function SetFillColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') { return $this->setColor('fill', $col1, $col2, $col3, $col4, $ret, $name); } /** * Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page. * @param $col1 (float) GRAY level for single color, or Red color for RGB (0-255), or CYAN color for CMYK (0-100). * @param $col2 (float) GREEN color for RGB (0-255), or MAGENTA color for CMYK (0-100). * @param $col3 (float) BLUE color for RGB (0-255), or YELLOW color for CMYK (0-100). * @param $col4 (float) KEY (BLACK) color for CMYK (0-100). * @param $ret (boolean) If true do not send the command. * @param $name (string) Spot color name (if any). * @return (string) Empty string. * @public * @since 1.3 * @see SetTextColorArray(), SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell() */ public function SetTextColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false, $name='') { return $this->setColor('text', $col1, $col2, $col3, $col4, $ret, $name); } /** * Returns the length of a string in user unit. A font must be selected.<br> * @param $s (string) The string whose length is to be computed * @param $fontname (string) Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained. * @param $fontstyle (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line-trough</li><li>O: overline</li></ul> or any combination. The default value is regular. * @param $fontsize (float) Font size in points. The default value is the current size. * @param $getarray (boolean) if true returns an array of characters widths, if false returns the total length. * @return mixed int total string length or array of characted widths * @author Nicola Asuni * @public * @since 1.2 */ public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) { return $this->GetArrStringWidth(TCPDF_FONTS::utf8Bidi(TCPDF_FONTS::UTF8StringToArray($s, $this->isunicode, $this->CurrentFont), $s, $this->tmprtl, $this->isunicode, $this->CurrentFont), $fontname, $fontstyle, $fontsize, $getarray); } /** * Returns the string length of an array of chars in user unit or an array of characters widths. A font must be selected.<br> * @param $sa (string) The array of chars whose total length is to be computed * @param $fontname (string) Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained. * @param $fontstyle (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line trough</li><li>O: overline</li></ul> or any combination. The default value is regular. * @param $fontsize (float) Font size in points. The default value is the current size. * @param $getarray (boolean) if true returns an array of characters widths, if false returns the total length. * @return mixed int total string length or array of characted widths * @author Nicola Asuni * @public * @since 2.4.000 (2008-03-06) */ public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) { // store current values if (!TCPDF_STATIC::empty_string($fontname)) { $prev_FontFamily = $this->FontFamily; $prev_FontStyle = $this->FontStyle; $prev_FontSizePt = $this->FontSizePt; $this->SetFont($fontname, $fontstyle, $fontsize, '', 'default', false); } // convert UTF-8 array to Latin1 if required if ($this->isunicode AND (!$this->isUnicodeFont())) { $sa = TCPDF_FONTS::UTF8ArrToLatin1Arr($sa); } $w = 0; // total width $wa = array(); // array of characters widths foreach ($sa as $ck => $char) { // character width $cw = $this->GetCharWidth($char, isset($sa[($ck + 1)])); $wa[] = $cw; $w += $cw; } // restore previous values if (!TCPDF_STATIC::empty_string($fontname)) { $this->SetFont($prev_FontFamily, $prev_FontStyle, $prev_FontSizePt, '', 'default', false); } if ($getarray) { return $wa; } return $w; } /** * Returns the length of the char in user unit for the current font considering current stretching and spacing (tracking). * @param $char (int) The char code whose length is to be returned * @param $notlast (boolean) If false ignore the font-spacing. * @return float char width * @author Nicola Asuni * @public * @since 2.4.000 (2008-03-06) */ public function GetCharWidth($char, $notlast=true) { // get raw width $chw = $this->getRawCharWidth($char); if (($this->font_spacing < 0) OR (($this->font_spacing > 0) AND $notlast)) { // increase/decrease font spacing $chw += $this->font_spacing; } if ($this->font_stretching != 100) { // fixed stretching mode $chw *= ($this->font_stretching / 100); } return $chw; } /** * Returns the length of the char in user unit for the current font. * @param $char (int) The char code whose length is to be returned * @return float char width * @author Nicola Asuni * @public * @since 5.9.000 (2010-09-28) */ public function getRawCharWidth($char) { if ($char == 173) { // SHY character will not be printed return (0); } if (isset($this->CurrentFont['cw'][$char])) { $w = $this->CurrentFont['cw'][$char]; } elseif (isset($this->CurrentFont['dw'])) { // default width $w = $this->CurrentFont['dw']; } elseif (isset($this->CurrentFont['cw'][32])) { // default width $w = $this->CurrentFont['cw'][32]; } else { $w = 600; } return $this->getAbsFontMeasure($w); } /** * Returns the numbero of characters in a string. * @param $s (string) The input string. * @return int number of characters * @public * @since 2.0.0001 (2008-01-07) */ public function GetNumChars($s) { if ($this->isUnicodeFont()) { return count(TCPDF_FONTS::UTF8StringToArray($s, $this->isunicode, $this->CurrentFont)); } return strlen($s); } /** * Fill the list of available fonts ($this->fontlist). * @protected * @since 4.0.013 (2008-07-28) */ protected function getFontsList() { if (($fontsdir = opendir(TCPDF_FONTS::_getfontpath())) !== false) { while (($file = readdir($fontsdir)) !== false) { if (substr($file, -4) == '.php') { array_push($this->fontlist, strtolower(basename($file, '.php'))); } } closedir($fontsdir); } } /** * Returns the unicode caracter specified by the value * @param $c (int) UTF-8 value * @return Returns the specified character. * @since 2.3.000 (2008-03-05) * @public * @deprecated */ public function unichr($c) { return TCPDF_FONTS::unichr($c, $this->isunicode); } /** * Convert and add the selected TrueType or Type1 font to the fonts folder (that must be writeable). * @param $fontfile (string) Font file (full path). * @param $fonttype (string) Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional. * @param $enc (string) Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats. * @param $flags (int) Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font. * @param $outpath (string) Output path for generated font files (must be writeable by the web server). Leave empty for default font folder. * @param $platid (int) Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1). * @param $encid (int) Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4. * @param $addcbbox (boolean) If true includes the character bounding box information on the php font file. * @return (string) TCPDF font name. * @author Nicola Asuni * @since 5.9.123 (2010-09-30) * @public * @deprecated */ public function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='', $platid=3, $encid=1, $addcbbox=false) { return TCPDF_FONTS::addTTFfont($fontfile, $fonttype, $enc, $flags, $outpath, $platid, $encid, $addcbbox); } /** * Imports a TrueType, Type1, core, or CID0 font and makes it available. * It is necessary to generate a font definition file first (read /fonts/utils/README.TXT). * The definition file (and the font file itself when embedding) must be present either in the current directory or in the one indicated by K_PATH_FONTS if the constant is defined. If it could not be found, the error "Could not include font definition file" is generated. * @param $family (string) Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font. * @param $style (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular (default)</li><li>B: bold</li><li>I: italic</li><li>BI or IB: bold italic</li></ul> * @param $fontfile (string) The font definition file. By default, the name is built from the family and style, in lower case with no spaces. * @return array containing the font data, or false in case of error. * @param $subset (mixed) if true embedd only a subset of the font (stores only the information related to the used characters); if false embedd full font; if 'default' uses the default value set using setFontSubsetting(). This option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The file size of the PDF would also be smaller because you are embedding only part of a font. * @public * @since 1.5 * @see SetFont(), setFontSubsetting() */ public function AddFont($family, $style='', $fontfile='', $subset='default') { if ($subset === 'default') { $subset = $this->font_subsetting; } if ($this->pdfa_mode) { $subset = false; } if (TCPDF_STATIC::empty_string($family)) { if (!TCPDF_STATIC::empty_string($this->FontFamily)) { $family = $this->FontFamily; } else { $this->Error('Empty font family'); } } // move embedded styles on $style if (substr($family, -1) == 'I') { $style .= 'I'; $family = substr($family, 0, -1); } if (substr($family, -1) == 'B') { $style .= 'B'; $family = substr($family, 0, -1); } // normalize family name $family = strtolower($family); if ((!$this->isunicode) AND ($family == 'arial')) { $family = 'helvetica'; } if (($family == 'symbol') OR ($family == 'zapfdingbats')) { $style = ''; } if ($this->pdfa_mode AND (isset($this->CoreFonts[$family]))) { // all fonts must be embedded $family = 'pdfa'.$family; } $tempstyle = strtoupper($style); $style = ''; // underline if (strpos($tempstyle, 'U') !== false) { $this->underline = true; } else { $this->underline = false; } // line-through (deleted) if (strpos($tempstyle, 'D') !== false) { $this->linethrough = true; } else { $this->linethrough = false; } // overline if (strpos($tempstyle, 'O') !== false) { $this->overline = true; } else { $this->overline = false; } // bold if (strpos($tempstyle, 'B') !== false) { $style .= 'B'; } // oblique if (strpos($tempstyle, 'I') !== false) { $style .= 'I'; } $bistyle = $style; $fontkey = $family.$style; $font_style = $style.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '').($this->overline ? 'O' : ''); $fontdata = array('fontkey' => $fontkey, 'family' => $family, 'style' => $font_style); // check if the font has been already added $fb = $this->getFontBuffer($fontkey); if ($fb !== false) { if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['fonts'][$fontkey] = $fb['i']; } return $fontdata; } if (isset($type)) { unset($type); } if (isset($cw)) { unset($cw); } // get specified font directory (if any) $fontdir = false; if (!TCPDF_STATIC::empty_string($fontfile)) { $fontdir = dirname($fontfile); if (TCPDF_STATIC::empty_string($fontdir) OR ($fontdir == '.')) { $fontdir = ''; } else { $fontdir .= '/'; } } $missing_style = false; // true when the font style variation is missing // search and include font file if (TCPDF_STATIC::empty_string($fontfile) OR (!file_exists($fontfile))) { // build a standard filenames for specified font $tmp_fontfile = str_replace(' ', '', $family).strtolower($style).'.php'; // search files on various directories if (($fontdir !== false) AND file_exists($fontdir.$tmp_fontfile)) { $fontfile = $fontdir.$tmp_fontfile; } elseif (file_exists(TCPDF_FONTS::_getfontpath().$tmp_fontfile)) { $fontfile = TCPDF_FONTS::_getfontpath().$tmp_fontfile; } elseif (file_exists($tmp_fontfile)) { $fontfile = $tmp_fontfile; } elseif (!TCPDF_STATIC::empty_string($style)) { $missing_style = true; // try to remove the style part $tmp_fontfile = str_replace(' ', '', $family).'.php'; if (($fontdir !== false) AND file_exists($fontdir.$tmp_fontfile)) { $fontfile = $fontdir.$tmp_fontfile; } elseif (file_exists(TCPDF_FONTS::_getfontpath().$tmp_fontfile)) { $fontfile = TCPDF_FONTS::_getfontpath().$tmp_fontfile; } else { $fontfile = $tmp_fontfile; } } } // include font file if (file_exists($fontfile)) { include($fontfile); } else { $this->Error('Could not include font definition file: '.$family.''); } // check font parameters if ((!isset($type)) OR (!isset($cw))) { $this->Error('The font definition file has a bad format: '.$fontfile.''); } // SET default parameters if (!isset($file) OR TCPDF_STATIC::empty_string($file)) { $file = ''; } if (!isset($enc) OR TCPDF_STATIC::empty_string($enc)) { $enc = ''; } if (!isset($cidinfo) OR TCPDF_STATIC::empty_string($cidinfo)) { $cidinfo = array('Registry'=>'Adobe', 'Ordering'=>'Identity', 'Supplement'=>0); $cidinfo['uni2cid'] = array(); } if (!isset($ctg) OR TCPDF_STATIC::empty_string($ctg)) { $ctg = ''; } if (!isset($desc) OR TCPDF_STATIC::empty_string($desc)) { $desc = array(); } if (!isset($up) OR TCPDF_STATIC::empty_string($up)) { $up = -100; } if (!isset($ut) OR TCPDF_STATIC::empty_string($ut)) { $ut = 50; } if (!isset($cw) OR TCPDF_STATIC::empty_string($cw)) { $cw = array(); } if (!isset($dw) OR TCPDF_STATIC::empty_string($dw)) { // set default width if (isset($desc['MissingWidth']) AND ($desc['MissingWidth'] > 0)) { $dw = $desc['MissingWidth']; } elseif (isset($cw[32])) { $dw = $cw[32]; } else { $dw = 600; } } ++$this->numfonts; if ($type == 'core') { $name = $this->CoreFonts[$fontkey]; $subset = false; } elseif (($type == 'TrueType') OR ($type == 'Type1')) { $subset = false; } elseif ($type == 'TrueTypeUnicode') { $enc = 'Identity-H'; } elseif ($type == 'cidfont0') { if ($this->pdfa_mode) { $this->Error('All fonts must be embedded in PDF/A mode!'); } } else { $this->Error('Unknow font type: '.$type.''); } // set name if unset if (!isset($name) OR empty($name)) { $name = $fontkey; } // create artificial font style variations if missing (only works with non-embedded fonts) if (($type != 'core') AND $missing_style) { // style variations $styles = array('' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic'); $name .= $styles[$bistyle]; // artificial bold if (strpos($bistyle, 'B') !== false) { if (isset($desc['StemV'])) { // from normal to bold $desc['StemV'] = round($desc['StemV'] * 1.75); } else { // bold $desc['StemV'] = 123; } } // artificial italic if (strpos($bistyle, 'I') !== false) { if (isset($desc['ItalicAngle'])) { $desc['ItalicAngle'] -= 11; } else { $desc['ItalicAngle'] = -11; } if (isset($desc['Flags'])) { $desc['Flags'] |= 64; //bit 7 } else { $desc['Flags'] = 64; } } } // check if the array of characters bounding boxes is defined if (!isset($cbbox)) { $cbbox = array(); } // initialize subsetchars $subsetchars = array_fill(0, 255, true); $this->setFontBuffer($fontkey, array('fontkey' => $fontkey, 'i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'cbbox' => $cbbox, 'dw' => $dw, 'enc' => $enc, 'cidinfo' => $cidinfo, 'file' => $file, 'ctg' => $ctg, 'subset' => $subset, 'subsetchars' => $subsetchars)); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['fonts'][$fontkey] = $this->numfonts; } if (isset($diff) AND (!empty($diff))) { //Search existing encodings $d = 0; $nb = count($this->diffs); for ($i=1; $i <= $nb; ++$i) { if ($this->diffs[$i] == $diff) { $d = $i; break; } } if ($d == 0) { $d = $nb + 1; $this->diffs[$d] = $diff; } $this->setFontSubBuffer($fontkey, 'diff', $d); } if (!TCPDF_STATIC::empty_string($file)) { if (!isset($this->FontFiles[$file])) { if ((strcasecmp($type,'TrueType') == 0) OR (strcasecmp($type, 'TrueTypeUnicode') == 0)) { $this->FontFiles[$file] = array('length1' => $originalsize, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey)); } elseif ($type != 'core') { $this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey)); } } else { // update fontkeys that are sharing this font file $this->FontFiles[$file]['subset'] = ($this->FontFiles[$file]['subset'] AND $subset); if (!in_array($fontkey, $this->FontFiles[$file]['fontkeys'])) { $this->FontFiles[$file]['fontkeys'][] = $fontkey; } } } return $fontdata; } /** * Sets the font used to print character strings. * The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe). * The method can be called before the first page is created and the font is retained from page to page. * If you just wish to change the current font size, it is simpler to call SetFontSize(). * Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:<ul><li>They are in the current directory (the one where the running script lies)</li><li>They are in one of the directories defined by the include_path parameter</li><li>They are in the directory defined by the K_PATH_FONTS constant</li></ul><br /> * @param $family (string) Family font. It can be either a name defined by AddFont() or one of the standard Type1 families (case insensitive):<ul><li>times (Times-Roman)</li><li>timesb (Times-Bold)</li><li>timesi (Times-Italic)</li><li>timesbi (Times-BoldItalic)</li><li>helvetica (Helvetica)</li><li>helveticab (Helvetica-Bold)</li><li>helveticai (Helvetica-Oblique)</li><li>helveticabi (Helvetica-BoldOblique)</li><li>courier (Courier)</li><li>courierb (Courier-Bold)</li><li>courieri (Courier-Oblique)</li><li>courierbi (Courier-BoldOblique)</li><li>symbol (Symbol)</li><li>zapfdingbats (ZapfDingbats)</li></ul> It is also possible to pass an empty string. In that case, the current family is retained. * @param $style (string) Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line trough</li><li>O: overline</li></ul> or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats basic fonts or other fonts when not defined. * @param $size (float) Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12 * @param $fontfile (string) The font definition file. By default, the name is built from the family and style, in lower case with no spaces. * @param $subset (mixed) if true embedd only a subset of the font (stores only the information related to the used characters); if false embedd full font; if 'default' uses the default value set using setFontSubsetting(). This option is valid only for TrueTypeUnicode fonts. If you want to enable users to change the document, set this parameter to false. If you subset the font, the person who receives your PDF would need to have your same font in order to make changes to your PDF. The file size of the PDF would also be smaller because you are embedding only part of a font. * @param $out (boolean) if true output the font size command, otherwise only set the font properties. * @author Nicola Asuni * @public * @since 1.0 * @see AddFont(), SetFontSize() */ public function SetFont($family, $style='', $size=null, $fontfile='', $subset='default', $out=true) { //Select a font; size given in points if ($size === null) { $size = $this->FontSizePt; } if ($size < 0) { $size = 0; } // try to add font (if not already added) $fontdata = $this->AddFont($family, $style, $fontfile, $subset); $this->FontFamily = $fontdata['family']; $this->FontStyle = $fontdata['style']; if (isset($this->CurrentFont['fontkey']) AND isset($this->CurrentFont['subsetchars'])) { // save subset chars of the previous font $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']); } $this->CurrentFont = $this->getFontBuffer($fontdata['fontkey']); $this->SetFontSize($size, $out); } /** * Defines the size of the current font. * @param $size (float) The font size in points. * @param $out (boolean) if true output the font size command, otherwise only set the font properties. * @public * @since 1.0 * @see SetFont() */ public function SetFontSize($size, $out=true) { // font size in points $this->FontSizePt = $size; // font size in user units $this->FontSize = $size / $this->k; // calculate some font metrics if (isset($this->CurrentFont['desc']['FontBBox'])) { $bbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1)); $font_height = ((intval($bbox[3]) - intval($bbox[1])) * $size / 1000); } else { $font_height = $size * 1.219; } if (isset($this->CurrentFont['desc']['Ascent']) AND ($this->CurrentFont['desc']['Ascent'] > 0)) { $font_ascent = ($this->CurrentFont['desc']['Ascent'] * $size / 1000); } if (isset($this->CurrentFont['desc']['Descent']) AND ($this->CurrentFont['desc']['Descent'] <= 0)) { $font_descent = (- $this->CurrentFont['desc']['Descent'] * $size / 1000); } if (!isset($font_ascent) AND !isset($font_descent)) { // core font $font_ascent = 0.76 * $font_height; $font_descent = $font_height - $font_ascent; } elseif (!isset($font_descent)) { $font_descent = $font_height - $font_ascent; } elseif (!isset($font_ascent)) { $font_ascent = $font_height - $font_descent; } $this->FontAscent = ($font_ascent / $this->k); $this->FontDescent = ($font_descent / $this->k); if ($out AND ($this->page > 0) AND (isset($this->CurrentFont['i'])) AND ($this->state == 2)) { $this->_out(sprintf('BT /F%d %F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); } } /** * Returns the bounding box of the current font in user units. * @return array * @public * @since 5.9.152 (2012-03-23) */ public function getFontBBox() { $fbbox = array(); if (isset($this->CurrentFont['desc']['FontBBox'])) { $tmpbbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1)); $fbbox = array_map(array($this,'getAbsFontMeasure'), $tmpbbox); } else { // Find max width if (isset($this->CurrentFont['desc']['MaxWidth'])) { $maxw = $this->getAbsFontMeasure(intval($this->CurrentFont['desc']['MaxWidth'])); } else { $maxw = 0; if (isset($this->CurrentFont['desc']['MissingWidth'])) { $maxw = max($maxw, $this->CurrentFont['desc']['MissingWidth']); } if (isset($this->CurrentFont['desc']['AvgWidth'])) { $maxw = max($maxw, $this->CurrentFont['desc']['AvgWidth']); } if (isset($this->CurrentFont['dw'])) { $maxw = max($maxw, $this->CurrentFont['dw']); } foreach ($this->CurrentFont['cw'] as $char => $w) { $maxw = max($maxw, $w); } if ($maxw == 0) { $maxw = 600; } $maxw = $this->getAbsFontMeasure($maxw); } $fbbox = array(0, (0 - $this->FontDescent), $maxw, $this->FontAscent); } return $fbbox; } /** * Convert a relative font measure into absolute value. * @param $s (int) Font measure. * @return float Absolute measure. * @since 5.9.186 (2012-09-13) */ public function getAbsFontMeasure($s) { return ($s * $this->FontSize / 1000); } /** * Returns the glyph bounding box of the specified character in the current font in user units. * @param $char (int) Input character code. * @return mixed array(xMin, yMin, xMax, yMax) or FALSE if not defined. * @since 5.9.186 (2012-09-13) */ public function getCharBBox($char) { if (isset($this->CurrentFont['cbbox'][$char])) { return array_map(array($this,'getAbsFontMeasure'), $this->CurrentFont['cbbox'][intval($char)]); } return false; } /** * Return the font descent value * @param $font (string) font name * @param $style (string) font style * @param $size (float) The size (in points) * @return int font descent * @public * @author Nicola Asuni * @since 4.9.003 (2010-03-30) */ public function getFontDescent($font, $style='', $size=0) { $fontdata = $this->AddFont($font, $style); $fontinfo = $this->getFontBuffer($fontdata['fontkey']); if (isset($fontinfo['desc']['Descent']) AND ($fontinfo['desc']['Descent'] <= 0)) { $descent = (- $fontinfo['desc']['Descent'] * $size / 1000); } else { $descent = (1.219 * 0.24 * $size); } return ($descent / $this->k); } /** * Return the font ascent value. * @param $font (string) font name * @param $style (string) font style * @param $size (float) The size (in points) * @return int font ascent * @public * @author Nicola Asuni * @since 4.9.003 (2010-03-30) */ public function getFontAscent($font, $style='', $size=0) { $fontdata = $this->AddFont($font, $style); $fontinfo = $this->getFontBuffer($fontdata['fontkey']); if (isset($fontinfo['desc']['Ascent']) AND ($fontinfo['desc']['Ascent'] > 0)) { $ascent = ($fontinfo['desc']['Ascent'] * $size / 1000); } else { $ascent = 1.219 * 0.76 * $size; } return ($ascent / $this->k); } /** * Return true in the character is present in the specified font. * @param $char (mixed) Character to check (integer value or string) * @param $font (string) Font name (family name). * @param $style (string) Font style. * @return (boolean) true if the char is defined, false otherwise. * @public * @since 5.9.153 (2012-03-28) */ public function isCharDefined($char, $font='', $style='') { if (is_string($char)) { // get character code $char = TCPDF_FONTS::UTF8StringToArray($char, $this->isunicode, $this->CurrentFont); $char = $char[0]; } if (TCPDF_STATIC::empty_string($font)) { if (TCPDF_STATIC::empty_string($style)) { return (isset($this->CurrentFont['cw'][intval($char)])); } $font = $this->FontFamily; } $fontdata = $this->AddFont($font, $style); $fontinfo = $this->getFontBuffer($fontdata['fontkey']); return (isset($fontinfo['cw'][intval($char)])); } /** * Replace missing font characters on selected font with specified substitutions. * @param $text (string) Text to process. * @param $font (string) Font name (family name). * @param $style (string) Font style. * @param $subs (array) Array of possible character substitutions. The key is the character to check (integer value) and the value is a single intege value or an array of possible substitutes. * @return (string) Processed text. * @public * @since 5.9.153 (2012-03-28) */ public function replaceMissingChars($text, $font='', $style='', $subs=array()) { if (empty($subs)) { return $text; } if (TCPDF_STATIC::empty_string($font)) { $font = $this->FontFamily; } $fontdata = $this->AddFont($font, $style); $fontinfo = $this->getFontBuffer($fontdata['fontkey']); $uniarr = TCPDF_FONTS::UTF8StringToArray($text, $this->isunicode, $this->CurrentFont); foreach ($uniarr as $k => $chr) { if (!isset($fontinfo['cw'][$chr])) { // this character is missing on the selected font if (isset($subs[$chr])) { // we have available substitutions if (is_array($subs[$chr])) { foreach($subs[$chr] as $s) { if (isset($fontinfo['cw'][$s])) { $uniarr[$k] = $s; break; } } } elseif (isset($fontinfo['cw'][$subs[$chr]])) { $uniarr[$k] = $subs[$chr]; } } } } return TCPDF_FONTS::UniArrSubString(TCPDF_FONTS::UTF8ArrayToUniArray($uniarr, $this->isunicode)); } /** * Defines the default monospaced font. * @param $font (string) Font name. * @public * @since 4.5.025 */ public function SetDefaultMonospacedFont($font) { $this->default_monospaced_font = $font; } /** * Creates a new internal link and returns its identifier. An internal link is a clickable area which directs to another place within the document.<br /> * The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is defined with SetLink(). * @public * @since 1.5 * @see Cell(), Write(), Image(), Link(), SetLink() */ public function AddLink() { //Create a new internal link $n = count($this->links) + 1; $this->links[$n] = array(0, 0); return $n; } /** * Defines the page and position a link points to. * @param $link (int) The link identifier returned by AddLink() * @param $y (float) Ordinate of target position; -1 indicates the current position. The default value is 0 (top of page) * @param $page (int) Number of target page; -1 indicates the current page. This is the default value * @public * @since 1.5 * @see AddLink() */ public function SetLink($link, $y=0, $page=-1) { if ($y == -1) { $y = $this->y; } if ($page == -1) { $page = $this->page; } $this->links[$link] = array($page, $y); } /** * Puts a link on a rectangular area of the page. * Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $w (float) Width of the rectangle * @param $h (float) Height of the rectangle * @param $link (mixed) URL or identifier returned by AddLink() * @param $spaces (int) number of spaces on the text to link * @public * @since 1.5 * @see AddLink(), Annotation(), Cell(), Write(), Image() */ public function Link($x, $y, $w, $h, $link, $spaces=0) { $this->Annotation($x, $y, $w, $h, $link, array('Subtype'=>'Link'), $spaces); } /** * Puts a markup annotation on a rectangular area of the page. * !!!!THE ANNOTATION SUPPORT IS NOT YET FULLY IMPLEMENTED !!!! * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $w (float) Width of the rectangle * @param $h (float) Height of the rectangle * @param $text (string) annotation text or alternate content * @param $opt (array) array of options (see section 8.4 of PDF reference 1.7). * @param $spaces (int) number of spaces on the text to link * @public * @since 4.0.018 (2008-08-06) */ public function Annotation($x, $y, $w, $h, $text, $opt=array('Subtype'=>'Text'), $spaces=0) { if ($this->inxobj) { // store parameters for later use on template $this->xobjects[$this->xobjid]['annotations'][] = array('x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'text' => $text, 'opt' => $opt, 'spaces' => $spaces); return; } if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); // recalculate coordinates to account for graphic transformations if (isset($this->transfmatrix) AND !empty($this->transfmatrix)) { for ($i=$this->transfmatrix_key; $i > 0; --$i) { $maxid = count($this->transfmatrix[$i]) - 1; for ($j=$maxid; $j >= 0; --$j) { $ctm = $this->transfmatrix[$i][$j]; if (isset($ctm['a'])) { $x = $x * $this->k; $y = ($this->h - $y) * $this->k; $w = $w * $this->k; $h = $h * $this->k; // top left $xt = $x; $yt = $y; $x1 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e']; $y1 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f']; // top right $xt = $x + $w; $yt = $y; $x2 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e']; $y2 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f']; // bottom left $xt = $x; $yt = $y - $h; $x3 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e']; $y3 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f']; // bottom right $xt = $x + $w; $yt = $y - $h; $x4 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e']; $y4 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f']; // new coordinates (rectangle area) $x = min($x1, $x2, $x3, $x4); $y = max($y1, $y2, $y3, $y4); $w = (max($x1, $x2, $x3, $x4) - $x) / $this->k; $h = ($y - min($y1, $y2, $y3, $y4)) / $this->k; $x = $x / $this->k; $y = $this->h - ($y / $this->k); } } } } if ($this->page <= 0) { $page = 1; } else { $page = $this->page; } if (!isset($this->PageAnnots[$page])) { $this->PageAnnots[$page] = array(); } $this->PageAnnots[$page][] = array('n' => ++$this->n, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces); if (!$this->pdfa_mode) { if ((($opt['Subtype'] == 'FileAttachment') OR ($opt['Subtype'] == 'Sound')) AND (!TCPDF_STATIC::empty_string($opt['FS'])) AND (file_exists($opt['FS']) OR TCPDF_STATIC::isValidURL($opt['FS'])) AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) { $this->embeddedfiles[basename($opt['FS'])] = array('f' => ++$this->n, 'n' => ++$this->n, 'file' => $opt['FS']); } } // Add widgets annotation's icons if (isset($opt['mk']['i']) AND file_exists($opt['mk']['i'])) { $this->Image($opt['mk']['i'], '', '', 10, 10, '', '', '', false, 300, '', false, false, 0, false, true); } if (isset($opt['mk']['ri']) AND file_exists($opt['mk']['ri'])) { $this->Image($opt['mk']['ri'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true); } if (isset($opt['mk']['ix']) AND file_exists($opt['mk']['ix'])) { $this->Image($opt['mk']['ix'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true); } } /** * Embedd the attached files. * @since 4.4.000 (2008-12-07) * @protected * @see Annotation() */ protected function _putEmbeddedFiles() { if ($this->pdfa_mode) { // embedded files are not allowed in PDF/A mode return; } reset($this->embeddedfiles); foreach ($this->embeddedfiles as $filename => $filedata) { // update name tree $this->efnames[$filename] = $filedata['f'].' 0 R'; // embedded file specification object $out = $this->_getobj($filedata['f'])."\n"; $out .= '<</Type /Filespec /F '.$this->_datastring($filename, $filedata['f']).' /EF <</F '.$filedata['n'].' 0 R>> >>'; $out .= "\n".'endobj'; $this->_out($out); // embedded file object $data = file_get_contents($filedata['file']); $filter = ''; $rawsize = strlen($data); if ($this->compress) { $data = gzcompress($data); $filter = ' /Filter /FlateDecode'; } $stream = $this->_getrawstream($data, $filedata['n']); $out = $this->_getobj($filedata['n'])."\n"; $out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' /Params <</Size '.$rawsize.'>> >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; $out .= "\n".'endobj'; $this->_out($out); } } /** * Prints a text cell at the specified position. * This method allows to place a string precisely on the page. * @param $x (float) Abscissa of the cell origin * @param $y (float) Ordinate of the cell origin * @param $txt (string) String to print * @param $fstroke (int) outline size in user units (false = disable) * @param $fclip (boolean) if true activate clipping mode (you must call StartTransform() before this function and StopTransform() to stop the clipping tranformation). * @param $ffill (boolean) if true fills the text * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0. * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul> * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $link (mixed) URL or identifier returned by AddLink(). * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible. * @param $ignore_min_height (boolean) if true ignore automatic minimum height value. * @param $calign (string) cell vertical alignment relative to the specified Y value. Possible values are:<ul><li>T : cell top</li><li>A : font top</li><li>L : font baseline</li><li>D : font bottom</li><li>B : cell bottom</li></ul> * @param $valign (string) text vertical alignment inside the cell. Possible values are:<ul><li>T : top</li><li>C : center</li><li>B : bottom</li></ul> * @param $rtloff (boolean) if true uses the page top-left corner as origin of axis for $x and $y initial position. * @public * @since 1.0 * @see Cell(), Write(), MultiCell(), WriteHTML(), WriteHTMLCell() */ public function Text($x, $y, $txt, $fstroke=false, $fclip=false, $ffill=true, $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M', $rtloff=false) { $textrendermode = $this->textrendermode; $textstrokewidth = $this->textstrokewidth; $this->setTextRenderingMode($fstroke, $ffill, $fclip); $this->SetXY($x, $y, $rtloff); $this->Cell(0, 0, $txt, $border, $ln, $align, $fill, $link, $stretch, $ignore_min_height, $calign, $valign); // restore previous rendering mode $this->textrendermode = $textrendermode; $this->textstrokewidth = $textstrokewidth; } /** * Whenever a page break condition is met, the method is called, and the break is issued or not depending on the returned value. * The default implementation returns a value according to the mode selected by SetAutoPageBreak().<br /> * This method is called automatically and should not be called directly by the application. * @return boolean * @public * @since 1.4 * @see SetAutoPageBreak() */ public function AcceptPageBreak() { if ($this->num_columns > 1) { // multi column mode if ($this->current_column < ($this->num_columns - 1)) { // go to next column $this->selectColumn($this->current_column + 1); } elseif ($this->AutoPageBreak) { // add a new page $this->AddPage(); // set first column $this->selectColumn(0); } // avoid page breaking from checkPageBreak() return false; } return $this->AutoPageBreak; } /** * Add page if needed. * @param $h (float) Cell height. Default value: 0. * @param $y (mixed) starting y position, leave empty for current position. * @param $addpage (boolean) if true add a page, otherwise only return the true/false state * @return boolean true in case of page break, false otherwise. * @since 3.2.000 (2008-07-01) * @protected */ protected function checkPageBreak($h=0, $y='', $addpage=true) { if (TCPDF_STATIC::empty_string($y)) { $y = $this->y; } $current_page = $this->page; if ((($y + $h) > $this->PageBreakTrigger) AND ($this->inPageBody()) AND ($this->AcceptPageBreak())) { if ($addpage) { //Automatic page break $x = $this->x; $this->AddPage($this->CurOrientation); $this->y = $this->tMargin; $oldpage = $this->page - 1; if ($this->rtl) { if ($this->pagedim[$this->page]['orm'] != $this->pagedim[$oldpage]['orm']) { $this->x = $x - ($this->pagedim[$this->page]['orm'] - $this->pagedim[$oldpage]['orm']); } else { $this->x = $x; } } else { if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) { $this->x = $x + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$oldpage]['olm']); } else { $this->x = $x; } } } return true; } if ($current_page != $this->page) { // account for columns mode return true; } return false; } /** * Prints a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br /> * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting. * @param $w (float) Cell width. If 0, the cell extends up to the right margin. * @param $h (float) Cell height. Default value: 0. * @param $txt (string) String to print. Default value: empty string. * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul> Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0. * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul> * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $link (mixed) URL or identifier returned by AddLink(). * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible. * @param $ignore_min_height (boolean) if true ignore automatic minimum height value. * @param $calign (string) cell vertical alignment relative to the specified Y value. Possible values are:<ul><li>T : cell top</li><li>C : center</li><li>B : cell bottom</li><li>A : font top</li><li>L : font baseline</li><li>D : font bottom</li></ul> * @param $valign (string) text vertical alignment inside the cell. Possible values are:<ul><li>T : top</li><li>C : center</li><li>B : bottom</li></ul> * @public * @since 1.0 * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), AddLink(), Ln(), MultiCell(), Write(), SetAutoPageBreak() */ public function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M') { $prev_cell_margin = $this->cell_margin; $prev_cell_padding = $this->cell_padding; $this->adjustCellPadding($border); if (!$ignore_min_height) { $min_cell_height = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B']; if ($h < $min_cell_height) { $h = $min_cell_height; } } $this->checkPageBreak($h + $this->cell_margin['T'] + $this->cell_margin['B']); // apply text shadow if enabled if ($this->txtshadow['enabled']) { // save data $x = $this->x; $y = $this->y; $bc = $this->bgcolor; $fc = $this->fgcolor; $sc = $this->strokecolor; $alpha = $this->alpha; // print shadow $this->x += $this->txtshadow['depth_w']; $this->y += $this->txtshadow['depth_h']; $this->SetFillColorArray($this->txtshadow['color']); $this->SetTextColorArray($this->txtshadow['color']); $this->SetDrawColorArray($this->txtshadow['color']); if ($this->txtshadow['opacity'] != $alpha['CA']) { $this->setAlpha($this->txtshadow['opacity'], $this->txtshadow['blend_mode']); } if ($this->state == 2) { $this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign)); } //restore data $this->x = $x; $this->y = $y; $this->SetFillColorArray($bc); $this->SetTextColorArray($fc); $this->SetDrawColorArray($sc); if ($this->txtshadow['opacity'] != $alpha['CA']) { $this->setAlpha($alpha['CA'], $alpha['BM'], $alpha['ca'], $alpha['AIS']); } } if ($this->state == 2) { $this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign)); } $this->cell_padding = $prev_cell_padding; $this->cell_margin = $prev_cell_margin; } /** * Returns the PDF string code to print a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br /> * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting. * @param $w (float) Cell width. If 0, the cell extends up to the right margin. * @param $h (float) Cell height. Default value: 0. * @param $txt (string) String to print. Default value: empty string. * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL languages)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0. * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul> * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $link (mixed) URL or identifier returned by AddLink(). * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible. * @param $ignore_min_height (boolean) if true ignore automatic minimum height value. * @param $calign (string) cell vertical alignment relative to the specified Y value. Possible values are:<ul><li>T : cell top</li><li>C : center</li><li>B : cell bottom</li><li>A : font top</li><li>L : font baseline</li><li>D : font bottom</li></ul> * @param $valign (string) text vertical alignment inside the cell. Possible values are:<ul><li>T : top</li><li>M : middle</li><li>B : bottom</li></ul> * @return string containing cell code * @protected * @since 1.0 * @see Cell() */ protected function getCellCode($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M') { // replace 'NO-BREAK SPACE' (U+00A0) character with a simple space $txt = str_replace(TCPDF_FONTS::unichr(160, $this->isunicode), ' ', $txt); $prev_cell_margin = $this->cell_margin; $prev_cell_padding = $this->cell_padding; $txt = TCPDF_STATIC::removeSHY($txt, $this->isunicode); $rs = ''; //string to be returned $this->adjustCellPadding($border); if (!$ignore_min_height) { $min_cell_height = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B']; if ($h < $min_cell_height) { $h = $min_cell_height; } } $k = $this->k; // check page for no-write regions and adapt page margins if necessary list($this->x, $this->y) = $this->checkPageRegions($h, $this->x, $this->y); if ($this->rtl) { $x = $this->x - $this->cell_margin['R']; } else { $x = $this->x + $this->cell_margin['L']; } $y = $this->y + $this->cell_margin['T']; $prev_font_stretching = $this->font_stretching; $prev_font_spacing = $this->font_spacing; // cell vertical alignment switch ($calign) { case 'A': { // font top switch ($valign) { case 'T': { // top $y -= $this->cell_padding['T']; break; } case 'B': { // bottom $y -= ($h - $this->cell_padding['B'] - $this->FontAscent - $this->FontDescent); break; } default: case 'C': case 'M': { // center $y -= (($h - $this->FontAscent - $this->FontDescent) / 2); break; } } break; } case 'L': { // font baseline switch ($valign) { case 'T': { // top $y -= ($this->cell_padding['T'] + $this->FontAscent); break; } case 'B': { // bottom $y -= ($h - $this->cell_padding['B'] - $this->FontDescent); break; } default: case 'C': case 'M': { // center $y -= (($h + $this->FontAscent - $this->FontDescent) / 2); break; } } break; } case 'D': { // font bottom switch ($valign) { case 'T': { // top $y -= ($this->cell_padding['T'] + $this->FontAscent + $this->FontDescent); break; } case 'B': { // bottom $y -= ($h - $this->cell_padding['B']); break; } default: case 'C': case 'M': { // center $y -= (($h + $this->FontAscent + $this->FontDescent) / 2); break; } } break; } case 'B': { // cell bottom $y -= $h; break; } case 'C': case 'M': { // cell center $y -= ($h / 2); break; } default: case 'T': { // cell top break; } } // text vertical alignment switch ($valign) { case 'T': { // top $yt = $y + $this->cell_padding['T']; break; } case 'B': { // bottom $yt = $y + $h - $this->cell_padding['B'] - $this->FontAscent - $this->FontDescent; break; } default: case 'C': case 'M': { // center $yt = $y + (($h - $this->FontAscent - $this->FontDescent) / 2); break; } } $basefonty = $yt + $this->FontAscent; if (TCPDF_STATIC::empty_string($w) OR ($w <= 0)) { if ($this->rtl) { $w = $x - $this->lMargin; } else { $w = $this->w - $this->rMargin - $x; } } $s = ''; // fill and borders if (is_string($border) AND (strlen($border) == 4)) { // full border $border = 1; } if ($fill OR ($border == 1)) { if ($fill) { $op = ($border == 1) ? 'B' : 'f'; } else { $op = 'S'; } if ($this->rtl) { $xk = (($x - $w) * $k); } else { $xk = ($x * $k); } $s .= sprintf('%F %F %F %F re %s ', $xk, (($this->h - $y) * $k), ($w * $k), (-$h * $k), $op); } // draw borders $s .= $this->getCellBorder($x, $y, $w, $h, $border); if ($txt != '') { $txt2 = $txt; if ($this->isunicode) { if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) { $txt2 = TCPDF_FONTS::UTF8ToLatin1($txt2, $this->isunicode, $this->CurrentFont); } else { $unicode = TCPDF_FONTS::UTF8StringToArray($txt, $this->isunicode, $this->CurrentFont); // array of UTF-8 unicode values $unicode = TCPDF_FONTS::utf8Bidi($unicode, '', $this->tmprtl, $this->isunicode, $this->CurrentFont); // replace thai chars (if any) if (defined('K_THAI_TOPCHARS') AND (K_THAI_TOPCHARS == true)) { // number of chars $numchars = count($unicode); // po pla, for far, for fan $longtail = array(0x0e1b, 0x0e1d, 0x0e1f); // do chada, to patak $lowtail = array(0x0e0e, 0x0e0f); // mai hun arkad, sara i, sara ii, sara ue, sara uee $upvowel = array(0x0e31, 0x0e34, 0x0e35, 0x0e36, 0x0e37); // mai ek, mai tho, mai tri, mai chattawa, karan $tonemark = array(0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c); // sara u, sara uu, pinthu $lowvowel = array(0x0e38, 0x0e39, 0x0e3a); $output = array(); for ($i = 0; $i < $numchars; $i++) { if (($unicode[$i] >= 0x0e00) && ($unicode[$i] <= 0x0e5b)) { $ch0 = $unicode[$i]; $ch1 = ($i > 0) ? $unicode[($i - 1)] : 0; $ch2 = ($i > 1) ? $unicode[($i - 2)] : 0; $chn = ($i < ($numchars - 1)) ? $unicode[($i + 1)] : 0; if (in_array($ch0, $tonemark)) { if ($chn == 0x0e33) { // sara um if (in_array($ch1, $longtail)) { // tonemark at upper left $output[] = $this->replaceChar($ch0, (0xf713 + $ch0 - 0x0e48)); } else { // tonemark at upper right (normal position) $output[] = $ch0; } } elseif (in_array($ch1, $longtail) OR (in_array($ch2, $longtail) AND in_array($ch1, $lowvowel))) { // tonemark at lower left $output[] = $this->replaceChar($ch0, (0xf705 + $ch0 - 0x0e48)); } elseif (in_array($ch1, $upvowel)) { if (in_array($ch2, $longtail)) { // tonemark at upper left $output[] = $this->replaceChar($ch0, (0xf713 + $ch0 - 0x0e48)); } else { // tonemark at upper right (normal position) $output[] = $ch0; } } else { // tonemark at lower right $output[] = $this->replaceChar($ch0, (0xf70a + $ch0 - 0x0e48)); } } elseif (($ch0 == 0x0e33) AND (in_array($ch1, $longtail) OR (in_array($ch2, $longtail) AND in_array($ch1, $tonemark)))) { // add lower left nikhahit and sara aa if ($this->isCharDefined(0xf711) AND $this->isCharDefined(0x0e32)) { $output[] = 0xf711; $this->CurrentFont['subsetchars'][0xf711] = true; $output[] = 0x0e32; $this->CurrentFont['subsetchars'][0x0e32] = true; } else { $output[] = $ch0; } } elseif (in_array($ch1, $longtail)) { if ($ch0 == 0x0e31) { // lower left mai hun arkad $output[] = $this->replaceChar($ch0, 0xf710); } elseif (in_array($ch0, $upvowel)) { // lower left $output[] = $this->replaceChar($ch0, (0xf701 + $ch0 - 0x0e34)); } elseif ($ch0 == 0x0e47) { // lower left mai tai koo $output[] = $this->replaceChar($ch0, 0xf712); } else { // normal character $output[] = $ch0; } } elseif (in_array($ch1, $lowtail) AND in_array($ch0, $lowvowel)) { // lower vowel $output[] = $this->replaceChar($ch0, (0xf718 + $ch0 - 0x0e38)); } elseif (($ch0 == 0x0e0d) AND in_array($chn, $lowvowel)) { // yo ying without lower part $output[] = $this->replaceChar($ch0, 0xf70f); } elseif (($ch0 == 0x0e10) AND in_array($chn, $lowvowel)) { // tho santan without lower part $output[] = $this->replaceChar($ch0, 0xf700); } else { $output[] = $ch0; } } else { // non-thai character $output[] = $unicode[$i]; } } $unicode = $output; // update font subsetchars $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']); } // end of K_THAI_TOPCHARS $txt2 = TCPDF_FONTS::arrUTF8ToUTF16BE($unicode, false); } } $txt2 = TCPDF_STATIC::_escape($txt2); // get current text width (considering general font stretching and spacing) $txwidth = $this->GetStringWidth($txt); $width = $txwidth; // check for stretch mode if ($stretch > 0) { // calculate ratio between cell width and text width if ($width <= 0) { $ratio = 1; } else { $ratio = (($w - $this->cell_padding['L'] - $this->cell_padding['R']) / $width); } // check if stretching is required if (($ratio < 1) OR (($ratio > 1) AND (($stretch % 2) == 0))) { // the text will be stretched to fit cell width if ($stretch > 2) { // set new character spacing $this->font_spacing += ($w - $this->cell_padding['L'] - $this->cell_padding['R'] - $width) / (max(($this->GetNumChars($txt) - 1), 1) * ($this->font_stretching / 100)); } else { // set new horizontal stretching $this->font_stretching *= $ratio; } // recalculate text width (the text fills the entire cell) $width = $w - $this->cell_padding['L'] - $this->cell_padding['R']; // reset alignment $align = ''; } } if ($this->font_stretching != 100) { // apply font stretching $rs .= sprintf('BT %F Tz ET ', $this->font_stretching); } if ($this->font_spacing != 0) { // increase/decrease font spacing $rs .= sprintf('BT %F Tc ET ', ($this->font_spacing * $this->k)); } if ($this->ColorFlag AND ($this->textrendermode < 4)) { $s .= 'q '.$this->TextColor.' '; } // rendering mode $s .= sprintf('BT %d Tr %F w ET ', $this->textrendermode, ($this->textstrokewidth * $this->k)); // count number of spaces $ns = substr_count($txt, chr(32)); // Justification $spacewidth = 0; if (($align == 'J') AND ($ns > 0)) { if ($this->isUnicodeFont()) { // get string width without spaces $width = $this->GetStringWidth(str_replace(' ', '', $txt)); // calculate average space width $spacewidth = -1000 * ($w - $width - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1) / $this->FontSize; if ($this->font_stretching != 100) { // word spacing is affected by stretching $spacewidth /= ($this->font_stretching / 100); } // set word position to be used with TJ operator $txt2 = str_replace(chr(0).chr(32), ') '.sprintf('%F', $spacewidth).' (', $txt2); $unicode_justification = true; } else { // get string width $width = $txwidth; // new space width $spacewidth = (($w - $width - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1)) * $this->k; if ($this->font_stretching != 100) { // word spacing (Tw) is affected by stretching $spacewidth /= ($this->font_stretching / 100); } // set word spacing $rs .= sprintf('BT %F Tw ET ', $spacewidth); } $width = $w - $this->cell_padding['L'] - $this->cell_padding['R']; } // replace carriage return characters $txt2 = str_replace("\r", ' ', $txt2); switch ($align) { case 'C': { $dx = ($w - $width) / 2; break; } case 'R': { if ($this->rtl) { $dx = $this->cell_padding['R']; } else { $dx = $w - $width - $this->cell_padding['R']; } break; } case 'L': { if ($this->rtl) { $dx = $w - $width - $this->cell_padding['L']; } else { $dx = $this->cell_padding['L']; } break; } case 'J': default: { if ($this->rtl) { $dx = $this->cell_padding['R']; } else { $dx = $this->cell_padding['L']; } break; } } if ($this->rtl) { $xdx = $x - $dx - $width; } else { $xdx = $x + $dx; } $xdk = $xdx * $k; // print text $s .= sprintf('BT %F %F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2); if (isset($uniblock)) { // print overlapping characters as separate string $xshift = 0; // horizontal shift $ty = (($this->h - $basefonty + (0.2 * $this->FontSize)) * $k); $spw = (($w - $txwidth - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1)); foreach ($uniblock as $uk => $uniarr) { if (($uk % 2) == 0) { // x space to skip if ($spacewidth != 0) { // justification shift $xshift += (count(array_keys($uniarr, 32)) * $spw); } $xshift += $this->GetArrStringWidth($uniarr); // + shift justification } else { // character to print $topchr = TCPDF_FONTS::arrUTF8ToUTF16BE($uniarr, false); $topchr = TCPDF_STATIC::_escape($topchr); $s .= sprintf(' BT %F %F Td [(%s)] TJ ET', ($xdk + ($xshift * $k)), $ty, $topchr); } } } if ($this->underline) { $s .= ' '.$this->_dounderlinew($xdx, $basefonty, $width); } if ($this->linethrough) { $s .= ' '.$this->_dolinethroughw($xdx, $basefonty, $width); } if ($this->overline) { $s .= ' '.$this->_dooverlinew($xdx, $basefonty, $width); } if ($this->ColorFlag AND ($this->textrendermode < 4)) { $s .= ' Q'; } if ($link) { $this->Link($xdx, $yt, $width, ($this->FontAscent + $this->FontDescent), $link, $ns); } } // output cell if ($s) { // output cell $rs .= $s; if ($this->font_spacing != 0) { // reset font spacing mode $rs .= ' BT 0 Tc ET'; } if ($this->font_stretching != 100) { // reset font stretching mode $rs .= ' BT 100 Tz ET'; } } // reset word spacing if (!$this->isUnicodeFont() AND ($align == 'J')) { $rs .= ' BT 0 Tw ET'; } // reset stretching and spacing $this->font_stretching = $prev_font_stretching; $this->font_spacing = $prev_font_spacing; $this->lasth = $h; if ($ln > 0) { //Go to the beginning of the next line $this->y = $y + $h + $this->cell_margin['B']; if ($ln == 1) { if ($this->rtl) { $this->x = $this->w - $this->rMargin; } else { $this->x = $this->lMargin; } } } else { // go left or right by case if ($this->rtl) { $this->x = $x - $w - $this->cell_margin['L']; } else { $this->x = $x + $w + $this->cell_margin['R']; } } $gstyles = ''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor."\n"; $rs = $gstyles.$rs; $this->cell_padding = $prev_cell_padding; $this->cell_margin = $prev_cell_margin; return $rs; } /** * Replace a char if is defined on the current font. * @param $oldchar (int) Integer code (unicode) of the character to replace. * @param $newchar (int) Integer code (unicode) of the new character. * @return int the replaced char or the old char in case the new char i not defined * @protected * @since 5.9.167 (2012-06-22) */ protected function replaceChar($oldchar, $newchar) { if ($this->isCharDefined($newchar)) { // add the new char on the subset list $this->CurrentFont['subsetchars'][$newchar] = true; // return the new character return $newchar; } // return the old char return $oldchar; } /** * Returns the code to draw the cell border * @param $x (float) X coordinate. * @param $y (float) Y coordinate. * @param $w (float) Cell width. * @param $h (float) Cell height. * @param $brd (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @return string containing cell border code * @protected * @see SetLineStyle() * @since 5.7.000 (2010-08-02) */ protected function getCellBorder($x, $y, $w, $h, $brd) { $s = ''; // string to be returned if (empty($brd)) { return $s; } if ($brd == 1) { $brd = array('LRTB' => true); } // calculate coordinates for border $k = $this->k; if ($this->rtl) { $xeL = ($x - $w) * $k; $xeR = $x * $k; } else { $xeL = $x * $k; $xeR = ($x + $w) * $k; } $yeL = (($this->h - ($y + $h)) * $k); $yeT = (($this->h - $y) * $k); $xeT = $xeL; $xeB = $xeR; $yeR = $yeT; $yeB = $yeL; if (is_string($brd)) { // convert string to array $slen = strlen($brd); $newbrd = array(); for ($i = 0; $i < $slen; ++$i) { $newbrd[$brd[$i]] = array('cap' => 'square', 'join' => 'miter'); } $brd = $newbrd; } if (isset($brd['mode'])) { $mode = $brd['mode']; unset($brd['mode']); } else { $mode = 'normal'; } foreach ($brd as $border => $style) { if (is_array($style) AND !empty($style)) { // apply border style $prev_style = $this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '; $s .= $this->SetLineStyle($style, true)."\n"; } switch ($mode) { case 'ext': { $off = (($this->LineWidth / 2) * $k); $xL = $xeL - $off; $xR = $xeR + $off; $yT = $yeT + $off; $yL = $yeL - $off; $xT = $xL; $xB = $xR; $yR = $yT; $yB = $yL; $w += $this->LineWidth; $h += $this->LineWidth; break; } case 'int': { $off = ($this->LineWidth / 2) * $k; $xL = $xeL + $off; $xR = $xeR - $off; $yT = $yeT - $off; $yL = $yeL + $off; $xT = $xL; $xB = $xR; $yR = $yT; $yB = $yL; $w -= $this->LineWidth; $h -= $this->LineWidth; break; } case 'normal': default: { $xL = $xeL; $xT = $xeT; $xB = $xeB; $xR = $xeR; $yL = $yeL; $yT = $yeT; $yB = $yeB; $yR = $yeR; break; } } // draw borders by case if (strlen($border) == 4) { $s .= sprintf('%F %F %F %F re S ', $xT, $yT, ($w * $k), (-$h * $k)); } elseif (strlen($border) == 3) { if (strpos($border,'B') === false) { // LTR $s .= sprintf('%F %F m ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= 'S '; } elseif (strpos($border,'L') === false) { // TRB $s .= sprintf('%F %F m ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= 'S '; } elseif (strpos($border,'T') === false) { // RBL $s .= sprintf('%F %F m ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= 'S '; } elseif (strpos($border,'R') === false) { // BLT $s .= sprintf('%F %F m ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= 'S '; } } elseif (strlen($border) == 2) { if ((strpos($border,'L') !== false) AND (strpos($border,'T') !== false)) { // LT $s .= sprintf('%F %F m ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= 'S '; } elseif ((strpos($border,'T') !== false) AND (strpos($border,'R') !== false)) { // TR $s .= sprintf('%F %F m ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= 'S '; } elseif ((strpos($border,'R') !== false) AND (strpos($border,'B') !== false)) { // RB $s .= sprintf('%F %F m ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= 'S '; } elseif ((strpos($border,'B') !== false) AND (strpos($border,'L') !== false)) { // BL $s .= sprintf('%F %F m ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= 'S '; } elseif ((strpos($border,'L') !== false) AND (strpos($border,'R') !== false)) { // LR $s .= sprintf('%F %F m ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= 'S '; $s .= sprintf('%F %F m ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= 'S '; } elseif ((strpos($border,'T') !== false) AND (strpos($border,'B') !== false)) { // TB $s .= sprintf('%F %F m ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= 'S '; $s .= sprintf('%F %F m ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= 'S '; } } else { // strlen($border) == 1 if (strpos($border,'L') !== false) { // L $s .= sprintf('%F %F m ', $xL, $yL); $s .= sprintf('%F %F l ', $xT, $yT); $s .= 'S '; } elseif (strpos($border,'T') !== false) { // T $s .= sprintf('%F %F m ', $xT, $yT); $s .= sprintf('%F %F l ', $xR, $yR); $s .= 'S '; } elseif (strpos($border,'R') !== false) { // R $s .= sprintf('%F %F m ', $xR, $yR); $s .= sprintf('%F %F l ', $xB, $yB); $s .= 'S '; } elseif (strpos($border,'B') !== false) { // B $s .= sprintf('%F %F m ', $xB, $yB); $s .= sprintf('%F %F l ', $xL, $yL); $s .= 'S '; } } if (is_array($style) AND !empty($style)) { // reset border style to previous value $s .= "\n".$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor."\n"; } } return $s; } /** * This method allows printing text with line breaks. * They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other.<br /> * Text can be aligned, centered or justified. The cell block can be framed and the background painted. * @param $w (float) Width of cells. If 0, they extend up to the right margin of the page. * @param $h (float) Cell minimum height. The cell extends automatically if needed. * @param $txt (string) String to print * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align</li><li>C: center</li><li>R: right align</li><li>J: justification (default value when $ishtml=false)</li></ul> * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $ln (int) Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line [DEFAULT]</li><li>2: below</li></ul> * @param $x (float) x position in user units * @param $y (float) y position in user units * @param $reseth (boolean) if true reset the last cell height (default true). * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible. * @param $ishtml (boolean) INTERNAL USE ONLY -- set to true if $txt is HTML content (default = false). Never set this parameter to true, use instead writeHTMLCell() or writeHTML() methods. * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width. * @param $maxh (float) maximum height. It should be >= $h and less then remaining space to the bottom of the page, or 0 for disable this feature. This feature works only when $ishtml=false. * @param $valign (string) Vertical alignment of text (requires $maxh = $h > 0). Possible values are:<ul><li>T: TOP</li><li>M: middle</li><li>B: bottom</li></ul>. This feature works only when $ishtml=false and the cell must fit in a single page. * @param $fitcell (boolean) if true attempt to fit all the text within the cell by reducing the font size (do not work in HTML mode). * @return int Return the number of cells or 1 for html mode. * @public * @since 1.3 * @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), Cell(), Write(), SetAutoPageBreak() */ public function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0, $valign='T', $fitcell=false) { $prev_cell_margin = $this->cell_margin; $prev_cell_padding = $this->cell_padding; // adjust internal padding $this->adjustCellPadding($border); $mc_padding = $this->cell_padding; $mc_margin = $this->cell_margin; $this->cell_padding['T'] = 0; $this->cell_padding['B'] = 0; $this->setCellMargins(0, 0, 0, 0); if (TCPDF_STATIC::empty_string($this->lasth) OR $reseth) { // reset row height $this->resetLastH(); } if (!TCPDF_STATIC::empty_string($y)) { $this->SetY($y); } else { $y = $this->GetY(); } $resth = 0; if (($h > 0) AND $this->inPageBody() AND (($y + $h + $mc_margin['T'] + $mc_margin['B']) > $this->PageBreakTrigger)) { // spit cell in more pages/columns $newh = ($this->PageBreakTrigger - $y); $resth = ($h - $newh); // cell to be printed on the next page/column $h = $newh; } // get current page number $startpage = $this->page; // get current column $startcolumn = $this->current_column; if (!TCPDF_STATIC::empty_string($x)) { $this->SetX($x); } else { $x = $this->GetX(); } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions(0, $x, $y); // apply margins $oy = $y + $mc_margin['T']; if ($this->rtl) { $ox = ($this->w - $x - $mc_margin['R']); } else { $ox = ($x + $mc_margin['L']); } $this->x = $ox; $this->y = $oy; // set width if (TCPDF_STATIC::empty_string($w) OR ($w <= 0)) { if ($this->rtl) { $w = ($this->x - $this->lMargin - $mc_margin['L']); } else { $w = ($this->w - $this->x - $this->rMargin - $mc_margin['R']); } } // store original margin values $lMargin = $this->lMargin; $rMargin = $this->rMargin; if ($this->rtl) { $this->rMargin = ($this->w - $this->x); $this->lMargin = ($this->x - $w); } else { $this->lMargin = ($this->x); $this->rMargin = ($this->w - $this->x - $w); } $this->clMargin = $this->lMargin; $this->crMargin = $this->rMargin; if ($autopadding) { // add top padding $this->y += $mc_padding['T']; } if ($ishtml) { // ******* Write HTML text $this->writeHTML($txt, true, false, $reseth, true, $align); $nl = 1; } else { // ******* Write simple text $prev_FontSizePt = $this->FontSizePt; // vertical alignment if ($maxh > 0) { // get text height $text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border); if ($fitcell) { // try to reduce font size to fit text on cell (use a quick search algorithm) $fmin = 1; $fmax = $this->FontSizePt; $prev_text_height = $text_height; $maxit = 100; // max number of iterations while ($maxit > 0) { $fmid = (($fmax + $fmin) / 2); $this->SetFontSize($fmid, false); $this->resetLastH(); $text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border); if (($text_height == $maxh) OR (($text_height < $maxh) AND ($fmin >= ($fmax - 0.01)))) { break; } elseif ($text_height < $maxh) { $fmin = $fmid; } else { $fmax = $fmid; } --$maxit; } $this->SetFontSize($this->FontSizePt); } if ($text_height < $maxh) { if ($valign == 'M') { // text vertically centered $this->y += (($maxh - $text_height) / 2); } elseif ($valign == 'B') { // text vertically aligned on bottom $this->y += ($maxh - $text_height); } } } $nl = $this->Write($this->lasth, $txt, '', 0, $align, true, $stretch, false, true, $maxh, 0, $mc_margin); if ($fitcell) { // restore font size $this->SetFontSize($prev_FontSizePt); } } if ($autopadding) { // add bottom padding $this->y += $mc_padding['B']; } // Get end-of-text Y position $currentY = $this->y; // get latest page number $endpage = $this->page; if ($resth > 0) { $skip = ($endpage - $startpage); $tmpresth = $resth; while ($tmpresth > 0) { if ($skip <= 0) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); } if ($this->num_columns > 1) { $tmpresth -= ($this->h - $this->y - $this->bMargin); } else { $tmpresth -= ($this->h - $this->tMargin - $this->bMargin); } --$skip; } $currentY = $this->y; $endpage = $this->page; } // get latest column $endcolumn = $this->current_column; if ($this->num_columns == 0) { $this->num_columns = 1; } // disable page regions check $check_page_regions = $this->check_page_regions; $this->check_page_regions = false; // get border modes $border_start = TCPDF_STATIC::getBorderMode($border, $position='start', $this->opencell); $border_end = TCPDF_STATIC::getBorderMode($border, $position='end', $this->opencell); $border_middle = TCPDF_STATIC::getBorderMode($border, $position='middle', $this->opencell); // design borders around HTML cells. for ($page = $startpage; $page <= $endpage; ++$page) { // for each page $ccode = ''; $this->setPage($page); if ($this->num_columns < 2) { // single-column mode $this->SetX($x); $this->y = $this->tMargin; } // account for margin changes if ($page > $startpage) { if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) { $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) { $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']); } } if ($startpage == $endpage) { // single page for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column $this->selectColumn($column); if ($this->rtl) { $this->x -= $mc_margin['R']; } else { $this->x += $mc_margin['L']; } if ($startcolumn == $endcolumn) { // single column $cborder = $border; $h = max($h, ($currentY - $oy)); $this->y = $oy; } elseif ($column == $startcolumn) { // first column $cborder = $border_start; $this->y = $oy; $h = $this->h - $this->y - $this->bMargin; } elseif ($column == $endcolumn) { // end column $cborder = $border_end; $h = $currentY - $this->y; if ($resth > $h) { $h = $resth; } } else { // middle column $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; $resth -= $h; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } elseif ($page == $startpage) { // first page for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column $this->selectColumn($column); if ($this->rtl) { $this->x -= $mc_margin['R']; } else { $this->x += $mc_margin['L']; } if ($column == $startcolumn) { // first column $cborder = $border_start; $this->y = $oy; $h = $this->h - $this->y - $this->bMargin; } else { // middle column $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; $resth -= $h; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } elseif ($page == $endpage) { // last page for ($column = 0; $column <= $endcolumn; ++$column) { // for each column $this->selectColumn($column); if ($this->rtl) { $this->x -= $mc_margin['R']; } else { $this->x += $mc_margin['L']; } if ($column == $endcolumn) { // end column $cborder = $border_end; $h = $currentY - $this->y; if ($resth > $h) { $h = $resth; } } else { // middle column $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; $resth -= $h; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } else { // middle page for ($column = 0; $column < $this->num_columns; ++$column) { // for each column $this->selectColumn($column); if ($this->rtl) { $this->x -= $mc_margin['R']; } else { $this->x += $mc_margin['L']; } $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; $resth -= $h; $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } if ($cborder OR $fill) { $offsetlen = strlen($ccode); // draw border and fill if ($this->inxobj) { // we are inside an XObject template if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) { $pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']); $pagemark = $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey]; $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey] += $offsetlen; } else { $pagemark = $this->xobjects[$this->xobjid]['intmrk']; $this->xobjects[$this->xobjid]['intmrk'] += $offsetlen; } $pagebuff = $this->xobjects[$this->xobjid]['outdata']; $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend; } else { if (end($this->transfmrk[$this->page]) !== false) { $pagemarkkey = key($this->transfmrk[$this->page]); $pagemark = $this->transfmrk[$this->page][$pagemarkkey]; $this->transfmrk[$this->page][$pagemarkkey] += $offsetlen; } elseif ($this->InFooter) { $pagemark = $this->footerpos[$this->page]; $this->footerpos[$this->page] += $offsetlen; } else { $pagemark = $this->intmrk[$this->page]; $this->intmrk[$this->page] += $offsetlen; } $pagebuff = $this->getPageBuffer($this->page); $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->setPageBuffer($this->page, $pstart.$ccode.$pend); } } } // end for each page // restore page regions check $this->check_page_regions = $check_page_regions; // Get end-of-cell Y position $currentY = $this->GetY(); // restore previous values if ($this->num_columns > 1) { $this->selectColumn(); } else { // restore original margins $this->lMargin = $lMargin; $this->rMargin = $rMargin; if ($this->page > $startpage) { // check for margin variations between pages (i.e. booklet mode) $dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$startpage]['olm']); $dr = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$startpage]['orm']); if (($dl != 0) OR ($dr != 0)) { $this->lMargin += $dl; $this->rMargin += $dr; } } } if ($ln > 0) { //Go to the beginning of the next line $this->SetY($currentY + $mc_margin['B']); if ($ln == 2) { $this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']); } } else { // go left or right by case $this->setPage($startpage); $this->y = $y; $this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']); } $this->setContentMark(); $this->cell_padding = $prev_cell_padding; $this->cell_margin = $prev_cell_margin; $this->clMargin = $this->lMargin; $this->crMargin = $this->rMargin; return $nl; } /** * This method return the estimated number of lines for print a simple text string using Multicell() method. * @param $txt (string) String for calculating his height * @param $w (float) Width of cells. If 0, they extend up to the right margin of the page. * @param $reseth (boolean) if true reset the last cell height (default false). * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width (default true). * @param $cellpadding (float) Internal cell padding, if empty uses default cell padding. * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @return float Return the minimal height needed for multicell method for printing the $txt param. * @author Alexander Escalona Fernndez, Nicola Asuni * @public * @since 4.5.011 */ public function getNumLines($txt, $w=0, $reseth=false, $autopadding=true, $cellpadding='', $border=0) { if ($txt === '') { // empty string return 1; } // adjust internal padding $prev_cell_padding = $this->cell_padding; $prev_lasth = $this->lasth; if (is_array($cellpadding)) { $this->cell_padding = $cellpadding; } $this->adjustCellPadding($border); if (TCPDF_STATIC::empty_string($w) OR ($w <= 0)) { if ($this->rtl) { $w = $this->x - $this->lMargin; } else { $w = $this->w - $this->rMargin - $this->x; } } $wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R']; if ($reseth) { // reset row height $this->resetLastH(); } $lines = 1; $sum = 0; $chars = TCPDF_FONTS::utf8Bidi(TCPDF_FONTS::UTF8StringToArray($txt, $this->isunicode, $this->CurrentFont), $txt, $this->tmprtl, $this->isunicode, $this->CurrentFont); $charsWidth = $this->GetArrStringWidth($chars, '', '', 0, true); $length = count($chars); $lastSeparator = -1; for ($i = 0; $i < $length; ++$i) { $charWidth = $charsWidth[$i]; if (preg_match($this->re_spaces, TCPDF_FONTS::unichr($chars[$i], $this->isunicode))) { $lastSeparator = $i; } if ((($sum + $charWidth) > $wmax) OR ($chars[$i] == 10)) { ++$lines; if ($chars[$i] == 10) { $lastSeparator = -1; $sum = 0; } elseif ($lastSeparator != -1) { $i = $lastSeparator; $lastSeparator = -1; $sum = 0; } else { $sum = $charWidth; } } else { $sum += $charWidth; } } if ($chars[($length - 1)] == 10) { --$lines; } $this->cell_padding = $prev_cell_padding; $this->lasth = $prev_lasth; return $lines; } /** * This method return the estimated height needed for printing a simple text string using the Multicell() method. * Generally, if you want to know the exact height for a block of content you can use the following alternative technique: * @pre * // store current object * $pdf->startTransaction(); * // store starting values * $start_y = $pdf->GetY(); * $start_page = $pdf->getPage(); * // call your printing functions with your parameters * // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * $pdf->MultiCell($w=0, $h=0, $txt, $border=1, $align='L', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0); * // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * // get the new Y * $end_y = $pdf->GetY(); * $end_page = $pdf->getPage(); * // calculate height * $height = 0; * if ($end_page == $start_page) { * $height = $end_y - $start_y; * } else { * for ($page=$start_page; $page <= $end_page; ++$page) { * $this->setPage($page); * if ($page == $start_page) { * // first page * $height = $this->h - $start_y - $this->bMargin; * } elseif ($page == $end_page) { * // last page * $height = $end_y - $this->tMargin; * } else { * $height = $this->h - $this->tMargin - $this->bMargin; * } * } * } * // restore previous object * $pdf = $pdf->rollbackTransaction(); * * @param $w (float) Width of cells. If 0, they extend up to the right margin of the page. * @param $txt (string) String for calculating his height * @param $reseth (boolean) if true reset the last cell height (default false). * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width (default true). * @param $cellpadding (float) Internal cell padding, if empty uses default cell padding. * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @return float Return the minimal height needed for multicell method for printing the $txt param. * @author Nicola Asuni, Alexander Escalona Fernndez * @public */ public function getStringHeight($w, $txt, $reseth=false, $autopadding=true, $cellpadding='', $border=0) { // adjust internal padding $prev_cell_padding = $this->cell_padding; $prev_lasth = $this->lasth; if (is_array($cellpadding)) { $this->cell_padding = $cellpadding; } $this->adjustCellPadding($border); $lines = $this->getNumLines($txt, $w, $reseth, $autopadding, $cellpadding, $border); $height = $lines * ($this->FontSize * $this->cell_height_ratio); if ($autopadding) { // add top and bottom padding $height += ($this->cell_padding['T'] + $this->cell_padding['B']); } $this->cell_padding = $prev_cell_padding; $this->lasth = $prev_lasth; return $height; } /** * This method prints text from the current position.<br /> * @param $h (float) Line height * @param $txt (string) String to print * @param $link (mixed) URL or identifier returned by AddLink() * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $align (string) Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li><li>J: justify</li></ul> * @param $ln (boolean) if true set cursor at the bottom of the line, otherwise set cursor at the top of the line. * @param $stretch (int) font stretch mode: <ul><li>0 = disabled</li><li>1 = horizontal scaling only if text is larger than cell width</li><li>2 = forced horizontal scaling to fit cell width</li><li>3 = character spacing only if text is larger than cell width</li><li>4 = forced character spacing to fit cell width</li></ul> General font stretching and scaling values will be preserved when possible. * @param $firstline (boolean) if true prints only the first line and return the remaining string. * @param $firstblock (boolean) if true the string is the starting of a line. * @param $maxh (float) maximum height. The remaining unprinted text will be returned. It should be >= $h and less then remaining space to the bottom of the page, or 0 for disable this feature. * @param $wadj (float) first line width will be reduced by this amount (used in HTML mode). * @param $margin (array) margin array of the parent container * @return mixed Return the number of cells or the remaining string if $firstline = true. * @public * @since 1.5 */ public function Write($h, $txt, $link='', $fill=false, $align='', $ln=false, $stretch=0, $firstline=false, $firstblock=false, $maxh=0, $wadj=0, $margin='') { // check page for no-write regions and adapt page margins if necessary list($this->x, $this->y) = $this->checkPageRegions($h, $this->x, $this->y); if (strlen($txt) == 0) { // fix empty text $txt = ' '; } if ($margin === '') { // set default margins $margin = $this->cell_margin; } // remove carriage returns $s = str_replace("\r", '', $txt); // check if string contains arabic text if (preg_match(TCPDF_FONT_DATA::$uni_RE_PATTERN_ARABIC, $s)) { $arabic = true; } else { $arabic = false; } // check if string contains RTL text if ($arabic OR ($this->tmprtl == 'R') OR preg_match(TCPDF_FONT_DATA::$uni_RE_PATTERN_RTL, $s)) { $rtlmode = true; } else { $rtlmode = false; } // get a char width $chrwidth = $this->GetCharWidth(46); // dot character // get array of unicode values $chars = TCPDF_FONTS::UTF8StringToArray($s, $this->isunicode, $this->CurrentFont); // calculate maximum width for a single character on string $chrw = $this->GetArrStringWidth($chars, '', '', 0, true); array_walk($chrw, array($this, 'getRawCharWidth')); $maxchwidth = max($chrw); // get array of chars $uchars = TCPDF_FONTS::UTF8ArrayToUniArray($chars, $this->isunicode); // get the number of characters $nb = count($chars); // replacement for SHY character (minus symbol) $shy_replacement = 45; $shy_replacement_char = TCPDF_FONTS::unichr($shy_replacement, $this->isunicode); // widht for SHY replacement $shy_replacement_width = $this->GetCharWidth($shy_replacement); // max Y $maxy = $this->y + $maxh - $h - $this->cell_padding['T'] - $this->cell_padding['B']; // page width $pw = $w = $this->w - $this->lMargin - $this->rMargin; // calculate remaining line width ($w) if ($this->rtl) { $w = $this->x - $this->lMargin; } else { $w = $this->w - $this->rMargin - $this->x; } // max column width $wmax = ($w - $wadj); if (!$firstline) { $wmax -= ($this->cell_padding['L'] + $this->cell_padding['R']); } if ((!$firstline) AND (($chrwidth > $wmax) OR ($maxchwidth > $wmax))) { // the maximum width character do not fit on column return ''; } // minimum row height $row_height = max($h, $this->FontSize * $this->cell_height_ratio); $start_page = $this->page; $i = 0; // character position $j = 0; // current starting position $sep = -1; // position of the last blank space $shy = false; // true if the last blank is a soft hypen (SHY) $l = 0; // current string length $nl = 0; //number of lines $linebreak = false; $pc = 0; // previous character // for each character while ($i < $nb) { if (($maxh > 0) AND ($this->y >= $maxy) ) { break; } //Get the current character $c = $chars[$i]; if ($c == 10) { // 10 = "\n" = new line //Explicit line break if ($align == 'J') { if ($this->rtl) { $talign = 'R'; } else { $talign = 'L'; } } else { $talign = $align; } $tmpstr = TCPDF_FONTS::UniArrSubString($uchars, $j, $i); if ($firstline) { $startx = $this->x; $tmparr = array_slice($chars, $j, ($i - $j)); if ($rtlmode) { $tmparr = TCPDF_FONTS::utf8Bidi($tmparr, $tmpstr, $this->tmprtl, $this->isunicode, $this->CurrentFont); } $linew = $this->GetArrStringWidth($tmparr); unset($tmparr); if ($this->rtl) { $this->endlinex = $startx - $linew; } else { $this->endlinex = $startx + $linew; } $w = $linew; $tmpcellpadding = $this->cell_padding; if ($maxh == 0) { $this->SetCellPadding(0); } } if ($firstblock AND $this->isRTLTextDir()) { $tmpstr = $this->stringRightTrim($tmpstr); } // Skip newlines at the begining of a page or column if (!empty($tmpstr) OR ($this->y < ($this->PageBreakTrigger - $row_height))) { $this->Cell($w, $h, $tmpstr, 0, 1, $talign, $fill, $link, $stretch); } unset($tmpstr); if ($firstline) { $this->cell_padding = $tmpcellpadding; return (TCPDF_FONTS::UniArrSubString($uchars, $i)); } ++$nl; $j = $i + 1; $l = 0; $sep = -1; $shy = false; // account for margin changes if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND ($this->inPageBody())) { $this->AcceptPageBreak(); if ($this->rtl) { $this->x -= $margin['R']; } else { $this->x += $margin['L']; } $this->lMargin += $margin['L']; $this->rMargin += $margin['R']; } $w = $this->getRemainingWidth(); $wmax = ($w - $this->cell_padding['L'] - $this->cell_padding['R']); } else { // 160 is the non-breaking space. // 173 is SHY (Soft Hypen). // \p{Z} or \p{Separator}: any kind of Unicode whitespace or invisible separator. // \p{Lo} or \p{Other_Letter}: a Unicode letter or ideograph that does not have lowercase and uppercase variants. // \p{Lo} is needed because Chinese characters are packed next to each other without spaces in between. if (($c != 160) AND (($c == 173) OR preg_match($this->re_spaces, TCPDF_FONTS::unichr($c, $this->isunicode)) OR (($c == 45) AND ($i < ($nb - 1)) AND @preg_match('/[\p{L}]/'.$this->re_space['m'], TCPDF_FONTS::unichr($pc, $this->isunicode)) AND @preg_match('/[\p{L}]/'.$this->re_space['m'], TCPDF_FONTS::unichr($chars[($i + 1)], $this->isunicode)) ) ) ) { // update last blank space position $sep = $i; // check if is a SHY if (($c == 173) OR ($c == 45)) { $shy = true; if ($pc == 45) { $tmp_shy_replacement_width = 0; $tmp_shy_replacement_char = ''; } else { $tmp_shy_replacement_width = $shy_replacement_width; $tmp_shy_replacement_char = $shy_replacement_char; } } else { $shy = false; } } // update string length if ($this->isUnicodeFont() AND ($arabic)) { // with bidirectional algorithm some chars may be changed affecting the line length // *** very slow *** $l = $this->GetArrStringWidth(TCPDF_FONTS::utf8Bidi(array_slice($chars, $j, ($i - $j)), '', $this->tmprtl, $this->isunicode, $this->CurrentFont)); } else { $l += $this->GetCharWidth($c); } if (($l > $wmax) OR (($c == 173) AND (($l + $tmp_shy_replacement_width) > $wmax)) ) { // we have reached the end of column if ($sep == -1) { // check if the line was already started if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $this->cell_padding['R'] - $margin['R'] - $chrwidth))) OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $this->cell_padding['L'] + $margin['L'] + $chrwidth)))) { // print a void cell and go to next line $this->Cell($w, $h, '', 0, 1); $linebreak = true; if ($firstline) { return (TCPDF_FONTS::UniArrSubString($uchars, $j)); } } else { // truncate the word because do not fit on column $tmpstr = TCPDF_FONTS::UniArrSubString($uchars, $j, $i); if ($firstline) { $startx = $this->x; $tmparr = array_slice($chars, $j, ($i - $j)); if ($rtlmode) { $tmparr = TCPDF_FONTS::utf8Bidi($tmparr, $tmpstr, $this->tmprtl, $this->isunicode, $this->CurrentFont); } $linew = $this->GetArrStringWidth($tmparr); unset($tmparr); if ($this->rtl) { $this->endlinex = $startx - $linew; } else { $this->endlinex = $startx + $linew; } $w = $linew; $tmpcellpadding = $this->cell_padding; if ($maxh == 0) { $this->SetCellPadding(0); } } if ($firstblock AND $this->isRTLTextDir()) { $tmpstr = $this->stringRightTrim($tmpstr); } $this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch); unset($tmpstr); if ($firstline) { $this->cell_padding = $tmpcellpadding; return (TCPDF_FONTS::UniArrSubString($uchars, $i)); } $j = $i; --$i; } } else { // word wrapping if ($this->rtl AND (!$firstblock) AND ($sep < $i)) { $endspace = 1; } else { $endspace = 0; } // check the length of the next string $strrest = TCPDF_FONTS::UniArrSubString($uchars, ($sep + $endspace)); $nextstr = preg_split('/'.$this->re_space['p'].'/'.$this->re_space['m'], $this->stringTrim($strrest)); if (isset($nextstr[0]) AND ($this->GetStringWidth($nextstr[0]) > $pw)) { // truncate the word because do not fit on a full page width $tmpstr = TCPDF_FONTS::UniArrSubString($uchars, $j, $i); if ($firstline) { $startx = $this->x; $tmparr = array_slice($chars, $j, ($i - $j)); if ($rtlmode) { $tmparr = TCPDF_FONTS::utf8Bidi($tmparr, $tmpstr, $this->tmprtl, $this->isunicode, $this->CurrentFont); } $linew = $this->GetArrStringWidth($tmparr); unset($tmparr); if ($this->rtl) { $this->endlinex = ($startx - $linew); } else { $this->endlinex = ($startx + $linew); } $w = $linew; $tmpcellpadding = $this->cell_padding; if ($maxh == 0) { $this->SetCellPadding(0); } } if ($firstblock AND $this->isRTLTextDir()) { $tmpstr = $this->stringRightTrim($tmpstr); } $this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch); unset($tmpstr); if ($firstline) { $this->cell_padding = $tmpcellpadding; return (TCPDF_FONTS::UniArrSubString($uchars, $i)); } $j = $i; --$i; } else { // word wrapping if ($shy) { // add hypen (minus symbol) at the end of the line $shy_width = $tmp_shy_replacement_width; if ($this->rtl) { $shy_char_left = $tmp_shy_replacement_char; $shy_char_right = ''; } else { $shy_char_left = ''; $shy_char_right = $tmp_shy_replacement_char; } } else { $shy_width = 0; $shy_char_left = ''; $shy_char_right = ''; } $tmpstr = TCPDF_FONTS::UniArrSubString($uchars, $j, ($sep + $endspace)); if ($firstline) { $startx = $this->x; $tmparr = array_slice($chars, $j, (($sep + $endspace) - $j)); if ($rtlmode) { $tmparr = TCPDF_FONTS::utf8Bidi($tmparr, $tmpstr, $this->tmprtl, $this->isunicode, $this->CurrentFont); } $linew = $this->GetArrStringWidth($tmparr); unset($tmparr); if ($this->rtl) { $this->endlinex = $startx - $linew - $shy_width; } else { $this->endlinex = $startx + $linew + $shy_width; } $w = $linew; $tmpcellpadding = $this->cell_padding; if ($maxh == 0) { $this->SetCellPadding(0); } } // print the line if ($firstblock AND $this->isRTLTextDir()) { $tmpstr = $this->stringRightTrim($tmpstr); } $this->Cell($w, $h, $shy_char_left.$tmpstr.$shy_char_right, 0, 1, $align, $fill, $link, $stretch); unset($tmpstr); if ($firstline) { if ($chars[$sep] == 45) { $endspace += 1; } // return the remaining text $this->cell_padding = $tmpcellpadding; return (TCPDF_FONTS::UniArrSubString($uchars, ($sep + $endspace))); } $i = $sep; $sep = -1; $shy = false; $j = ($i + 1); } } // account for margin changes if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND ($this->inPageBody())) { $this->AcceptPageBreak(); if ($this->rtl) { $this->x -= $margin['R']; } else { $this->x += $margin['L']; } $this->lMargin += $margin['L']; $this->rMargin += $margin['R']; } $w = $this->getRemainingWidth(); $wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R']; if ($linebreak) { $linebreak = false; } else { ++$nl; $l = 0; } } } // save last character $pc = $c; ++$i; } // end while i < nb // print last substring (if any) if ($l > 0) { switch ($align) { case 'J': case 'C': { $w = $w; break; } case 'L': { if ($this->rtl) { $w = $w; } else { $w = $l; } break; } case 'R': { if ($this->rtl) { $w = $l; } else { $w = $w; } break; } default: { $w = $l; break; } } $tmpstr = TCPDF_FONTS::UniArrSubString($uchars, $j, $nb); if ($firstline) { $startx = $this->x; $tmparr = array_slice($chars, $j, ($nb - $j)); if ($rtlmode) { $tmparr = TCPDF_FONTS::utf8Bidi($tmparr, $tmpstr, $this->tmprtl, $this->isunicode, $this->CurrentFont); } $linew = $this->GetArrStringWidth($tmparr); unset($tmparr); if ($this->rtl) { $this->endlinex = $startx - $linew; } else { $this->endlinex = $startx + $linew; } $w = $linew; $tmpcellpadding = $this->cell_padding; if ($maxh == 0) { $this->SetCellPadding(0); } } if ($firstblock AND $this->isRTLTextDir()) { $tmpstr = $this->stringRightTrim($tmpstr); } $this->Cell($w, $h, $tmpstr, 0, $ln, $align, $fill, $link, $stretch); unset($tmpstr); if ($firstline) { $this->cell_padding = $tmpcellpadding; return (TCPDF_FONTS::UniArrSubString($uchars, $nb)); } ++$nl; } if ($firstline) { return ''; } return $nl; } /** * Returns the remaining width between the current position and margins. * @return int Return the remaining width * @protected */ protected function getRemainingWidth() { list($this->x, $this->y) = $this->checkPageRegions(0, $this->x, $this->y); if ($this->rtl) { return ($this->x - $this->lMargin); } else { return ($this->w - $this->rMargin - $this->x); } } /** * Set the block dimensions accounting for page breaks and page/column fitting * @param $w (float) width * @param $h (float) height * @param $x (float) X coordinate * @param $y (float) Y coodiante * @param $fitonpage (boolean) if true the block is resized to not exceed page dimensions. * @return array($w, $h, $x, $y) * @protected * @since 5.5.009 (2010-07-05) */ protected function fitBlock($w, $h, $x, $y, $fitonpage=false) { if ($w <= 0) { // set maximum width $w = ($this->w - $this->lMargin - $this->rMargin); } if ($h <= 0) { // set maximum height $h = ($this->PageBreakTrigger - $this->tMargin); } // resize the block to be vertically contained on a single page or single column if ($fitonpage OR $this->AutoPageBreak) { $ratio_wh = ($w / $h); if ($h > ($this->PageBreakTrigger - $this->tMargin)) { $h = $this->PageBreakTrigger - $this->tMargin; $w = ($h * $ratio_wh); } // resize the block to be horizontally contained on a single page or single column if ($fitonpage) { $maxw = ($this->w - $this->lMargin - $this->rMargin); if ($w > $maxw) { $w = $maxw; $h = ($w / $ratio_wh); } } } // Check whether we need a new page or new column first as this does not fit $prev_x = $this->x; $prev_y = $this->y; if ($this->checkPageBreak($h, $y) OR ($this->y < $prev_y)) { $y = $this->y; if ($this->rtl) { $x += ($prev_x - $this->x); } else { $x += ($this->x - $prev_x); } $this->newline = true; } // resize the block to be contained on the remaining available page or column space if ($fitonpage) { $ratio_wh = ($w / $h); if (($y + $h) > $this->PageBreakTrigger) { $h = $this->PageBreakTrigger - $y; $w = ($h * $ratio_wh); } if ((!$this->rtl) AND (($x + $w) > ($this->w - $this->rMargin))) { $w = $this->w - $this->rMargin - $x; $h = ($w / $ratio_wh); } elseif (($this->rtl) AND (($x - $w) < ($this->lMargin))) { $w = $x - $this->lMargin; $h = ($w / $ratio_wh); } } return array($w, $h, $x, $y); } /** * Puts an image in the page. * The upper-left corner must be given. * The dimensions can be specified in different ways:<ul> * <li>explicit width and height (expressed in user unit)</li> * <li>one explicit dimension, the other being calculated automatically in order to keep the original proportions</li> * <li>no explicit dimension, in which case the image is put at 72 dpi</li></ul> * Supported formats are JPEG and PNG images whitout GD library and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM; * The format can be specified explicitly or inferred from the file extension.<br /> * It is possible to put a link on the image.<br /> * Remark: if an image is used several times, only one copy will be embedded in the file.<br /> * @param $file (string) Name of the file containing the image or a '@' character followed by the image data string. To link an image without embedding it on the document, set an asterisk character before the URL (i.e.: '*http://www.example.com/image.jpg'). * @param $x (float) Abscissa of the upper-left corner (LTR) or upper-right corner (RTL). * @param $y (float) Ordinate of the upper-left corner (LTR) or upper-right corner (RTL). * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $type (string) Image format. Possible values are (case insensitive): JPEG and PNG (whitout GD library) and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM;. If not specified, the type is inferred from the file extension. * @param $link (mixed) URL or identifier returned by AddLink(). * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul> * @param $resize (mixed) If true resize (reduce) the image to fit $w and $h (requires GD or ImageMagick library); if false do not resize; if 2 force resize in all cases (upscaling and downscaling). * @param $dpi (int) dot-per-inch resolution used on resize * @param $palign (string) Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul> * @param $ismask (boolean) true if this image is a mask, false otherwise * @param $imgmask (mixed) image object returned by this function or false * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $fitbox (mixed) If not false scale image dimensions proportionally to fit within the ($w, $h) box. $fitbox can be true or a 2 characters string indicating the image alignment inside the box. The first character indicate the horizontal alignment (L = left, C = center, R = right) the second character indicate the vertical algnment (T = top, M = middle, B = bottom). * @param $hidden (boolean) If true do not display the image. * @param $fitonpage (boolean) If true the image is resized to not exceed page dimensions. * @param $alt (boolean) If true the image will be added as alternative and not directly printed (the ID of the image will be returned). * @param $altimgs (array) Array of alternate images IDs. Each alternative image must be an array with two values: an integer representing the image ID (the value returned by the Image method) and a boolean value to indicate if the image is the default for printing. * @return image information * @public * @since 1.1 */ public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array()) { if ($this->state != 2) { return; } if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); $exurl = ''; // external streams // check if we are passing an image as file or string if ($file[0] === '@') { // image from string $imgdata = substr($file, 1); } else { // image file if ($file{0} === '*') { // image as external stream $file = substr($file, 1); $exurl = $file; } // check if is local file if (!@file_exists($file)) { // encode spaces on filename (file is probably an URL) $file = str_replace(' ', '%20', $file); } if (@file_exists($file)) { // get image dimensions $imsize = @getimagesize($file); } else { $imsize = FALSE; } if ($imsize === FALSE) { if (function_exists('curl_init')) { // try to get remote file data using cURL $cs = curl_init(); // curl session curl_setopt($cs, CURLOPT_URL, $file); curl_setopt($cs, CURLOPT_BINARYTRANSFER, true); curl_setopt($cs, CURLOPT_FAILONERROR, true); curl_setopt($cs, CURLOPT_RETURNTRANSFER, true); if ((ini_get('open_basedir') == '') AND (!ini_get('safe_mode'))) { curl_setopt($cs, CURLOPT_FOLLOWLOCATION, true); } curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($cs, CURLOPT_TIMEOUT, 30); curl_setopt($cs, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($cs, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($cs, CURLOPT_USERAGENT, 'TCPDF'); $imgdata = curl_exec($cs); curl_close($cs); } else { $imgdata = @file_get_contents($file); } } } if (isset($imgdata) AND ($imgdata !== FALSE)) { // copy image to cache $file = TCPDF_STATIC::getObjFilename('img'); $fp = fopen($file, 'w'); fwrite($fp, $imgdata); fclose($fp); unset($imgdata); $imsize = @getimagesize($file); if ($imsize === FALSE) { unlink($file); } else { $this->cached_files[] = $file; } } if ($imsize === FALSE) { if (($w > 0) AND ($h > 0)) { // get measures from specified data $pw = $this->getHTMLUnitToUnits($w, 0, $this->pdfunit, true) * $this->imgscale * $this->k; $ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k; $imsize = array($pw, $ph); } else { $this->Error('[Image] Unable to get image: '.$file); } } // file hash $filehash = md5($this->file_id.$file); // get original image width and height in pixels list($pixw, $pixh) = $imsize; // calculate image width and height on document if (($w <= 0) AND ($h <= 0)) { // convert image size to document unit $w = $this->pixelsToUnits($pixw); $h = $this->pixelsToUnits($pixh); } elseif ($w <= 0) { $w = $h * $pixw / $pixh; } elseif ($h <= 0) { $h = $w * $pixh / $pixw; } elseif (($fitbox !== false) AND ($w > 0) AND ($h > 0)) { if (strlen($fitbox) !== 2) { // set default alignment $fitbox = '--'; } // scale image dimensions proportionally to fit within the ($w, $h) box if ((($w * $pixh) / ($h * $pixw)) < 1) { // store current height $oldh = $h; // calculate new height $h = $w * $pixh / $pixw; // height difference $hdiff = ($oldh - $h); // vertical alignment switch (strtoupper($fitbox{1})) { case 'T': { break; } case 'M': { $y += ($hdiff / 2); break; } case 'B': { $y += $hdiff; break; } } } else { // store current width $oldw = $w; // calculate new width $w = $h * $pixw / $pixh; // width difference $wdiff = ($oldw - $w); // horizontal alignment switch (strtoupper($fitbox{0})) { case 'L': { if ($this->rtl) { $x -= $wdiff; } break; } case 'C': { if ($this->rtl) { $x -= ($wdiff / 2); } else { $x += ($wdiff / 2); } break; } case 'R': { if (!$this->rtl) { $x += $wdiff; } break; } } } } // fit the image on available space list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage); // calculate new minimum dimensions in pixels $neww = round($w * $this->k * $dpi / $this->dpi); $newh = round($h * $this->k * $dpi / $this->dpi); // check if resize is necessary (resize is used only to reduce the image) $newsize = ($neww * $newh); $pixsize = ($pixw * $pixh); if (intval($resize) == 2) { $resize = true; } elseif ($newsize >= $pixsize) { $resize = false; } // check if image has been already added on document $newimage = true; if (in_array($file, $this->imagekeys)) { $newimage = false; // get existing image data $info = $this->getImageBuffer($file); if (substr($file, 0, -34) != K_PATH_CACHE.'msk') { // check if the newer image is larger $oldsize = ($info['w'] * $info['h']); if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) { $newimage = true; } } } elseif (substr($file, 0, -34) != K_PATH_CACHE.'msk') { // check for cached images with alpha channel $tempfile_plain = K_PATH_CACHE.'mskp_'.$filehash; $tempfile_alpha = K_PATH_CACHE.'mska_'.$filehash; if (in_array($tempfile_plain, $this->imagekeys)) { // get existing image data $info = $this->getImageBuffer($tempfile_plain); // check if the newer image is larger $oldsize = ($info['w'] * $info['h']); if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) { $newimage = true; } else { $newimage = false; // embed mask image $imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false); // embed image, masked with previously embedded mask return $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask); } } } if ($newimage) { //First use of image, get info $type = strtolower($type); if ($type == '') { $type = TCPDF_IMAGES::getImageFileType($file, $imsize); } elseif ($type == 'jpg') { $type = 'jpeg'; } $mqr = TCPDF_STATIC::get_mqr(); TCPDF_STATIC::set_mqr(false); // Specific image handlers (defined on TCPDF_IMAGES CLASS) $mtd = '_parse'.$type; // GD image handler function $gdfunction = 'imagecreatefrom'.$type; $info = false; if ((method_exists('TCPDF_IMAGES', $mtd)) AND (!($resize AND (function_exists($gdfunction) OR extension_loaded('imagick'))))) { // TCPDF image functions $info = TCPDF_IMAGES::$mtd($file); if ($info == 'pngalpha') { return $this->ImagePngAlpha($file, $x, $y, $pixw, $pixh, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign, $filehash); } } if (!$info) { if (function_exists($gdfunction)) { // GD library $img = $gdfunction($file); if ($resize) { $imgr = imagecreatetruecolor($neww, $newh); if (($type == 'gif') OR ($type == 'png')) { $imgr = TCPDF_IMAGES::setGDImageTransparency($imgr, $img); } imagecopyresampled($imgr, $img, 0, 0, 0, 0, $neww, $newh, $pixw, $pixh); if (($type == 'gif') OR ($type == 'png')) { $info = TCPDF_IMAGES::_toPNG($imgr); } else { $info = TCPDF_IMAGES::_toJPEG($imgr, $this->jpeg_quality); } } else { if (($type == 'gif') OR ($type == 'png')) { $info = TCPDF_IMAGES::_toPNG($img); } else { $info = TCPDF_IMAGES::_toJPEG($img, $this->jpeg_quality); } } } elseif (extension_loaded('imagick')) { // ImageMagick library $img = new Imagick(); if ($type == 'SVG') { // get SVG file content $svgimg = file_get_contents($file); // get width and height $regs = array(); if (preg_match('/<svg([^\>]*)>/si', $svgimg, $regs)) { $svgtag = $regs[1]; $tmp = array(); if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) { $ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); $owu = sprintf('%F', ($ow * $dpi / 72)).$this->pdfunit; $svgtag = preg_replace('/[\s]+width[\s]*=[\s]*"[^"]*"/si', ' width="'.$owu.'"', $svgtag, 1); } else { $ow = $w; } $tmp = array(); if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) { $oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); $ohu = sprintf('%F', ($oh * $dpi / 72)).$this->pdfunit; $svgtag = preg_replace('/[\s]+height[\s]*=[\s]*"[^"]*"/si', ' height="'.$ohu.'"', $svgtag, 1); } else { $oh = $h; } $tmp = array(); if (!preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $svgtag, $tmp)) { $vbw = ($ow * $this->imgscale * $this->k); $vbh = ($oh * $this->imgscale * $this->k); $vbox = sprintf(' viewBox="0 0 %F %F" ', $vbw, $vbh); $svgtag = $vbox.$svgtag; } $svgimg = preg_replace('/<svg([^\>]*)>/si', '<svg'.$svgtag.'>', $svgimg, 1); } $img->readImageBlob($svgimg); } else { $img->readImage($file); } if ($resize) { $img->resizeImage($neww, $newh, 10, 1, false); } $img->setCompressionQuality($this->jpeg_quality); $img->setImageFormat('jpeg'); $tempname = TCPDF_STATIC::getObjFilename('jpg'); $img->writeImage($tempname); $info = TCPDF_IMAGES::_parsejpeg($tempname); unlink($tempname); $img->destroy(); } else { return; } } if ($info === false) { //If false, we cannot process image return; } TCPDF_STATIC::set_mqr($mqr); if ($ismask) { // force grayscale $info['cs'] = 'DeviceGray'; } if ($imgmask !== false) { $info['masked'] = $imgmask; } if (!empty($exurl)) { $info['exurl'] = $exurl; } // array of alternative images $info['altimgs'] = $altimgs; // add image to document $info['i'] = $this->setImageBuffer($file, $info); } // set alignment $this->img_rb_y = $y + $h; // set alignment if ($this->rtl) { if ($palign == 'L') { $ximg = $this->lMargin; } elseif ($palign == 'C') { $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $ximg = $this->w - $this->rMargin - $w; } else { $ximg = $x - $w; } $this->img_rb_x = $ximg; } else { if ($palign == 'L') { $ximg = $this->lMargin; } elseif ($palign == 'C') { $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $ximg = $this->w - $this->rMargin - $w; } else { $ximg = $x; } $this->img_rb_x = $ximg + $w; } if ($ismask OR $hidden) { // image is not displayed return $info['i']; } $xkimg = $ximg * $this->k; if (!$alt) { // only non-alternative immages will be set $this->_out(sprintf('q %F 0 0 %F %F %F cm /I%u Do Q', ($w * $this->k), ($h * $this->k), $xkimg, (($this->h - ($y + $h)) * $this->k), $info['i'])); } if (!empty($border)) { $bx = $this->x; $by = $this->y; $this->x = $ximg; if ($this->rtl) { $this->x += $w; } $this->y = $y; $this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true); $this->x = $bx; $this->y = $by; } if ($link) { $this->Link($ximg, $y, $w, $h, $link, 0); } // set pointer to align the next text/objects switch($align) { case 'T': { $this->y = $y; $this->x = $this->img_rb_x; break; } case 'M': { $this->y = $y + round($h/2); $this->x = $this->img_rb_x; break; } case 'B': { $this->y = $this->img_rb_y; $this->x = $this->img_rb_x; break; } case 'N': { $this->SetY($this->img_rb_y); break; } default:{ break; } } $this->endlinex = $this->img_rb_x; if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['images'][] = $info['i']; } return $info['i']; } /** * Extract info from a PNG image with alpha channel using the GD library. * @param $file (string) Name of the file containing the image. * @param $x (float) Abscissa of the upper-left corner. * @param $y (float) Ordinate of the upper-left corner. * @param $wpx (float) Original width of the image in pixels. * @param $hpx (float) original height of the image in pixels. * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $type (string) Image format. Possible values are (case insensitive): JPEG and PNG (whitout GD library) and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM;. If not specified, the type is inferred from the file extension. * @param $link (mixed) URL or identifier returned by AddLink(). * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul> * @param $resize (boolean) If true resize (reduce) the image to fit $w and $h (requires GD library). * @param $dpi (int) dot-per-inch resolution used on resize * @param $palign (string) Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul> * @param $filehash (string) File hash used to build unique file names. * @author Nicola Asuni * @protected * @since 4.3.007 (2008-12-04) * @see Image() */ protected function ImagePngAlpha($file, $x, $y, $wpx, $hpx, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $filehash='') { if (empty($filehash)) { $filehash = md5($this->file_id.$file); } // create temp image file (without alpha channel) $tempfile_plain = K_PATH_CACHE.'mskp_'.$filehash; // create temp alpha file $tempfile_alpha = K_PATH_CACHE.'mska_'.$filehash; if (extension_loaded('imagick')) { // ImageMagick extension // ImageMagick library $img = new Imagick(); $img->readImage($file); // clone image object $imga = TCPDF_STATIC::objclone($img); // extract alpha channel if (method_exists($img, 'setImageAlphaChannel') AND defined('Imagick::ALPHACHANNEL_EXTRACT')) { $img->setImageAlphaChannel(Imagick::ALPHACHANNEL_EXTRACT); } else { $img->separateImageChannel(8); // 8 = (imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE); $img->negateImage(true); } $img->setImageFormat('png'); $img->writeImage($tempfile_alpha); // remove alpha channel if (method_exists($imga, 'setImageMatte')) { $imga->setImageMatte(false); } else { $imga->separateImageChannel(39); // 39 = (imagick::CHANNEL_ALL & ~(imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE)); } $imga->setImageFormat('png'); $imga->writeImage($tempfile_plain); } elseif (function_exists('imagecreatefrompng')) { // GD extension // generate images $img = imagecreatefrompng($file); $imgalpha = imagecreate($wpx, $hpx); // generate gray scale palette (0 -> 255) for ($c = 0; $c < 256; ++$c) { ImageColorAllocate($imgalpha, $c, $c, $c); } // extract alpha channel for ($xpx = 0; $xpx < $wpx; ++$xpx) { for ($ypx = 0; $ypx < $hpx; ++$ypx) { $color = imagecolorat($img, $xpx, $ypx); $alpha = $this->getGDgamma($color); // correct gamma imagesetpixel($imgalpha, $xpx, $ypx, $alpha); } } imagepng($imgalpha, $tempfile_alpha); imagedestroy($imgalpha); // extract image without alpha channel $imgplain = imagecreatetruecolor($wpx, $hpx); imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx); imagepng($imgplain, $tempfile_plain); imagedestroy($imgplain); } else { $this->Error('TCPDF requires the Imagick or GD extension to handle PNG images with alpha channel.'); } // embed mask image $imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false); // embed image, masked with previously embedded mask $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask); // remove temp files unlink($tempfile_alpha); unlink($tempfile_plain); } /** * Get the GD-corrected PNG gamma value from alpha color * @param $c (int) alpha color * @protected * @since 4.3.007 (2008-12-04) */ protected function getGDgamma($c) { if (!isset($this->gdgammacache["'".$c."'"])) { // shifts off the first 24 bits (where 8x3 are used for each color), // and returns the remaining 7 allocated bits (commonly used for alpha) $alpha = ($c >> 24); // GD alpha is only 7 bit (0 -> 127) $alpha = (((127 - $alpha) / 127) * 255); // correct gamma $this->gdgammacache["'".$c."'"] = (pow(($alpha / 255), 2.2) * 255); // store the latest values on cache to improve performances if (count($this->gdgammacache) > 8) { // remove one element from the cache array array_shift($this->gdgammacache); } } return $this->gdgammacache["'".$c."'"]; } /** * Performs a line break. * The current abscissa goes back to the left margin and the ordinate increases by the amount passed in parameter. * @param $h (float) The height of the break. By default, the value equals the height of the last printed cell. * @param $cell (boolean) if true add the current left (or right o for RTL) padding to the X coordinate * @public * @since 1.0 * @see Cell() */ public function Ln($h='', $cell=false) { if (($this->num_columns > 1) AND ($this->y == $this->columns[$this->current_column]['y']) AND isset($this->columns[$this->current_column]['x']) AND ($this->x == $this->columns[$this->current_column]['x'])) { // revove vertical space from the top of the column return; } if ($cell) { if ($this->rtl) { $cellpadding = $this->cell_padding['R']; } else { $cellpadding = $this->cell_padding['L']; } } else { $cellpadding = 0; } if ($this->rtl) { $this->x = $this->w - $this->rMargin - $cellpadding; } else { $this->x = $this->lMargin + $cellpadding; } if (is_string($h)) { $this->y += $this->lasth; } else { $this->y += $h; } $this->newline = true; } /** * Returns the relative X value of current position. * The value is relative to the left border for LTR languages and to the right border for RTL languages. * @return float * @public * @since 1.2 * @see SetX(), GetY(), SetY() */ public function GetX() { //Get x position if ($this->rtl) { return ($this->w - $this->x); } else { return $this->x; } } /** * Returns the absolute X value of current position. * @return float * @public * @since 1.2 * @see SetX(), GetY(), SetY() */ public function GetAbsX() { return $this->x; } /** * Returns the ordinate of the current position. * @return float * @public * @since 1.0 * @see SetY(), GetX(), SetX() */ public function GetY() { return $this->y; } /** * Defines the abscissa of the current position. * If the passed value is negative, it is relative to the right of the page (or left if language is RTL). * @param $x (float) The value of the abscissa in user units. * @param $rtloff (boolean) if true always uses the page top-left corner as origin of axis. * @public * @since 1.2 * @see GetX(), GetY(), SetY(), SetXY() */ public function SetX($x, $rtloff=false) { $x = floatval($x); if (!$rtloff AND $this->rtl) { if ($x >= 0) { $this->x = $this->w - $x; } else { $this->x = abs($x); } } else { if ($x >= 0) { $this->x = $x; } else { $this->x = $this->w + $x; } } if ($this->x < 0) { $this->x = 0; } if ($this->x > $this->w) { $this->x = $this->w; } } /** * Moves the current abscissa back to the left margin and sets the ordinate. * If the passed value is negative, it is relative to the bottom of the page. * @param $y (float) The value of the ordinate in user units. * @param $resetx (bool) if true (default) reset the X position. * @param $rtloff (boolean) if true always uses the page top-left corner as origin of axis. * @public * @since 1.0 * @see GetX(), GetY(), SetY(), SetXY() */ public function SetY($y, $resetx=true, $rtloff=false) { $y = floatval($y); if ($resetx) { //reset x if (!$rtloff AND $this->rtl) { $this->x = $this->w - $this->rMargin; } else { $this->x = $this->lMargin; } } if ($y >= 0) { $this->y = $y; } else { $this->y = $this->h + $y; } if ($this->y < 0) { $this->y = 0; } if ($this->y > $this->h) { $this->y = $this->h; } } /** * Defines the abscissa and ordinate of the current position. * If the passed values are negative, they are relative respectively to the right and bottom of the page. * @param $x (float) The value of the abscissa. * @param $y (float) The value of the ordinate. * @param $rtloff (boolean) if true always uses the page top-left corner as origin of axis. * @public * @since 1.2 * @see SetX(), SetY() */ public function SetXY($x, $y, $rtloff=false) { $this->SetY($y, false, $rtloff); $this->SetX($x, $rtloff); } /** * Set the absolute X coordinate of the current pointer. * @param $x (float) The value of the abscissa in user units. * @public * @since 5.9.186 (2012-09-13) * @see setAbsX(), setAbsY(), SetAbsXY() */ public function SetAbsX($x) { $this->x = floatval($x); } /** * Set the absolute Y coordinate of the current pointer. * @param $y (float) (float) The value of the ordinate in user units. * @public * @since 5.9.186 (2012-09-13) * @see setAbsX(), setAbsY(), SetAbsXY() */ public function SetAbsY($y) { $this->y = floatval($y); } /** * Set the absolute X and Y coordinates of the current pointer. * @param $x (float) The value of the abscissa in user units. * @param $y (float) (float) The value of the ordinate in user units. * @public * @since 5.9.186 (2012-09-13) * @see setAbsX(), setAbsY(), SetAbsXY() */ public function SetAbsXY($x, $y) { $this->SetAbsX($x); $this->SetAbsY($y); } /** * Send the document to a given destination: string, local file or browser. * In the last case, the plug-in may be used (if present) or a download ("Save as" dialog box) may be forced.<br /> * The method first calls Close() if necessary to terminate the document. * @param $name (string) The name of the file when saved. Note that special characters are removed and blanks characters are replaced with the underscore character. * @param $dest (string) Destination where to send the document. It can take one of the following values:<ul><li>I: send the file inline to the browser (default). The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.</li><li>D: send to the browser and force a file download with the name given by name.</li><li>F: save to a local server file with the name given by name.</li><li>S: return the document as a string (name is ignored).</li><li>FI: equivalent to F + I option</li><li>FD: equivalent to F + D option</li><li>E: return the document as base64 mime multi-part email attachment (RFC 2045)</li></ul> * @public * @since 1.0 * @see Close() */ public function Output($name='doc.pdf', $dest='I') { //Output PDF to some destination //Finish document if necessary if ($this->state < 3) { $this->Close(); } //Normalize parameters if (is_bool($dest)) { $dest = $dest ? 'D' : 'F'; } $dest = strtoupper($dest); if ($dest{0} != 'F') { $name = preg_replace('/[\s]+/', '_', $name); $name = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $name); } if ($this->sign) { // *** apply digital signature to the document *** // get the document content $pdfdoc = $this->getBuffer(); // remove last newline $pdfdoc = substr($pdfdoc, 0, -1); // Remove the original buffer if (isset($this->diskcache) AND $this->diskcache) { // remove buffer file from cache unlink($this->buffer); } unset($this->buffer); // remove filler space $byterange_string_len = strlen(TCPDF_STATIC::$byterange_string); // define the ByteRange $byte_range = array(); $byte_range[0] = 0; $byte_range[1] = strpos($pdfdoc, TCPDF_STATIC::$byterange_string) + $byterange_string_len + 10; $byte_range[2] = $byte_range[1] + $this->signature_max_length + 2; $byte_range[3] = strlen($pdfdoc) - $byte_range[2]; $pdfdoc = substr($pdfdoc, 0, $byte_range[1]).substr($pdfdoc, $byte_range[2]); // replace the ByteRange $byterange = sprintf('/ByteRange[0 %u %u %u]', $byte_range[1], $byte_range[2], $byte_range[3]); $byterange .= str_repeat(' ', ($byterange_string_len - strlen($byterange))); $pdfdoc = str_replace(TCPDF_STATIC::$byterange_string, $byterange, $pdfdoc); // write the document to a temporary folder $tempdoc = TCPDF_STATIC::getObjFilename('tmppdf'); $f = fopen($tempdoc, 'wb'); if (!$f) { $this->Error('Unable to create temporary file: '.$tempdoc); } $pdfdoc_length = strlen($pdfdoc); fwrite($f, $pdfdoc, $pdfdoc_length); fclose($f); // get digital signature via openssl library $tempsign = TCPDF_STATIC::getObjFilename('tmpsig'); if (empty($this->signature_data['extracerts'])) { openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED); } else { openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']); } unlink($tempdoc); // read signature $signature = file_get_contents($tempsign); unlink($tempsign); // extract signature $signature = substr($signature, $pdfdoc_length); $signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13)); $tmparr = explode("\n\n", $signature); $signature = $tmparr[1]; unset($tmparr); // decode signature $signature = base64_decode(trim($signature)); // convert signature to hex $signature = current(unpack('H*', $signature)); $signature = str_pad($signature, $this->signature_max_length, '0'); // disable disk caching $this->diskcache = false; // Add signature to the document $this->buffer = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, $byte_range[1]); $this->bufferlen = strlen($this->buffer); } switch($dest) { case 'I': { // Send PDF to the standard output if (ob_get_contents()) { $this->Error('Some data has already been output, can\'t send PDF file'); } if (php_sapi_name() != 'cli') { // send output to a browser header('Content-Type: application/pdf'); if (headers_sent()) { $this->Error('Some data has already been output to browser, can\'t send PDF file'); } header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1'); //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1 header('Pragma: public'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); header('Content-Disposition: inline; filename="'.basename($name).'"'); TCPDF_STATIC::sendOutputData($this->getBuffer(), $this->bufferlen); } else { echo $this->getBuffer(); } break; } case 'D': { // download PDF as file if (ob_get_contents()) { $this->Error('Some data has already been output, can\'t send PDF file'); } header('Content-Description: File Transfer'); if (headers_sent()) { $this->Error('Some data has already been output to browser, can\'t send PDF file'); } header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1'); //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1 header('Pragma: public'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // force download dialog if (strpos(php_sapi_name(), 'cgi') === false) { header('Content-Type: application/force-download'); header('Content-Type: application/octet-stream', false); header('Content-Type: application/download', false); header('Content-Type: application/pdf', false); } else { header('Content-Type: application/pdf'); } // use the Content-Disposition header to supply a recommended filename header('Content-Disposition: attachment; filename="'.basename($name).'"'); header('Content-Transfer-Encoding: binary'); TCPDF_STATIC::sendOutputData($this->getBuffer(), $this->bufferlen); break; } case 'F': case 'FI': case 'FD': { // save PDF to a local file if ($this->diskcache) { copy($this->buffer, $name); } else { $f = fopen($name, 'wb'); if (!$f) { $this->Error('Unable to create output file: '.$name); } fwrite($f, $this->getBuffer(), $this->bufferlen); fclose($f); } if ($dest == 'FI') { // send headers to browser header('Content-Type: application/pdf'); header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1'); //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1 header('Pragma: public'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); header('Content-Disposition: inline; filename="'.basename($name).'"'); TCPDF_STATIC::sendOutputData(file_get_contents($name), filesize($name)); } elseif ($dest == 'FD') { // send headers to browser if (ob_get_contents()) { $this->Error('Some data has already been output, can\'t send PDF file'); } header('Content-Description: File Transfer'); if (headers_sent()) { $this->Error('Some data has already been output to browser, can\'t send PDF file'); } header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1'); header('Pragma: public'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // force download dialog if (strpos(php_sapi_name(), 'cgi') === false) { header('Content-Type: application/force-download'); header('Content-Type: application/octet-stream', false); header('Content-Type: application/download', false); header('Content-Type: application/pdf', false); } else { header('Content-Type: application/pdf'); } // use the Content-Disposition header to supply a recommended filename header('Content-Disposition: attachment; filename="'.basename($name).'"'); header('Content-Transfer-Encoding: binary'); TCPDF_STATIC::sendOutputData(file_get_contents($name), filesize($name)); } break; } case 'E': { // return PDF as base64 mime multi-part email attachment (RFC 2045) $retval = 'Content-Type: application/pdf;'."\r\n"; $retval .= ' name="'.$name.'"'."\r\n"; $retval .= 'Content-Transfer-Encoding: base64'."\r\n"; $retval .= 'Content-Disposition: attachment;'."\r\n"; $retval .= ' filename="'.$name.'"'."\r\n\r\n"; $retval .= chunk_split(base64_encode($this->getBuffer()), 76, "\r\n"); return $retval; } case 'S': { // returns PDF as a string return $this->getBuffer(); } default: { $this->Error('Incorrect output destination: '.$dest); } } return ''; } /** * Unset all class variables except the following critical variables. * @param $destroyall (boolean) if true destroys all class variables, otherwise preserves critical variables. * @param $preserve_objcopy (boolean) if true preserves the objcopy variable * @public * @since 4.5.016 (2009-02-24) */ public function _destroy($destroyall=false, $preserve_objcopy=false) { if ($destroyall AND isset($this->diskcache) AND $this->diskcache AND (!$preserve_objcopy) AND (!TCPDF_STATIC::empty_string($this->buffer))) { // remove buffer file from cache unlink($this->buffer); } if ($destroyall AND isset($this->cached_files) AND !empty($this->cached_files)) { // remove cached files foreach ($this->cached_files as $cachefile) { if (is_file($cachefile)) { unlink($cachefile); } } unset($this->cached_files); } foreach (array_keys(get_object_vars($this)) as $val) { if ($destroyall OR ( ($val != 'internal_encoding') AND ($val != 'state') AND ($val != 'bufferlen') AND ($val != 'buffer') AND ($val != 'diskcache') AND ($val != 'cached_files') AND ($val != 'sign') AND ($val != 'signature_data') AND ($val != 'signature_max_length') AND ($val != 'byterange_string') )) { if ((!$preserve_objcopy OR ($val != 'objcopy')) AND isset($this->$val)) { unset($this->$val); } } } } /** * Check for locale-related bug * @protected */ protected function _dochecks() { //Check for locale-related bug if (1.1 == 1) { $this->Error('Don\'t alter the locale before including class file'); } //Check for decimal separator if (sprintf('%.1F', 1.0) != '1.0') { setlocale(LC_NUMERIC, 'C'); } } /** * Return an array containing variations for the basic page number alias. * @param $a (string) Base alias. * @return array of page number aliases * @protected */ protected function getInternalPageNumberAliases($a= '') { $alias = array(); // build array of Unicode + ASCII variants (the order is important) $alias = array('u' => array(), 'a' => array()); $u = '{'.$a.'}'; $alias['u'][] = TCPDF_STATIC::_escape($u); if ($this->isunicode) { $alias['u'][] = TCPDF_STATIC::_escape(TCPDF_FONTS::UTF8ToLatin1($u, $this->isunicode, $this->CurrentFont)); $alias['u'][] = TCPDF_STATIC::_escape(TCPDF_FONTS::utf8StrRev($u, false, $this->tmprtl, $this->isunicode, $this->CurrentFont)); $alias['a'][] = TCPDF_STATIC::_escape(TCPDF_FONTS::UTF8ToLatin1($a, $this->isunicode, $this->CurrentFont)); $alias['a'][] = TCPDF_STATIC::_escape(TCPDF_FONTS::utf8StrRev($a, false, $this->tmprtl, $this->isunicode, $this->CurrentFont)); } $alias['a'][] = TCPDF_STATIC::_escape($a); return $alias; } /** * Return an array containing all internal page aliases. * @return array of page number aliases * @protected */ protected function getAllInternalPageNumberAliases() { $basic_alias = array(TCPDF_STATIC::$alias_tot_pages, TCPDF_STATIC::$alias_num_page, TCPDF_STATIC::$alias_group_tot_pages, TCPDF_STATIC::$alias_group_num_page, TCPDF_STATIC::$alias_right_shift); $pnalias = array(); foreach($basic_alias as $k => $a) { $pnalias[$k] = $this->getInternalPageNumberAliases($a); } return $pnalias; } /** * Replace right shift page number aliases with spaces to correct right alignment. * This works perfectly only when using monospaced fonts. * @param $page (string) Page content. * @param $aliases (array) Array of page aliases. * @param $diff (int) initial difference to add. * @return replaced page content. * @protected */ protected function replaceRightShiftPageNumAliases($page, $aliases, $diff) { foreach ($aliases as $type => $alias) { foreach ($alias as $a) { // find position of compensation factor $startnum = (strpos($a, ':') + 1); $a = substr($a, 0, $startnum); if (($pos = strpos($page, $a)) !== false) { // end of alias $endnum = strpos($page, '}', $pos); // string to be replaced $aa = substr($page, $pos, ($endnum - $pos + 1)); // get compensation factor $ratio = substr($page, ($pos + $startnum), ($endnum - $pos - $startnum)); $ratio = preg_replace('/[^0-9\.]/', '', $ratio); $ratio = floatval($ratio); if ($type == 'u') { $chrdiff = floor(($diff + 12) * $ratio); $shift = str_repeat(' ', $chrdiff); $shift = TCPDF_FONTS::UTF8ToUTF16BE($shift, false, $this->isunicode, $this->CurrentFont); } else { $chrdiff = floor(($diff + 11) * $ratio); $shift = str_repeat(' ', $chrdiff); } $page = str_replace($aa, $shift, $page); } } } return $page; } /** * Set page boxes to be included on page descriptions. * @param $boxes (array) Array of page boxes to set on document: ('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'). * @protected */ protected function setPageBoxTypes($boxes) { $this->page_boxes = array(); foreach ($boxes as $box) { if (in_array($box, TCPDF_STATIC::$pageboxes)) { $this->page_boxes[] = $box; } } } /** * Output pages (and replace page number aliases). * @protected */ protected function _putpages() { $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; // get internal aliases for page numbers $pnalias = $this->getAllInternalPageNumberAliases(); $num_pages = $this->numpages; $ptpa = TCPDF_STATIC::formatPageNumber(($this->starting_page_number + $num_pages - 1)); $ptpu = TCPDF_FONTS::UTF8ToUTF16BE($ptpa, false, $this->isunicode, $this->CurrentFont); $ptp_num_chars = $this->GetNumChars($ptpa); $pagegroupnum = 0; $groupnum = 0; $ptgu = 1; $ptga = 1; for ($n = 1; $n <= $num_pages; ++$n) { // get current page $temppage = $this->getPageBuffer($n); $pagelen = strlen($temppage); // set replacements for total pages number $pnpa = TCPDF_STATIC::formatPageNumber(($this->starting_page_number + $n - 1)); $pnpu = TCPDF_FONTS::UTF8ToUTF16BE($pnpa, false, $this->isunicode, $this->CurrentFont); $pnp_num_chars = $this->GetNumChars($pnpa); $pdiff = 0; // difference used for right shift alignment of page numbers $gdiff = 0; // difference used for right shift alignment of page group numbers if (!empty($this->pagegroups)) { if (isset($this->newpagegroup[$n])) { $pagegroupnum = 0; ++$groupnum; $ptga = TCPDF_STATIC::formatPageNumber($this->pagegroups[$groupnum]); $ptgu = TCPDF_FONTS::UTF8ToUTF16BE($ptga, false, $this->isunicode, $this->CurrentFont); $ptg_num_chars = $this->GetNumChars($ptga); } ++$pagegroupnum; $pnga = TCPDF_STATIC::formatPageNumber($pagegroupnum); $pngu = TCPDF_FONTS::UTF8ToUTF16BE($pnga, false, $this->isunicode, $this->CurrentFont); $png_num_chars = $this->GetNumChars($pnga); // replace page numbers $replace = array(); $replace[] = array($ptgu, $ptg_num_chars, 9, $pnalias[2]['u']); $replace[] = array($ptga, $ptg_num_chars, 7, $pnalias[2]['a']); $replace[] = array($pngu, $png_num_chars, 9, $pnalias[3]['u']); $replace[] = array($pnga, $png_num_chars, 7, $pnalias[3]['a']); list($temppage, $gdiff) = TCPDF_STATIC::replacePageNumAliases($temppage, $replace, $gdiff); } // replace page numbers $replace = array(); $replace[] = array($ptpu, $ptp_num_chars, 9, $pnalias[0]['u']); $replace[] = array($ptpa, $ptp_num_chars, 7, $pnalias[0]['a']); $replace[] = array($pnpu, $pnp_num_chars, 9, $pnalias[1]['u']); $replace[] = array($pnpa, $pnp_num_chars, 7, $pnalias[1]['a']); list($temppage, $pdiff) = TCPDF_STATIC::replacePageNumAliases($temppage, $replace, $pdiff); // replace right shift alias $temppage = $this->replaceRightShiftPageNumAliases($temppage, $pnalias[4], max($pdiff, $gdiff)); // replace EPS marker $temppage = str_replace($this->epsmarker, '', $temppage); //Page $this->page_obj_id[$n] = $this->_newobj(); $out = '<<'; $out .= ' /Type /Page'; $out .= ' /Parent 1 0 R'; $out .= ' /LastModified '.$this->_datestring(0, $this->doc_modification_timestamp); $out .= ' /Resources 2 0 R'; foreach ($this->page_boxes as $box) { $out .= ' /'.$box; $out .= sprintf(' [%F %F %F %F]', $this->pagedim[$n][$box]['llx'], $this->pagedim[$n][$box]['lly'], $this->pagedim[$n][$box]['urx'], $this->pagedim[$n][$box]['ury']); } if (isset($this->pagedim[$n]['BoxColorInfo']) AND !empty($this->pagedim[$n]['BoxColorInfo'])) { $out .= ' /BoxColorInfo <<'; foreach ($this->page_boxes as $box) { if (isset($this->pagedim[$n]['BoxColorInfo'][$box])) { $out .= ' /'.$box.' <<'; if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['C'])) { $color = $this->pagedim[$n]['BoxColorInfo'][$box]['C']; $out .= ' /C ['; $out .= sprintf(' %F %F %F', ($color[0] / 255), ($color[1] / 255), ($color[2] / 255)); $out .= ' ]'; } if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['W'])) { $out .= ' /W '.($this->pagedim[$n]['BoxColorInfo'][$box]['W'] * $this->k); } if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['S'])) { $out .= ' /S /'.$this->pagedim[$n]['BoxColorInfo'][$box]['S']; } if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['D'])) { $dashes = $this->pagedim[$n]['BoxColorInfo'][$box]['D']; $out .= ' /D ['; foreach ($dashes as $dash) { $out .= sprintf(' %F', ($dash * $this->k)); } $out .= ' ]'; } $out .= ' >>'; } } $out .= ' >>'; } $out .= ' /Contents '.($this->n + 1).' 0 R'; $out .= ' /Rotate '.$this->pagedim[$n]['Rotate']; if (!$this->pdfa_mode) { $out .= ' /Group << /Type /Group /S /Transparency /CS /DeviceRGB >>'; } if (isset($this->pagedim[$n]['trans']) AND !empty($this->pagedim[$n]['trans'])) { // page transitions if (isset($this->pagedim[$n]['trans']['Dur'])) { $out .= ' /Dur '.$this->pagedim[$n]['trans']['Dur']; } $out .= ' /Trans <<'; $out .= ' /Type /Trans'; if (isset($this->pagedim[$n]['trans']['S'])) { $out .= ' /S /'.$this->pagedim[$n]['trans']['S']; } if (isset($this->pagedim[$n]['trans']['D'])) { $out .= ' /D '.$this->pagedim[$n]['trans']['D']; } if (isset($this->pagedim[$n]['trans']['Dm'])) { $out .= ' /Dm /'.$this->pagedim[$n]['trans']['Dm']; } if (isset($this->pagedim[$n]['trans']['M'])) { $out .= ' /M /'.$this->pagedim[$n]['trans']['M']; } if (isset($this->pagedim[$n]['trans']['Di'])) { $out .= ' /Di '.$this->pagedim[$n]['trans']['Di']; } if (isset($this->pagedim[$n]['trans']['SS'])) { $out .= ' /SS '.$this->pagedim[$n]['trans']['SS']; } if (isset($this->pagedim[$n]['trans']['B'])) { $out .= ' /B '.$this->pagedim[$n]['trans']['B']; } $out .= ' >>'; } $out .= $this->_getannotsrefs($n); $out .= ' /PZ '.$this->pagedim[$n]['PZ']; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); //Page content $p = ($this->compress) ? gzcompress($temppage) : $temppage; $this->_newobj(); $p = $this->_getrawstream($p); $this->_out('<<'.$filter.'/Length '.strlen($p).'>> stream'."\n".$p."\n".'endstream'."\n".'endobj'); if ($this->diskcache) { // remove temporary files unlink($this->pages[$n]); } } //Pages root $out = $this->_getobj(1)."\n"; $out .= '<< /Type /Pages /Kids ['; foreach($this->page_obj_id as $page_obj) { $out .= ' '.$page_obj.' 0 R'; } $out .= ' ] /Count '.$num_pages.' >>'; $out .= "\n".'endobj'; $this->_out($out); } /** * Output references to page annotations * @param $n (int) page number * @protected * @author Nicola Asuni * @since 4.7.000 (2008-08-29) * @deprecated */ protected function _putannotsrefs($n) { $this->_out($this->_getannotsrefs($n)); } /** * Get references to page annotations. * @param $n (int) page number * @return string * @protected * @author Nicola Asuni * @since 5.0.010 (2010-05-17) */ protected function _getannotsrefs($n) { if (!(isset($this->PageAnnots[$n]) OR ($this->sign AND isset($this->signature_data['cert_type'])))) { return ''; } $out = ' /Annots ['; if (isset($this->PageAnnots[$n])) { foreach ($this->PageAnnots[$n] as $key => $val) { if (!in_array($val['n'], $this->radio_groups)) { $out .= ' '.$val['n'].' 0 R'; } } // add radiobutton groups if (isset($this->radiobutton_groups[$n])) { foreach ($this->radiobutton_groups[$n] as $key => $data) { if (isset($data['n'])) { $out .= ' '.$data['n'].' 0 R'; } } } } if ($this->sign AND ($n == $this->signature_appearance['page']) AND isset($this->signature_data['cert_type'])) { // set reference for signature object $out .= ' '.$this->sig_obj_id.' 0 R'; } if (!empty($this->empty_signature_appearance)) { foreach ($this->empty_signature_appearance as $esa) { if ($esa['page'] == $n) { // set reference for empty signature objects $out .= ' '.$esa['objid'].' 0 R'; } } } $out .= ' ]'; return $out; } /** * Output annotations objects for all pages. * !!! THIS METHOD IS NOT YET COMPLETED !!! * See section 12.5 of PDF 32000_2008 reference. * @protected * @author Nicola Asuni * @since 4.0.018 (2008-08-06) */ protected function _putannotsobjs() { // reset object counter for ($n=1; $n <= $this->numpages; ++$n) { if (isset($this->PageAnnots[$n])) { // set page annotations foreach ($this->PageAnnots[$n] as $key => $pl) { $annot_obj_id = $this->PageAnnots[$n][$key]['n']; // create annotation object for grouping radiobuttons if (isset($this->radiobutton_groups[$n][$pl['txt']]) AND is_array($this->radiobutton_groups[$n][$pl['txt']])) { $radio_button_obj_id = $this->radiobutton_groups[$n][$pl['txt']]['n']; $annots = '<<'; $annots .= ' /Type /Annot'; $annots .= ' /Subtype /Widget'; $annots .= ' /Rect [0 0 0 0]'; if ($this->radiobutton_groups[$n][$pl['txt']]['#readonly#']) { // read only $annots .= ' /F 68'; $annots .= ' /Ff 49153'; } else { $annots .= ' /F 4'; // default print for PDF/A $annots .= ' /Ff 49152'; } $annots .= ' /T '.$this->_datastring($pl['txt'], $radio_button_obj_id); if (isset($pl['opt']['tu']) AND is_string($pl['opt']['tu'])) { $annots .= ' /TU '.$this->_datastring($pl['opt']['tu'], $radio_button_obj_id); } $annots .= ' /FT /Btn'; $annots .= ' /Kids ['; $defval = ''; foreach ($this->radiobutton_groups[$n][$pl['txt']] as $key => $data) { if (isset($data['kid'])) { $annots .= ' '.$data['kid'].' 0 R'; if ($data['def'] !== 'Off') { $defval = $data['def']; } } } $annots .= ' ]'; if (!empty($defval)) { $annots .= ' /V /'.$defval; } $annots .= ' >>'; $this->_out($this->_getobj($radio_button_obj_id)."\n".$annots."\n".'endobj'); $this->form_obj_id[] = $radio_button_obj_id; // store object id to be used on Parent entry of Kids $this->radiobutton_groups[$n][$pl['txt']] = $radio_button_obj_id; } $formfield = false; $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER); $a = $pl['x'] * $this->k; $b = $this->pagedim[$n]['h'] - (($pl['y'] + $pl['h']) * $this->k); $c = $pl['w'] * $this->k; $d = $pl['h'] * $this->k; $rect = sprintf('%F %F %F %F', $a, $b, $a+$c, $b+$d); // create new annotation object $annots = '<</Type /Annot'; $annots .= ' /Subtype /'.$pl['opt']['subtype']; $annots .= ' /Rect ['.$rect.']'; $ft = array('Btn', 'Tx', 'Ch', 'Sig'); if (isset($pl['opt']['ft']) AND in_array($pl['opt']['ft'], $ft)) { $annots .= ' /FT /'.$pl['opt']['ft']; $formfield = true; } $annots .= ' /Contents '.$this->_textstring($pl['txt'], $annot_obj_id); $annots .= ' /P '.$this->page_obj_id[$n].' 0 R'; $annots .= ' /NM '.$this->_datastring(sprintf('%04u-%04u', $n, $key), $annot_obj_id); $annots .= ' /M '.$this->_datestring($annot_obj_id, $this->doc_modification_timestamp); if (isset($pl['opt']['f'])) { $fval = 0; if (is_array($pl['opt']['f'])) { foreach ($pl['opt']['f'] as $f) { switch (strtolower($f)) { case 'invisible': { $fval += 1 << 0; break; } case 'hidden': { $fval += 1 << 1; break; } case 'print': { $fval += 1 << 2; break; } case 'nozoom': { $fval += 1 << 3; break; } case 'norotate': { $fval += 1 << 4; break; } case 'noview': { $fval += 1 << 5; break; } case 'readonly': { $fval += 1 << 6; break; } case 'locked': { $fval += 1 << 8; break; } case 'togglenoview': { $fval += 1 << 9; break; } case 'lockedcontents': { $fval += 1 << 10; break; } default: { break; } } } } else { $fval = intval($pl['opt']['f']); } } else { $fval = 4; } if ($this->pdfa_mode) { // force print flag for PDF/A mode $fval |= 4; } $annots .= ' /F '.intval($fval); if (isset($pl['opt']['as']) AND is_string($pl['opt']['as'])) { $annots .= ' /AS /'.$pl['opt']['as']; } if (isset($pl['opt']['ap'])) { // appearance stream $annots .= ' /AP <<'; if (is_array($pl['opt']['ap'])) { foreach ($pl['opt']['ap'] as $apmode => $apdef) { // $apmode can be: n = normal; r = rollover; d = down; $annots .= ' /'.strtoupper($apmode); if (is_array($apdef)) { $annots .= ' <<'; foreach ($apdef as $apstate => $stream) { // reference to XObject that define the appearance for this mode-state $apsobjid = $this->_putAPXObject($c, $d, $stream); $annots .= ' /'.$apstate.' '.$apsobjid.' 0 R'; } $annots .= ' >>'; } else { // reference to XObject that define the appearance for this mode $apsobjid = $this->_putAPXObject($c, $d, $apdef); $annots .= ' '.$apsobjid.' 0 R'; } } } else { $annots .= $pl['opt']['ap']; } $annots .= ' >>'; } if (isset($pl['opt']['bs']) AND (is_array($pl['opt']['bs']))) { $annots .= ' /BS <<'; $annots .= ' /Type /Border'; if (isset($pl['opt']['bs']['w'])) { $annots .= ' /W '.intval($pl['opt']['bs']['w']); } $bstyles = array('S', 'D', 'B', 'I', 'U'); if (isset($pl['opt']['bs']['s']) AND in_array($pl['opt']['bs']['s'], $bstyles)) { $annots .= ' /S /'.$pl['opt']['bs']['s']; } if (isset($pl['opt']['bs']['d']) AND (is_array($pl['opt']['bs']['d']))) { $annots .= ' /D ['; foreach ($pl['opt']['bs']['d'] as $cord) { $annots .= ' '.intval($cord); } $annots .= ']'; } $annots .= ' >>'; } else { $annots .= ' /Border ['; if (isset($pl['opt']['border']) AND (count($pl['opt']['border']) >= 3)) { $annots .= intval($pl['opt']['border'][0]).' '; $annots .= intval($pl['opt']['border'][1]).' '; $annots .= intval($pl['opt']['border'][2]); if (isset($pl['opt']['border'][3]) AND is_array($pl['opt']['border'][3])) { $annots .= ' ['; foreach ($pl['opt']['border'][3] as $dash) { $annots .= intval($dash).' '; } $annots .= ']'; } } else { $annots .= '0 0 0'; } $annots .= ']'; } if (isset($pl['opt']['be']) AND (is_array($pl['opt']['be']))) { $annots .= ' /BE <<'; $bstyles = array('S', 'C'); if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $bstyles)) { $annots .= ' /S /'.$pl['opt']['bs']['s']; } else { $annots .= ' /S /S'; } if (isset($pl['opt']['be']['i']) AND ($pl['opt']['be']['i'] >= 0) AND ($pl['opt']['be']['i'] <= 2)) { $annots .= ' /I '.sprintf(' %F', $pl['opt']['be']['i']); } $annots .= '>>'; } if (isset($pl['opt']['c']) AND (is_array($pl['opt']['c'])) AND !empty($pl['opt']['c'])) { $annots .= ' /C '.TCPDF_COLORS::getColorStringFromArray($pl['opt']['c']); } //$annots .= ' /StructParent '; //$annots .= ' /OC '; $markups = array('text', 'freetext', 'line', 'square', 'circle', 'polygon', 'polyline', 'highlight', 'underline', 'squiggly', 'strikeout', 'stamp', 'caret', 'ink', 'fileattachment', 'sound'); if (in_array(strtolower($pl['opt']['subtype']), $markups)) { // this is a markup type if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) { $annots .= ' /T '.$this->_textstring($pl['opt']['t'], $annot_obj_id); } //$annots .= ' /Popup '; if (isset($pl['opt']['ca'])) { $annots .= ' /CA '.sprintf('%F', floatval($pl['opt']['ca'])); } if (isset($pl['opt']['rc'])) { $annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id); } $annots .= ' /CreationDate '.$this->_datestring($annot_obj_id, $this->doc_creation_timestamp); //$annots .= ' /IRT '; if (isset($pl['opt']['subj'])) { $annots .= ' /Subj '.$this->_textstring($pl['opt']['subj'], $annot_obj_id); } //$annots .= ' /RT '; //$annots .= ' /IT '; //$annots .= ' /ExData '; } $lineendings = array('Square', 'Circle', 'Diamond', 'OpenArrow', 'ClosedArrow', 'None', 'Butt', 'ROpenArrow', 'RClosedArrow', 'Slash'); // Annotation types switch (strtolower($pl['opt']['subtype'])) { case 'text': { if (isset($pl['opt']['open'])) { $annots .= ' /Open '. (strtolower($pl['opt']['open']) == 'true' ? 'true' : 'false'); } $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) { $annots .= ' /Name /'.$pl['opt']['name']; } else { $annots .= ' /Name /Note'; } $statemodels = array('Marked', 'Review'); if (isset($pl['opt']['statemodel']) AND in_array($pl['opt']['statemodel'], $statemodels)) { $annots .= ' /StateModel /'.$pl['opt']['statemodel']; } else { $pl['opt']['statemodel'] = 'Marked'; $annots .= ' /StateModel /'.$pl['opt']['statemodel']; } if ($pl['opt']['statemodel'] == 'Marked') { $states = array('Accepted', 'Unmarked'); } else { $states = array('Accepted', 'Rejected', 'Cancelled', 'Completed', 'None'); } if (isset($pl['opt']['state']) AND in_array($pl['opt']['state'], $states)) { $annots .= ' /State /'.$pl['opt']['state']; } else { if ($pl['opt']['statemodel'] == 'Marked') { $annots .= ' /State /Unmarked'; } else { $annots .= ' /State /None'; } } break; } case 'link': { if (is_string($pl['txt'])) { if ($pl['txt'][0] == '#') { // internal destination $annots .= ' /Dest /'.TCPDF_STATIC::encodeNameObject(substr($pl['txt'], 1)); } elseif ($pl['txt'][0] == '%') { // embedded PDF file $filename = basename(substr($pl['txt'], 1)); $annots .= ' /A << /S /GoToE /D [0 /Fit] /NewWindow true /T << /R /C /P '.($n - 1).' /A '.$this->embeddedfiles[$filename]['a'].' >> >>'; } elseif ($pl['txt'][0] == '*') { // embedded generic file $filename = basename(substr($pl['txt'], 1)); $jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="'.$filename.'") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});'; $annots .= ' /A << /S /JavaScript /JS '.$this->_textstring($jsa, $annot_obj_id).'>>'; } else { // external URI link $annots .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($pl['txt']), $annot_obj_id).'>>'; } } elseif (isset($this->links[$pl['txt']])) { // internal link ID $l = $this->links[$pl['txt']]; if (isset($this->page_obj_id[($l[0])])) { $annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k))); } } $hmodes = array('N', 'I', 'O', 'P'); if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmodes)) { $annots .= ' /H /'.$pl['opt']['h']; } else { $annots .= ' /H /I'; } //$annots .= ' /PA '; //$annots .= ' /Quadpoints '; break; } case 'freetext': { if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) { $annots .= ' /DA ('.$pl['opt']['da'].')'; } if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) { $annots .= ' /Q '.intval($pl['opt']['q']); } if (isset($pl['opt']['rc'])) { $annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id); } if (isset($pl['opt']['ds'])) { $annots .= ' /DS '.$this->_textstring($pl['opt']['ds'], $annot_obj_id); } if (isset($pl['opt']['cl']) AND is_array($pl['opt']['cl'])) { $annots .= ' /CL ['; foreach ($pl['opt']['cl'] as $cl) { $annots .= sprintf('%F ', $cl * $this->k); } $annots .= ']'; } $tfit = array('FreeText', 'FreeTextCallout', 'FreeTextTypeWriter'); if (isset($pl['opt']['it']) AND in_array($pl['opt']['it'], $tfit)) { $annots .= ' /IT /'.$pl['opt']['it']; } if (isset($pl['opt']['rd']) AND is_array($pl['opt']['rd'])) { $l = $pl['opt']['rd'][0] * $this->k; $r = $pl['opt']['rd'][1] * $this->k; $t = $pl['opt']['rd'][2] * $this->k; $b = $pl['opt']['rd'][3] * $this->k; $annots .= ' /RD ['.sprintf('%F %F %F %F', $l, $r, $t, $b).']'; } if (isset($pl['opt']['le']) AND in_array($pl['opt']['le'], $lineendings)) { $annots .= ' /LE /'.$pl['opt']['le']; } break; } case 'line': { break; } case 'square': { break; } case 'circle': { break; } case 'polygon': { break; } case 'polyline': { break; } case 'highlight': { break; } case 'underline': { break; } case 'squiggly': { break; } case 'strikeout': { break; } case 'stamp': { break; } case 'caret': { break; } case 'ink': { break; } case 'popup': { break; } case 'fileattachment': { if ($this->pdfa_mode) { // embedded files are not allowed in PDF/A mode break; } if (!isset($pl['opt']['fs'])) { break; } $filename = basename($pl['opt']['fs']); if (isset($this->embeddedfiles[$filename]['f'])) { $annots .= ' /FS '.$this->embeddedfiles[$filename]['f'].' 0 R'; $iconsapp = array('Graph', 'Paperclip', 'PushPin', 'Tag'); if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) { $annots .= ' /Name /'.$pl['opt']['name']; } else { $annots .= ' /Name /PushPin'; } // index (zero-based) of the annotation in the Annots array of this page $this->embeddedfiles[$filename]['a'] = $key; } break; } case 'sound': { if (!isset($pl['opt']['fs'])) { break; } $filename = basename($pl['opt']['fs']); if (isset($this->embeddedfiles[$filename]['f'])) { // ... TO BE COMPLETED ... // /R /C /B /E /CO /CP $annots .= ' /Sound '.$this->embeddedfiles[$filename]['f'].' 0 R'; $iconsapp = array('Speaker', 'Mic'); if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) { $annots .= ' /Name /'.$pl['opt']['name']; } else { $annots .= ' /Name /Speaker'; } } break; } case 'movie': { break; } case 'widget': { $hmode = array('N', 'I', 'O', 'P', 'T'); if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmode)) { $annots .= ' /H /'.$pl['opt']['h']; } if (isset($pl['opt']['mk']) AND (is_array($pl['opt']['mk'])) AND !empty($pl['opt']['mk'])) { $annots .= ' /MK <<'; if (isset($pl['opt']['mk']['r'])) { $annots .= ' /R '.$pl['opt']['mk']['r']; } if (isset($pl['opt']['mk']['bc']) AND (is_array($pl['opt']['mk']['bc']))) { $annots .= ' /BC '.TCPDF_COLORS::getColorStringFromArray($pl['opt']['mk']['bc']); } if (isset($pl['opt']['mk']['bg']) AND (is_array($pl['opt']['mk']['bg']))) { $annots .= ' /BG '.TCPDF_COLORS::getColorStringFromArray($pl['opt']['mk']['bg']); } if (isset($pl['opt']['mk']['ca'])) { $annots .= ' /CA '.$pl['opt']['mk']['ca']; } if (isset($pl['opt']['mk']['rc'])) { $annots .= ' /RC '.$pl['opt']['mk']['rc']; } if (isset($pl['opt']['mk']['ac'])) { $annots .= ' /AC '.$pl['opt']['mk']['ac']; } if (isset($pl['opt']['mk']['i'])) { $info = $this->getImageBuffer($pl['opt']['mk']['i']); if ($info !== false) { $annots .= ' /I '.$info['n'].' 0 R'; } } if (isset($pl['opt']['mk']['ri'])) { $info = $this->getImageBuffer($pl['opt']['mk']['ri']); if ($info !== false) { $annots .= ' /RI '.$info['n'].' 0 R'; } } if (isset($pl['opt']['mk']['ix'])) { $info = $this->getImageBuffer($pl['opt']['mk']['ix']); if ($info !== false) { $annots .= ' /IX '.$info['n'].' 0 R'; } } if (isset($pl['opt']['mk']['if']) AND (is_array($pl['opt']['mk']['if'])) AND !empty($pl['opt']['mk']['if'])) { $annots .= ' /IF <<'; $if_sw = array('A', 'B', 'S', 'N'); if (isset($pl['opt']['mk']['if']['sw']) AND in_array($pl['opt']['mk']['if']['sw'], $if_sw)) { $annots .= ' /SW /'.$pl['opt']['mk']['if']['sw']; } $if_s = array('A', 'P'); if (isset($pl['opt']['mk']['if']['s']) AND in_array($pl['opt']['mk']['if']['s'], $if_s)) { $annots .= ' /S /'.$pl['opt']['mk']['if']['s']; } if (isset($pl['opt']['mk']['if']['a']) AND (is_array($pl['opt']['mk']['if']['a'])) AND !empty($pl['opt']['mk']['if']['a'])) { $annots .= sprintf(' /A [%F %F]', $pl['opt']['mk']['if']['a'][0], $pl['opt']['mk']['if']['a'][1]); } if (isset($pl['opt']['mk']['if']['fb']) AND ($pl['opt']['mk']['if']['fb'])) { $annots .= ' /FB true'; } $annots .= '>>'; } if (isset($pl['opt']['mk']['tp']) AND ($pl['opt']['mk']['tp'] >= 0) AND ($pl['opt']['mk']['tp'] <= 6)) { $annots .= ' /TP '.intval($pl['opt']['mk']['tp']); } $annots .= '>>'; } // end MK // --- Entries for field dictionaries --- if (isset($this->radiobutton_groups[$n][$pl['txt']])) { // set parent $annots .= ' /Parent '.$this->radiobutton_groups[$n][$pl['txt']].' 0 R'; } if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) { $annots .= ' /T '.$this->_datastring($pl['opt']['t'], $annot_obj_id); } if (isset($pl['opt']['tu']) AND is_string($pl['opt']['tu'])) { $annots .= ' /TU '.$this->_datastring($pl['opt']['tu'], $annot_obj_id); } if (isset($pl['opt']['tm']) AND is_string($pl['opt']['tm'])) { $annots .= ' /TM '.$this->_datastring($pl['opt']['tm'], $annot_obj_id); } if (isset($pl['opt']['ff'])) { if (is_array($pl['opt']['ff'])) { // array of bit settings $flag = 0; foreach($pl['opt']['ff'] as $val) { $flag += 1 << ($val - 1); } } else { $flag = intval($pl['opt']['ff']); } $annots .= ' /Ff '.$flag; } if (isset($pl['opt']['maxlen'])) { $annots .= ' /MaxLen '.intval($pl['opt']['maxlen']); } if (isset($pl['opt']['v'])) { $annots .= ' /V'; if (is_array($pl['opt']['v'])) { foreach ($pl['opt']['v'] AS $optval) { if (is_float($optval)) { $optval = sprintf('%F', $optval); } $annots .= ' '.$optval; } } else { $annots .= ' '.$this->_textstring($pl['opt']['v'], $annot_obj_id); } } if (isset($pl['opt']['dv'])) { $annots .= ' /DV'; if (is_array($pl['opt']['dv'])) { foreach ($pl['opt']['dv'] AS $optval) { if (is_float($optval)) { $optval = sprintf('%F', $optval); } $annots .= ' '.$optval; } } else { $annots .= ' '.$this->_textstring($pl['opt']['dv'], $annot_obj_id); } } if (isset($pl['opt']['rv'])) { $annots .= ' /RV'; if (is_array($pl['opt']['rv'])) { foreach ($pl['opt']['rv'] AS $optval) { if (is_float($optval)) { $optval = sprintf('%F', $optval); } $annots .= ' '.$optval; } } else { $annots .= ' '.$this->_textstring($pl['opt']['rv'], $annot_obj_id); } } if (isset($pl['opt']['a']) AND !empty($pl['opt']['a'])) { $annots .= ' /A << '.$pl['opt']['a'].' >>'; } if (isset($pl['opt']['aa']) AND !empty($pl['opt']['aa'])) { $annots .= ' /AA << '.$pl['opt']['aa'].' >>'; } if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) { $annots .= ' /DA ('.$pl['opt']['da'].')'; } if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) { $annots .= ' /Q '.intval($pl['opt']['q']); } if (isset($pl['opt']['opt']) AND (is_array($pl['opt']['opt'])) AND !empty($pl['opt']['opt'])) { $annots .= ' /Opt ['; foreach($pl['opt']['opt'] AS $copt) { if (is_array($copt)) { $annots .= ' ['.$this->_textstring($copt[0], $annot_obj_id).' '.$this->_textstring($copt[1], $annot_obj_id).']'; } else { $annots .= ' '.$this->_textstring($copt, $annot_obj_id); } } $annots .= ']'; } if (isset($pl['opt']['ti'])) { $annots .= ' /TI '.intval($pl['opt']['ti']); } if (isset($pl['opt']['i']) AND (is_array($pl['opt']['i'])) AND !empty($pl['opt']['i'])) { $annots .= ' /I ['; foreach($pl['opt']['i'] AS $copt) { $annots .= intval($copt).' '; } $annots .= ']'; } break; } case 'screen': { break; } case 'printermark': { break; } case 'trapnet': { break; } case 'watermark': { break; } case '3d': { break; } default: { break; } } $annots .= '>>'; // create new annotation object $this->_out($this->_getobj($annot_obj_id)."\n".$annots."\n".'endobj'); if ($formfield AND !isset($this->radiobutton_groups[$n][$pl['txt']])) { // store reference of form object $this->form_obj_id[] = $annot_obj_id; } } } } // end for each page } /** * Put appearance streams XObject used to define annotation's appearance states. * @param $w (int) annotation width * @param $h (int) annotation height * @param $stream (string) appearance stream * @return int object ID * @protected * @since 4.8.001 (2009-09-09) */ protected function _putAPXObject($w=0, $h=0, $stream='') { $stream = trim($stream); $out = $this->_getobj()."\n"; $this->xobjects['AX'.$this->n] = array('n' => $this->n); $out .= '<<'; $out .= ' /Type /XObject'; $out .= ' /Subtype /Form'; $out .= ' /FormType 1'; if ($this->compress) { $stream = gzcompress($stream); $out .= ' /Filter /FlateDecode'; } $rect = sprintf('%F %F', $w, $h); $out .= ' /BBox [0 0 '.$rect.']'; $out .= ' /Matrix [1 0 0 1 0 0]'; $out .= ' /Resources 2 0 R'; $stream = $this->_getrawstream($stream); $out .= ' /Length '.strlen($stream); $out .= ' >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; $out .= "\n".'endobj'; $this->_out($out); return $this->n; } /** * Output fonts. * @author Nicola Asuni * @protected */ protected function _putfonts() { $nf = $this->n; foreach ($this->diffs as $diff) { //Encodings $this->_newobj(); $this->_out('<< /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.'] >>'."\n".'endobj'); } $mqr = TCPDF_STATIC::get_mqr(); TCPDF_STATIC::set_mqr(false); foreach ($this->FontFiles as $file => $info) { // search and get font file to embedd $fontdir = $info['fontdir']; $file = strtolower($file); $fontfile = ''; // search files on various directories if (($fontdir !== false) AND file_exists($fontdir.$file)) { $fontfile = $fontdir.$file; } elseif (file_exists(TCPDF_FONTS::_getfontpath().$file)) { $fontfile = TCPDF_FONTS::_getfontpath().$file; } elseif (file_exists($file)) { $fontfile = $file; } if (!TCPDF_STATIC::empty_string($fontfile)) { $font = file_get_contents($fontfile); $compressed = (substr($file, -2) == '.z'); if ((!$compressed) AND (isset($info['length2']))) { $header = (ord($font{0}) == 128); if ($header) { // strip first binary header $font = substr($font, 6); } if ($header AND (ord($font[$info['length1']]) == 128)) { // strip second binary header $font = substr($font, 0, $info['length1']).substr($font, ($info['length1'] + 6)); } } elseif ($info['subset'] AND ((!$compressed) OR ($compressed AND function_exists('gzcompress')))) { if ($compressed) { // uncompress font $font = gzuncompress($font); } // merge subset characters $subsetchars = array(); // used chars foreach ($info['fontkeys'] as $fontkey) { $fontinfo = $this->getFontBuffer($fontkey); $subsetchars += $fontinfo['subsetchars']; } // rebuild a font subset $font = TCPDF_FONTS::_getTrueTypeFontSubset($font, $subsetchars); // calculate new font length $info['length1'] = strlen($font); if ($compressed) { // recompress font $font = gzcompress($font); } } $this->_newobj(); $this->FontFiles[$file]['n'] = $this->n; $stream = $this->_getrawstream($font); $out = '<< /Length '.strlen($stream); if ($compressed) { $out .= ' /Filter /FlateDecode'; } $out .= ' /Length1 '.$info['length1']; if (isset($info['length2'])) { $out .= ' /Length2 '.$info['length2'].' /Length3 0'; } $out .= ' >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; $out .= "\n".'endobj'; $this->_out($out); } } TCPDF_STATIC::set_mqr($mqr); foreach ($this->fontkeys as $k) { //Font objects $font = $this->getFontBuffer($k); $type = $font['type']; $name = $font['name']; if ($type == 'core') { // standard core font $out = $this->_getobj($this->font_obj_ids[$k])."\n"; $out .= '<</Type /Font'; $out .= ' /Subtype /Type1'; $out .= ' /BaseFont /'.$name; $out .= ' /Name /F'.$font['i']; if ((strtolower($name) != 'symbol') AND (strtolower($name) != 'zapfdingbats')) { $out .= ' /Encoding /WinAnsiEncoding'; } if ($k == 'helvetica') { // add default font for annotations $this->annotation_fonts[$k] = $font['i']; } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } elseif (($type == 'Type1') OR ($type == 'TrueType')) { // additional Type1 or TrueType font $out = $this->_getobj($this->font_obj_ids[$k])."\n"; $out .= '<</Type /Font'; $out .= ' /Subtype /'.$type; $out .= ' /BaseFont /'.$name; $out .= ' /Name /F'.$font['i']; $out .= ' /FirstChar 32 /LastChar 255'; $out .= ' /Widths '.($this->n + 1).' 0 R'; $out .= ' /FontDescriptor '.($this->n + 2).' 0 R'; if ($font['enc']) { if (isset($font['diff'])) { $out .= ' /Encoding '.($nf + $font['diff']).' 0 R'; } else { $out .= ' /Encoding /WinAnsiEncoding'; } } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); // Widths $this->_newobj(); $s = '['; for ($i = 32; $i < 256; ++$i) { if (isset($font['cw'][$i])) { $s .= $font['cw'][$i].' '; } else { $s .= $font['dw'].' '; } } $s .= ']'; $s .= "\n".'endobj'; $this->_out($s); //Descriptor $this->_newobj(); $s = '<</Type /FontDescriptor /FontName /'.$name; foreach ($font['desc'] as $fdk => $fdv) { if (is_float($fdv)) { $fdv = sprintf('%F', $fdv); } $s .= ' /'.$fdk.' '.$fdv.''; } if (!TCPDF_STATIC::empty_string($font['file'])) { $s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R'; } $s .= '>>'; $s .= "\n".'endobj'; $this->_out($s); } else { // additional types $mtd = '_put'.strtolower($type); if (!method_exists($this, $mtd)) { $this->Error('Unsupported font type: '.$type); } $this->$mtd($font); } } } /** * Adds unicode fonts.<br> * Based on PDF Reference 1.3 (section 5) * @param $font (array) font data * @protected * @author Nicola Asuni * @since 1.52.0.TC005 (2005-01-05) */ protected function _puttruetypeunicode($font) { $fontname = ''; if ($font['subset']) { // change name for font subsetting $subtag = sprintf('%06u', $font['i']); $subtag = strtr($subtag, '0123456789', 'ABCDEFGHIJ'); $fontname .= $subtag.'+'; } $fontname .= $font['name']; // Type0 Font // A composite font composed of other fonts, organized hierarchically $out = $this->_getobj($this->font_obj_ids[$font['fontkey']])."\n"; $out .= '<< /Type /Font'; $out .= ' /Subtype /Type0'; $out .= ' /BaseFont /'.$fontname; $out .= ' /Name /F'.$font['i']; $out .= ' /Encoding /'.$font['enc']; $out .= ' /ToUnicode '.($this->n + 1).' 0 R'; $out .= ' /DescendantFonts ['.($this->n + 2).' 0 R]'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); // ToUnicode map for Identity-H $stream = TCPDF_FONT_DATA::$uni_identity_h; // ToUnicode Object $this->_newobj(); $stream = ($this->compress) ? gzcompress($stream) : $stream; $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; $stream = $this->_getrawstream($stream); $this->_out('<<'.$filter.'/Length '.strlen($stream).'>> stream'."\n".$stream."\n".'endstream'."\n".'endobj'); // CIDFontType2 // A CIDFont whose glyph descriptions are based on TrueType font technology $oid = $this->_newobj(); $out = '<< /Type /Font'; $out .= ' /Subtype /CIDFontType2'; $out .= ' /BaseFont /'.$fontname; // A dictionary containing entries that define the character collection of the CIDFont. $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry'], $oid); $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering'], $oid); $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement']; $out .= ' /CIDSystemInfo << '.$cidinfo.' >>'; $out .= ' /FontDescriptor '.($this->n + 1).' 0 R'; $out .= ' /DW '.$font['dw']; // default width $out .= "\n".TCPDF_FONTS::_putfontwidths($font, 0); if (isset($font['ctg']) AND (!TCPDF_STATIC::empty_string($font['ctg']))) { $out .= "\n".'/CIDToGIDMap '.($this->n + 2).' 0 R'; } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); // Font descriptor // A font descriptor describing the CIDFont default metrics other than its glyph widths $this->_newobj(); $out = '<< /Type /FontDescriptor'; $out .= ' /FontName /'.$fontname; foreach ($font['desc'] as $key => $value) { if (is_float($value)) { $value = sprintf('%F', $value); } $out .= ' /'.$key.' '.$value; } $fontdir = false; if (!TCPDF_STATIC::empty_string($font['file'])) { // A stream containing a TrueType font $out .= ' /FontFile2 '.$this->FontFiles[$font['file']]['n'].' 0 R'; $fontdir = $this->FontFiles[$font['file']]['fontdir']; } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); if (isset($font['ctg']) AND (!TCPDF_STATIC::empty_string($font['ctg']))) { $this->_newobj(); // Embed CIDToGIDMap // A specification of the mapping from CIDs to glyph indices // search and get CTG font file to embedd $ctgfile = strtolower($font['ctg']); // search and get ctg font file to embedd $fontfile = ''; // search files on various directories if (($fontdir !== false) AND file_exists($fontdir.$ctgfile)) { $fontfile = $fontdir.$ctgfile; } elseif (file_exists(TCPDF_FONTS::_getfontpath().$ctgfile)) { $fontfile = TCPDF_FONTS::_getfontpath().$ctgfile; } elseif (file_exists($ctgfile)) { $fontfile = $ctgfile; } if (TCPDF_STATIC::empty_string($fontfile)) { $this->Error('Font file not found: '.$ctgfile); } $stream = $this->_getrawstream(file_get_contents($fontfile)); $out = '<< /Length '.strlen($stream).''; if (substr($fontfile, -2) == '.z') { // check file extension // Decompresses data encoded using the public-domain // zlib/deflate compression method, reproducing the // original text or binary data $out .= ' /Filter /FlateDecode'; } $out .= ' >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; $out .= "\n".'endobj'; $this->_out($out); } } /** * Output CID-0 fonts. * A Type 0 CIDFont contains glyph descriptions based on the Adobe Type 1 font format * @param $font (array) font data * @protected * @author Andrew Whitehead, Nicola Asuni, Yukihiro Nakadaira * @since 3.2.000 (2008-06-23) */ protected function _putcidfont0($font) { $cidoffset = 0; if (!isset($font['cw'][1])) { $cidoffset = 31; } if (isset($font['cidinfo']['uni2cid'])) { // convert unicode to cid. $uni2cid = $font['cidinfo']['uni2cid']; $cw = array(); foreach ($font['cw'] as $uni => $width) { if (isset($uni2cid[$uni])) { $cw[($uni2cid[$uni] + $cidoffset)] = $width; } elseif ($uni < 256) { $cw[$uni] = $width; } // else unknown character } $font = array_merge($font, array('cw' => $cw)); } $name = $font['name']; $enc = $font['enc']; if ($enc) { $longname = $name.'-'.$enc; } else { $longname = $name; } $out = $this->_getobj($this->font_obj_ids[$font['fontkey']])."\n"; $out .= '<</Type /Font'; $out .= ' /Subtype /Type0'; $out .= ' /BaseFont /'.$longname; $out .= ' /Name /F'.$font['i']; if ($enc) { $out .= ' /Encoding /'.$enc; } $out .= ' /DescendantFonts ['.($this->n + 1).' 0 R]'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); $oid = $this->_newobj(); $out = '<</Type /Font'; $out .= ' /Subtype /CIDFontType0'; $out .= ' /BaseFont /'.$name; $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry'], $oid); $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering'], $oid); $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement']; $out .= ' /CIDSystemInfo <<'.$cidinfo.'>>'; $out .= ' /FontDescriptor '.($this->n + 1).' 0 R'; $out .= ' /DW '.$font['dw']; $out .= "\n".TCPDF_FONTS::_putfontwidths($font, $cidoffset); $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); $this->_newobj(); $s = '<</Type /FontDescriptor /FontName /'.$name; foreach ($font['desc'] as $k => $v) { if ($k != 'Style') { if (is_float($v)) { $v = sprintf('%F', $v); } $s .= ' /'.$k.' '.$v.''; } } $s .= '>>'; $s .= "\n".'endobj'; $this->_out($s); } /** * Output images. * @protected */ protected function _putimages() { $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; foreach ($this->imagekeys as $file) { $info = $this->getImageBuffer($file); // set object for alternate images array if ((!$this->pdfa_mode) AND isset($info['altimgs']) AND !empty($info['altimgs'])) { $altoid = $this->_newobj(); $out = '['; foreach ($info['altimgs'] as $altimage) { if (isset($this->xobjects['I'.$altimage[0]]['n'])) { $out .= ' << /Image '.$this->xobjects['I'.$altimage[0]]['n'].' 0 R'; $out .= ' /DefaultForPrinting'; if ($altimage[1] === true) { $out .= ' true'; } else { $out .= ' false'; } $out .= ' >>'; } } $out .= ' ]'; $out .= "\n".'endobj'; $this->_out($out); } // set image object $oid = $this->_newobj(); $this->xobjects['I'.$info['i']] = array('n' => $oid); $this->setImageSubBuffer($file, 'n', $this->n); $out = '<</Type /XObject'; $out .= ' /Subtype /Image'; $out .= ' /Width '.$info['w']; $out .= ' /Height '.$info['h']; if (array_key_exists('masked', $info)) { $out .= ' /SMask '.($this->n - 1).' 0 R'; } // set color space $icc = false; if (isset($info['icc']) AND ($info['icc'] !== false)) { // ICC Colour Space $icc = true; $out .= ' /ColorSpace [/ICCBased '.($this->n + 1).' 0 R]'; } elseif ($info['cs'] == 'Indexed') { // Indexed Colour Space $out .= ' /ColorSpace [/Indexed /DeviceRGB '.((strlen($info['pal']) / 3) - 1).' '.($this->n + 1).' 0 R]'; } else { // Device Colour Space $out .= ' /ColorSpace /'.$info['cs']; } if ($info['cs'] == 'DeviceCMYK') { $out .= ' /Decode [1 0 1 0 1 0 1 0]'; } $out .= ' /BitsPerComponent '.$info['bpc']; if (isset($altoid) AND ($altoid > 0)) { // reference to alternate images dictionary $out .= ' /Alternates '.$altoid.' 0 R'; } if (isset($info['exurl']) AND !empty($info['exurl'])) { // external stream $out .= ' /Length 0'; $out .= ' /F << /FS /URL /F '.$this->_datastring($info['exurl'], $oid).' >>'; if (isset($info['f'])) { $out .= ' /FFilter /'.$info['f']; } $out .= ' >>'; $out .= ' stream'."\n".'endstream'; } else { if (isset($info['f'])) { $out .= ' /Filter /'.$info['f']; } if (isset($info['parms'])) { $out .= ' '.$info['parms']; } if (isset($info['trns']) AND is_array($info['trns'])) { $trns = ''; $count_info = count($info['trns']); for ($i=0; $i < $count_info; ++$i) { $trns .= $info['trns'][$i].' '.$info['trns'][$i].' '; } $out .= ' /Mask ['.$trns.']'; } $stream = $this->_getrawstream($info['data']); $out .= ' /Length '.strlen($stream).' >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; } $out .= "\n".'endobj'; $this->_out($out); if ($icc) { // ICC colour profile $this->_newobj(); $icc = ($this->compress) ? gzcompress($info['icc']) : $info['icc']; $icc = $this->_getrawstream($icc); $this->_out('<</N '.$info['ch'].' /Alternate /'.$info['cs'].' '.$filter.'/Length '.strlen($icc).'>> stream'."\n".$icc."\n".'endstream'."\n".'endobj'); } elseif ($info['cs'] == 'Indexed') { // colour palette $this->_newobj(); $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal']; $pal = $this->_getrawstream($pal); $this->_out('<<'.$filter.'/Length '.strlen($pal).'>> stream'."\n".$pal."\n".'endstream'."\n".'endobj'); } } } /** * Output Form XObjects Templates. * @author Nicola Asuni * @since 5.8.017 (2010-08-24) * @protected * @see startTemplate(), endTemplate(), printTemplate() */ protected function _putxobjects() { foreach ($this->xobjects as $key => $data) { if (isset($data['outdata'])) { $stream = str_replace($this->epsmarker, '', trim($data['outdata'])); $out = $this->_getobj($data['n'])."\n"; $out .= '<<'; $out .= ' /Type /XObject'; $out .= ' /Subtype /Form'; $out .= ' /FormType 1'; if ($this->compress) { $stream = gzcompress($stream); $out .= ' /Filter /FlateDecode'; } $out .= sprintf(' /BBox [%F %F %F %F]', ($data['x'] * $this->k), (-$data['y'] * $this->k), (($data['w'] + $data['x']) * $this->k), (($data['h'] - $data['y']) * $this->k)); $out .= ' /Matrix [1 0 0 1 0 0]'; $out .= ' /Resources <<'; $out .= ' /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'; if (!$this->pdfa_mode) { // transparency if (isset($data['extgstates']) AND !empty($data['extgstates'])) { $out .= ' /ExtGState <<'; foreach ($data['extgstates'] as $k => $extgstate) { if (isset($this->extgstates[$k]['name'])) { $out .= ' /'.$this->extgstates[$k]['name']; } else { $out .= ' /GS'.$k; } $out .= ' '.$this->extgstates[$k]['n'].' 0 R'; } $out .= ' >>'; } if (isset($data['gradients']) AND !empty($data['gradients'])) { $gp = ''; $gs = ''; foreach ($data['gradients'] as $id => $grad) { // gradient patterns $gp .= ' /p'.$id.' '.$this->gradients[$id]['pattern'].' 0 R'; // gradient shadings $gs .= ' /Sh'.$id.' '.$this->gradients[$id]['id'].' 0 R'; } $out .= ' /Pattern <<'.$gp.' >>'; $out .= ' /Shading <<'.$gs.' >>'; } } // spot colors if (isset($data['spot_colors']) AND !empty($data['spot_colors'])) { $out .= ' /ColorSpace <<'; foreach ($data['spot_colors'] as $name => $color) { $out .= ' /CS'.$color['i'].' '.$this->spot_colors[$name]['n'].' 0 R'; } $out .= ' >>'; } // fonts if (!empty($data['fonts'])) { $out .= ' /Font <<'; foreach ($data['fonts'] as $fontkey => $fontid) { $out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R'; } $out .= ' >>'; } // images or nested xobjects if (!empty($data['images']) OR !empty($data['xobjects'])) { $out .= ' /XObject <<'; foreach ($data['images'] as $imgid) { $out .= ' /I'.$imgid.' '.$this->xobjects['I'.$imgid]['n'].' 0 R'; } foreach ($data['xobjects'] as $sub_id => $sub_objid) { $out .= ' /'.$sub_id.' '.$sub_objid['n'].' 0 R'; } $out .= ' >>'; } $out .= ' >>'; //end resources if (isset($data['group']) AND ($data['group'] !== false)) { // set transparency group $out .= ' /Group << /Type /Group /S /Transparency'; if (is_array($data['group'])) { if (isset($data['group']['CS']) AND !empty($data['group']['CS'])) { $out .= ' /CS /'.$data['group']['CS']; } if (isset($data['group']['I'])) { $out .= ' /I /'.($data['group']['I']===true?'true':'false'); } if (isset($data['group']['K'])) { $out .= ' /K /'.($data['group']['K']===true?'true':'false'); } } $out .= ' >>'; } $stream = $this->_getrawstream($stream, $data['n']); $out .= ' /Length '.strlen($stream); $out .= ' >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; $out .= "\n".'endobj'; $this->_out($out); } } } /** * Output Spot Colors Resources. * @protected * @since 4.0.024 (2008-09-12) */ protected function _putspotcolors() { foreach ($this->spot_colors as $name => $color) { $this->_newobj(); $this->spot_colors[$name]['n'] = $this->n; $out = '[/Separation /'.str_replace(' ', '#20', $name); $out .= ' /DeviceCMYK <<'; $out .= ' /Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0]'; $out .= ' '.sprintf('/C1 [%F %F %F %F] ', ($color['C'] / 100), ($color['M'] / 100), ($color['Y'] / 100), ($color['K'] / 100)); $out .= ' /FunctionType 2 /Domain [0 1] /N 1>>]'; $out .= "\n".'endobj'; $this->_out($out); } } /** * Return XObjects Dictionary. * @return string XObjects dictionary * @protected * @since 5.8.014 (2010-08-23) */ protected function _getxobjectdict() { $out = ''; foreach ($this->xobjects as $id => $objid) { $out .= ' /'.$id.' '.$objid['n'].' 0 R'; } return $out; } /** * Output Resources Dictionary. * @protected */ protected function _putresourcedict() { $out = $this->_getobj(2)."\n"; $out .= '<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'; $out .= ' /Font <<'; foreach ($this->fontkeys as $fontkey) { $font = $this->getFontBuffer($fontkey); $out .= ' /F'.$font['i'].' '.$font['n'].' 0 R'; } $out .= ' >>'; $out .= ' /XObject <<'; $out .= $this->_getxobjectdict(); $out .= ' >>'; // layers if (!empty($this->pdflayers)) { $out .= ' /Properties <<'; foreach ($this->pdflayers as $layer) { $out .= ' /'.$layer['layer'].' '.$layer['objid'].' 0 R'; } $out .= ' >>'; } if (!$this->pdfa_mode) { // transparency if (isset($this->extgstates) AND !empty($this->extgstates)) { $out .= ' /ExtGState <<'; foreach ($this->extgstates as $k => $extgstate) { if (isset($extgstate['name'])) { $out .= ' /'.$extgstate['name']; } else { $out .= ' /GS'.$k; } $out .= ' '.$extgstate['n'].' 0 R'; } $out .= ' >>'; } if (isset($this->gradients) AND !empty($this->gradients)) { $gp = ''; $gs = ''; foreach ($this->gradients as $id => $grad) { // gradient patterns $gp .= ' /p'.$id.' '.$grad['pattern'].' 0 R'; // gradient shadings $gs .= ' /Sh'.$id.' '.$grad['id'].' 0 R'; } $out .= ' /Pattern <<'.$gp.' >>'; $out .= ' /Shading <<'.$gs.' >>'; } } // spot colors if (isset($this->spot_colors) AND !empty($this->spot_colors)) { $out .= ' /ColorSpace <<'; foreach ($this->spot_colors as $color) { $out .= ' /CS'.$color['i'].' '.$color['n'].' 0 R'; } $out .= ' >>'; } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } /** * Output Resources. * @protected */ protected function _putresources() { $this->_putextgstates(); $this->_putocg(); $this->_putfonts(); $this->_putimages(); $this->_putspotcolors(); $this->_putshaders(); $this->_putxobjects(); $this->_putresourcedict(); $this->_putdests(); $this->_putEmbeddedFiles(); $this->_putannotsobjs(); $this->_putjavascript(); $this->_putbookmarks(); $this->_putencryption(); } /** * Adds some Metadata information (Document Information Dictionary) * (see Chapter 14.3.3 Document Information Dictionary of PDF32000_2008.pdf Reference) * @return int object id * @protected */ protected function _putinfo() { $oid = $this->_newobj(); $out = '<<'; // store current isunicode value $prev_isunicode = $this->isunicode; if ($this->docinfounicode) { $this->isunicode = true; } if (!TCPDF_STATIC::empty_string($this->title)) { // The document's title. $out .= ' /Title '.$this->_textstring($this->title, $oid); } if (!TCPDF_STATIC::empty_string($this->author)) { // The name of the person who created the document. $out .= ' /Author '.$this->_textstring($this->author, $oid); } if (!TCPDF_STATIC::empty_string($this->subject)) { // The subject of the document. $out .= ' /Subject '.$this->_textstring($this->subject, $oid); } if (!TCPDF_STATIC::empty_string($this->keywords)) { // Keywords associated with the document. $out .= ' /Keywords '.$this->_textstring($this->keywords.' TCPDF', $oid); } if (!TCPDF_STATIC::empty_string($this->creator)) { // If the document was converted to PDF from another format, the name of the conforming product that created the original document from which it was converted. $out .= ' /Creator '.$this->_textstring($this->creator, $oid); } // restore previous isunicode value $this->isunicode = $prev_isunicode; // default producer $out .= ' /Producer '.$this->_textstring(TCPDF_STATIC::getTCPDFProducer(), $oid); // The date and time the document was created, in human-readable form $out .= ' /CreationDate '.$this->_datestring(0, $this->doc_creation_timestamp); // The date and time the document was most recently modified, in human-readable form $out .= ' /ModDate '.$this->_datestring(0, $this->doc_modification_timestamp); // A name object indicating whether the document has been modified to include trapping information $out .= ' /Trapped /False'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); return $oid; } /** * Set additional XMP data to be added on the default XMP data just before the end of "x:xmpmeta" tag. * IMPORTANT: This data is added as-is without controls, so you have to validate your data before using this method! * @param $xmp (string) Custom XMP data. * @since 5.9.128 (2011-10-06) * @public */ public function setExtraXMP($xmp) { $this->custom_xmp = $xmp; } /** * Put XMP data object and return ID. * @return (int) The object ID. * @since 5.9.121 (2011-09-28) * @protected */ protected function _putXMP() { $oid = $this->_newobj(); // store current isunicode value $prev_isunicode = $this->isunicode; $this->isunicode = true; $prev_encrypted = $this->encrypted; $this->encrypted = false; // set XMP data $xmp = '<?xpacket begin="'.TCPDF_FONTS::unichr(0xfeff, $this->isunicode).'" id="W5M0MpCehiHzreSzNTczkc9d"?>'."\n"; $xmp .= '<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:08:04">'."\n"; $xmp .= "\t".'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'."\n"; $xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n"; $xmp .= "\t\t\t".'<dc:format>application/pdf</dc:format>'."\n"; $xmp .= "\t\t\t".'<dc:title>'."\n"; $xmp .= "\t\t\t\t".'<rdf:Alt>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li xml:lang="x-default">'.TCPDF_STATIC::_escapeXML($this->title).'</rdf:li>'."\n"; $xmp .= "\t\t\t\t".'</rdf:Alt>'."\n"; $xmp .= "\t\t\t".'</dc:title>'."\n"; $xmp .= "\t\t\t".'<dc:creator>'."\n"; $xmp .= "\t\t\t\t".'<rdf:Seq>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li>'.TCPDF_STATIC::_escapeXML($this->author).'</rdf:li>'."\n"; $xmp .= "\t\t\t\t".'</rdf:Seq>'."\n"; $xmp .= "\t\t\t".'</dc:creator>'."\n"; $xmp .= "\t\t\t".'<dc:description>'."\n"; $xmp .= "\t\t\t\t".'<rdf:Alt>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li xml:lang="x-default">'.TCPDF_STATIC::_escapeXML($this->subject).'</rdf:li>'."\n"; $xmp .= "\t\t\t\t".'</rdf:Alt>'."\n"; $xmp .= "\t\t\t".'</dc:description>'."\n"; $xmp .= "\t\t\t".'<dc:subject>'."\n"; $xmp .= "\t\t\t\t".'<rdf:Bag>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li>'.TCPDF_STATIC::_escapeXML($this->keywords).' TCPDF</rdf:li>'."\n"; $xmp .= "\t\t\t\t".'</rdf:Bag>'."\n"; $xmp .= "\t\t\t".'</dc:subject>'."\n"; $xmp .= "\t\t".'</rdf:Description>'."\n"; // convert doc creation date format $dcdate = TCPDF_STATIC::getFormattedDate($this->doc_creation_timestamp); $doccreationdate = substr($dcdate, 0, 4).'-'.substr($dcdate, 4, 2).'-'.substr($dcdate, 6, 2); $doccreationdate .= 'T'.substr($dcdate, 8, 2).':'.substr($dcdate, 10, 2).':'.substr($dcdate, 12, 2); $doccreationdate .= '+'.substr($dcdate, 15, 2).':'.substr($dcdate, 18, 2); $doccreationdate = TCPDF_STATIC::_escapeXML($doccreationdate); // convert doc modification date format $dmdate = TCPDF_STATIC::getFormattedDate($this->doc_modification_timestamp); $docmoddate = substr($dmdate, 0, 4).'-'.substr($dmdate, 4, 2).'-'.substr($dmdate, 6, 2); $docmoddate .= 'T'.substr($dmdate, 8, 2).':'.substr($dmdate, 10, 2).':'.substr($dmdate, 12, 2); $docmoddate .= '+'.substr($dmdate, 15, 2).':'.substr($dmdate, 18, 2); $docmoddate = TCPDF_STATIC::_escapeXML($docmoddate); $xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">'."\n"; $xmp .= "\t\t\t".'<xmp:CreateDate>'.$doccreationdate.'</xmp:CreateDate>'."\n"; $xmp .= "\t\t\t".'<xmp:CreatorTool>'.$this->creator.'</xmp:CreatorTool>'."\n"; $xmp .= "\t\t\t".'<xmp:ModifyDate>'.$docmoddate.'</xmp:ModifyDate>'."\n"; $xmp .= "\t\t\t".'<xmp:MetadataDate>'.$doccreationdate.'</xmp:MetadataDate>'."\n"; $xmp .= "\t\t".'</rdf:Description>'."\n"; $xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:pdf="http://ns.adobe.com/pdf/1.3/">'."\n"; $xmp .= "\t\t\t".'<pdf:Keywords>'.TCPDF_STATIC::_escapeXML($this->keywords).' TCPDF</pdf:Keywords>'."\n"; $xmp .= "\t\t\t".'<pdf:Producer>'.TCPDF_STATIC::_escapeXML(TCPDF_STATIC::getTCPDFProducer()).'</pdf:Producer>'."\n"; $xmp .= "\t\t".'</rdf:Description>'."\n"; $xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">'."\n"; $uuid = 'uuid:'.substr($this->file_id, 0, 8).'-'.substr($this->file_id, 8, 4).'-'.substr($this->file_id, 12, 4).'-'.substr($this->file_id, 16, 4).'-'.substr($this->file_id, 20, 12); $xmp .= "\t\t\t".'<xmpMM:DocumentID>'.$uuid.'</xmpMM:DocumentID>'."\n"; $xmp .= "\t\t\t".'<xmpMM:InstanceID>'.$uuid.'</xmpMM:InstanceID>'."\n"; $xmp .= "\t\t".'</rdf:Description>'."\n"; if ($this->pdfa_mode) { $xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">'."\n"; $xmp .= "\t\t\t".'<pdfaid:part>1</pdfaid:part>'."\n"; $xmp .= "\t\t\t".'<pdfaid:conformance>B</pdfaid:conformance>'."\n"; $xmp .= "\t\t".'</rdf:Description>'."\n"; } // XMP extension schemas $xmp .= "\t\t".'<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">'."\n"; $xmp .= "\t\t\t".'<pdfaExtension:schemas>'."\n"; $xmp .= "\t\t\t\t".'<rdf:Bag>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:namespaceURI>http://ns.adobe.com/pdf/1.3/</pdfaSchema:namespaceURI>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:prefix>pdf</pdfaSchema:prefix>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema>'."\n"; $xmp .= "\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:namespaceURI>http://ns.adobe.com/xap/1.0/mm/</pdfaSchema:namespaceURI>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:prefix>xmpMM</pdfaSchema:prefix>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>XMP Media Management Schema</pdfaSchema:schema>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:property>'."\n"; $xmp .= "\t\t\t\t\t\t\t".'<rdf:Seq>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>UUID based identifier for specific incarnation of a document</pdfaProperty:description>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>InstanceID</pdfaProperty:name>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>URI</pdfaProperty:valueType>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t\t\t\t".'</rdf:Seq>'."\n"; $xmp .= "\t\t\t\t\t\t".'</pdfaSchema:property>'."\n"; $xmp .= "\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:namespaceURI>http://www.aiim.org/pdfa/ns/id/</pdfaSchema:namespaceURI>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:prefix>pdfaid</pdfaSchema:prefix>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>PDF/A ID Schema</pdfaSchema:schema>'."\n"; $xmp .= "\t\t\t\t\t\t".'<pdfaSchema:property>'."\n"; $xmp .= "\t\t\t\t\t\t\t".'<rdf:Seq>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>Part of PDF/A standard</pdfaProperty:description>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>part</pdfaProperty:name>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Integer</pdfaProperty:valueType>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>Amendment of PDF/A standard</pdfaProperty:description>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>amd</pdfaProperty:name>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Text</pdfaProperty:valueType>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>Conformance level of PDF/A standard</pdfaProperty:description>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>conformance</pdfaProperty:name>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Text</pdfaProperty:valueType>'."\n"; $xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t\t\t\t".'</rdf:Seq>'."\n"; $xmp .= "\t\t\t\t\t\t".'</pdfaSchema:property>'."\n"; $xmp .= "\t\t\t\t\t".'</rdf:li>'."\n"; $xmp .= "\t\t\t\t".'</rdf:Bag>'."\n"; $xmp .= "\t\t\t".'</pdfaExtension:schemas>'."\n"; $xmp .= "\t\t".'</rdf:Description>'."\n"; $xmp .= "\t".'</rdf:RDF>'."\n"; $xmp .= $this->custom_xmp; $xmp .= '</x:xmpmeta>'."\n"; $xmp .= '<?xpacket end="w"?>'; $out = '<< /Type /Metadata /Subtype /XML /Length '.strlen($xmp).' >> stream'."\n".$xmp."\n".'endstream'."\n".'endobj'; // restore previous isunicode value $this->isunicode = $prev_isunicode; $this->encrypted = $prev_encrypted; $this->_out($out); return $oid; } /** * Output Catalog. * @return int object id * @protected */ protected function _putcatalog() { // put XMP $xmpobj = $this->_putXMP(); // if required, add standard sRGB_IEC61966-2.1 blackscaled ICC colour profile if ($this->pdfa_mode OR $this->force_srgb) { $iccobj = $this->_newobj(); $icc = file_get_contents(dirname(__FILE__).'/include/sRGB.icc'); $filter = ''; if ($this->compress) { $filter = ' /Filter /FlateDecode'; $icc = gzcompress($icc); } $icc = $this->_getrawstream($icc); $this->_out('<</N 3 '.$filter.'/Length '.strlen($icc).'>> stream'."\n".$icc."\n".'endstream'."\n".'endobj'); } // start catalog $oid = $this->_newobj(); $out = '<< /Type /Catalog'; $out .= ' /Version /'.$this->PDFVersion; //$out .= ' /Extensions <<>>'; $out .= ' /Pages 1 0 R'; //$out .= ' /PageLabels ' //...; $out .= ' /Names <<'; if ((!$this->pdfa_mode) AND !empty($this->n_js)) { $out .= ' /JavaScript '.$this->n_js; } if (!empty($this->efnames)) { $out .= ' /EmbeddedFiles <</Names ['; foreach ($this->efnames AS $fn => $fref) { $out .= ' '.$this->_datastring($fn).' '.$fref; } $out .= ' ]>>'; } $out .= ' >>'; if (!empty($this->dests)) { $out .= ' /Dests '.($this->n_dests).' 0 R'; } $out .= $this->_putviewerpreferences(); if (isset($this->LayoutMode) AND (!TCPDF_STATIC::empty_string($this->LayoutMode))) { $out .= ' /PageLayout /'.$this->LayoutMode; } if (isset($this->PageMode) AND (!TCPDF_STATIC::empty_string($this->PageMode))) { $out .= ' /PageMode /'.$this->PageMode; } if (count($this->outlines) > 0) { $out .= ' /Outlines '.$this->OutlineRoot.' 0 R'; $out .= ' /PageMode /UseOutlines'; } //$out .= ' /Threads []'; if ($this->ZoomMode == 'fullpage') { $out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /Fit]'; } elseif ($this->ZoomMode == 'fullwidth') { $out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /FitH null]'; } elseif ($this->ZoomMode == 'real') { $out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /XYZ null null 1]'; } elseif (!is_string($this->ZoomMode)) { $out .= sprintf(' /OpenAction ['.$this->page_obj_id[1].' 0 R /XYZ null null %F]', ($this->ZoomMode / 100)); } //$out .= ' /AA <<>>'; //$out .= ' /URI <<>>'; $out .= ' /Metadata '.$xmpobj.' 0 R'; //$out .= ' /StructTreeRoot <<>>'; //$out .= ' /MarkInfo <<>>'; if (isset($this->l['a_meta_language'])) { $out .= ' /Lang '.$this->_textstring($this->l['a_meta_language'], $oid); } //$out .= ' /SpiderInfo <<>>'; // set OutputIntent to sRGB IEC61966-2.1 if required if ($this->pdfa_mode OR $this->force_srgb) { $out .= ' /OutputIntents [<<'; $out .= ' /Type /OutputIntent'; $out .= ' /S /GTS_PDFA1'; $out .= ' /OutputCondition '.$this->_textstring('sRGB IEC61966-2.1', $oid); $out .= ' /OutputConditionIdentifier '.$this->_textstring('sRGB IEC61966-2.1', $oid); $out .= ' /RegistryName '.$this->_textstring('http://www.color.org', $oid); $out .= ' /Info '.$this->_textstring('sRGB IEC61966-2.1', $oid); $out .= ' /DestOutputProfile '.$iccobj.' 0 R'; $out .= ' >>]'; } //$out .= ' /PieceInfo <<>>'; if (!empty($this->pdflayers)) { $lyrobjs = ''; $lyrobjs_print = ''; $lyrobjs_view = ''; foreach ($this->pdflayers as $layer) { $lyrobjs .= ' '.$layer['objid'].' 0 R'; if ($layer['print']) { $lyrobjs_print .= ' '.$layer['objid'].' 0 R'; } if ($layer['view']) { $lyrobjs_view .= ' '.$layer['objid'].' 0 R'; } } $out .= ' /OCProperties << /OCGs ['.$lyrobjs.']'; $out .= ' /D <<'; $out .= ' /Name '.$this->_textstring('Layers', $oid); $out .= ' /Creator '.$this->_textstring('TCPDF', $oid); $out .= ' /BaseState /ON'; $out .= ' /ON ['.$lyrobjs_print.']'; $out .= ' /OFF ['.$lyrobjs_view.']'; $out .= ' /Intent /View'; $out .= ' /AS ['; $out .= ' << /Event /Print /OCGs ['.$lyrobjs.'] /Category [/Print] >>'; $out .= ' << /Event /View /OCGs ['.$lyrobjs.'] /Category [/View] >>'; $out .= ' ]'; $out .= ' /Order ['.$lyrobjs.']'; $out .= ' /ListMode /AllPages'; //$out .= ' /RBGroups ['..']'; //$out .= ' /Locked ['..']'; $out .= ' >>'; $out .= ' >>'; } // AcroForm if (!empty($this->form_obj_id) OR ($this->sign AND isset($this->signature_data['cert_type']))) { $out .= ' /AcroForm <<'; $objrefs = ''; if ($this->sign AND isset($this->signature_data['cert_type'])) { // set reference for signature object $objrefs .= $this->sig_obj_id.' 0 R'; } if (!empty($this->empty_signature_appearance)) { foreach ($this->empty_signature_appearance as $esa) { // set reference for empty signature objects $objrefs .= ' '.$esa['objid'].' 0 R'; } } if (!empty($this->form_obj_id)) { foreach($this->form_obj_id as $objid) { $objrefs .= ' '.$objid.' 0 R'; } } $out .= ' /Fields ['.$objrefs.']'; // It's better to turn off this value and set the appearance stream for each annotation (/AP) to avoid conflicts with signature fields. $out .= ' /NeedAppearances false'; if ($this->sign AND isset($this->signature_data['cert_type'])) { if ($this->signature_data['cert_type'] > 0) { $out .= ' /SigFlags 3'; } else { $out .= ' /SigFlags 1'; } } //$out .= ' /CO '; if (isset($this->annotation_fonts) AND !empty($this->annotation_fonts)) { $out .= ' /DR <<'; $out .= ' /Font <<'; foreach ($this->annotation_fonts as $fontkey => $fontid) { $out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R'; } $out .= ' >> >>'; } $font = $this->getFontBuffer('helvetica'); $out .= ' /DA (/F'.$font['i'].' 0 Tf 0 g)'; $out .= ' /Q '.(($this->rtl)?'2':'0'); //$out .= ' /XFA '; $out .= ' >>'; // signatures if ($this->sign AND isset($this->signature_data['cert_type'])) { if ($this->signature_data['cert_type'] > 0) { $out .= ' /Perms << /DocMDP '.($this->sig_obj_id + 1).' 0 R >>'; } else { $out .= ' /Perms << /UR3 '.($this->sig_obj_id + 1).' 0 R >>'; } } } //$out .= ' /Legal <<>>'; //$out .= ' /Requirements []'; //$out .= ' /Collection <<>>'; //$out .= ' /NeedsRendering true'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); return $oid; } /** * Output viewer preferences. * @return string for viewer preferences * @author Nicola asuni * @since 3.1.000 (2008-06-09) * @protected */ protected function _putviewerpreferences() { $vp = $this->viewer_preferences; $out = ' /ViewerPreferences <<'; if ($this->rtl) { $out .= ' /Direction /R2L'; } else { $out .= ' /Direction /L2R'; } if (isset($vp['HideToolbar']) AND ($vp['HideToolbar'])) { $out .= ' /HideToolbar true'; } if (isset($vp['HideMenubar']) AND ($vp['HideMenubar'])) { $out .= ' /HideMenubar true'; } if (isset($vp['HideWindowUI']) AND ($vp['HideWindowUI'])) { $out .= ' /HideWindowUI true'; } if (isset($vp['FitWindow']) AND ($vp['FitWindow'])) { $out .= ' /FitWindow true'; } if (isset($vp['CenterWindow']) AND ($vp['CenterWindow'])) { $out .= ' /CenterWindow true'; } if (isset($vp['DisplayDocTitle']) AND ($vp['DisplayDocTitle'])) { $out .= ' /DisplayDocTitle true'; } if (isset($vp['NonFullScreenPageMode'])) { $out .= ' /NonFullScreenPageMode /'.$vp['NonFullScreenPageMode']; } if (isset($vp['ViewArea'])) { $out .= ' /ViewArea /'.$vp['ViewArea']; } if (isset($vp['ViewClip'])) { $out .= ' /ViewClip /'.$vp['ViewClip']; } if (isset($vp['PrintArea'])) { $out .= ' /PrintArea /'.$vp['PrintArea']; } if (isset($vp['PrintClip'])) { $out .= ' /PrintClip /'.$vp['PrintClip']; } if (isset($vp['PrintScaling'])) { $out .= ' /PrintScaling /'.$vp['PrintScaling']; } if (isset($vp['Duplex']) AND (!TCPDF_STATIC::empty_string($vp['Duplex']))) { $out .= ' /Duplex /'.$vp['Duplex']; } if (isset($vp['PickTrayByPDFSize'])) { if ($vp['PickTrayByPDFSize']) { $out .= ' /PickTrayByPDFSize true'; } else { $out .= ' /PickTrayByPDFSize false'; } } if (isset($vp['PrintPageRange'])) { $PrintPageRangeNum = ''; foreach ($vp['PrintPageRange'] as $k => $v) { $PrintPageRangeNum .= ' '.($v - 1).''; } $out .= ' /PrintPageRange ['.substr($PrintPageRangeNum,1).']'; } if (isset($vp['NumCopies'])) { $out .= ' /NumCopies '.intval($vp['NumCopies']); } $out .= ' >>'; return $out; } /** * Output PDF File Header (7.5.2). * @protected */ protected function _putheader() { $this->_out('%PDF-'.$this->PDFVersion); $this->_out('%'.chr(0xe2).chr(0xe3).chr(0xcf).chr(0xd3)); } /** * Output end of document (EOF). * @protected */ protected function _enddoc() { if (isset($this->CurrentFont['fontkey']) AND isset($this->CurrentFont['subsetchars'])) { // save subset chars of the previous font $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']); } $this->state = 1; $this->_putheader(); $this->_putpages(); $this->_putresources(); // empty signature fields if (!empty($this->empty_signature_appearance)) { foreach ($this->empty_signature_appearance as $key => $esa) { // widget annotation for empty signature $out = $this->_getobj($esa['objid'])."\n"; $out .= '<< /Type /Annot'; $out .= ' /Subtype /Widget'; $out .= ' /Rect ['.$esa['rect'].']'; $out .= ' /P '.$this->page_obj_id[($esa['page'])].' 0 R'; // link to signature appearance page $out .= ' /F 4'; $out .= ' /FT /Sig'; $signame = $esa['name'].sprintf(' [%03d]', ($key + 1)); $out .= ' /T '.$this->_textstring($signame, $esa['objid']); $out .= ' /Ff 0'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } } // Signature if ($this->sign AND isset($this->signature_data['cert_type'])) { // widget annotation for signature $out = $this->_getobj($this->sig_obj_id)."\n"; $out .= '<< /Type /Annot'; $out .= ' /Subtype /Widget'; $out .= ' /Rect ['.$this->signature_appearance['rect'].']'; $out .= ' /P '.$this->page_obj_id[($this->signature_appearance['page'])].' 0 R'; // link to signature appearance page $out .= ' /F 4'; $out .= ' /FT /Sig'; $out .= ' /T '.$this->_textstring($this->signature_appearance['name'], $this->sig_obj_id); $out .= ' /Ff 0'; $out .= ' /V '.($this->sig_obj_id + 1).' 0 R'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); // signature $this->_putsignature(); } // Info $objid_info = $this->_putinfo(); // Catalog $objid_catalog = $this->_putcatalog(); // Cross-ref $o = $this->bufferlen; // XREF section $this->_out('xref'); $this->_out('0 '.($this->n + 1)); $this->_out('0000000000 65535 f '); $freegen = ($this->n + 2); for ($i=1; $i <= $this->n; ++$i) { if (!isset($this->offsets[$i]) AND ($i > 1)) { $this->_out(sprintf('0000000000 %05d f ', $freegen)); ++$freegen; } else { $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i])); } } // TRAILER $out = 'trailer'."\n"; $out .= '<<'; $out .= ' /Size '.($this->n + 1); $out .= ' /Root '.$objid_catalog.' 0 R'; $out .= ' /Info '.$objid_info.' 0 R'; if ($this->encrypted) { $out .= ' /Encrypt '.$this->encryptdata['objid'].' 0 R'; } $out .= ' /ID [ <'.$this->file_id.'> <'.$this->file_id.'> ]'; $out .= ' >>'; $this->_out($out); $this->_out('startxref'); $this->_out($o); $this->_out('%%EOF'); $this->state = 3; // end-of-doc if ($this->diskcache) { // remove temporary files used for images foreach ($this->imagekeys as $key) { // remove temporary files unlink($this->images[$key]); } foreach ($this->fontkeys as $key) { // remove temporary files unlink($this->fonts[$key]); } } } /** * Initialize a new page. * @param $orientation (string) page orientation. Possible values are (case insensitive):<ul><li>P or PORTRAIT (default)</li><li>L or LANDSCAPE</li></ul> * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat(). * @protected * @see getPageSizeFromFormat(), setPageFormat() */ protected function _beginpage($orientation='', $format='') { ++$this->page; $this->pageobjects[$this->page] = array(); $this->setPageBuffer($this->page, ''); // initialize array for graphics tranformation positions inside a page buffer $this->transfmrk[$this->page] = array(); $this->state = 2; if (TCPDF_STATIC::empty_string($orientation)) { if (isset($this->CurOrientation)) { $orientation = $this->CurOrientation; } elseif ($this->fwPt > $this->fhPt) { // landscape $orientation = 'L'; } else { // portrait $orientation = 'P'; } } if (TCPDF_STATIC::empty_string($format)) { $this->pagedim[$this->page] = $this->pagedim[($this->page - 1)]; $this->setPageOrientation($orientation); } else { $this->setPageFormat($format, $orientation); } if ($this->rtl) { $this->x = $this->w - $this->rMargin; } else { $this->x = $this->lMargin; } $this->y = $this->tMargin; if (isset($this->newpagegroup[$this->page])) { // start a new group $this->currpagegroup = $this->newpagegroup[$this->page]; $this->pagegroups[$this->currpagegroup] = 1; } elseif (isset($this->currpagegroup) AND ($this->currpagegroup > 0)) { ++$this->pagegroups[$this->currpagegroup]; } } /** * Mark end of page. * @protected */ protected function _endpage() { $this->setVisibility('all'); $this->state = 1; } /** * Begin a new object and return the object number. * @return int object number * @protected */ protected function _newobj() { $this->_out($this->_getobj()); return $this->n; } /** * Return the starting object string for the selected object ID. * @param $objid (int) Object ID (leave empty to get a new ID). * @return string the starting object string * @protected * @since 5.8.009 (2010-08-20) */ protected function _getobj($objid='') { if ($objid === '') { ++$this->n; $objid = $this->n; } $this->offsets[$objid] = $this->bufferlen; $this->pageobjects[$this->page][] = $objid; return $objid.' 0 obj'; } /** * Underline text. * @param $x (int) X coordinate * @param $y (int) Y coordinate * @param $txt (string) text to underline * @protected */ protected function _dounderline($x, $y, $txt) { $w = $this->GetStringWidth($txt); return $this->_dounderlinew($x, $y, $w); } /** * Underline for rectangular text area. * @param $x (int) X coordinate * @param $y (int) Y coordinate * @param $w (int) width to underline * @protected * @since 4.8.008 (2009-09-29) */ protected function _dounderlinew($x, $y, $w) { $linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt; return sprintf('%F %F %F %F re f', $x * $this->k, ((($this->h - $y) * $this->k) + $linew), $w * $this->k, $linew); } /** * Line through text. * @param $x (int) X coordinate * @param $y (int) Y coordinate * @param $txt (string) text to linethrough * @protected */ protected function _dolinethrough($x, $y, $txt) { $w = $this->GetStringWidth($txt); return $this->_dolinethroughw($x, $y, $w); } /** * Line through for rectangular text area. * @param $x (int) X coordinate * @param $y (int) Y coordinate * @param $w (int) line length (width) * @protected * @since 4.9.008 (2009-09-29) */ protected function _dolinethroughw($x, $y, $w) { $linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt; return sprintf('%F %F %F %F re f', $x * $this->k, ((($this->h - $y) * $this->k) + $linew + ($this->FontSizePt / 3)), $w * $this->k, $linew); } /** * Overline text. * @param $x (int) X coordinate * @param $y (int) Y coordinate * @param $txt (string) text to overline * @protected * @since 4.9.015 (2010-04-19) */ protected function _dooverline($x, $y, $txt) { $w = $this->GetStringWidth($txt); return $this->_dooverlinew($x, $y, $w); } /** * Overline for rectangular text area. * @param $x (int) X coordinate * @param $y (int) Y coordinate * @param $w (int) width to overline * @protected * @since 4.9.015 (2010-04-19) */ protected function _dooverlinew($x, $y, $w) { $linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt; return sprintf('%F %F %F %F re f', $x * $this->k, (($this->h - $y + $this->FontAscent) * $this->k) - $linew, $w * $this->k, $linew); } /** * Format a data string for meta information * @param $s (string) data string to escape. * @param $n (int) object ID * @return string escaped string. * @protected */ protected function _datastring($s, $n=0) { if ($n == 0) { $n = $this->n; } $s = $this->_encrypt_data($n, $s); return '('. TCPDF_STATIC::_escape($s).')'; } /** * Set the document creation timestamp * @param $time (mixed) Document creation timestamp in seconds or date-time string. * @public * @since 5.9.152 (2012-03-23) */ public function setDocCreationTimestamp($time) { if (is_string($time)) { $time = TCPDF_STATIC::getTimestamp($time); } $this->doc_creation_timestamp = intval($time); } /** * Set the document modification timestamp * @param $time (mixed) Document modification timestamp in seconds or date-time string. * @public * @since 5.9.152 (2012-03-23) */ public function setDocModificationTimestamp($time) { if (is_string($time)) { $time = TCPDF_STATIC::getTimestamp($time); } $this->doc_modification_timestamp = intval($time); } /** * Returns document creation timestamp in seconds. * @return (int) Creation timestamp in seconds. * @public * @since 5.9.152 (2012-03-23) */ public function getDocCreationTimestamp() { return $this->doc_creation_timestamp; } /** * Returns document modification timestamp in seconds. * @return (int) Modfication timestamp in seconds. * @public * @since 5.9.152 (2012-03-23) */ public function getDocModificationTimestamp() { return $this->doc_modification_timestamp; } /** * Returns a formatted date for meta information * @param $n (int) Object ID. * @param $timestamp (int) Timestamp to convert. * @return string escaped date string. * @protected * @since 4.6.028 (2009-08-25) */ protected function _datestring($n=0, $timestamp=0) { if ((empty($timestamp)) OR ($timestamp < 0)) { $timestamp = $this->doc_creation_timestamp; } return $this->_datastring('D:'.TCPDF_STATIC::getFormattedDate($timestamp), $n); } /** * Format a text string for meta information * @param $s (string) string to escape. * @param $n (int) object ID * @return string escaped string. * @protected */ protected function _textstring($s, $n=0) { if ($this->isunicode) { //Convert string to UTF-16BE $s = TCPDF_FONTS::UTF8ToUTF16BE($s, true, $this->isunicode, $this->CurrentFont); } return $this->_datastring($s, $n); } /** * THIS METHOD IS DEPRECATED * Format a text string * @param $s (string) string to escape. * @return string escaped string. * @protected * @deprecated */ protected function _escapetext($s) { if ($this->isunicode) { if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) { $s = TCPDF_FONTS::UTF8ToLatin1($s, $this->isunicode, $this->CurrentFont); } else { //Convert string to UTF-16BE and reverse RTL language $s = TCPDF_FONTS::utf8StrRev($s, false, $this->tmprtl, $this->isunicode, $this->CurrentFont); } } return TCPDF_STATIC::_escape($s); } /** * get raw output stream. * @param $s (string) string to output. * @param $n (int) object reference for encryption mode * @protected * @author Nicola Asuni * @since 5.5.000 (2010-06-22) */ protected function _getrawstream($s, $n=0) { if ($n <= 0) { // default to current object $n = $this->n; } return $this->_encrypt_data($n, $s); } /** * Format output stream (DEPRECATED). * @param $s (string) string to output. * @param $n (int) object reference for encryption mode * @protected * @deprecated */ protected function _getstream($s, $n=0) { return 'stream'."\n".$this->_getrawstream($s, $n)."\n".'endstream'; } /** * Output a stream (DEPRECATED). * @param $s (string) string to output. * @param $n (int) object reference for encryption mode * @protected * @deprecated */ protected function _putstream($s, $n=0) { $this->_out($this->_getstream($s, $n)); } /** * Output a string to the document. * @param $s (string) string to output. * @protected */ protected function _out($s) { if ($this->state == 2) { if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['outdata'] .= $s."\n"; } elseif ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { // puts data before page footer $pagebuff = $this->getPageBuffer($this->page); $page = substr($pagebuff, 0, -$this->footerlen[$this->page]); $footer = substr($pagebuff, -$this->footerlen[$this->page]); $this->setPageBuffer($this->page, $page.$s."\n".$footer); // update footer position $this->footerpos[$this->page] += strlen($s."\n"); } else { // set page data $this->setPageBuffer($this->page, $s."\n", true); } } elseif ($this->state > 0) { // set general data $this->setBuffer($s."\n"); } } /** * Set header font. * @param $font (array) font * @public * @since 1.1 */ public function setHeaderFont($font) { $this->header_font = $font; } /** * Get header font. * @return array() * @public * @since 4.0.012 (2008-07-24) */ public function getHeaderFont() { return $this->header_font; } /** * Set footer font. * @param $font (array) font * @public * @since 1.1 */ public function setFooterFont($font) { $this->footer_font = $font; } /** * Get Footer font. * @return array() * @public * @since 4.0.012 (2008-07-24) */ public function getFooterFont() { return $this->footer_font; } /** * Set language array. * @param $language (array) * @public * @since 1.1 */ public function setLanguageArray($language) { $this->l = $language; if (isset($this->l['a_meta_dir'])) { $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false; } else { $this->rtl = false; } } /** * Returns the PDF data. * @public */ public function getPDFData() { if ($this->state < 3) { $this->Close(); } return $this->buffer; } /** * Output anchor link. * @param $url (string) link URL or internal link (i.e.: <a href="#23,4.5">link to page 23 at 4.5 Y position</a>) * @param $name (string) link name * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $firstline (boolean) if true prints only the first line and return the remaining string. * @param $color (array) array of RGB text color * @param $style (string) font style (U, D, B, I) * @param $firstblock (boolean) if true the string is the starting of a line. * @return the number of cells used or the remaining text if $firstline = true; * @public */ public function addHtmlLink($url, $name, $fill=false, $firstline=false, $color='', $style=-1, $firstblock=false) { if (!TCPDF_STATIC::empty_string($url) AND ($url[0] == '#') AND is_numeric($url[1])) { // convert url to internal link $lnkdata = explode(',', $url); if (isset($lnkdata[0])) { $page = intval(substr($lnkdata[0], 1)); if (empty($page) OR ($page <= 0)) { $page = $this->page; } if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) { $lnky = floatval($lnkdata[1]); } else { $lnky = 0; } $url = $this->AddLink(); $this->SetLink($url, $lnky, $page); } } // store current settings $prevcolor = $this->fgcolor; $prevstyle = $this->FontStyle; if (empty($color)) { $this->SetTextColorArray($this->htmlLinkColorArray); } else { $this->SetTextColorArray($color); } if ($style == -1) { $this->SetFont('', $this->FontStyle.$this->htmlLinkFontStyle); } else { $this->SetFont('', $this->FontStyle.$style); } $ret = $this->Write($this->lasth, $name, $url, $fill, '', false, 0, $firstline, $firstblock, 0); // restore settings $this->SetFont('', $prevstyle); $this->SetTextColorArray($prevcolor); return $ret; } /** * Converts pixels to User's Units. * @param $px (int) pixels * @return float value in user's unit * @public * @see setImageScale(), getImageScale() */ public function pixelsToUnits($px) { return ($px / ($this->imgscale * $this->k)); } /** * Reverse function for htmlentities. * Convert entities in UTF-8. * @param $text_to_convert (string) Text to convert. * @return string converted text string * @public */ public function unhtmlentities($text_to_convert) { return @html_entity_decode($text_to_convert, ENT_QUOTES, $this->encoding); } // ENCRYPTION METHODS ---------------------------------- /** * Compute encryption key depending on object number where the encrypted data is stored. * This is used for all strings and streams without crypt filter specifier. * @param $n (int) object number * @return int object key * @protected * @author Nicola Asuni * @since 2.0.000 (2008-01-02) */ protected function _objectkey($n) { $objkey = $this->encryptdata['key'].pack('VXxx', $n); if ($this->encryptdata['mode'] == 2) { // AES-128 // AES padding $objkey .= "\x73\x41\x6C\x54"; // sAlT } $objkey = substr(TCPDF_STATIC::_md5_16($objkey), 0, (($this->encryptdata['Length'] / 8) + 5)); $objkey = substr($objkey, 0, 16); return $objkey; } /** * Encrypt the input string. * @param $n (int) object number * @param $s (string) data string to encrypt * @return encrypted string * @protected * @author Nicola Asuni * @since 5.0.005 (2010-05-11) */ protected function _encrypt_data($n, $s) { if (!$this->encrypted) { return $s; } switch ($this->encryptdata['mode']) { case 0: // RC4-40 case 1: { // RC4-128 $s = TCPDF_STATIC::_RC4($this->_objectkey($n), $s, $this->last_enc_key, $this->last_enc_key_c); break; } case 2: { // AES-128 $s = TCPDF_STATIC::_AES($this->_objectkey($n), $s); break; } case 3: { // AES-256 $s = TCPDF_STATIC::_AES($this->encryptdata['key'], $s); break; } } return $s; } /** * Put encryption on PDF document. * @protected * @author Nicola Asuni * @since 2.0.000 (2008-01-02) */ protected function _putencryption() { if (!$this->encrypted) { return; } $this->encryptdata['objid'] = $this->_newobj(); $out = '<<'; if (!isset($this->encryptdata['Filter']) OR empty($this->encryptdata['Filter'])) { $this->encryptdata['Filter'] = 'Standard'; } $out .= ' /Filter /'.$this->encryptdata['Filter']; if (isset($this->encryptdata['SubFilter']) AND !empty($this->encryptdata['SubFilter'])) { $out .= ' /SubFilter /'.$this->encryptdata['SubFilter']; } if (!isset($this->encryptdata['V']) OR empty($this->encryptdata['V'])) { $this->encryptdata['V'] = 1; } // V is a code specifying the algorithm to be used in encrypting and decrypting the document $out .= ' /V '.$this->encryptdata['V']; if (isset($this->encryptdata['Length']) AND !empty($this->encryptdata['Length'])) { // The length of the encryption key, in bits. The value shall be a multiple of 8, in the range 40 to 256 $out .= ' /Length '.$this->encryptdata['Length']; } else { $out .= ' /Length 40'; } if ($this->encryptdata['V'] >= 4) { if (!isset($this->encryptdata['StmF']) OR empty($this->encryptdata['StmF'])) { $this->encryptdata['StmF'] = 'Identity'; } if (!isset($this->encryptdata['StrF']) OR empty($this->encryptdata['StrF'])) { // The name of the crypt filter that shall be used when decrypting all strings in the document. $this->encryptdata['StrF'] = 'Identity'; } // A dictionary whose keys shall be crypt filter names and whose values shall be the corresponding crypt filter dictionaries. if (isset($this->encryptdata['CF']) AND !empty($this->encryptdata['CF'])) { $out .= ' /CF <<'; $out .= ' /'.$this->encryptdata['StmF'].' <<'; $out .= ' /Type /CryptFilter'; if (isset($this->encryptdata['CF']['CFM']) AND !empty($this->encryptdata['CF']['CFM'])) { // The method used $out .= ' /CFM /'.$this->encryptdata['CF']['CFM']; if ($this->encryptdata['pubkey']) { $out .= ' /Recipients ['; foreach ($this->encryptdata['Recipients'] as $rec) { $out .= ' <'.$rec.'>'; } $out .= ' ]'; if (isset($this->encryptdata['CF']['EncryptMetadata']) AND (!$this->encryptdata['CF']['EncryptMetadata'])) { $out .= ' /EncryptMetadata false'; } else { $out .= ' /EncryptMetadata true'; } } } else { $out .= ' /CFM /None'; } if (isset($this->encryptdata['CF']['AuthEvent']) AND !empty($this->encryptdata['CF']['AuthEvent'])) { // The event to be used to trigger the authorization that is required to access encryption keys used by this filter. $out .= ' /AuthEvent /'.$this->encryptdata['CF']['AuthEvent']; } else { $out .= ' /AuthEvent /DocOpen'; } if (isset($this->encryptdata['CF']['Length']) AND !empty($this->encryptdata['CF']['Length'])) { // The bit length of the encryption key. $out .= ' /Length '.$this->encryptdata['CF']['Length']; } $out .= ' >> >>'; } // The name of the crypt filter that shall be used by default when decrypting streams. $out .= ' /StmF /'.$this->encryptdata['StmF']; // The name of the crypt filter that shall be used when decrypting all strings in the document. $out .= ' /StrF /'.$this->encryptdata['StrF']; if (isset($this->encryptdata['EFF']) AND !empty($this->encryptdata['EFF'])) { // The name of the crypt filter that shall be used when encrypting embedded file streams that do not have their own crypt filter specifier. $out .= ' /EFF /'.$this->encryptdata['']; } } // Additional encryption dictionary entries for the standard security handler if ($this->encryptdata['pubkey']) { if (($this->encryptdata['V'] < 4) AND isset($this->encryptdata['Recipients']) AND !empty($this->encryptdata['Recipients'])) { $out .= ' /Recipients ['; foreach ($this->encryptdata['Recipients'] as $rec) { $out .= ' <'.$rec.'>'; } $out .= ' ]'; } } else { $out .= ' /R'; if ($this->encryptdata['V'] == 5) { // AES-256 $out .= ' 5'; $out .= ' /OE ('.TCPDF_STATIC::_escape($this->encryptdata['OE']).')'; $out .= ' /UE ('.TCPDF_STATIC::_escape($this->encryptdata['UE']).')'; $out .= ' /Perms ('.TCPDF_STATIC::_escape($this->encryptdata['perms']).')'; } elseif ($this->encryptdata['V'] == 4) { // AES-128 $out .= ' 4'; } elseif ($this->encryptdata['V'] < 2) { // RC-40 $out .= ' 2'; } else { // RC-128 $out .= ' 3'; } $out .= ' /O ('.TCPDF_STATIC::_escape($this->encryptdata['O']).')'; $out .= ' /U ('.TCPDF_STATIC::_escape($this->encryptdata['U']).')'; $out .= ' /P '.$this->encryptdata['P']; if (isset($this->encryptdata['EncryptMetadata']) AND (!$this->encryptdata['EncryptMetadata'])) { $out .= ' /EncryptMetadata false'; } else { $out .= ' /EncryptMetadata true'; } } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } /** * Compute U value (used for encryption) * @return string U value * @protected * @since 2.0.000 (2008-01-02) * @author Nicola Asuni */ protected function _Uvalue() { if ($this->encryptdata['mode'] == 0) { // RC4-40 return TCPDF_STATIC::_RC4($this->encryptdata['key'], TCPDF_STATIC::$enc_padding, $this->last_enc_key, $this->last_enc_key_c); } elseif ($this->encryptdata['mode'] < 3) { // RC4-128, AES-128 $tmp = TCPDF_STATIC::_md5_16(TCPDF_STATIC::$enc_padding.$this->encryptdata['fileid']); $enc = TCPDF_STATIC::_RC4($this->encryptdata['key'], $tmp, $this->last_enc_key, $this->last_enc_key_c); $len = strlen($tmp); for ($i = 1; $i <= 19; ++$i) { $ek = ''; for ($j = 0; $j < $len; ++$j) { $ek .= chr(ord($this->encryptdata['key'][$j]) ^ $i); } $enc = TCPDF_STATIC::_RC4($ek, $enc, $this->last_enc_key, $this->last_enc_key_c); } $enc .= str_repeat("\x00", 16); return substr($enc, 0, 32); } elseif ($this->encryptdata['mode'] == 3) { // AES-256 $seed = TCPDF_STATIC::_md5_16(TCPDF_STATIC::getRandomSeed()); // User Validation Salt $this->encryptdata['UVS'] = substr($seed, 0, 8); // User Key Salt $this->encryptdata['UKS'] = substr($seed, 8, 16); return hash('sha256', $this->encryptdata['user_password'].$this->encryptdata['UVS'], true).$this->encryptdata['UVS'].$this->encryptdata['UKS']; } } /** * Compute UE value (used for encryption) * @return string UE value * @protected * @since 5.9.006 (2010-10-19) * @author Nicola Asuni */ protected function _UEvalue() { $hashkey = hash('sha256', $this->encryptdata['user_password'].$this->encryptdata['UKS'], true); $iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)); return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashkey, $this->encryptdata['key'], MCRYPT_MODE_CBC, $iv); } /** * Compute O value (used for encryption) * @return string O value * @protected * @since 2.0.000 (2008-01-02) * @author Nicola Asuni */ protected function _Ovalue() { if ($this->encryptdata['mode'] < 3) { // RC4-40, RC4-128, AES-128 $tmp = TCPDF_STATIC::_md5_16($this->encryptdata['owner_password']); if ($this->encryptdata['mode'] > 0) { for ($i = 0; $i < 50; ++$i) { $tmp = TCPDF_STATIC::_md5_16($tmp); } } $owner_key = substr($tmp, 0, ($this->encryptdata['Length'] / 8)); $enc = TCPDF_STATIC::_RC4($owner_key, $this->encryptdata['user_password'], $this->last_enc_key, $this->last_enc_key_c); if ($this->encryptdata['mode'] > 0) { $len = strlen($owner_key); for ($i = 1; $i <= 19; ++$i) { $ek = ''; for ($j = 0; $j < $len; ++$j) { $ek .= chr(ord($owner_key[$j]) ^ $i); } $enc = TCPDF_STATIC::_RC4($ek, $enc, $this->last_enc_key, $this->last_enc_key_c); } } return $enc; } elseif ($this->encryptdata['mode'] == 3) { // AES-256 $seed = TCPDF_STATIC::_md5_16(TCPDF_STATIC::getRandomSeed()); // Owner Validation Salt $this->encryptdata['OVS'] = substr($seed, 0, 8); // Owner Key Salt $this->encryptdata['OKS'] = substr($seed, 8, 16); return hash('sha256', $this->encryptdata['owner_password'].$this->encryptdata['OVS'].$this->encryptdata['U'], true).$this->encryptdata['OVS'].$this->encryptdata['OKS']; } } /** * Compute OE value (used for encryption) * @return string OE value * @protected * @since 5.9.006 (2010-10-19) * @author Nicola Asuni */ protected function _OEvalue() { $hashkey = hash('sha256', $this->encryptdata['owner_password'].$this->encryptdata['OKS'].$this->encryptdata['U'], true); $iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)); return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashkey, $this->encryptdata['key'], MCRYPT_MODE_CBC, $iv); } /** * Convert password for AES-256 encryption mode * @param $password (string) password * @return string password * @protected * @since 5.9.006 (2010-10-19) * @author Nicola Asuni */ protected function _fixAES256Password($password) { $psw = ''; // password to be returned $psw_array = TCPDF_FONTS::utf8Bidi(TCPDF_FONTS::UTF8StringToArray($password, $this->isunicode, $this->CurrentFont), $password, $this->rtl, $this->isunicode, $this->CurrentFont); foreach ($psw_array as $c) { $psw .= TCPDF_FONTS::unichr($c, $this->isunicode); } return substr($psw, 0, 127); } /** * Compute encryption key * @protected * @since 2.0.000 (2008-01-02) * @author Nicola Asuni */ protected function _generateencryptionkey() { $keybytelen = ($this->encryptdata['Length'] / 8); if (!$this->encryptdata['pubkey']) { // standard mode if ($this->encryptdata['mode'] == 3) { // AES-256 // generate 256 bit random key $this->encryptdata['key'] = substr(hash('sha256', TCPDF_STATIC::getRandomSeed(), true), 0, $keybytelen); // truncate passwords $this->encryptdata['user_password'] = $this->_fixAES256Password($this->encryptdata['user_password']); $this->encryptdata['owner_password'] = $this->_fixAES256Password($this->encryptdata['owner_password']); // Compute U value $this->encryptdata['U'] = $this->_Uvalue(); // Compute UE value $this->encryptdata['UE'] = $this->_UEvalue(); // Compute O value $this->encryptdata['O'] = $this->_Ovalue(); // Compute OE value $this->encryptdata['OE'] = $this->_OEvalue(); // Compute P value $this->encryptdata['P'] = $this->encryptdata['protection']; // Computing the encryption dictionary's Perms (permissions) value $perms = TCPDF_STATIC::getEncPermissionsString($this->encryptdata['protection']); // bytes 0-3 $perms .= chr(255).chr(255).chr(255).chr(255); // bytes 4-7 if (isset($this->encryptdata['CF']['EncryptMetadata']) AND (!$this->encryptdata['CF']['EncryptMetadata'])) { // byte 8 $perms .= 'F'; } else { $perms .= 'T'; } $perms .= 'adb'; // bytes 9-11 $perms .= 'nick'; // bytes 12-15 $iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB)); $this->encryptdata['perms'] = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->encryptdata['key'], $perms, MCRYPT_MODE_ECB, $iv); } else { // RC4-40, RC4-128, AES-128 // Pad passwords $this->encryptdata['user_password'] = substr($this->encryptdata['user_password'].TCPDF_STATIC::$enc_padding, 0, 32); $this->encryptdata['owner_password'] = substr($this->encryptdata['owner_password'].TCPDF_STATIC::$enc_padding, 0, 32); // Compute O value $this->encryptdata['O'] = $this->_Ovalue(); // get default permissions (reverse byte order) $permissions = TCPDF_STATIC::getEncPermissionsString($this->encryptdata['protection']); // Compute encryption key $tmp = TCPDF_STATIC::_md5_16($this->encryptdata['user_password'].$this->encryptdata['O'].$permissions.$this->encryptdata['fileid']); if ($this->encryptdata['mode'] > 0) { for ($i = 0; $i < 50; ++$i) { $tmp = TCPDF_STATIC::_md5_16(substr($tmp, 0, $keybytelen)); } } $this->encryptdata['key'] = substr($tmp, 0, $keybytelen); // Compute U value $this->encryptdata['U'] = $this->_Uvalue(); // Compute P value $this->encryptdata['P'] = $this->encryptdata['protection']; } } else { // Public-Key mode // random 20-byte seed $seed = sha1(TCPDF_STATIC::getRandomSeed(), true); $recipient_bytes = ''; foreach ($this->encryptdata['pubkeys'] as $pubkey) { // for each public certificate if (isset($pubkey['p'])) { $pkprotection = TCPDF_STATIC::getUserPermissionCode($pubkey['p'], $this->encryptdata['mode']); } else { $pkprotection = $this->encryptdata['protection']; } // get default permissions (reverse byte order) $pkpermissions = TCPDF_STATIC::getEncPermissionsString($pkprotection); // envelope data $envelope = $seed.$pkpermissions; // write the envelope data to a temporary file $tempkeyfile = TCPDF_STATIC::getObjFilename('tmpkey'); $f = fopen($tempkeyfile, 'wb'); if (!$f) { $this->Error('Unable to create temporary key file: '.$tempkeyfile); } $envelope_length = strlen($envelope); fwrite($f, $envelope, $envelope_length); fclose($f); $tempencfile = TCPDF_STATIC::getObjFilename('tmpenc'); if (!openssl_pkcs7_encrypt($tempkeyfile, $tempencfile, $pubkey['c'], array(), PKCS7_BINARY | PKCS7_DETACHED)) { $this->Error('Unable to encrypt the file: '.$tempkeyfile); } unlink($tempkeyfile); // read encryption signature $signature = file_get_contents($tempencfile, false, null, $envelope_length); unlink($tempencfile); // extract signature $signature = substr($signature, strpos($signature, 'Content-Disposition')); $tmparr = explode("\n\n", $signature); $signature = trim($tmparr[1]); unset($tmparr); // decode signature $signature = base64_decode($signature); // convert signature to hex $hexsignature = current(unpack('H*', $signature)); // store signature on recipients array $this->encryptdata['Recipients'][] = $hexsignature; // The bytes of each item in the Recipients array of PKCS#7 objects in the order in which they appear in the array $recipient_bytes .= $signature; } // calculate encryption key if ($this->encryptdata['mode'] == 3) { // AES-256 $this->encryptdata['key'] = substr(hash('sha256', $seed.$recipient_bytes, true), 0, $keybytelen); } else { // RC4-40, RC4-128, AES-128 $this->encryptdata['key'] = substr(sha1($seed.$recipient_bytes, true), 0, $keybytelen); } } } /** * Set document protection * Remark: the protection against modification is for people who have the full Acrobat product. * If you don't set any password, the document will open as usual. If you set a user password, the PDF viewer will ask for it before displaying the document. The master password, if different from the user one, can be used to get full access. * Note: protecting a document requires to encrypt it, which increases the processing time a lot. This can cause a PHP time-out in some cases, especially if the document contains images or fonts. * @param $permissions (Array) the set of permissions (specify the ones you want to block):<ul><li>print : Print the document;</li><li>modify : Modify the contents of the document by operations other than those controlled by 'fill-forms', 'extract' and 'assemble';</li><li>copy : Copy or otherwise extract text and graphics from the document;</li><li>annot-forms : Add or modify text annotations, fill in interactive form fields, and, if 'modify' is also set, create or modify interactive form fields (including signature fields);</li><li>fill-forms : Fill in existing interactive form fields (including signature fields), even if 'annot-forms' is not specified;</li><li>extract : Extract text and graphics (in support of accessibility to users with disabilities or for other purposes);</li><li>assemble : Assemble the document (insert, rotate, or delete pages and create bookmarks or thumbnail images), even if 'modify' is not set;</li><li>print-high : Print the document to a representation from which a faithful digital copy of the PDF content could be generated. When this is not set, printing is limited to a low-level representation of the appearance, possibly of degraded quality.</li><li>owner : (inverted logic - only for public-key) when set permits change of encryption and enables all other permissions.</li></ul> * @param $user_pass (String) user password. Empty by default. * @param $owner_pass (String) owner password. If not specified, a random value is used. * @param $mode (int) encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit. * @param $pubkeys (String) array of recipients containing public-key certificates ('c') and permissions ('p'). For example: array(array('c' => 'file://../config/cert/tcpdf.crt', 'p' => array('print'))) * @public * @since 2.0.000 (2008-01-02) * @author Nicola Asuni */ public function SetProtection($permissions=array('print', 'modify', 'copy', 'annot-forms', 'fill-forms', 'extract', 'assemble', 'print-high'), $user_pass='', $owner_pass=null, $mode=0, $pubkeys=null) { if ($this->pdfa_mode) { // encryption is not allowed in PDF/A mode return; } $this->encryptdata['protection'] = TCPDF_STATIC::getUserPermissionCode($permissions, $mode); if (($pubkeys !== null) AND (is_array($pubkeys))) { // public-key mode $this->encryptdata['pubkeys'] = $pubkeys; if ($mode == 0) { // public-Key Security requires at least 128 bit $mode = 1; } if (!function_exists('openssl_pkcs7_encrypt')) { $this->Error('Public-Key Security requires openssl library.'); } // Set Public-Key filter (availabe are: Entrust.PPKEF, Adobe.PPKLite, Adobe.PubSec) $this->encryptdata['pubkey'] = true; $this->encryptdata['Filter'] = 'Adobe.PubSec'; $this->encryptdata['StmF'] = 'DefaultCryptFilter'; $this->encryptdata['StrF'] = 'DefaultCryptFilter'; } else { // standard mode (password mode) $this->encryptdata['pubkey'] = false; $this->encryptdata['Filter'] = 'Standard'; $this->encryptdata['StmF'] = 'StdCF'; $this->encryptdata['StrF'] = 'StdCF'; } if ($mode > 1) { // AES if (!extension_loaded('mcrypt')) { $this->Error('AES encryption requires mcrypt library (http://www.php.net/manual/en/mcrypt.requirements.php).'); } if (mcrypt_get_cipher_name(MCRYPT_RIJNDAEL_128) === false) { $this->Error('AES encryption requires MCRYPT_RIJNDAEL_128 cypher.'); } if (($mode == 3) AND !function_exists('hash')) { // the Hash extension requires no external libraries and is enabled by default as of PHP 5.1.2. $this->Error('AES 256 encryption requires HASH Message Digest Framework (http://www.php.net/manual/en/book.hash.php).'); } } if ($owner_pass === null) { $owner_pass = md5(TCPDF_STATIC::getRandomSeed()); } $this->encryptdata['user_password'] = $user_pass; $this->encryptdata['owner_password'] = $owner_pass; $this->encryptdata['mode'] = $mode; switch ($mode) { case 0: { // RC4 40 bit $this->encryptdata['V'] = 1; $this->encryptdata['Length'] = 40; $this->encryptdata['CF']['CFM'] = 'V2'; break; } case 1: { // RC4 128 bit $this->encryptdata['V'] = 2; $this->encryptdata['Length'] = 128; $this->encryptdata['CF']['CFM'] = 'V2'; if ($this->encryptdata['pubkey']) { $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s4'; $this->encryptdata['Recipients'] = array(); } break; } case 2: { // AES 128 bit $this->encryptdata['V'] = 4; $this->encryptdata['Length'] = 128; $this->encryptdata['CF']['CFM'] = 'AESV2'; $this->encryptdata['CF']['Length'] = 128; if ($this->encryptdata['pubkey']) { $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5'; $this->encryptdata['Recipients'] = array(); } break; } case 3: { // AES 256 bit $this->encryptdata['V'] = 5; $this->encryptdata['Length'] = 256; $this->encryptdata['CF']['CFM'] = 'AESV3'; $this->encryptdata['CF']['Length'] = 256; if ($this->encryptdata['pubkey']) { $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5'; $this->encryptdata['Recipients'] = array(); } break; } } $this->encrypted = true; $this->encryptdata['fileid'] = TCPDF_STATIC::convertHexStringToString($this->file_id); $this->_generateencryptionkey(); } // END OF ENCRYPTION FUNCTIONS ------------------------- // START TRANSFORMATIONS SECTION ----------------------- /** * Starts a 2D tranformation saving current graphic state. * This function must be called before scaling, mirroring, translation, rotation and skewing. * Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior. * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function StartTransform() { if ($this->state != 2) { return; } $this->_out('q'); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['transfmrk'][] = strlen($this->xobjects[$this->xobjid]['outdata']); } else { $this->transfmrk[$this->page][] = $this->pagelen[$this->page]; } ++$this->transfmatrix_key; $this->transfmatrix[$this->transfmatrix_key] = array(); } /** * Stops a 2D tranformation restoring previous graphic state. * This function must be called after scaling, mirroring, translation, rotation and skewing. * Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior. * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function StopTransform() { if ($this->state != 2) { return; } $this->_out('Q'); if (isset($this->transfmatrix[$this->transfmatrix_key])) { array_pop($this->transfmatrix[$this->transfmatrix_key]); --$this->transfmatrix_key; } if ($this->inxobj) { // we are inside an XObject template array_pop($this->xobjects[$this->xobjid]['transfmrk']); } else { array_pop($this->transfmrk[$this->page]); } } /** * Horizontal Scaling. * @param $s_x (float) scaling factor for width as percent. 0 is not allowed. * @param $x (int) abscissa of the scaling center. Default is current x position * @param $y (int) ordinate of the scaling center. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function ScaleX($s_x, $x='', $y='') { $this->Scale($s_x, 100, $x, $y); } /** * Vertical Scaling. * @param $s_y (float) scaling factor for height as percent. 0 is not allowed. * @param $x (int) abscissa of the scaling center. Default is current x position * @param $y (int) ordinate of the scaling center. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function ScaleY($s_y, $x='', $y='') { $this->Scale(100, $s_y, $x, $y); } /** * Vertical and horizontal proportional Scaling. * @param $s (float) scaling factor for width and height as percent. 0 is not allowed. * @param $x (int) abscissa of the scaling center. Default is current x position * @param $y (int) ordinate of the scaling center. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function ScaleXY($s, $x='', $y='') { $this->Scale($s, $s, $x, $y); } /** * Vertical and horizontal non-proportional Scaling. * @param $s_x (float) scaling factor for width as percent. 0 is not allowed. * @param $s_y (float) scaling factor for height as percent. 0 is not allowed. * @param $x (int) abscissa of the scaling center. Default is current x position * @param $y (int) ordinate of the scaling center. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function Scale($s_x, $s_y, $x='', $y='') { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } if (($s_x == 0) OR ($s_y == 0)) { $this->Error('Please do not use values equal to zero for scaling'); } $y = ($this->h - $y) * $this->k; $x *= $this->k; //calculate elements of transformation matrix $s_x /= 100; $s_y /= 100; $tm = array(); $tm[0] = $s_x; $tm[1] = 0; $tm[2] = 0; $tm[3] = $s_y; $tm[4] = $x * (1 - $s_x); $tm[5] = $y * (1 - $s_y); //scale the coordinate system $this->Transform($tm); } /** * Horizontal Mirroring. * @param $x (int) abscissa of the point. Default is current x position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function MirrorH($x='') { $this->Scale(-100, 100, $x); } /** * Verical Mirroring. * @param $y (int) ordinate of the point. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function MirrorV($y='') { $this->Scale(100, -100, '', $y); } /** * Point reflection mirroring. * @param $x (int) abscissa of the point. Default is current x position * @param $y (int) ordinate of the point. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function MirrorP($x='',$y='') { $this->Scale(-100, -100, $x, $y); } /** * Reflection against a straight line through point (x, y) with the gradient angle (angle). * @param $angle (float) gradient angle of the straight line. Default is 0 (horizontal line). * @param $x (int) abscissa of the point. Default is current x position * @param $y (int) ordinate of the point. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function MirrorL($angle=0, $x='',$y='') { $this->Scale(-100, 100, $x, $y); $this->Rotate(-2*($angle-90), $x, $y); } /** * Translate graphic object horizontally. * @param $t_x (int) movement to the right (or left for RTL) * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function TranslateX($t_x) { $this->Translate($t_x, 0); } /** * Translate graphic object vertically. * @param $t_y (int) movement to the bottom * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function TranslateY($t_y) { $this->Translate(0, $t_y); } /** * Translate graphic object horizontally and vertically. * @param $t_x (int) movement to the right * @param $t_y (int) movement to the bottom * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function Translate($t_x, $t_y) { //calculate elements of transformation matrix $tm = array(); $tm[0] = 1; $tm[1] = 0; $tm[2] = 0; $tm[3] = 1; $tm[4] = $t_x * $this->k; $tm[5] = -$t_y * $this->k; //translate the coordinate system $this->Transform($tm); } /** * Rotate object. * @param $angle (float) angle in degrees for counter-clockwise rotation * @param $x (int) abscissa of the rotation center. Default is current x position * @param $y (int) ordinate of the rotation center. Default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function Rotate($angle, $x='', $y='') { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } $y = ($this->h - $y) * $this->k; $x *= $this->k; //calculate elements of transformation matrix $tm = array(); $tm[0] = cos(deg2rad($angle)); $tm[1] = sin(deg2rad($angle)); $tm[2] = -$tm[1]; $tm[3] = $tm[0]; $tm[4] = $x + ($tm[1] * $y) - ($tm[0] * $x); $tm[5] = $y - ($tm[0] * $y) - ($tm[1] * $x); //rotate the coordinate system around ($x,$y) $this->Transform($tm); } /** * Skew horizontally. * @param $angle_x (float) angle in degrees between -90 (skew to the left) and 90 (skew to the right) * @param $x (int) abscissa of the skewing center. default is current x position * @param $y (int) ordinate of the skewing center. default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function SkewX($angle_x, $x='', $y='') { $this->Skew($angle_x, 0, $x, $y); } /** * Skew vertically. * @param $angle_y (float) angle in degrees between -90 (skew to the bottom) and 90 (skew to the top) * @param $x (int) abscissa of the skewing center. default is current x position * @param $y (int) ordinate of the skewing center. default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function SkewY($angle_y, $x='', $y='') { $this->Skew(0, $angle_y, $x, $y); } /** * Skew. * @param $angle_x (float) angle in degrees between -90 (skew to the left) and 90 (skew to the right) * @param $angle_y (float) angle in degrees between -90 (skew to the bottom) and 90 (skew to the top) * @param $x (int) abscissa of the skewing center. default is current x position * @param $y (int) ordinate of the skewing center. default is current y position * @public * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ public function Skew($angle_x, $angle_y, $x='', $y='') { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } if (($angle_x <= -90) OR ($angle_x >= 90) OR ($angle_y <= -90) OR ($angle_y >= 90)) { $this->Error('Please use values between -90 and +90 degrees for Skewing.'); } $x *= $this->k; $y = ($this->h - $y) * $this->k; //calculate elements of transformation matrix $tm = array(); $tm[0] = 1; $tm[1] = tan(deg2rad($angle_y)); $tm[2] = tan(deg2rad($angle_x)); $tm[3] = 1; $tm[4] = -$tm[2] * $y; $tm[5] = -$tm[1] * $x; //skew the coordinate system $this->Transform($tm); } /** * Apply graphic transformations. * @param $tm (array) transformation matrix * @protected * @since 2.1.000 (2008-01-07) * @see StartTransform(), StopTransform() */ protected function Transform($tm) { if ($this->state != 2) { return; } $this->_out(sprintf('%F %F %F %F %F %F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); // add tranformation matrix $this->transfmatrix[$this->transfmatrix_key][] = array('a' => $tm[0], 'b' => $tm[1], 'c' => $tm[2], 'd' => $tm[3], 'e' => $tm[4], 'f' => $tm[5]); // update transformation mark if ($this->inxobj) { // we are inside an XObject template if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) { $key = key($this->xobjects[$this->xobjid]['transfmrk']); $this->xobjects[$this->xobjid]['transfmrk'][$key] = strlen($this->xobjects[$this->xobjid]['outdata']); } } elseif (end($this->transfmrk[$this->page]) !== false) { $key = key($this->transfmrk[$this->page]); $this->transfmrk[$this->page][$key] = $this->pagelen[$this->page]; } } // END TRANSFORMATIONS SECTION ------------------------- // START GRAPHIC FUNCTIONS SECTION --------------------- // The following section is based on the code provided by David Hernandez Sanz /** * Defines the line width. By default, the value equals 0.2 mm. The method can be called before the first page is created and the value is retained from page to page. * @param $width (float) The width. * @public * @since 1.0 * @see Line(), Rect(), Cell(), MultiCell() */ public function SetLineWidth($width) { //Set line width $this->LineWidth = $width; $this->linestyleWidth = sprintf('%F w', ($width * $this->k)); if ($this->state == 2) { $this->_out($this->linestyleWidth); } } /** * Returns the current the line width. * @return int Line width * @public * @since 2.1.000 (2008-01-07) * @see Line(), SetLineWidth() */ public function GetLineWidth() { return $this->LineWidth; } /** * Set line style. * @param $style (array) Line style. Array with keys among the following: * <ul> * <li>width (float): Width of the line in user units.</li> * <li>cap (string): Type of cap to put on the line. Possible values are: * butt, round, square. The difference between "square" and "butt" is that * "square" projects a flat end past the end of the line.</li> * <li>join (string): Type of join. Possible values are: miter, round, * bevel.</li> * <li>dash (mixed): Dash pattern. Is 0 (without dash) or string with * series of length values, which are the lengths of the on and off dashes. * For example: "2" represents 2 on, 2 off, 2 on, 2 off, ...; "2,1" is 2 on, * 1 off, 2 on, 1 off, ...</li> * <li>phase (integer): Modifier on the dash pattern which is used to shift * the point at which the pattern starts.</li> * <li>color (array): Draw color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName).</li> * </ul> * @param $ret (boolean) if true do not send the command. * @return string the PDF command * @public * @since 2.1.000 (2008-01-08) */ public function SetLineStyle($style, $ret=false) { $s = ''; // string to be returned if (!is_array($style)) { return; } if (isset($style['width'])) { $this->LineWidth = $style['width']; $this->linestyleWidth = sprintf('%F w', ($style['width'] * $this->k)); $s .= $this->linestyleWidth.' '; } if (isset($style['cap'])) { $ca = array('butt' => 0, 'round'=> 1, 'square' => 2); if (isset($ca[$style['cap']])) { $this->linestyleCap = $ca[$style['cap']].' J'; $s .= $this->linestyleCap.' '; } } if (isset($style['join'])) { $ja = array('miter' => 0, 'round' => 1, 'bevel' => 2); if (isset($ja[$style['join']])) { $this->linestyleJoin = $ja[$style['join']].' j'; $s .= $this->linestyleJoin.' '; } } if (isset($style['dash'])) { $dash_string = ''; if ($style['dash']) { if (preg_match('/^.+,/', $style['dash']) > 0) { $tab = explode(',', $style['dash']); } else { $tab = array($style['dash']); } $dash_string = ''; foreach ($tab as $i => $v) { if ($i) { $dash_string .= ' '; } $dash_string .= sprintf('%F', $v); } } if (!isset($style['phase']) OR !$style['dash']) { $style['phase'] = 0; } $this->linestyleDash = sprintf('[%s] %F d', $dash_string, $style['phase']); $s .= $this->linestyleDash.' '; } if (isset($style['color'])) { $s .= $this->SetDrawColorArray($style['color'], true).' '; } if (!$ret AND ($this->state == 2)) { $this->_out($s); } return $s; } /** * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment. * @param $x (float) Abscissa of point. * @param $y (float) Ordinate of point. * @protected * @since 2.1.000 (2008-01-08) */ protected function _outPoint($x, $y) { if ($this->state == 2) { $this->_out(sprintf('%F %F m', ($x * $this->k), (($this->h - $y) * $this->k))); } } /** * Append a straight line segment from the current point to the point (x, y). * The new current point shall be (x, y). * @param $x (float) Abscissa of end point. * @param $y (float) Ordinate of end point. * @protected * @since 2.1.000 (2008-01-08) */ protected function _outLine($x, $y) { if ($this->state == 2) { $this->_out(sprintf('%F %F l', ($x * $this->k), (($this->h - $y) * $this->k))); } } /** * Append a rectangle to the current path as a complete subpath, with lower-left corner (x, y) and dimensions widthand height in user space. * @param $x (float) Abscissa of upper-left corner. * @param $y (float) Ordinate of upper-left corner. * @param $w (float) Width. * @param $h (float) Height. * @param $op (string) options * @protected * @since 2.1.000 (2008-01-08) */ protected function _outRect($x, $y, $w, $h, $op) { if ($this->state == 2) { $this->_out(sprintf('%F %F %F %F re %s', ($x * $this->k), (($this->h - $y) * $this->k), ($w * $this->k), (-$h * $this->k), $op)); } } /** * Append a cubic Bzier curve to the current path. The curve shall extend from the current point to the point (x3, y3), using (x1, y1) and (x2, y2) as the Bzier control points. * The new current point shall be (x3, y3). * @param $x1 (float) Abscissa of control point 1. * @param $y1 (float) Ordinate of control point 1. * @param $x2 (float) Abscissa of control point 2. * @param $y2 (float) Ordinate of control point 2. * @param $x3 (float) Abscissa of end point. * @param $y3 (float) Ordinate of end point. * @protected * @since 2.1.000 (2008-01-08) */ protected function _outCurve($x1, $y1, $x2, $y2, $x3, $y3) { if ($this->state == 2) { $this->_out(sprintf('%F %F %F %F %F %F c', ($x1 * $this->k), (($this->h - $y1) * $this->k), ($x2 * $this->k), (($this->h - $y2) * $this->k), ($x3 * $this->k), (($this->h - $y3) * $this->k))); } } /** * Append a cubic Bzier curve to the current path. The curve shall extend from the current point to the point (x3, y3), using the current point and (x2, y2) as the Bzier control points. * The new current point shall be (x3, y3). * @param $x2 (float) Abscissa of control point 2. * @param $y2 (float) Ordinate of control point 2. * @param $x3 (float) Abscissa of end point. * @param $y3 (float) Ordinate of end point. * @protected * @since 4.9.019 (2010-04-26) */ protected function _outCurveV($x2, $y2, $x3, $y3) { if ($this->state == 2) { $this->_out(sprintf('%F %F %F %F v', ($x2 * $this->k), (($this->h - $y2) * $this->k), ($x3 * $this->k), (($this->h - $y3) * $this->k))); } } /** * Append a cubic Bzier curve to the current path. The curve shall extend from the current point to the point (x3, y3), using (x1, y1) and (x3, y3) as the Bzier control points. * The new current point shall be (x3, y3). * @param $x1 (float) Abscissa of control point 1. * @param $y1 (float) Ordinate of control point 1. * @param $x3 (float) Abscissa of end point. * @param $y3 (float) Ordinate of end point. * @protected * @since 2.1.000 (2008-01-08) */ protected function _outCurveY($x1, $y1, $x3, $y3) { if ($this->state == 2) { $this->_out(sprintf('%F %F %F %F y', ($x1 * $this->k), (($this->h - $y1) * $this->k), ($x3 * $this->k), (($this->h - $y3) * $this->k))); } } /** * Draws a line between two points. * @param $x1 (float) Abscissa of first point. * @param $y1 (float) Ordinate of first point. * @param $x2 (float) Abscissa of second point. * @param $y2 (float) Ordinate of second point. * @param $style (array) Line style. Array like for SetLineStyle(). Default value: default line style (empty array). * @public * @since 1.0 * @see SetLineWidth(), SetDrawColor(), SetLineStyle() */ public function Line($x1, $y1, $x2, $y2, $style=array()) { if ($this->state != 2) { return; } if (is_array($style)) { $this->SetLineStyle($style); } $this->_outPoint($x1, $y1); $this->_outLine($x2, $y2); $this->_out('S'); } /** * Draws a rectangle. * @param $x (float) Abscissa of upper-left corner. * @param $y (float) Ordinate of upper-left corner. * @param $w (float) Width. * @param $h (float) Height. * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $border_style (array) Border style of rectangle. Array with keys among the following: * <ul> * <li>all: Line style of all borders. Array like for SetLineStyle().</li> * <li>L, T, R, B or combinations: Line style of left, top, right or bottom border. Array like for SetLineStyle().</li> * </ul> * If a key is not present or is null, the correspondent border is not drawn. Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @public * @since 1.0 * @see SetLineStyle() */ public function Rect($x, $y, $w, $h, $style='', $border_style=array(), $fill_color=array()) { if ($this->state != 2) { return; } if (empty($style)) { $style = 'S'; } if (!(strpos($style, 'F') === false) AND !empty($fill_color)) { // set background color $this->SetFillColorArray($fill_color); } if (!empty($border_style)) { if (isset($border_style['all']) AND !empty($border_style['all'])) { //set global style for border $this->SetLineStyle($border_style['all']); $border_style = array(); } else { // remove stroke operator from style $opnostroke = array('S' => '', 'D' => '', 's' => '', 'd' => '', 'B' => 'F', 'FD' => 'F', 'DF' => 'F', 'B*' => 'F*', 'F*D' => 'F*', 'DF*' => 'F*', 'b' => 'f', 'fd' => 'f', 'df' => 'f', 'b*' => 'f*', 'f*d' => 'f*', 'df*' => 'f*' ); if (isset($opnostroke[$style])) { $style = $opnostroke[$style]; } } } if (!empty($style)) { $op = TCPDF_STATIC::getPathPaintOperator($style); $this->_outRect($x, $y, $w, $h, $op); } if (!empty($border_style)) { $border_style2 = array(); foreach ($border_style as $line => $value) { $length = strlen($line); for ($i = 0; $i < $length; ++$i) { $border_style2[$line[$i]] = $value; } } $border_style = $border_style2; if (isset($border_style['L']) AND $border_style['L']) { $this->Line($x, $y, $x, $y + $h, $border_style['L']); } if (isset($border_style['T']) AND $border_style['T']) { $this->Line($x, $y, $x + $w, $y, $border_style['T']); } if (isset($border_style['R']) AND $border_style['R']) { $this->Line($x + $w, $y, $x + $w, $y + $h, $border_style['R']); } if (isset($border_style['B']) AND $border_style['B']) { $this->Line($x, $y + $h, $x + $w, $y + $h, $border_style['B']); } } } /** * Draws a Bezier curve. * The Bezier curve is a tangent to the line between the control points at * either end of the curve. * @param $x0 (float) Abscissa of start point. * @param $y0 (float) Ordinate of start point. * @param $x1 (float) Abscissa of control point 1. * @param $y1 (float) Ordinate of control point 1. * @param $x2 (float) Abscissa of control point 2. * @param $y2 (float) Ordinate of control point 2. * @param $x3 (float) Abscissa of end point. * @param $y3 (float) Ordinate of end point. * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of curve. Array like for SetLineStyle(). Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @public * @see SetLineStyle() * @since 2.1.000 (2008-01-08) */ public function Curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3, $style='', $line_style=array(), $fill_color=array()) { if ($this->state != 2) { return; } if (!(false === strpos($style, 'F')) AND isset($fill_color)) { $this->SetFillColorArray($fill_color); } $op = TCPDF_STATIC::getPathPaintOperator($style); if ($line_style) { $this->SetLineStyle($line_style); } $this->_outPoint($x0, $y0); $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3); $this->_out($op); } /** * Draws a poly-Bezier curve. * Each Bezier curve segment is a tangent to the line between the control points at * either end of the curve. * @param $x0 (float) Abscissa of start point. * @param $y0 (float) Ordinate of start point. * @param $segments (float) An array of bezier descriptions. Format: array(x1, y1, x2, y2, x3, y3). * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of curve. Array like for SetLineStyle(). Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @public * @see SetLineStyle() * @since 3.0008 (2008-05-12) */ public function Polycurve($x0, $y0, $segments, $style='', $line_style=array(), $fill_color=array()) { if ($this->state != 2) { return; } if (!(false === strpos($style, 'F')) AND isset($fill_color)) { $this->SetFillColorArray($fill_color); } $op = TCPDF_STATIC::getPathPaintOperator($style); if ($op == 'f') { $line_style = array(); } if ($line_style) { $this->SetLineStyle($line_style); } $this->_outPoint($x0, $y0); foreach ($segments as $segment) { list($x1, $y1, $x2, $y2, $x3, $y3) = $segment; $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3); } $this->_out($op); } /** * Draws an ellipse. * An ellipse is formed from n Bezier curves. * @param $x0 (float) Abscissa of center point. * @param $y0 (float) Ordinate of center point. * @param $rx (float) Horizontal radius. * @param $ry (float) Vertical radius (if ry = 0 then is a circle, see Circle()). Default value: 0. * @param $angle: (float) Angle oriented (anti-clockwise). Default value: 0. * @param $astart: (float) Angle start of draw line. Default value: 0. * @param $afinish: (float) Angle finish of draw line. Default value: 360. * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of ellipse. Array like for SetLineStyle(). Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @param $nc (integer) Number of curves used to draw a 90 degrees portion of ellipse. * @author Nicola Asuni * @public * @since 2.1.000 (2008-01-08) */ public function Ellipse($x0, $y0, $rx, $ry='', $angle=0, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=2) { if ($this->state != 2) { return; } if (TCPDF_STATIC::empty_string($ry) OR ($ry == 0)) { $ry = $rx; } if (!(false === strpos($style, 'F')) AND isset($fill_color)) { $this->SetFillColorArray($fill_color); } $op = TCPDF_STATIC::getPathPaintOperator($style); if ($op == 'f') { $line_style = array(); } if ($line_style) { $this->SetLineStyle($line_style); } $this->_outellipticalarc($x0, $y0, $rx, $ry, $angle, $astart, $afinish, false, $nc, true, true, false); $this->_out($op); } /** * Append an elliptical arc to the current path. * An ellipse is formed from n Bezier curves. * @param $xc (float) Abscissa of center point. * @param $yc (float) Ordinate of center point. * @param $rx (float) Horizontal radius. * @param $ry (float) Vertical radius (if ry = 0 then is a circle, see Circle()). Default value: 0. * @param $xang: (float) Angle between the X-axis and the major axis of the ellipse. Default value: 0. * @param $angs: (float) Angle start of draw line. Default value: 0. * @param $angf: (float) Angle finish of draw line. Default value: 360. * @param $pie (boolean) if true do not mark the border point (used to draw pie sectors). * @param $nc (integer) Number of curves used to draw a 90 degrees portion of ellipse. * @param $startpoint (boolean) if true output a starting point. * @param $ccw (boolean) if true draws in counter-clockwise. * @param $svg (boolean) if true the angles are in svg mode (already calculated). * @return array bounding box coordinates (x min, y min, x max, y max) * @author Nicola Asuni * @protected * @since 4.9.019 (2010-04-26) */ protected function _outellipticalarc($xc, $yc, $rx, $ry, $xang=0, $angs=0, $angf=360, $pie=false, $nc=2, $startpoint=true, $ccw=true, $svg=false) { $k = $this->k; if ($nc < 2) { $nc = 2; } $xmin = 2147483647; $ymin = 2147483647; $xmax = 0; $ymax = 0; if ($pie) { // center of the arc $this->_outPoint($xc, $yc); } $xang = deg2rad((float) $xang); $angs = deg2rad((float) $angs); $angf = deg2rad((float) $angf); if ($svg) { $as = $angs; $af = $angf; } else { $as = atan2((sin($angs) / $ry), (cos($angs) / $rx)); $af = atan2((sin($angf) / $ry), (cos($angf) / $rx)); } if ($as < 0) { $as += (2 * M_PI); } if ($af < 0) { $af += (2 * M_PI); } if ($ccw AND ($as > $af)) { // reverse rotation $as -= (2 * M_PI); } elseif (!$ccw AND ($as < $af)) { // reverse rotation $af -= (2 * M_PI); } $total_angle = ($af - $as); if ($nc < 2) { $nc = 2; } // total arcs to draw $nc *= (2 * abs($total_angle) / M_PI); $nc = round($nc) + 1; // angle of each arc $arcang = ($total_angle / $nc); // center point in PDF coordinates $x0 = $xc; $y0 = ($this->h - $yc); // starting angle $ang = $as; $alpha = sin($arcang) * ((sqrt(4 + (3 * pow(tan(($arcang) / 2), 2))) - 1) / 3); $cos_xang = cos($xang); $sin_xang = sin($xang); $cos_ang = cos($ang); $sin_ang = sin($ang); // first arc point $px1 = $x0 + ($rx * $cos_xang * $cos_ang) - ($ry * $sin_xang * $sin_ang); $py1 = $y0 + ($rx * $sin_xang * $cos_ang) + ($ry * $cos_xang * $sin_ang); // first Bezier control point $qx1 = ($alpha * ((-$rx * $cos_xang * $sin_ang) - ($ry * $sin_xang * $cos_ang))); $qy1 = ($alpha * ((-$rx * $sin_xang * $sin_ang) + ($ry * $cos_xang * $cos_ang))); if ($pie) { // line from center to arc starting point $this->_outLine($px1, $this->h - $py1); } elseif ($startpoint) { // arc starting point $this->_outPoint($px1, $this->h - $py1); } // draw arcs for ($i = 1; $i <= $nc; ++$i) { // starting angle $ang = $as + ($i * $arcang); if ($i == $nc) { $ang = $af; } $cos_ang = cos($ang); $sin_ang = sin($ang); // second arc point $px2 = $x0 + ($rx * $cos_xang * $cos_ang) - ($ry * $sin_xang * $sin_ang); $py2 = $y0 + ($rx * $sin_xang * $cos_ang) + ($ry * $cos_xang * $sin_ang); // second Bezier control point $qx2 = ($alpha * ((-$rx * $cos_xang * $sin_ang) - ($ry * $sin_xang * $cos_ang))); $qy2 = ($alpha * ((-$rx * $sin_xang * $sin_ang) + ($ry * $cos_xang * $cos_ang))); // draw arc $cx1 = ($px1 + $qx1); $cy1 = ($this->h - ($py1 + $qy1)); $cx2 = ($px2 - $qx2); $cy2 = ($this->h - ($py2 - $qy2)); $cx3 = $px2; $cy3 = ($this->h - $py2); $this->_outCurve($cx1, $cy1, $cx2, $cy2, $cx3, $cy3); // get bounding box coordinates $xmin = min($xmin, $cx1, $cx2, $cx3); $ymin = min($ymin, $cy1, $cy2, $cy3); $xmax = max($xmax, $cx1, $cx2, $cx3); $ymax = max($ymax, $cy1, $cy2, $cy3); // move to next point $px1 = $px2; $py1 = $py2; $qx1 = $qx2; $qy1 = $qy2; } if ($pie) { $this->_outLine($xc, $yc); // get bounding box coordinates $xmin = min($xmin, $xc); $ymin = min($ymin, $yc); $xmax = max($xmax, $xc); $ymax = max($ymax, $yc); } return array($xmin, $ymin, $xmax, $ymax); } /** * Draws a circle. * A circle is formed from n Bezier curves. * @param $x0 (float) Abscissa of center point. * @param $y0 (float) Ordinate of center point. * @param $r (float) Radius. * @param $angstr: (float) Angle start of draw line. Default value: 0. * @param $angend: (float) Angle finish of draw line. Default value: 360. * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of circle. Array like for SetLineStyle(). Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(red, green, blue). Default value: default color (empty array). * @param $nc (integer) Number of curves used to draw a 90 degrees portion of circle. * @public * @since 2.1.000 (2008-01-08) */ public function Circle($x0, $y0, $r, $angstr=0, $angend=360, $style='', $line_style=array(), $fill_color=array(), $nc=2) { $this->Ellipse($x0, $y0, $r, $r, 0, $angstr, $angend, $style, $line_style, $fill_color, $nc); } /** * Draws a polygonal line * @param $p (array) Points 0 to ($np - 1). Array with values (x0, y0, x1, y1,..., x(np-1), y(np - 1)) * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of polygon. Array with keys among the following: * <ul> * <li>all: Line style of all lines. Array like for SetLineStyle().</li> * <li>0 to ($np - 1): Line style of each line. Array like for SetLineStyle().</li> * </ul> * If a key is not present or is null, not draws the line. Default value is default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @since 4.8.003 (2009-09-15) * @public */ public function PolyLine($p, $style='', $line_style=array(), $fill_color=array()) { $this->Polygon($p, $style, $line_style, $fill_color, false); } /** * Draws a polygon. * @param $p (array) Points 0 to ($np - 1). Array with values (x0, y0, x1, y1,..., x(np-1), y(np - 1)) * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of polygon. Array with keys among the following: * <ul> * <li>all: Line style of all lines. Array like for SetLineStyle().</li> * <li>0 to ($np - 1): Line style of each line. Array like for SetLineStyle().</li> * </ul> * If a key is not present or is null, not draws the line. Default value is default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @param $closed (boolean) if true the polygon is closes, otherwise will remain open * @public * @since 2.1.000 (2008-01-08) */ public function Polygon($p, $style='', $line_style=array(), $fill_color=array(), $closed=true) { if ($this->state != 2) { return; } $nc = count($p); // number of coordinates $np = $nc / 2; // number of points if ($closed) { // close polygon by adding the first 2 points at the end (one line) for ($i = 0; $i < 4; ++$i) { $p[$nc + $i] = $p[$i]; } // copy style for the last added line if (isset($line_style[0])) { $line_style[$np] = $line_style[0]; } $nc += 4; } if (!(false === strpos($style, 'F')) AND isset($fill_color)) { $this->SetFillColorArray($fill_color); } $op = TCPDF_STATIC::getPathPaintOperator($style); if ($op == 'f') { $line_style = array(); } $draw = true; if ($line_style) { if (isset($line_style['all'])) { $this->SetLineStyle($line_style['all']); } else { $draw = false; if ($op == 'B') { // draw fill $op = 'f'; $this->_outPoint($p[0], $p[1]); for ($i = 2; $i < $nc; $i = $i + 2) { $this->_outLine($p[$i], $p[$i + 1]); } $this->_out($op); } // draw outline $this->_outPoint($p[0], $p[1]); for ($i = 2; $i < $nc; $i = $i + 2) { $line_num = ($i / 2) - 1; if (isset($line_style[$line_num])) { if ($line_style[$line_num] != 0) { if (is_array($line_style[$line_num])) { $this->_out('S'); $this->SetLineStyle($line_style[$line_num]); $this->_outPoint($p[$i - 2], $p[$i - 1]); $this->_outLine($p[$i], $p[$i + 1]); $this->_out('S'); $this->_outPoint($p[$i], $p[$i + 1]); } else { $this->_outLine($p[$i], $p[$i + 1]); } } } else { $this->_outLine($p[$i], $p[$i + 1]); } } $this->_out($op); } } if ($draw) { $this->_outPoint($p[0], $p[1]); for ($i = 2; $i < $nc; $i = $i + 2) { $this->_outLine($p[$i], $p[$i + 1]); } $this->_out($op); } } /** * Draws a regular polygon. * @param $x0 (float) Abscissa of center point. * @param $y0 (float) Ordinate of center point. * @param $r: (float) Radius of inscribed circle. * @param $ns (integer) Number of sides. * @param $angle (float) Angle oriented (anti-clockwise). Default value: 0. * @param $draw_circle (boolean) Draw inscribed circle or not. Default value: false. * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of polygon sides. Array with keys among the following: * <ul> * <li>all: Line style of all sides. Array like for SetLineStyle().</li> * <li>0 to ($ns - 1): Line style of each side. Array like for SetLineStyle().</li> * </ul> * If a key is not present or is null, not draws the side. Default value is default line style (empty array). * @param $fill_color (array) Fill color. Format: array(red, green, blue). Default value: default color (empty array). * @param $circle_style (string) Style of rendering of inscribed circle (if draws). Possible values are: * <ul> * <li>D or empty string: Draw (default).</li> * <li>F: Fill.</li> * <li>DF or FD: Draw and fill.</li> * <li>CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).</li> * <li>CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).</li> * </ul> * @param $circle_outLine_style (array) Line style of inscribed circle (if draws). Array like for SetLineStyle(). Default value: default line style (empty array). * @param $circle_fill_color (array) Fill color of inscribed circle (if draws). Format: array(red, green, blue). Default value: default color (empty array). * @public * @since 2.1.000 (2008-01-08) */ public function RegularPolygon($x0, $y0, $r, $ns, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) { if (3 > $ns) { $ns = 3; } if ($draw_circle) { $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color); } $p = array(); for ($i = 0; $i < $ns; ++$i) { $a = $angle + ($i * 360 / $ns); $a_rad = deg2rad((float) $a); $p[] = $x0 + ($r * sin($a_rad)); $p[] = $y0 + ($r * cos($a_rad)); } $this->Polygon($p, $style, $line_style, $fill_color); } /** * Draws a star polygon * @param $x0 (float) Abscissa of center point. * @param $y0 (float) Ordinate of center point. * @param $r (float) Radius of inscribed circle. * @param $nv (integer) Number of vertices. * @param $ng (integer) Number of gap (if ($ng % $nv = 1) then is a regular polygon). * @param $angle: (float) Angle oriented (anti-clockwise). Default value: 0. * @param $draw_circle: (boolean) Draw inscribed circle or not. Default value is false. * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $line_style (array) Line style of polygon sides. Array with keys among the following: * <ul> * <li>all: Line style of all sides. Array like for * SetLineStyle().</li> * <li>0 to (n - 1): Line style of each side. Array like for SetLineStyle().</li> * </ul> * If a key is not present or is null, not draws the side. Default value is default line style (empty array). * @param $fill_color (array) Fill color. Format: array(red, green, blue). Default value: default color (empty array). * @param $circle_style (string) Style of rendering of inscribed circle (if draws). Possible values are: * <ul> * <li>D or empty string: Draw (default).</li> * <li>F: Fill.</li> * <li>DF or FD: Draw and fill.</li> * <li>CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).</li> * <li>CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).</li> * </ul> * @param $circle_outLine_style (array) Line style of inscribed circle (if draws). Array like for SetLineStyle(). Default value: default line style (empty array). * @param $circle_fill_color (array) Fill color of inscribed circle (if draws). Format: array(red, green, blue). Default value: default color (empty array). * @public * @since 2.1.000 (2008-01-08) */ public function StarPolygon($x0, $y0, $r, $nv, $ng, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) { if ($nv < 2) { $nv = 2; } if ($draw_circle) { $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color); } $p2 = array(); $visited = array(); for ($i = 0; $i < $nv; ++$i) { $a = $angle + ($i * 360 / $nv); $a_rad = deg2rad((float) $a); $p2[] = $x0 + ($r * sin($a_rad)); $p2[] = $y0 + ($r * cos($a_rad)); $visited[] = false; } $p = array(); $i = 0; do { $p[] = $p2[$i * 2]; $p[] = $p2[($i * 2) + 1]; $visited[$i] = true; $i += $ng; $i %= $nv; } while (!$visited[$i]); $this->Polygon($p, $style, $line_style, $fill_color); } /** * Draws a rounded rectangle. * @param $x (float) Abscissa of upper-left corner. * @param $y (float) Ordinate of upper-left corner. * @param $w (float) Width. * @param $h (float) Height. * @param $r (float) the radius of the circle used to round off the corners of the rectangle. * @param $round_corner (string) Draws rounded corner or not. String with a 0 (not rounded i-corner) or 1 (rounded i-corner) in i-position. Positions are, in order and begin to 0: top right, bottom right, bottom left and top left. Default value: all rounded corner ("1111"). * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $border_style (array) Border style of rectangle. Array like for SetLineStyle(). Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @public * @since 2.1.000 (2008-01-08) */ public function RoundedRect($x, $y, $w, $h, $r, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) { $this->RoundedRectXY($x, $y, $w, $h, $r, $r, $round_corner, $style, $border_style, $fill_color); } /** * Draws a rounded rectangle. * @param $x (float) Abscissa of upper-left corner. * @param $y (float) Ordinate of upper-left corner. * @param $w (float) Width. * @param $h (float) Height. * @param $rx (float) the x-axis radius of the ellipse used to round off the corners of the rectangle. * @param $ry (float) the y-axis radius of the ellipse used to round off the corners of the rectangle. * @param $round_corner (string) Draws rounded corner or not. String with a 0 (not rounded i-corner) or 1 (rounded i-corner) in i-position. Positions are, in order and begin to 0: top right, bottom right, bottom left and top left. Default value: all rounded corner ("1111"). * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $border_style (array) Border style of rectangle. Array like for SetLineStyle(). Default value: default line style (empty array). * @param $fill_color (array) Fill color. Format: array(GREY) or array(R,G,B) or array(C,M,Y,K) or array(C,M,Y,K,SpotColorName). Default value: default color (empty array). * @public * @since 4.9.019 (2010-04-22) */ public function RoundedRectXY($x, $y, $w, $h, $rx, $ry, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) { if ($this->state != 2) { return; } if (($round_corner == '0000') OR (($rx == $ry) AND ($rx == 0))) { // Not rounded $this->Rect($x, $y, $w, $h, $style, $border_style, $fill_color); return; } // Rounded if (!(false === strpos($style, 'F')) AND isset($fill_color)) { $this->SetFillColorArray($fill_color); } $op = TCPDF_STATIC::getPathPaintOperator($style); if ($op == 'f') { $border_style = array(); } if ($border_style) { $this->SetLineStyle($border_style); } $MyArc = 4 / 3 * (sqrt(2) - 1); $this->_outPoint($x + $rx, $y); $xc = $x + $w - $rx; $yc = $y + $ry; $this->_outLine($xc, $y); if ($round_corner[0]) { $this->_outCurve($xc + ($rx * $MyArc), $yc - $ry, $xc + $rx, $yc - ($ry * $MyArc), $xc + $rx, $yc); } else { $this->_outLine($x + $w, $y); } $xc = $x + $w - $rx; $yc = $y + $h - $ry; $this->_outLine($x + $w, $yc); if ($round_corner[1]) { $this->_outCurve($xc + $rx, $yc + ($ry * $MyArc), $xc + ($rx * $MyArc), $yc + $ry, $xc, $yc + $ry); } else { $this->_outLine($x + $w, $y + $h); } $xc = $x + $rx; $yc = $y + $h - $ry; $this->_outLine($xc, $y + $h); if ($round_corner[2]) { $this->_outCurve($xc - ($rx * $MyArc), $yc + $ry, $xc - $rx, $yc + ($ry * $MyArc), $xc - $rx, $yc); } else { $this->_outLine($x, $y + $h); } $xc = $x + $rx; $yc = $y + $ry; $this->_outLine($x, $yc); if ($round_corner[3]) { $this->_outCurve($xc - $rx, $yc - ($ry * $MyArc), $xc - ($rx * $MyArc), $yc - $ry, $xc, $yc - $ry); } else { $this->_outLine($x, $y); $this->_outLine($x + $rx, $y); } $this->_out($op); } /** * Draws a grahic arrow. * @param $x0 (float) Abscissa of first point. * @param $y0 (float) Ordinate of first point. * @param $x1 (float) Abscissa of second point. * @param $y1 (float) Ordinate of second point. * @param $head_style (int) (0 = draw only arrowhead arms, 1 = draw closed arrowhead, but no fill, 2 = closed and filled arrowhead, 3 = filled arrowhead) * @param $arm_size (float) length of arrowhead arms * @param $arm_angle (int) angle between an arm and the shaft * @author Piotr Galecki, Nicola Asuni, Andy Meier * @since 4.6.018 (2009-07-10) */ public function Arrow($x0, $y0, $x1, $y1, $head_style=0, $arm_size=5, $arm_angle=15) { // getting arrow direction angle // 0 deg angle is when both arms go along X axis. angle grows clockwise. $dir_angle = atan2(($y0 - $y1), ($x0 - $x1)); if ($dir_angle < 0) { $dir_angle += (2 * M_PI); } $arm_angle = deg2rad($arm_angle); $sx1 = $x1; $sy1 = $y1; if ($head_style > 0) { // calculate the stopping point for the arrow shaft $sx1 = $x1 + (($arm_size - $this->LineWidth) * cos($dir_angle)); $sy1 = $y1 + (($arm_size - $this->LineWidth) * sin($dir_angle)); } // main arrow line / shaft $this->Line($x0, $y0, $sx1, $sy1); // left arrowhead arm tip $x2L = $x1 + ($arm_size * cos($dir_angle + $arm_angle)); $y2L = $y1 + ($arm_size * sin($dir_angle + $arm_angle)); // right arrowhead arm tip $x2R = $x1 + ($arm_size * cos($dir_angle - $arm_angle)); $y2R = $y1 + ($arm_size * sin($dir_angle - $arm_angle)); $mode = 'D'; $style = array(); switch ($head_style) { case 0: { // draw only arrowhead arms $mode = 'D'; $style = array(1, 1, 0); break; } case 1: { // draw closed arrowhead, but no fill $mode = 'D'; break; } case 2: { // closed and filled arrowhead $mode = 'DF'; break; } case 3: { // filled arrowhead $mode = 'F'; break; } } $this->Polygon(array($x2L, $y2L, $x1, $y1, $x2R, $y2R), $mode, $style, array()); } // END GRAPHIC FUNCTIONS SECTION ----------------------- /** * Add a Named Destination. * NOTE: destination names are unique, so only last entry will be saved. * @param $name (string) Destination name. * @param $y (float) Y position in user units of the destiantion on the selected page (default = -1 = current position; 0 = page start;). * @param $page (int) Target page number (leave empty for current page). * @param $x (float) X position in user units of the destiantion on the selected page (default = -1 = current position;). * @return (string) Stripped named destination identifier or false in case of error. * @public * @author Christian Deligant, Nicola Asuni * @since 5.9.097 (2011-06-23) */ public function setDestination($name, $y=-1, $page='', $x=-1) { // remove unsupported characters $name = TCPDF_STATIC::encodeNameObject($name); if (TCPDF_STATIC::empty_string($name)) { return false; } if ($y == -1) { $y = $this->GetY(); } elseif ($y < 0) { $y = 0; } elseif ($y > $this->h) { $y = $this->h; } if ($x == -1) { $x = $this->GetX(); } elseif ($x < 0) { $x = 0; } elseif ($x > $this->w) { $x = $this->w; } if (empty($page)) { $page = $this->PageNo(); if (empty($page)) { return; } } $this->dests[$name] = array('x' => $x, 'y' => $y, 'p' => $page); return $name; } /** * Return the Named Destination array. * @return (array) Named Destination array. * @public * @author Nicola Asuni * @since 5.9.097 (2011-06-23) */ public function getDestination() { return $this->dests; } /** * Insert Named Destinations. * @protected * @author Johannes Gntert, Nicola Asuni * @since 5.9.098 (2011-06-23) */ protected function _putdests() { if (empty($this->dests)) { return; } $this->n_dests = $this->_newobj(); $out = ' <<'; foreach($this->dests as $name => $o) { $out .= ' /'.$name.' '.sprintf('[%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k))); } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } /** * Adds a bookmark - alias for Bookmark(). * @param $txt (string) Bookmark description. * @param $level (int) Bookmark level (minimum value is 0). * @param $y (float) Y position in user units of the bookmark on the selected page (default = -1 = current position; 0 = page start;). * @param $page (int) Target page number (leave empty for current page). * @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic. * @param $color (array) RGB color array (values from 0 to 255). * @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;). * @param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name). * @public */ public function setBookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1, $link='') { $this->Bookmark($txt, $level, $y, $page, $style, $color, $x, $link); } /** * Adds a bookmark. * @param $txt (string) Bookmark description. * @param $level (int) Bookmark level (minimum value is 0). * @param $y (float) Y position in user units of the bookmark on the selected page (default = -1 = current position; 0 = page start;). * @param $page (int) Target page number (leave empty for current page). * @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic. * @param $color (array) RGB color array (values from 0 to 255). * @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;). * @param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name). * @public * @since 2.1.002 (2008-02-12) */ public function Bookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1, $link='') { if ($level < 0) { $level = 0; } if (isset($this->outlines[0])) { $lastoutline = end($this->outlines); $maxlevel = $lastoutline['l'] + 1; } else { $maxlevel = 0; } if ($level > $maxlevel) { $level = $maxlevel; } if ($y == -1) { $y = $this->GetY(); } elseif ($y < 0) { $y = 0; } elseif ($y > $this->h) { $y = $this->h; } if ($x == -1) { $x = $this->GetX(); } elseif ($x < 0) { $x = 0; } elseif ($x > $this->w) { $x = $this->w; } if (empty($page)) { $page = $this->PageNo(); if (empty($page)) { return; } } $this->outlines[] = array('t' => $txt, 'l' => $level, 'x' => $x, 'y' => $y, 'p' => $page, 's' => strtoupper($style), 'c' => $color, 'u' => $link); } /** * Sort bookmarks for page and key. * @protected * @since 5.9.119 (2011-09-19) */ protected function sortBookmarks() { // get sorting columns $outline_p = array(); $outline_y = array(); foreach ($this->outlines as $key => $row) { $outline_p[$key] = $row['p']; $outline_k[$key] = $key; } // sort outlines by page and original position array_multisort($outline_p, SORT_NUMERIC, SORT_ASC, $outline_k, SORT_NUMERIC, SORT_ASC, $this->outlines); } /** * Create a bookmark PDF string. * @protected * @author Olivier Plathey, Nicola Asuni * @since 2.1.002 (2008-02-12) */ protected function _putbookmarks() { $nb = count($this->outlines); if ($nb == 0) { return; } // sort bookmarks $this->sortBookmarks(); $lru = array(); $level = 0; foreach ($this->outlines as $i => $o) { if ($o['l'] > 0) { $parent = $lru[($o['l'] - 1)]; //Set parent and last pointers $this->outlines[$i]['parent'] = $parent; $this->outlines[$parent]['last'] = $i; if ($o['l'] > $level) { //Level increasing: set first pointer $this->outlines[$parent]['first'] = $i; } } else { $this->outlines[$i]['parent'] = $nb; } if (($o['l'] <= $level) AND ($i > 0)) { //Set prev and next pointers $prev = $lru[$o['l']]; $this->outlines[$prev]['next'] = $i; $this->outlines[$i]['prev'] = $prev; } $lru[$o['l']] = $i; $level = $o['l']; } //Outline items $n = $this->n + 1; $nltags = '/<br[\s]?\/>|<\/(blockquote|dd|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|p|pre|ul|tcpdf|table|tr|td)>/si'; foreach ($this->outlines as $i => $o) { $oid = $this->_newobj(); // covert HTML title to string $title = preg_replace($nltags, "\n", $o['t']); $title = preg_replace("/[\r]+/si", '', $title); $title = preg_replace("/[\n]+/si", "\n", $title); $title = strip_tags($title); $title = $this->stringTrim($title); $out = '<_textstring($title, $oid); $out .= ' /Parent '.($n + $o['parent']).' 0 R'; if (isset($o['prev'])) { $out .= ' /Prev '.($n + $o['prev']).' 0 R'; } if (isset($o['next'])) { $out .= ' /Next '.($n + $o['next']).' 0 R'; } if (isset($o['first'])) { $out .= ' /First '.($n + $o['first']).' 0 R'; } if (isset($o['last'])) { $out .= ' /Last '.($n + $o['last']).' 0 R'; } if (isset($o['u']) AND !empty($o['u'])) { // link if (is_string($o['u'])) { if ($o['u'][0] == '#') { // internal destination $out .= ' /Dest /'.TCPDF_STATIC::encodeNameObject(substr($o['u'], 1)); } elseif ($o['u'][0] == '%') { // embedded PDF file $filename = basename(substr($o['u'], 1)); $out .= ' /A <embeddedfiles[$filename]['a'].' >> >>'; } elseif ($o['u'][0] == '*') { // embedded generic file $filename = basename(substr($o['u'], 1)); $jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="'.$filename.'") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});'; $out .= ' /A <_textstring($jsa, $oid).'>>'; } else { // external URI link $out .= ' /A <_datastring($this->unhtmlentities($o['u']), $oid).'>>'; } } elseif (isset($this->links[$o['u']])) { // internal link ID $l = $this->links[$o['u']]; if (isset($this->page_obj_id[($l[0])])) { $out .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k))); } } } elseif (isset($this->page_obj_id[($o['p'])])) { // link to a page $out .= ' '.sprintf('/Dest [%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k))); } // set font style $style = 0; if (!empty($o['s'])) { // bold if (strpos($o['s'], 'B') !== false) { $style |= 2; } // oblique if (strpos($o['s'], 'I') !== false) { $style |= 1; } } $out .= sprintf(' /F %d', $style); // set bookmark color if (isset($o['c']) AND is_array($o['c']) AND (count($o['c']) == 3)) { $color = array_values($o['c']); $out .= sprintf(' /C [%F %F %F]', ($color[0] / 255), ($color[1] / 255), ($color[2] / 255)); } else { // black $out .= ' /C [0.0 0.0 0.0]'; } $out .= ' /Count 0'; // normally closed item $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } //Outline root $this->OutlineRoot = $this->_newobj(); $this->_out('<< /Type /Outlines /First '.$n.' 0 R /Last '.($n + $lru[0]).' 0 R >>'."\n".'endobj'); } // --- JAVASCRIPT ------------------------------------------------------ /** * Adds a javascript * @param $script (string) Javascript code * @public * @author Johannes Gntert, Nicola Asuni * @since 2.1.002 (2008-02-12) */ public function IncludeJS($script) { $this->javascript .= $script; } /** * Adds a javascript object and return object ID * @param $script (string) Javascript code * @param $onload (boolean) if true executes this object when opening the document * @return int internal object ID * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function addJavascriptObject($script, $onload=false) { if ($this->pdfa_mode) { // javascript is not allowed in PDF/A mode return false; } ++$this->n; $this->js_objects[$this->n] = array('n' => $this->n, 'js' => $script, 'onload' => $onload); return $this->n; } /** * Create a javascript PDF string. * @protected * @author Johannes Gntert, Nicola Asuni * @since 2.1.002 (2008-02-12) */ protected function _putjavascript() { if ($this->pdfa_mode OR (empty($this->javascript) AND empty($this->js_objects))) { return; } if (strpos($this->javascript, 'this.addField') > 0) { if (!$this->ur['enabled']) { //$this->setUserRights(); } // the following two lines are used to avoid form fields duplication after saving // The addField method only works when releasing user rights (UR3) $jsa = sprintf("ftcpdfdocsaved=this.addField('%s','%s',%d,[%F,%F,%F,%F]);", 'tcpdfdocsaved', 'text', 0, 0, 1, 0, 1); $jsb = "getField('tcpdfdocsaved').value='saved';"; $this->javascript = $jsa."\n".$this->javascript."\n".$jsb; } // name tree for javascript $this->n_js = '<< /Names ['; if (!empty($this->javascript)) { $this->n_js .= ' (EmbeddedJS) '.($this->n + 1).' 0 R'; } if (!empty($this->js_objects)) { foreach ($this->js_objects as $key => $val) { if ($val['onload']) { $this->n_js .= ' (JS'.$key.') '.$key.' 0 R'; } } } $this->n_js .= ' ] >>'; // default Javascript object if (!empty($this->javascript)) { $obj_id = $this->_newobj(); $out = '<< /S /JavaScript'; $out .= ' /JS '.$this->_textstring($this->javascript, $obj_id); $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } // additional Javascript objects if (!empty($this->js_objects)) { foreach ($this->js_objects as $key => $val) { $out = $this->_getobj($key)."\n".' << /S /JavaScript /JS '.$this->_textstring($val['js'], $key).' >>'."\n".'endobj'; $this->_out($out); } } } /** * Adds a javascript form field. * @param $type (string) field type * @param $name (string) field name * @param $x (int) horizontal position * @param $y (int) vertical position * @param $w (int) width * @param $h (int) height * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @protected * @author Denis Van Nuffelen, Nicola Asuni * @since 2.1.002 (2008-02-12) */ protected function _addfield($type, $name, $x, $y, $w, $h, $prop) { if ($this->rtl) { $x = $x - $w; } // the followind avoid fields duplication after saving the document $this->javascript .= "if (getField('tcpdfdocsaved').value != 'saved') {"; $k = $this->k; $this->javascript .= sprintf("f".$name."=this.addField('%s','%s',%u,[%F,%F,%F,%F]);", $name, $type, $this->PageNo()-1, $x*$k, ($this->h-$y)*$k+1, ($x+$w)*$k, ($this->h-$y-$h)*$k+1)."\n"; $this->javascript .= 'f'.$name.'.textSize='.$this->FontSizePt.";\n"; while (list($key, $val) = each($prop)) { if (strcmp(substr($key, -5), 'Color') == 0) { $val = TCPDF_COLORS::_JScolor($val); } else { $val = "'".$val."'"; } $this->javascript .= 'f'.$name.'.'.$key.'='.$val.";\n"; } if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } $this->javascript .= '}'; } // --- FORM FIELDS ----------------------------------------------------- /** * Set default properties for form fields. * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-06) */ public function setFormDefaultProp($prop=array()) { $this->default_form_prop = $prop; } /** * Return the default properties for form fields. * @return array $prop javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-06) */ public function getFormDefaultProp() { return $this->default_form_prop; } /** * Creates a text field * @param $name (string) field name * @param $w (float) Width of the rectangle * @param $h (float) Height of the rectangle * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered). * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function TextField($name, $w, $h, $prop=array(), $opt=array(), $x='', $y='', $js=false) { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); if ($js) { $this->_addfield('text', $name, $x, $y, $w, $h, $prop); return; } // get default style $prop = array_merge($this->getFormDefaultProp(), $prop); // get annotation data $popt = TCPDF_STATIC::getAnnotOptFromJSProp($prop, $this->spot_colors, $this->rtl); // set default appearance stream $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i']; $fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor); $popt['da'] = $fontstyle; // build appearance stream $popt['ap'] = array(); $popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' '; $text = ''; if (isset($prop['value']) AND !empty($prop['value'])) { $text = $prop['value']; } elseif (isset($opt['v']) AND !empty($opt['v'])) { $text = $opt['v']; } $tmpid = $this->startTemplate($w, $h, false); $align = ''; if (isset($popt['q'])) { switch ($popt['q']) { case 0: { $align = 'L'; break; } case 1: { $align = 'C'; break; } case 2: { $align = 'R'; break; } default: { $align = ''; break; } } } $this->MultiCell($w, $h, $text, 0, $align, false, 0, 0, 0, true, 0, false, true, 0, 'T', false); $this->endTemplate(); --$this->n; $popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata']; unset($this->xobjects[$tmpid]); $popt['ap']['n'] .= 'Q EMC'; // merge options $opt = array_merge($popt, $opt); // remove some conflicting options unset($opt['bs']); // set remaining annotation data $opt['Subtype'] = 'Widget'; $opt['ft'] = 'Tx'; $opt['t'] = $name; // Additional annotation's parameters (check _putannotsobj() method): //$opt['f'] //$opt['as'] //$opt['bs'] //$opt['be'] //$opt['c'] //$opt['border'] //$opt['h'] //$opt['mk']; //$opt['mk']['r'] //$opt['mk']['bc']; //$opt['mk']['bg']; unset($opt['mk']['ca']); unset($opt['mk']['rc']); unset($opt['mk']['ac']); unset($opt['mk']['i']); unset($opt['mk']['ri']); unset($opt['mk']['ix']); unset($opt['mk']['if']); //$opt['mk']['if']['sw']; //$opt['mk']['if']['s']; //$opt['mk']['if']['a']; //$opt['mk']['if']['fb']; unset($opt['mk']['tp']); //$opt['tu'] //$opt['tm'] //$opt['ff'] //$opt['v'] //$opt['dv'] //$opt['a'] //$opt['aa'] //$opt['q'] $this->Annotation($x, $y, $w, $h, $name, $opt, 0); if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } } /** * Creates a RadioButton field. * @param $name (string) Field name. * @param $w (int) Width of the radio button. * @param $prop (array) Javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $opt (array) Annotation parameters. Possible values are described on official PDF32000_2008 reference. * @param $onvalue (string) Value to be returned if selected. * @param $checked (boolean) Define the initial state. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $js (boolean) If true put the field using JavaScript (requires Acrobat Writer to be rendered). * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function RadioButton($name, $w, $prop=array(), $opt=array(), $onvalue='On', $checked=false, $x='', $y='', $js=false) { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($w, $x, $y); if ($js) { $this->_addfield('radiobutton', $name, $x, $y, $w, $w, $prop); return; } if (TCPDF_STATIC::empty_string($onvalue)) { $onvalue = 'On'; } if ($checked) { $defval = $onvalue; } else { $defval = 'Off'; } // set font $font = 'zapfdingbats'; if ($this->pdfa_mode) { // all fonts must be embedded $font = 'pdfa'.$font; } $this->AddFont($font); $tmpfont = $this->getFontBuffer($font); // set data for parent group if (!isset($this->radiobutton_groups[$this->page])) { $this->radiobutton_groups[$this->page] = array(); } if (!isset($this->radiobutton_groups[$this->page][$name])) { $this->radiobutton_groups[$this->page][$name] = array(); ++$this->n; $this->radiobutton_groups[$this->page][$name]['n'] = $this->n; $this->radio_groups[] = $this->n; } $kid = ($this->n + 1); // save object ID to be added on Kids entry on parent object $this->radiobutton_groups[$this->page][$name][] = array('kid' => $kid, 'def' => $defval); // get default style $prop = array_merge($this->getFormDefaultProp(), $prop); $prop['NoToggleToOff'] = 'true'; $prop['Radio'] = 'true'; $prop['borderStyle'] = 'inset'; // get annotation data $popt = TCPDF_STATIC::getAnnotOptFromJSProp($prop, $this->spot_colors, $this->rtl); // set additional default options $this->annotation_fonts[$tmpfont['fontkey']] = $tmpfont['i']; $fontstyle = sprintf('/F%d %F Tf %s', $tmpfont['i'], $this->FontSizePt, $this->TextColor); $popt['da'] = $fontstyle; // build appearance stream $popt['ap'] = array(); $popt['ap']['n'] = array(); $fx = ((($w - $this->getAbsFontMeasure($tmpfont['cw'][108])) / 2) * $this->k); $fy = (($w - ((($tmpfont['desc']['Ascent'] - $tmpfont['desc']['Descent']) * $this->FontSizePt / 1000) / $this->k)) * $this->k); $popt['ap']['n'][$onvalue] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(108).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy); $popt['ap']['n']['Off'] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(109).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy); if (!isset($popt['mk'])) { $popt['mk'] = array(); } $popt['mk']['ca'] = '(l)'; // merge options $opt = array_merge($popt, $opt); // set remaining annotation data $opt['Subtype'] = 'Widget'; $opt['ft'] = 'Btn'; if ($checked) { $opt['v'] = array('/'.$onvalue); $opt['as'] = $onvalue; } else { $opt['as'] = 'Off'; } // store readonly flag if (!isset($this->radiobutton_groups[$this->page][$name]['#readonly#'])) { $this->radiobutton_groups[$this->page][$name]['#readonly#'] = false; } $this->radiobutton_groups[$this->page][$name]['#readonly#'] |= ($opt['f'] & 64); $this->Annotation($x, $y, $w, $w, $name, $opt, 0); if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } } /** * Creates a List-box field * @param $name (string) field name * @param $w (int) width * @param $h (int) height * @param $values (array) array containing the list of values. * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered). * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function ListBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); if ($js) { $this->_addfield('listbox', $name, $x, $y, $w, $h, $prop); $s = ''; foreach ($values as $value) { if (is_array($value)) { $s .= ',[\''.addslashes($value[1]).'\',\''.addslashes($value[0]).'\']'; } else { $s .= ',[\''.addslashes($value).'\',\''.addslashes($value).'\']'; } } $this->javascript .= 'f'.$name.'.setItems('.substr($s, 1).');'."\n"; return; } // get default style $prop = array_merge($this->getFormDefaultProp(), $prop); // get annotation data $popt = TCPDF_STATIC::getAnnotOptFromJSProp($prop, $this->spot_colors, $this->rtl); // set additional default values $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i']; $fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor); $popt['da'] = $fontstyle; // build appearance stream $popt['ap'] = array(); $popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' '; $text = ''; foreach($values as $item) { if (is_array($item)) { $text .= $item[1]."\n"; } else { $text .= $item."\n"; } } $tmpid = $this->startTemplate($w, $h, false); $this->MultiCell($w, $h, $text, 0, '', false, 0, 0, 0, true, 0, false, true, 0, 'T', false); $this->endTemplate(); --$this->n; $popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata']; unset($this->xobjects[$tmpid]); $popt['ap']['n'] .= 'Q EMC'; // merge options $opt = array_merge($popt, $opt); // set remaining annotation data $opt['Subtype'] = 'Widget'; $opt['ft'] = 'Ch'; $opt['t'] = $name; $opt['opt'] = $values; unset($opt['mk']['ca']); unset($opt['mk']['rc']); unset($opt['mk']['ac']); unset($opt['mk']['i']); unset($opt['mk']['ri']); unset($opt['mk']['ix']); unset($opt['mk']['if']); unset($opt['mk']['tp']); $this->Annotation($x, $y, $w, $h, $name, $opt, 0); if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } } /** * Creates a Combo-box field * @param $name (string) field name * @param $w (int) width * @param $h (int) height * @param $values (array) array containing the list of values. * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered). * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function ComboBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); if ($js) { $this->_addfield('combobox', $name, $x, $y, $w, $h, $prop); $s = ''; foreach ($values as $value) { if (is_array($value)) { $s .= ',[\''.addslashes($value[1]).'\',\''.addslashes($value[0]).'\']'; } else { $s .= ',[\''.addslashes($value).'\',\''.addslashes($value).'\']'; } } $this->javascript .= 'f'.$name.'.setItems('.substr($s, 1).');'."\n"; return; } // get default style $prop = array_merge($this->getFormDefaultProp(), $prop); $prop['Combo'] = true; // get annotation data $popt = TCPDF_STATIC::getAnnotOptFromJSProp($prop, $this->spot_colors, $this->rtl); // set additional default options $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i']; $fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor); $popt['da'] = $fontstyle; // build appearance stream $popt['ap'] = array(); $popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' '; $text = ''; foreach($values as $item) { if (is_array($item)) { $text .= $item[1]."\n"; } else { $text .= $item."\n"; } } $tmpid = $this->startTemplate($w, $h, false); $this->MultiCell($w, $h, $text, 0, '', false, 0, 0, 0, true, 0, false, true, 0, 'T', false); $this->endTemplate(); --$this->n; $popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata']; unset($this->xobjects[$tmpid]); $popt['ap']['n'] .= 'Q EMC'; // merge options $opt = array_merge($popt, $opt); // set remaining annotation data $opt['Subtype'] = 'Widget'; $opt['ft'] = 'Ch'; $opt['t'] = $name; $opt['opt'] = $values; unset($opt['mk']['ca']); unset($opt['mk']['rc']); unset($opt['mk']['ac']); unset($opt['mk']['i']); unset($opt['mk']['ri']); unset($opt['mk']['ix']); unset($opt['mk']['if']); unset($opt['mk']['tp']); $this->Annotation($x, $y, $w, $h, $name, $opt, 0); if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } } /** * Creates a CheckBox field * @param $name (string) field name * @param $w (int) width * @param $checked (boolean) define the initial state. * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference. * @param $onvalue (string) value to be returned if selected. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered). * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function CheckBox($name, $w, $checked=false, $prop=array(), $opt=array(), $onvalue='Yes', $x='', $y='', $js=false) { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($w, $x, $y); if ($js) { $this->_addfield('checkbox', $name, $x, $y, $w, $w, $prop); return; } if (!isset($prop['value'])) { $prop['value'] = array('Yes'); } // get default style $prop = array_merge($this->getFormDefaultProp(), $prop); $prop['borderStyle'] = 'inset'; // get annotation data $popt = TCPDF_STATIC::getAnnotOptFromJSProp($prop, $this->spot_colors, $this->rtl); // set additional default options $font = 'zapfdingbats'; if ($this->pdfa_mode) { // all fonts must be embedded $font = 'pdfa'.$font; } $this->AddFont($font); $tmpfont = $this->getFontBuffer($font); $this->annotation_fonts[$tmpfont['fontkey']] = $tmpfont['i']; $fontstyle = sprintf('/F%d %F Tf %s', $tmpfont['i'], $this->FontSizePt, $this->TextColor); $popt['da'] = $fontstyle; // build appearance stream $popt['ap'] = array(); $popt['ap']['n'] = array(); $fx = ((($w - $this->getAbsFontMeasure($tmpfont['cw'][110])) / 2) * $this->k); $fy = (($w - ((($tmpfont['desc']['Ascent'] - $tmpfont['desc']['Descent']) * $this->FontSizePt / 1000) / $this->k)) * $this->k); $popt['ap']['n']['Yes'] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(110).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy); $popt['ap']['n']['Off'] = sprintf('q %s BT /F%d %F Tf %F %F Td ('.chr(111).') Tj ET Q', $this->TextColor, $tmpfont['i'], $this->FontSizePt, $fx, $fy); // merge options $opt = array_merge($popt, $opt); // set remaining annotation data $opt['Subtype'] = 'Widget'; $opt['ft'] = 'Btn'; $opt['t'] = $name; if (TCPDF_STATIC::empty_string($onvalue)) { $onvalue = 'Yes'; } $opt['opt'] = array($onvalue); if ($checked) { $opt['v'] = array('/Yes'); $opt['as'] = 'Yes'; } else { $opt['v'] = array('/Off'); $opt['as'] = 'Off'; } $this->Annotation($x, $y, $w, $w, $name, $opt, 0); if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } } /** * Creates a button field * @param $name (string) field name * @param $w (int) width * @param $h (int) height * @param $caption (string) caption. * @param $action (mixed) action triggered by pressing the button. Use a string to specify a javascript action. Use an array to specify a form action options as on section 12.7.5 of PDF32000_2008. * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $opt (array) annotation parameters. Possible values are described on official PDF32000_2008 reference. * @param $x (float) Abscissa of the upper-left corner of the rectangle * @param $y (float) Ordinate of the upper-left corner of the rectangle * @param $js (boolean) if true put the field using JavaScript (requires Acrobat Writer to be rendered). * @public * @author Nicola Asuni * @since 4.8.000 (2009-09-07) */ public function Button($name, $w, $h, $caption, $action, $prop=array(), $opt=array(), $x='', $y='', $js=false) { if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); if ($js) { $this->_addfield('button', $name, $this->x, $this->y, $w, $h, $prop); $this->javascript .= 'f'.$name.".buttonSetCaption('".addslashes($caption)."');\n"; $this->javascript .= 'f'.$name.".setAction('MouseUp','".addslashes($action)."');\n"; $this->javascript .= 'f'.$name.".highlight='push';\n"; $this->javascript .= 'f'.$name.".print=false;\n"; return; } // get default style $prop = array_merge($this->getFormDefaultProp(), $prop); $prop['Pushbutton'] = 'true'; $prop['highlight'] = 'push'; $prop['display'] = 'display.noPrint'; // get annotation data $popt = TCPDF_STATIC::getAnnotOptFromJSProp($prop, $this->spot_colors, $this->rtl); $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i']; $fontstyle = sprintf('/F%d %F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor); $popt['da'] = $fontstyle; // build appearance stream $popt['ap'] = array(); $popt['ap']['n'] = '/Tx BMC q '.$fontstyle.' '; $tmpid = $this->startTemplate($w, $h, false); $bw = (2 / $this->k); // border width $border = array( 'L' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(231)), 'R' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(51)), 'T' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(231)), 'B' => array('width' => $bw, 'cap' => 'square', 'join' => 'miter', 'dash' => 0, 'color' => array(51))); $this->SetFillColor(204); $this->Cell($w, $h, $caption, $border, 0, 'C', true, '', 1, false, 'T', 'M'); $this->endTemplate(); --$this->n; $popt['ap']['n'] .= $this->xobjects[$tmpid]['outdata']; unset($this->xobjects[$tmpid]); $popt['ap']['n'] .= 'Q EMC'; // set additional default options if (!isset($popt['mk'])) { $popt['mk'] = array(); } $ann_obj_id = ($this->n + 1); if (!empty($action) AND !is_array($action)) { $ann_obj_id = ($this->n + 2); } $popt['mk']['ca'] = $this->_textstring($caption, $ann_obj_id); $popt['mk']['rc'] = $this->_textstring($caption, $ann_obj_id); $popt['mk']['ac'] = $this->_textstring($caption, $ann_obj_id); // merge options $opt = array_merge($popt, $opt); // set remaining annotation data $opt['Subtype'] = 'Widget'; $opt['ft'] = 'Btn'; $opt['t'] = $caption; $opt['v'] = $name; if (!empty($action)) { if (is_array($action)) { // form action options as on section 12.7.5 of PDF32000_2008. $opt['aa'] = '/D <<'; $bmode = array('SubmitForm', 'ResetForm', 'ImportData'); foreach ($action AS $key => $val) { if (($key == 'S') AND in_array($val, $bmode)) { $opt['aa'] .= ' /S /'.$val; } elseif (($key == 'F') AND (!empty($val))) { $opt['aa'] .= ' /F '.$this->_datastring($val, $ann_obj_id); } elseif (($key == 'Fields') AND is_array($val) AND !empty($val)) { $opt['aa'] .= ' /Fields ['; foreach ($val AS $field) { $opt['aa'] .= ' '.$this->_textstring($field, $ann_obj_id); } $opt['aa'] .= ']'; } elseif (($key == 'Flags')) { $ff = 0; if (is_array($val)) { foreach ($val AS $flag) { switch ($flag) { case 'Include/Exclude': { $ff += 1 << 0; break; } case 'IncludeNoValueFields': { $ff += 1 << 1; break; } case 'ExportFormat': { $ff += 1 << 2; break; } case 'GetMethod': { $ff += 1 << 3; break; } case 'SubmitCoordinates': { $ff += 1 << 4; break; } case 'XFDF': { $ff += 1 << 5; break; } case 'IncludeAppendSaves': { $ff += 1 << 6; break; } case 'IncludeAnnotations': { $ff += 1 << 7; break; } case 'SubmitPDF': { $ff += 1 << 8; break; } case 'CanonicalFormat': { $ff += 1 << 9; break; } case 'ExclNonUserAnnots': { $ff += 1 << 10; break; } case 'ExclFKey': { $ff += 1 << 11; break; } case 'EmbedForm': { $ff += 1 << 13; break; } } } } else { $ff = intval($val); } $opt['aa'] .= ' /Flags '.$ff; } } $opt['aa'] .= ' >>'; } else { // Javascript action or raw action command $js_obj_id = $this->addJavascriptObject($action); $opt['aa'] = '/D '.$js_obj_id.' 0 R'; } } $this->Annotation($x, $y, $w, $h, $name, $opt, 0); if ($this->rtl) { $this->x -= $w; } else { $this->x += $w; } } // --- END FORMS FIELDS ------------------------------------------------ /** * Add certification signature (DocMDP or UR3) * You can set only one signature type * @protected * @author Nicola Asuni * @since 4.6.008 (2009-05-07) */ protected function _putsignature() { if ((!$this->sign) OR (!isset($this->signature_data['cert_type']))) { return; } $sigobjid = ($this->sig_obj_id + 1); $out = $this->_getobj($sigobjid)."\n"; $out .= '<< /Type /Sig'; $out .= ' /Filter /Adobe.PPKLite'; $out .= ' /SubFilter /adbe.pkcs7.detached'; $out .= ' '.TCPDF_STATIC::$byterange_string; $out .= ' /Contents<'.str_repeat('0', $this->signature_max_length).'>'; $out .= ' /Reference ['; // array of signature reference dictionaries $out .= ' << /Type /SigRef'; if ($this->signature_data['cert_type'] > 0) { $out .= ' /TransformMethod /DocMDP'; $out .= ' /TransformParams <<'; $out .= ' /Type /TransformParams'; $out .= ' /P '.$this->signature_data['cert_type']; $out .= ' /V /1.2'; } else { $out .= ' /TransformMethod /UR3'; $out .= ' /TransformParams <<'; $out .= ' /Type /TransformParams'; $out .= ' /V /2.2'; if (!TCPDF_STATIC::empty_string($this->ur['document'])) { $out .= ' /Document['.$this->ur['document'].']'; } if (!TCPDF_STATIC::empty_string($this->ur['form'])) { $out .= ' /Form['.$this->ur['form'].']'; } if (!TCPDF_STATIC::empty_string($this->ur['signature'])) { $out .= ' /Signature['.$this->ur['signature'].']'; } if (!TCPDF_STATIC::empty_string($this->ur['annots'])) { $out .= ' /Annots['.$this->ur['annots'].']'; } if (!TCPDF_STATIC::empty_string($this->ur['ef'])) { $out .= ' /EF['.$this->ur['ef'].']'; } if (!TCPDF_STATIC::empty_string($this->ur['formex'])) { $out .= ' /FormEX['.$this->ur['formex'].']'; } } $out .= ' >>'; // close TransformParams // optional digest data (values must be calculated and replaced later) //$out .= ' /Data ********** 0 R'; //$out .= ' /DigestMethod/MD5'; //$out .= ' /DigestLocation[********** 34]'; //$out .= ' /DigestValue<********************************>'; $out .= ' >>'; $out .= ' ]'; // end of reference if (isset($this->signature_data['info']['Name']) AND !TCPDF_STATIC::empty_string($this->signature_data['info']['Name'])) { $out .= ' /Name '.$this->_textstring($this->signature_data['info']['Name'], $sigobjid); } if (isset($this->signature_data['info']['Location']) AND !TCPDF_STATIC::empty_string($this->signature_data['info']['Location'])) { $out .= ' /Location '.$this->_textstring($this->signature_data['info']['Location'], $sigobjid); } if (isset($this->signature_data['info']['Reason']) AND !TCPDF_STATIC::empty_string($this->signature_data['info']['Reason'])) { $out .= ' /Reason '.$this->_textstring($this->signature_data['info']['Reason'], $sigobjid); } if (isset($this->signature_data['info']['ContactInfo']) AND !TCPDF_STATIC::empty_string($this->signature_data['info']['ContactInfo'])) { $out .= ' /ContactInfo '.$this->_textstring($this->signature_data['info']['ContactInfo'], $sigobjid); } $out .= ' /M '.$this->_datestring($sigobjid, $this->doc_modification_timestamp); $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } /** * Set User's Rights for PDF Reader * WARNING: This is experimental and currently do not work. * Check the PDF Reference 8.7.1 Transform Methods, * Table 8.105 Entries in the UR transform parameters dictionary * @param $enable (boolean) if true enable user's rights on PDF reader * @param $document (string) Names specifying additional document-wide usage rights for the document. The only defined value is "/FullSave", which permits a user to save the document along with modified form and/or annotation data. * @param $annots (string) Names specifying additional annotation-related usage rights for the document. Valid names in PDF 1.5 and later are /Create/Delete/Modify/Copy/Import/Export, which permit the user to perform the named operation on annotations. * @param $form (string) Names specifying additional form-field-related usage rights for the document. Valid names are: /Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate * @param $signature (string) Names specifying additional signature-related usage rights for the document. The only defined value is /Modify, which permits a user to apply a digital signature to an existing signature form field or clear a signed signature form field. * @param $ef (string) Names specifying additional usage rights for named embedded files in the document. Valid names are /Create/Delete/Modify/Import, which permit the user to perform the named operation on named embedded files Names specifying additional embedded-files-related usage rights for the document. * @param $formex (string) Names specifying additional form-field-related usage rights. The only valid name is BarcodePlaintext, which permits text form field data to be encoded as a plaintext two-dimensional barcode. * @public * @author Nicola Asuni * @since 2.9.000 (2008-03-26) */ public function setUserRights( $enable=true, $document='/FullSave', $annots='/Create/Delete/Modify/Copy/Import/Export', $form='/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate', $signature='/Modify', $ef='/Create/Delete/Modify/Import', $formex='') { $this->ur['enabled'] = $enable; $this->ur['document'] = $document; $this->ur['annots'] = $annots; $this->ur['form'] = $form; $this->ur['signature'] = $signature; $this->ur['ef'] = $ef; $this->ur['formex'] = $formex; if (!$this->sign) { $this->setSignature('', '', '', '', 0, array()); } } /** * Enable document signature (requires the OpenSSL Library). * The digital signature improve document authenticity and integrity and allows o enable extra features on Acrobat Reader. * To create self-signed signature: openssl req -x509 -nodes -days 365000 -newkey rsa:1024 -keyout tcpdf.crt -out tcpdf.crt * To export crt to p12: openssl pkcs12 -export -in tcpdf.crt -out tcpdf.p12 * To convert pfx certificate to pem: openssl pkcs12 -in tcpdf.pfx -out tcpdf.crt -nodes * @param $signing_cert (mixed) signing certificate (string or filename prefixed with 'file://') * @param $private_key (mixed) private key (string or filename prefixed with 'file://') * @param $private_key_password (string) password * @param $extracerts (string) specifies the name of a file containing a bunch of extra certificates to include in the signature which can for example be used to help the recipient to verify the certificate that you used. * @param $cert_type (int) The access permissions granted for this document. Valid values shall be: 1 = No changes to the document shall be permitted; any change to the document shall invalidate the signature; 2 = Permitted changes shall be filling in forms, instantiating page templates, and signing; other changes shall invalidate the signature; 3 = Permitted changes shall be the same as for 2, as well as annotation creation, deletion, and modification; other changes shall invalidate the signature. * @param $info (array) array of option information: Name, Location, Reason, ContactInfo. * @public * @author Nicola Asuni * @since 4.6.005 (2009-04-24) */ public function setSignature($signing_cert='', $private_key='', $private_key_password='', $extracerts='', $cert_type=2, $info=array()) { // to create self-signed signature: openssl req -x509 -nodes -days 365000 -newkey rsa:1024 -keyout tcpdf.crt -out tcpdf.crt // to export crt to p12: openssl pkcs12 -export -in tcpdf.crt -out tcpdf.p12 // to convert pfx certificate to pem: openssl // OpenSSL> pkcs12 -in -out -nodes $this->sign = true; ++$this->n; $this->sig_obj_id = $this->n; // signature widget ++$this->n; // signature object ($this->sig_obj_id + 1) $this->signature_data = array(); if (strlen($signing_cert) == 0) { $signing_cert = 'file://'.dirname(__FILE__).'/config/cert/tcpdf.crt'; $private_key_password = 'tcpdfdemo'; } if (strlen($private_key) == 0) { $private_key = $signing_cert; } $this->signature_data['signcert'] = $signing_cert; $this->signature_data['privkey'] = $private_key; $this->signature_data['password'] = $private_key_password; $this->signature_data['extracerts'] = $extracerts; $this->signature_data['cert_type'] = $cert_type; $this->signature_data['info'] = $info; } /** * Set the digital signature appearance (a cliccable rectangle area to get signature properties) * @param $x (float) Abscissa of the upper-left corner. * @param $y (float) Ordinate of the upper-left corner. * @param $w (float) Width of the signature area. * @param $h (float) Height of the signature area. * @param $page (int) option page number (if < 0 the current page is used). * @param $name (string) Name of the signature. * @public * @author Nicola Asuni * @since 5.3.011 (2010-06-17) */ public function setSignatureAppearance($x=0, $y=0, $w=0, $h=0, $page=-1, $name='') { $this->signature_appearance = $this->getSignatureAppearanceArray($x, $y, $w, $h, $page, $name); } /** * Add an empty digital signature appearance (a cliccable rectangle area to get signature properties) * @param $x (float) Abscissa of the upper-left corner. * @param $y (float) Ordinate of the upper-left corner. * @param $w (float) Width of the signature area. * @param $h (float) Height of the signature area. * @param $page (int) option page number (if < 0 the current page is used). * @param $name (string) Name of the signature. * @public * @author Nicola Asuni * @since 5.9.101 (2011-07-06) */ public function addEmptySignatureAppearance($x=0, $y=0, $w=0, $h=0, $page=-1, $name='') { ++$this->n; $this->empty_signature_appearance[] = array('objid' => $this->n) + $this->getSignatureAppearanceArray($x, $y, $w, $h, $page, $name); } /** * Get the array that defines the signature appearance (page and rectangle coordinates). * @param $x (float) Abscissa of the upper-left corner. * @param $y (float) Ordinate of the upper-left corner. * @param $w (float) Width of the signature area. * @param $h (float) Height of the signature area. * @param $page (int) option page number (if < 0 the current page is used). * @param $name (string) Name of the signature. * @return (array) Array defining page and rectangle coordinates of signature appearance. * @protected * @author Nicola Asuni * @since 5.9.101 (2011-07-06) */ protected function getSignatureAppearanceArray($x=0, $y=0, $w=0, $h=0, $page=-1, $name='') { $sigapp = array(); if (($page < 1) OR ($page > $this->numpages)) { $sigapp['page'] = $this->page; } else { $sigapp['page'] = intval($page); } if (empty($name)) { $sigapp['name'] = 'Signature'; } else { $sigapp['name'] = $name; } $a = $x * $this->k; $b = $this->pagedim[($sigapp['page'])]['h'] - (($y + $h) * $this->k); $c = $w * $this->k; $d = $h * $this->k; $sigapp['rect'] = sprintf('%F %F %F %F', $a, $b, ($a + $c), ($b + $d)); return $sigapp; } /** * Create a new page group. * NOTE: call this function before calling AddPage() * @param $page (int) starting group page (leave empty for next page). * @public * @since 3.0.000 (2008-03-27) */ public function startPageGroup($page='') { if (empty($page)) { $page = $this->page + 1; } $this->newpagegroup[$page] = sizeof($this->newpagegroup) + 1; } /** * Set the starting page number. * @param $num (int) Starting page number. * @since 5.9.093 (2011-06-16) * @public */ public function setStartingPageNumber($num=1) { $this->starting_page_number = max(0, intval($num)); } /** * Returns the string alias used right align page numbers. * If the current font is unicode type, the returned string wil contain an additional open curly brace. * @return string * @since 5.9.099 (2011-06-27) * @public */ public function getAliasRightShift() { // calculate aproximatively the ratio between widths of aliases and replacements. $ref = '{'.TCPDF_STATIC::$alias_right_shift.'}{'.TCPDF_STATIC::$alias_tot_pages.'}{'.TCPDF_STATIC::$alias_num_page.'}'; $rep = str_repeat(' ', $this->GetNumChars($ref)); $wdiff = max(1, ($this->GetStringWidth($ref) / $this->GetStringWidth($rep))); $sdiff = sprintf('%F', $wdiff); $alias = TCPDF_STATIC::$alias_right_shift.$sdiff.'}'; if ($this->isUnicodeFont()) { $alias = '{'.$alias; } return $alias; } /** * Returns the string alias used for the total number of pages. * If the current font is unicode type, the returned string is surrounded by additional curly braces. * This alias will be replaced by the total number of pages in the document. * @return string * @since 4.0.018 (2008-08-08) * @public */ public function getAliasNbPages() { if ($this->isUnicodeFont()) { return '{'.TCPDF_STATIC::$alias_tot_pages.'}'; } return TCPDF_STATIC::$alias_tot_pages; } /** * Returns the string alias used for the page number. * If the current font is unicode type, the returned string is surrounded by additional curly braces. * This alias will be replaced by the page number. * @return string * @since 4.5.000 (2009-01-02) * @public */ public function getAliasNumPage() { if ($this->isUnicodeFont()) { return '{'.TCPDF_STATIC::$alias_num_page.'}'; } return TCPDF_STATIC::$alias_num_page; } /** * Return the alias for the total number of pages in the current page group. * If the current font is unicode type, the returned string is surrounded by additional curly braces. * This alias will be replaced by the total number of pages in this group. * @return alias of the current page group * @public * @since 3.0.000 (2008-03-27) */ public function getPageGroupAlias() { if ($this->isUnicodeFont()) { return '{'.TCPDF_STATIC::$alias_group_tot_pages.'}'; } return TCPDF_STATIC::$alias_group_tot_pages; } /** * Return the alias for the page number on the current page group. * If the current font is unicode type, the returned string is surrounded by additional curly braces. * This alias will be replaced by the page number (relative to the belonging group). * @return alias of the current page group * @public * @since 4.5.000 (2009-01-02) */ public function getPageNumGroupAlias() { if ($this->isUnicodeFont()) { return '{'.TCPDF_STATIC::$alias_group_num_page.'}'; } return TCPDF_STATIC::$alias_group_num_page; } /** * Return the current page in the group. * @return current page in the group * @public * @since 3.0.000 (2008-03-27) */ public function getGroupPageNo() { return $this->pagegroups[$this->currpagegroup]; } /** * Returns the current group page number formatted as a string. * @public * @since 4.3.003 (2008-11-18) * @see PaneNo(), formatPageNumber() */ public function getGroupPageNoFormatted() { return TCPDF_STATIC::formatPageNumber($this->getGroupPageNo()); } /** * Returns the current page number formatted as a string. * @public * @since 4.2.005 (2008-11-06) * @see PaneNo(), formatPageNumber() */ public function PageNoFormatted() { return TCPDF_STATIC::formatPageNumber($this->PageNo()); } /** * Put pdf layers. * @protected * @since 3.0.000 (2008-03-27) */ protected function _putocg() { if (empty($this->pdflayers)) { return; } foreach ($this->pdflayers as $key => $layer) { $this->pdflayers[$key]['objid'] = $this->_newobj(); $out = '<< /Type /OCG'; $out .= ' /Name '.$this->_textstring($layer['name'], $this->pdflayers[$key]['objid']); $out .= ' /Usage <<'; $out .= ' /Print <>'; $out .= ' /View <>'; $out .= ' >> >>'; $out .= "\n".'endobj'; $this->_out($out); } } /** * Start a new pdf layer. * @param $name (string) Layer name (only a-z letters and numbers). Leave empty for automatic name. * @param $print (boolean) Set to true to print this layer. * @param $view (boolean) Set to true to view this layer. * @public * @since 5.9.102 (2011-07-13) */ public function startLayer($name='', $print=true, $view=true) { if ($this->state != 2) { return; } $layer = sprintf('LYR%03d', (count($this->pdflayers) + 1)); if (empty($name)) { $name = $layer; } else { $name = preg_replace('/[^a-zA-Z0-9_\-]/', '', $name); } $this->pdflayers[] = array('layer' => $layer, 'name' => $name, 'print' => $print, 'view' => $view); $this->openMarkedContent = true; $this->_out('/OC /'.$layer.' BDC'); } /** * End the current PDF layer. * @public * @since 5.9.102 (2011-07-13) */ public function endLayer() { if ($this->state != 2) { return; } if ($this->openMarkedContent) { // close existing open marked-content layer $this->_out('EMC'); $this->openMarkedContent = false; } } /** * Set the visibility of the successive elements. * This can be useful, for instance, to put a background * image or color that will show on screen but won't print. * @param $v (string) visibility mode. Legal values are: all, print, screen or view. * @public * @since 3.0.000 (2008-03-27) */ public function setVisibility($v) { if ($this->state != 2) { return; } $this->endLayer(); switch($v) { case 'print': { $this->startLayer('Print', true, false); break; } case 'view': case 'screen': { $this->startLayer('View', false, true); break; } case 'all': { $this->_out(''); break; } default: { $this->Error('Incorrect visibility: '.$v); break; } } } /** * Add transparency parameters to the current extgstate * @param $parms (array) parameters * @return the number of extgstates * @protected * @since 3.0.000 (2008-03-27) */ protected function addExtGState($parms) { if ($this->pdfa_mode) { // transparencies are not allowed in PDF/A mode return; } // check if this ExtGState already exist foreach ($this->extgstates as $i => $ext) { if ($ext['parms'] == $parms) { if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['extgstates'][$i] = $ext; } // return reference to existing ExtGState return $i; } } $n = (count($this->extgstates) + 1); $this->extgstates[$n] = array('parms' => $parms); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['extgstates'][$n] = $this->extgstates[$n]; } return $n; } /** * Add an extgstate * @param $gs (array) extgstate * @protected * @since 3.0.000 (2008-03-27) */ protected function setExtGState($gs) { if ($this->pdfa_mode OR ($this->state != 2)) { // transparency is not allowed in PDF/A mode return; } $this->_out(sprintf('/GS%d gs', $gs)); } /** * Put extgstates for object transparency * @protected * @since 3.0.000 (2008-03-27) */ protected function _putextgstates() { foreach ($this->extgstates as $i => $ext) { $this->extgstates[$i]['n'] = $this->_newobj(); $out = '<< /Type /ExtGState'; foreach ($ext['parms'] as $k => $v) { if (is_float($v)) { $v = sprintf('%F', $v); } elseif ($v === true) { $v = 'true'; } elseif ($v === false) { $v = 'false'; } $out .= ' /'.$k.' '.$v; } $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } } /** * Set overprint mode for stroking (OP) and non-stroking (op) painting operations. * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008). * @param $stroking (boolean) If true apply overprint for stroking operations. * @param $nonstroking (boolean) If true apply overprint for painting operations other than stroking. * @param $mode (integer) Overprint mode: (0 = each source colour component value replaces the value previously painted for the corresponding device colorant; 1 = a tint value of 0.0 for a source colour component shall leave the corresponding component of the previously painted colour unchanged). * @public * @since 5.9.152 (2012-03-23) */ public function setOverprint($stroking=true, $nonstroking='', $mode=0) { if ($this->state != 2) { return; } $stroking = $stroking ? true : false; if (TCPDF_STATIC::empty_string($nonstroking)) { // default value if not set $nonstroking = $stroking; } else { $nonstroking = $nonstroking ? true : false; } if (($mode != 0) AND ($mode != 1)) { $mode = 0; } $this->overprint = array('OP' => $stroking, 'op' => $nonstroking, 'OPM' => $mode); $gs = $this->addExtGState($this->overprint); $this->setExtGState($gs); } /** * Get the overprint mode array (OP, op, OPM). * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008). * @return array. * @public * @since 5.9.152 (2012-03-23) */ public function getOverprint() { return $this->overprint; } /** * Set alpha for stroking (CA) and non-stroking (ca) operations. * @param $stroking (float) Alpha value for stroking operations: real value from 0 (transparent) to 1 (opaque). * @param $bm (string) blend mode, one of the following: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity * @param $nonstroking (float) Alpha value for non-stroking operations: real value from 0 (transparent) to 1 (opaque). * @param $ais (boolean) * @public * @since 3.0.000 (2008-03-27) */ public function setAlpha($stroking=1, $bm='Normal', $nonstroking='', $ais=false) { if ($this->pdfa_mode) { // transparency is not allowed in PDF/A mode return; } $stroking = floatval($stroking); if (TCPDF_STATIC::empty_string($nonstroking)) { // default value if not set $nonstroking = $stroking; } else { $nonstroking = floatval($nonstroking); } if ($bm[0] == '/') { // remove trailing slash $bm = substr($bm, 1); } if (!in_array($bm, array('Normal', 'Multiply', 'Screen', 'Overlay', 'Darken', 'Lighten', 'ColorDodge', 'ColorBurn', 'HardLight', 'SoftLight', 'Difference', 'Exclusion', 'Hue', 'Saturation', 'Color', 'Luminosity'))) { $bm = 'Normal'; } $ais = $ais ? true : false; $this->alpha = array('CA' => $stroking, 'ca' => $nonstroking, 'BM' => '/'.$bm, 'AIS' => $ais); $gs = $this->addExtGState($this->alpha); $this->setExtGState($gs); } /** * Get the alpha mode array (CA, ca, BM, AIS). * (Check the "Entries in a Graphics State Parameter Dictionary" on PDF 32000-1:2008). * @return array. * @public * @since 5.9.152 (2012-03-23) */ public function getAlpha() { return $this->alpha; } /** * Set the default JPEG compression quality (1-100) * @param $quality (int) JPEG quality, integer between 1 and 100 * @public * @since 3.0.000 (2008-03-27) */ public function setJPEGQuality($quality) { if (($quality < 1) OR ($quality > 100)) { $quality = 75; } $this->jpeg_quality = intval($quality); } /** * Set the default number of columns in a row for HTML tables. * @param $cols (int) number of columns * @public * @since 3.0.014 (2008-06-04) */ public function setDefaultTableColumns($cols=4) { $this->default_table_columns = intval($cols); } /** * Set the height of the cell (line height) respect the font height. * @param $h (int) cell proportion respect font height (typical value = 1.25). * @public * @since 3.0.014 (2008-06-04) */ public function setCellHeightRatio($h) { $this->cell_height_ratio = $h; } /** * return the height of cell repect font height. * @public * @since 4.0.012 (2008-07-24) */ public function getCellHeightRatio() { return $this->cell_height_ratio; } /** * Set the PDF version (check PDF reference for valid values). * @param $version (string) PDF document version. * @public * @since 3.1.000 (2008-06-09) */ public function setPDFVersion($version='1.7') { if ($this->pdfa_mode) { // PDF/A mode $this->PDFVersion = '1.4'; } else { $this->PDFVersion = $version; } } /** * Set the viewer preferences dictionary controlling the way the document is to be presented on the screen or in print. * (see Section 8.1 of PDF reference, "Viewer Preferences"). * * @param $preferences (array) array of options. * @author Nicola Asuni * @public * @since 3.1.000 (2008-06-09) */ public function setViewerPreferences($preferences) { $this->viewer_preferences = $preferences; } /** * Paints color transition registration bars * @param $x (float) abscissa of the top left corner of the rectangle. * @param $y (float) ordinate of the top left corner of the rectangle. * @param $w (float) width of the rectangle. * @param $h (float) height of the rectangle. * @param $transition (boolean) if true prints tcolor transitions to white. * @param $vertical (boolean) if true prints bar vertically. * @param $colors (string) colors to print, one letter per color separated by comma (for example 'A,W,R,G,B,C,M,Y,K'): A=black, W=white, R=red, G=green, B=blue, C=cyan, M=magenta, Y=yellow, K=black. * @author Nicola Asuni * @since 4.9.000 (2010-03-26) * @public */ public function colorRegistrationBar($x, $y, $w, $h, $transition=true, $vertical=false, $colors='A,R,G,B,C,M,Y,K') { $bars = explode(',', $colors); $numbars = count($bars); // number of bars to print // set bar measures if ($vertical) { $coords = array(0, 0, 0, 1); $wb = $w / $numbars; // bar width $hb = $h; // bar height $xd = $wb; // delta x $yd = 0; // delta y } else { $coords = array(1, 0, 0, 0); $wb = $w; // bar width $hb = $h / $numbars; // bar height $xd = 0; // delta x $yd = $hb; // delta y } $xb = $x; $yb = $y; foreach ($bars as $col) { switch ($col) { // set transition colors case 'A': { // BLACK $col_a = array(255); $col_b = array(0); break; } case 'W': { // WHITE $col_a = array(0); $col_b = array(255); break; } case 'R': { // R $col_a = array(255,255,255); $col_b = array(255,0,0); break; } case 'G': { // G $col_a = array(255,255,255); $col_b = array(0,255,0); break; } case 'B': { // B $col_a = array(255,255,255); $col_b = array(0,0,255); break; } case 'C': { // C $col_a = array(0,0,0,0); $col_b = array(100,0,0,0); break; } case 'M': { // M $col_a = array(0,0,0,0); $col_b = array(0,100,0,0); break; } case 'Y': { // Y $col_a = array(0,0,0,0); $col_b = array(0,0,100,0); break; } case 'K': { // K $col_a = array(0,0,0,0); $col_b = array(0,0,0,100); break; } default: { // GRAY $col_a = array(255); $col_b = array(0); break; } } if ($transition) { // color gradient $this->LinearGradient($xb, $yb, $wb, $hb, $col_a, $col_b, $coords); } else { // color rectangle $this->SetFillColorArray($col_b); $this->Rect($xb, $yb, $wb, $hb, 'F', array()); } $xb += $xd; $yb += $yd; } } /** * Paints crop marks. * @param $x (float) abscissa of the crop mark center. * @param $y (float) ordinate of the crop mark center. * @param $w (float) width of the crop mark. * @param $h (float) height of the crop mark. * @param $type (string) type of crop mark, one symbol per type separated by comma: T = TOP, F = BOTTOM, L = LEFT, R = RIGHT, TL = A = TOP-LEFT, TR = B = TOP-RIGHT, BL = C = BOTTOM-LEFT, BR = D = BOTTOM-RIGHT. * @param $color (array) crop mark color (default black). * @author Nicola Asuni * @since 4.9.000 (2010-03-26) * @public */ public function cropMark($x, $y, $w, $h, $type='T,R,B,L', $color=array(0,0,0)) { $this->SetLineStyle(array('width' => (0.5 / $this->k), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $color)); $type = strtoupper($type); $type = preg_replace('/[^A-Z\-\,]*/', '', $type); // split type in single components $type = str_replace('-', ',', $type); $type = str_replace('TL', 'T,L', $type); $type = str_replace('TR', 'T,R', $type); $type = str_replace('BL', 'F,L', $type); $type = str_replace('BR', 'F,R', $type); $type = str_replace('A', 'T,L', $type); $type = str_replace('B', 'T,R', $type); $type = str_replace('T,RO', 'BO', $type); $type = str_replace('C', 'F,L', $type); $type = str_replace('D', 'F,R', $type); $crops = explode(',', strtoupper($type)); // remove duplicates $crops = array_unique($crops); $dw = ($w / 4); // horizontal space to leave before the intersection point $dh = ($h / 4); // vertical space to leave before the intersection point foreach ($crops as $crop) { switch ($crop) { case 'T': case 'TOP': { $x1 = $x; $y1 = ($y - $h); $x2 = $x; $y2 = ($y - $dh); break; } case 'F': case 'BOTTOM': { $x1 = $x; $y1 = ($y + $dh); $x2 = $x; $y2 = ($y + $h); break; } case 'L': case 'LEFT': { $x1 = ($x - $w); $y1 = $y; $x2 = ($x - $dw); $y2 = $y; break; } case 'R': case 'RIGHT': { $x1 = ($x + $dw); $y1 = $y; $x2 = ($x + $w); $y2 = $y; break; } } $this->Line($x1, $y1, $x2, $y2); } } /** * Paints a registration mark * @param $x (float) abscissa of the registration mark center. * @param $y (float) ordinate of the registration mark center. * @param $r (float) radius of the crop mark. * @param $double (boolean) if true print two concentric crop marks. * @param $cola (array) crop mark color (default black). * @param $colb (array) second crop mark color. * @author Nicola Asuni * @since 4.9.000 (2010-03-26) * @public */ public function registrationMark($x, $y, $r, $double=false, $cola=array(0,0,0), $colb=array(255,255,255)) { $line_style = array('width' => (0.5 / $this->k), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $cola); $this->SetFillColorArray($cola); $this->PieSector($x, $y, $r, 90, 180, 'F'); $this->PieSector($x, $y, $r, 270, 360, 'F'); $this->Circle($x, $y, $r, 0, 360, 'C', $line_style, array(), 8); if ($double) { $r2 = $r * 0.5; $this->SetFillColorArray($colb); $this->PieSector($x, $y, $r2, 90, 180, 'F'); $this->PieSector($x, $y, $r2, 270, 360, 'F'); $this->SetFillColorArray($cola); $this->PieSector($x, $y, $r2, 0, 90, 'F'); $this->PieSector($x, $y, $r2, 180, 270, 'F'); $this->Circle($x, $y, $r2, 0, 360, 'C', $line_style, array(), 8); } } /** * Paints a linear colour gradient. * @param $x (float) abscissa of the top left corner of the rectangle. * @param $y (float) ordinate of the top left corner of the rectangle. * @param $w (float) width of the rectangle. * @param $h (float) height of the rectangle. * @param $col1 (array) first color (Grayscale, RGB or CMYK components). * @param $col2 (array) second color (Grayscale, RGB or CMYK components). * @param $coords (array) array of the form (x1, y1, x2, y2) which defines the gradient vector (see linear_gradient_coords.jpg). The default value is from left to right (x1=0, y1=0, x2=1, y2=0). * @author Andreas Wrmser, Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function LinearGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0,0,1,0)) { $this->Clip($x, $y, $w, $h); $this->Gradient(2, $coords, array(array('color' => $col1, 'offset' => 0, 'exponent' => 1), array('color' => $col2, 'offset' => 1, 'exponent' => 1)), array(), false); } /** * Paints a radial colour gradient. * @param $x (float) abscissa of the top left corner of the rectangle. * @param $y (float) ordinate of the top left corner of the rectangle. * @param $w (float) width of the rectangle. * @param $h (float) height of the rectangle. * @param $col1 (array) first color (Grayscale, RGB or CMYK components). * @param $col2 (array) second color (Grayscale, RGB or CMYK components). * @param $coords (array) array of the form (fx, fy, cx, cy, r) where (fx, fy) is the starting point of the gradient with color1, (cx, cy) is the center of the circle with color2, and r is the radius of the circle (see radial_gradient_coords.jpg). (fx, fy) should be inside the circle, otherwise some areas will not be defined. * @author Andreas Wrmser, Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function RadialGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0.5,0.5,0.5,0.5,1)) { $this->Clip($x, $y, $w, $h); $this->Gradient(3, $coords, array(array('color' => $col1, 'offset' => 0, 'exponent' => 1), array('color' => $col2, 'offset' => 1, 'exponent' => 1)), array(), false); } /** * Paints a coons patch mesh. * @param $x (float) abscissa of the top left corner of the rectangle. * @param $y (float) ordinate of the top left corner of the rectangle. * @param $w (float) width of the rectangle. * @param $h (float) height of the rectangle. * @param $col1 (array) first color (lower left corner) (RGB components). * @param $col2 (array) second color (lower right corner) (RGB components). * @param $col3 (array) third color (upper right corner) (RGB components). * @param $col4 (array) fourth color (upper left corner) (RGB components). * @param $coords (array) * @param $coords_min (array) minimum value used by the coordinates. If a coordinate's value is smaller than this it will be cut to coords_min. default: 0 * @param $coords_max (array) maximum value used by the coordinates. If a coordinate's value is greater than this it will be cut to coords_max. default: 1 * @param $antialias (boolean) A flag indicating whether to filter the shading function to prevent aliasing artifacts. * @author Andreas Wrmser, Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function CoonsPatchMesh($x, $y, $w, $h, $col1=array(), $col2=array(), $col3=array(), $col4=array(), $coords=array(0.00,0.0,0.33,0.00,0.67,0.00,1.00,0.00,1.00,0.33,1.00,0.67,1.00,1.00,0.67,1.00,0.33,1.00,0.00,1.00,0.00,0.67,0.00,0.33), $coords_min=0, $coords_max=1, $antialias=false) { if ($this->pdfa_mode OR ($this->state != 2)) { return; } $this->Clip($x, $y, $w, $h); $n = count($this->gradients) + 1; $this->gradients[$n] = array(); $this->gradients[$n]['type'] = 6; //coons patch mesh $this->gradients[$n]['coords'] = array(); $this->gradients[$n]['antialias'] = $antialias; $this->gradients[$n]['colors'] = array(); $this->gradients[$n]['transparency'] = false; //check the coords array if it is the simple array or the multi patch array if (!isset($coords[0]['f'])) { //simple array -> convert to multi patch array if (!isset($col1[1])) { $col1[1] = $col1[2] = $col1[0]; } if (!isset($col2[1])) { $col2[1] = $col2[2] = $col2[0]; } if (!isset($col3[1])) { $col3[1] = $col3[2] = $col3[0]; } if (!isset($col4[1])) { $col4[1] = $col4[2] = $col4[0]; } $patch_array[0]['f'] = 0; $patch_array[0]['points'] = $coords; $patch_array[0]['colors'][0]['r'] = $col1[0]; $patch_array[0]['colors'][0]['g'] = $col1[1]; $patch_array[0]['colors'][0]['b'] = $col1[2]; $patch_array[0]['colors'][1]['r'] = $col2[0]; $patch_array[0]['colors'][1]['g'] = $col2[1]; $patch_array[0]['colors'][1]['b'] = $col2[2]; $patch_array[0]['colors'][2]['r'] = $col3[0]; $patch_array[0]['colors'][2]['g'] = $col3[1]; $patch_array[0]['colors'][2]['b'] = $col3[2]; $patch_array[0]['colors'][3]['r'] = $col4[0]; $patch_array[0]['colors'][3]['g'] = $col4[1]; $patch_array[0]['colors'][3]['b'] = $col4[2]; } else { //multi patch array $patch_array = $coords; } $bpcd = 65535; //16 bits per coordinate //build the data stream $this->gradients[$n]['stream'] = ''; $count_patch = count($patch_array); for ($i=0; $i < $count_patch; ++$i) { $this->gradients[$n]['stream'] .= chr($patch_array[$i]['f']); //start with the edge flag as 8 bit $count_points = count($patch_array[$i]['points']); for ($j=0; $j < $count_points; ++$j) { //each point as 16 bit $patch_array[$i]['points'][$j] = (($patch_array[$i]['points'][$j] - $coords_min) / ($coords_max - $coords_min)) * $bpcd; if ($patch_array[$i]['points'][$j] < 0) { $patch_array[$i]['points'][$j] = 0; } if ($patch_array[$i]['points'][$j] > $bpcd) { $patch_array[$i]['points'][$j] = $bpcd; } $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] / 256)); $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] % 256)); } $count_cols = count($patch_array[$i]['colors']); for ($j=0; $j < $count_cols; ++$j) { //each color component as 8 bit $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['r']); $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['g']); $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['b']); } } //paint the gradient $this->_out('/Sh'.$n.' sh'); //restore previous Graphic State $this->_out('Q'); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['gradients'][$n] = $this->gradients[$n]; } } /** * Set a rectangular clipping area. * @param $x (float) abscissa of the top left corner of the rectangle (or top right corner for RTL mode). * @param $y (float) ordinate of the top left corner of the rectangle. * @param $w (float) width of the rectangle. * @param $h (float) height of the rectangle. * @author Andreas Wrmser, Nicola Asuni * @since 3.1.000 (2008-06-09) * @protected */ protected function Clip($x, $y, $w, $h) { if ($this->state != 2) { return; } if ($this->rtl) { $x = $this->w - $x - $w; } //save current Graphic State $s = 'q'; //set clipping area $s .= sprintf(' %F %F %F %F re W n', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k); //set up transformation matrix for gradient $s .= sprintf(' %F 0 0 %F %F %F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k); $this->_out($s); } /** * Output gradient. * @param $type (int) type of gradient (1 Function-based shading; 2 Axial shading; 3 Radial shading; 4 Free-form Gouraud-shaded triangle mesh; 5 Lattice-form Gouraud-shaded triangle mesh; 6 Coons patch mesh; 7 Tensor-product patch mesh). (Not all types are currently supported) * @param $coords (array) array of coordinates. * @param $stops (array) array gradient color components: color = array of GRAY, RGB or CMYK color components; offset = (0 to 1) represents a location along the gradient vector; exponent = exponent of the exponential interpolation function (default = 1). * @param $background (array) An array of colour components appropriate to the colour space, specifying a single background colour value. * @param $antialias (boolean) A flag indicating whether to filter the shading function to prevent aliasing artifacts. * @author Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function Gradient($type, $coords, $stops, $background=array(), $antialias=false) { if ($this->pdfa_mode OR ($this->state != 2)) { return; } $n = count($this->gradients) + 1; $this->gradients[$n] = array(); $this->gradients[$n]['type'] = $type; $this->gradients[$n]['coords'] = $coords; $this->gradients[$n]['antialias'] = $antialias; $this->gradients[$n]['colors'] = array(); $this->gradients[$n]['transparency'] = false; // color space $numcolspace = count($stops[0]['color']); $bcolor = array_values($background); switch($numcolspace) { case 4: { // CMYK $this->gradients[$n]['colspace'] = 'DeviceCMYK'; if (!empty($background)) { $this->gradients[$n]['background'] = sprintf('%F %F %F %F', $bcolor[0]/100, $bcolor[1]/100, $bcolor[2]/100, $bcolor[3]/100); } break; } case 3: { // RGB $this->gradients[$n]['colspace'] = 'DeviceRGB'; if (!empty($background)) { $this->gradients[$n]['background'] = sprintf('%F %F %F', $bcolor[0]/255, $bcolor[1]/255, $bcolor[2]/255); } break; } case 1: { // Gray scale $this->gradients[$n]['colspace'] = 'DeviceGray'; if (!empty($background)) { $this->gradients[$n]['background'] = sprintf('%F', $bcolor[0]/255); } break; } } $num_stops = count($stops); $last_stop_id = $num_stops - 1; foreach ($stops as $key => $stop) { $this->gradients[$n]['colors'][$key] = array(); // offset represents a location along the gradient vector if (isset($stop['offset'])) { $this->gradients[$n]['colors'][$key]['offset'] = $stop['offset']; } else { if ($key == 0) { $this->gradients[$n]['colors'][$key]['offset'] = 0; } elseif ($key == $last_stop_id) { $this->gradients[$n]['colors'][$key]['offset'] = 1; } else { $offsetstep = (1 - $this->gradients[$n]['colors'][($key - 1)]['offset']) / ($num_stops - $key); $this->gradients[$n]['colors'][$key]['offset'] = $this->gradients[$n]['colors'][($key - 1)]['offset'] + $offsetstep; } } if (isset($stop['opacity'])) { $this->gradients[$n]['colors'][$key]['opacity'] = $stop['opacity']; if ((!$this->pdfa_mode) AND ($stop['opacity'] < 1)) { $this->gradients[$n]['transparency'] = true; } } else { $this->gradients[$n]['colors'][$key]['opacity'] = 1; } // exponent for the exponential interpolation function if (isset($stop['exponent'])) { $this->gradients[$n]['colors'][$key]['exponent'] = $stop['exponent']; } else { $this->gradients[$n]['colors'][$key]['exponent'] = 1; } // set colors $color = array_values($stop['color']); switch($numcolspace) { case 4: { // CMYK $this->gradients[$n]['colors'][$key]['color'] = sprintf('%F %F %F %F', $color[0]/100, $color[1]/100, $color[2]/100, $color[3]/100); break; } case 3: { // RGB $this->gradients[$n]['colors'][$key]['color'] = sprintf('%F %F %F', $color[0]/255, $color[1]/255, $color[2]/255); break; } case 1: { // Gray scale $this->gradients[$n]['colors'][$key]['color'] = sprintf('%F', $color[0]/255); break; } } } if ($this->gradients[$n]['transparency']) { // paint luminosity gradient $this->_out('/TGS'.$n.' gs'); } //paint the gradient $this->_out('/Sh'.$n.' sh'); //restore previous Graphic State $this->_out('Q'); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['gradients'][$n] = $this->gradients[$n]; } } /** * Output gradient shaders. * @author Nicola Asuni * @since 3.1.000 (2008-06-09) * @protected */ function _putshaders() { if ($this->pdfa_mode) { return; } $idt = count($this->gradients); //index for transparency gradients foreach ($this->gradients as $id => $grad) { if (($grad['type'] == 2) OR ($grad['type'] == 3)) { $fc = $this->_newobj(); $out = '<<'; $out .= ' /FunctionType 3'; $out .= ' /Domain [0 1]'; $functions = ''; $bounds = ''; $encode = ''; $i = 1; $num_cols = count($grad['colors']); $lastcols = $num_cols - 1; for ($i = 1; $i < $num_cols; ++$i) { $functions .= ($fc + $i).' 0 R '; if ($i < $lastcols) { $bounds .= sprintf('%F ', $grad['colors'][$i]['offset']); } $encode .= '0 1 '; } $out .= ' /Functions ['.trim($functions).']'; $out .= ' /Bounds ['.trim($bounds).']'; $out .= ' /Encode ['.trim($encode).']'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); for ($i = 1; $i < $num_cols; ++$i) { $this->_newobj(); $out = '<<'; $out .= ' /FunctionType 2'; $out .= ' /Domain [0 1]'; $out .= ' /C0 ['.$grad['colors'][($i - 1)]['color'].']'; $out .= ' /C1 ['.$grad['colors'][$i]['color'].']'; $out .= ' /N '.$grad['colors'][$i]['exponent']; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } // set transparency fuctions if ($grad['transparency']) { $ft = $this->_newobj(); $out = '<<'; $out .= ' /FunctionType 3'; $out .= ' /Domain [0 1]'; $functions = ''; $i = 1; $num_cols = count($grad['colors']); for ($i = 1; $i < $num_cols; ++$i) { $functions .= ($ft + $i).' 0 R '; } $out .= ' /Functions ['.trim($functions).']'; $out .= ' /Bounds ['.trim($bounds).']'; $out .= ' /Encode ['.trim($encode).']'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); for ($i = 1; $i < $num_cols; ++$i) { $this->_newobj(); $out = '<<'; $out .= ' /FunctionType 2'; $out .= ' /Domain [0 1]'; $out .= ' /C0 ['.$grad['colors'][($i - 1)]['opacity'].']'; $out .= ' /C1 ['.$grad['colors'][$i]['opacity'].']'; $out .= ' /N '.$grad['colors'][$i]['exponent']; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); } } } // set shading object $this->_newobj(); $out = '<< /ShadingType '.$grad['type']; if (isset($grad['colspace'])) { $out .= ' /ColorSpace /'.$grad['colspace']; } else { $out .= ' /ColorSpace /DeviceRGB'; } if (isset($grad['background']) AND !empty($grad['background'])) { $out .= ' /Background ['.$grad['background'].']'; } if (isset($grad['antialias']) AND ($grad['antialias'] === true)) { $out .= ' /AntiAlias true'; } if ($grad['type'] == 2) { $out .= ' '.sprintf('/Coords [%F %F %F %F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]); $out .= ' /Domain [0 1]'; $out .= ' /Function '.$fc.' 0 R'; $out .= ' /Extend [true true]'; $out .= ' >>'; } elseif ($grad['type'] == 3) { //x0, y0, r0, x1, y1, r1 //at this this time radius of inner circle is 0 $out .= ' '.sprintf('/Coords [%F %F 0 %F %F %F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]); $out .= ' /Domain [0 1]'; $out .= ' /Function '.$fc.' 0 R'; $out .= ' /Extend [true true]'; $out .= ' >>'; } elseif ($grad['type'] == 6) { $out .= ' /BitsPerCoordinate 16'; $out .= ' /BitsPerComponent 8'; $out .= ' /Decode[0 1 0 1 0 1 0 1 0 1]'; $out .= ' /BitsPerFlag 8'; $stream = $this->_getrawstream($grad['stream']); $out .= ' /Length '.strlen($stream); $out .= ' >>'; $out .= ' stream'."\n".$stream."\n".'endstream'; } $out .= "\n".'endobj'; $this->_out($out); if ($grad['transparency']) { $shading_transparency = preg_replace('/\/ColorSpace \/[^\s]+/si', '/ColorSpace /DeviceGray', $out); $shading_transparency = preg_replace('/\/Function [0-9]+ /si', '/Function '.$ft.' ', $shading_transparency); } $this->gradients[$id]['id'] = $this->n; // set pattern object $this->_newobj(); $out = '<< /Type /Pattern /PatternType 2'; $out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); $this->gradients[$id]['pattern'] = $this->n; // set shading and pattern for transparency mask if ($grad['transparency']) { // luminosity pattern $idgs = $id + $idt; $this->_newobj(); $this->_out($shading_transparency); $this->gradients[$idgs]['id'] = $this->n; $this->_newobj(); $out = '<< /Type /Pattern /PatternType 2'; $out .= ' /Shading '.$this->gradients[$idgs]['id'].' 0 R'; $out .= ' >>'; $out .= "\n".'endobj'; $this->_out($out); $this->gradients[$idgs]['pattern'] = $this->n; // luminosity XObject $oid = $this->_newobj(); $this->xobjects['LX'.$oid] = array('n' => $oid); $filter = ''; $stream = 'q /a0 gs /Pattern cs /p'.$idgs.' scn 0 0 '.$this->wPt.' '.$this->hPt.' re f Q'; if ($this->compress) { $filter = ' /Filter /FlateDecode'; $stream = gzcompress($stream); } $stream = $this->_getrawstream($stream); $out = '<< /Type /XObject /Subtype /Form /FormType 1'.$filter; $out .= ' /Length '.strlen($stream); $rect = sprintf('%F %F', $this->wPt, $this->hPt); $out .= ' /BBox [0 0 '.$rect.']'; $out .= ' /Group << /Type /Group /S /Transparency /CS /DeviceGray >>'; $out .= ' /Resources <<'; $out .= ' /ExtGState << /a0 << /ca 1 /CA 1 >> >>'; $out .= ' /Pattern << /p'.$idgs.' '.$this->gradients[$idgs]['pattern'].' 0 R >>'; $out .= ' >>'; $out .= ' >> '; $out .= ' stream'."\n".$stream."\n".'endstream'; $out .= "\n".'endobj'; $this->_out($out); // SMask $this->_newobj(); $out = '<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj'; $this->_out($out); // ExtGState $this->_newobj(); $out = '<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj'; $this->_out($out); $this->extgstates[] = array('n' => $this->n, 'name' => 'TGS'.$id); } } } /** * Draw the sector of a circle. * It can be used for instance to render pie charts. * @param $xc (float) abscissa of the center. * @param $yc (float) ordinate of the center. * @param $r (float) radius. * @param $a (float) start angle (in degrees). * @param $b (float) end angle (in degrees). * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $cw: (float) indicates whether to go clockwise (default: true). * @param $o: (float) origin of angles (0 for 3 o'clock, 90 for noon, 180 for 9 o'clock, 270 for 6 o'clock). Default: 90. * @author Maxime Delorme, Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function PieSector($xc, $yc, $r, $a, $b, $style='FD', $cw=true, $o=90) { $this->PieSectorXY($xc, $yc, $r, $r, $a, $b, $style, $cw, $o); } /** * Draw the sector of an ellipse. * It can be used for instance to render pie charts. * @param $xc (float) abscissa of the center. * @param $yc (float) ordinate of the center. * @param $rx (float) the x-axis radius. * @param $ry (float) the y-axis radius. * @param $a (float) start angle (in degrees). * @param $b (float) end angle (in degrees). * @param $style (string) Style of rendering. See the getPathPaintOperator() function for more information. * @param $cw: (float) indicates whether to go clockwise. * @param $o: (float) origin of angles (0 for 3 o'clock, 90 for noon, 180 for 9 o'clock, 270 for 6 o'clock). * @param $nc (integer) Number of curves used to draw a 90 degrees portion of arc. * @author Maxime Delorme, Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function PieSectorXY($xc, $yc, $rx, $ry, $a, $b, $style='FD', $cw=false, $o=0, $nc=2) { if ($this->state != 2) { return; } if ($this->rtl) { $xc = ($this->w - $xc); } $op = TCPDF_STATIC::getPathPaintOperator($style); if ($op == 'f') { $line_style = array(); } if ($cw) { $d = $b; $b = (360 - $a + $o); $a = (360 - $d + $o); } else { $b += $o; $a += $o; } $this->_outellipticalarc($xc, $yc, $rx, $ry, 0, $a, $b, true, $nc); $this->_out($op); } /** * Embed vector-based Adobe Illustrator (AI) or AI-compatible EPS files. * NOTE: EPS is not yet fully implemented, use the setRasterizeVectorImages() method to enable/disable rasterization of vector images using ImageMagick library. * Only vector drawing is supported, not text or bitmap. * Although the script was successfully tested with various AI format versions, best results are probably achieved with files that were exported in the AI3 format (tested with Illustrator CS2, Freehand MX and Photoshop CS2). * @param $file (string) Name of the file containing the image or a '@' character followed by the EPS/AI data string. * @param $x (float) Abscissa of the upper-left corner. * @param $y (float) Ordinate of the upper-left corner. * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $link (mixed) URL or identifier returned by AddLink(). * @param $useBoundingBox (boolean) specifies whether to position the bounding box (true) or the complete canvas (false) at location (x,y). Default value is true. * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be: * @param $palign (string) Allows to center or align the image on the current line. Possible values are: * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number: or a string containing some or all of the following characters (in any order): or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $fitonpage (boolean) if true the image is resized to not exceed page dimensions. * @param $fixoutvals (boolean) if true remove values outside the bounding box. * @author Valentin Schmidt, Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function ImageEps($file, $x='', $y='', $w=0, $h=0, $link='', $useBoundingBox=true, $align='', $palign='', $border=0, $fitonpage=false, $fixoutvals=false) { if ($this->state != 2) { return; } if ($this->rasterize_vector_images AND ($w > 0) AND ($h > 0)) { // convert EPS to raster image using GD or ImageMagick libraries return $this->Image($file, $x, $y, $w, $h, 'EPS', $link, $align, true, 300, $palign, false, false, $border, false, false, $fitonpage); } if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); $k = $this->k; if ($file{0} === '@') { // image from string $data = substr($file, 1); } else { // EPS/AI file $data = file_get_contents($file); } if ($data === false) { $this->Error('EPS file not found: '.$file); } $regs = array(); // EPS/AI compatibility check (only checks files created by Adobe Illustrator!) preg_match("/%%Creator:([^\r\n]+)/", $data, $regs); # find Creator if (count($regs) > 1) { $version_str = trim($regs[1]); # e.g. "Adobe Illustrator(R) 8.0" if (strpos($version_str, 'Adobe Illustrator') !== false) { $versexp = explode(' ', $version_str); $version = (float)array_pop($versexp); if ($version >= 9) { $this->Error('This version of Adobe Illustrator file is not supported: '.$file); } } } // strip binary bytes in front of PS-header $start = strpos($data, '%!PS-Adobe'); if ($start > 0) { $data = substr($data, $start); } // find BoundingBox params preg_match("/%%BoundingBox:([^\r\n]+)/", $data, $regs); if (count($regs) > 1) { list($x1, $y1, $x2, $y2) = explode(' ', trim($regs[1])); } else { $this->Error('No BoundingBox found in EPS/AI file: '.$file); } $start = strpos($data, '%%EndSetup'); if ($start === false) { $start = strpos($data, '%%EndProlog'); } if ($start === false) { $start = strpos($data, '%%BoundingBox'); } $data = substr($data, $start); $end = strpos($data, '%%PageTrailer'); if ($end===false) { $end = strpos($data, 'showpage'); } if ($end) { $data = substr($data, 0, $end); } // calculate image width and height on document if (($w <= 0) AND ($h <= 0)) { $w = ($x2 - $x1) / $k; $h = ($y2 - $y1) / $k; } elseif ($w <= 0) { $w = ($x2-$x1) / $k * ($h / (($y2 - $y1) / $k)); } elseif ($h <= 0) { $h = ($y2 - $y1) / $k * ($w / (($x2 - $x1) / $k)); } // fit the image on available space list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage); if ($this->rasterize_vector_images) { // convert EPS to raster image using GD or ImageMagick libraries return $this->Image($file, $x, $y, $w, $h, 'EPS', $link, $align, true, 300, $palign, false, false, $border, false, false, $fitonpage); } // set scaling factors $scale_x = $w / (($x2 - $x1) / $k); $scale_y = $h / (($y2 - $y1) / $k); // set alignment $this->img_rb_y = $y + $h; // set alignment if ($this->rtl) { if ($palign == 'L') { $ximg = $this->lMargin; } elseif ($palign == 'C') { $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $ximg = $this->w - $this->rMargin - $w; } else { $ximg = $x - $w; } $this->img_rb_x = $ximg; } else { if ($palign == 'L') { $ximg = $this->lMargin; } elseif ($palign == 'C') { $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $ximg = $this->w - $this->rMargin - $w; } else { $ximg = $x; } $this->img_rb_x = $ximg + $w; } if ($useBoundingBox) { $dx = $ximg * $k - $x1; $dy = $y * $k - $y1; } else { $dx = $ximg * $k; $dy = $y * $k; } // save the current graphic state $this->_out('q'.$this->epsmarker); // translate $this->_out(sprintf('%F %F %F %F %F %F cm', 1, 0, 0, 1, $dx, $dy + ($this->hPt - (2 * $y * $k) - ($y2 - $y1)))); // scale if (isset($scale_x)) { $this->_out(sprintf('%F %F %F %F %F %F cm', $scale_x, 0, 0, $scale_y, $x1 * (1 - $scale_x), $y2 * (1 - $scale_y))); } // handle pc/unix/mac line endings $lines = preg_split('/[\r\n]+/si', $data, -1, PREG_SPLIT_NO_EMPTY); $u=0; $cnt = count($lines); for ($i=0; $i < $cnt; ++$i) { $line = $lines[$i]; if (($line == '') OR ($line{0} == '%')) { continue; } $len = strlen($line); // check for spot color names $color_name = ''; if (strcasecmp('x', substr(trim($line), -1)) == 0) { if (preg_match('/\([^\)]*\)/', $line, $matches) > 0) { // extract spot color name $color_name = $matches[0]; // remove color name from string $line = str_replace(' '.$color_name, '', $line); // remove pharentesis from color name $color_name = substr($color_name, 1, -1); } } $chunks = explode(' ', $line); $cmd = trim(array_pop($chunks)); // RGB if (($cmd == 'Xa') OR ($cmd == 'XA')) { $b = array_pop($chunks); $g = array_pop($chunks); $r = array_pop($chunks); $this->_out(''.$r.' '.$g.' '.$b.' '.($cmd=='Xa'?'rg':'RG')); //substr($line, 0, -2).'rg' -> in EPS (AI8): c m y k r g b rg! continue; } $skip = false; if ($fixoutvals) { // check for values outside the bounding box switch ($cmd) { case 'm': case 'l': case 'L': { // skip values outside bounding box foreach ($chunks as $key => $val) { if ((($key % 2) == 0) AND (($val < $x1) OR ($val > $x2))) { $skip = true; } elseif ((($key % 2) != 0) AND (($val < $y1) OR ($val > $y2))) { $skip = true; } } } } } switch ($cmd) { case 'm': case 'l': case 'v': case 'y': case 'c': case 'k': case 'K': case 'g': case 'G': case 's': case 'S': case 'J': case 'j': case 'w': case 'M': case 'd': case 'n': { if ($skip) { break; } $this->_out($line); break; } case 'x': {// custom fill color if (empty($color_name)) { // CMYK color list($col_c, $col_m, $col_y, $col_k) = $chunks; $this->_out(''.$col_c.' '.$col_m.' '.$col_y.' '.$col_k.' k'); } else { // Spot Color (CMYK + tint) list($col_c, $col_m, $col_y, $col_k, $col_t) = $chunks; $this->AddSpotColor($color_name, ($col_c * 100), ($col_m * 100), ($col_y * 100), ($col_k * 100)); $color_cmd = sprintf('/CS%d cs %F scn', $this->spot_colors[$color_name]['i'], (1 - $col_t)); $this->_out($color_cmd); } break; } case 'X': { // custom stroke color if (empty($color_name)) { // CMYK color list($col_c, $col_m, $col_y, $col_k) = $chunks; $this->_out(''.$col_c.' '.$col_m.' '.$col_y.' '.$col_k.' K'); } else { // Spot Color (CMYK + tint) list($col_c, $col_m, $col_y, $col_k, $col_t) = $chunks; $this->AddSpotColor($color_name, ($col_c * 100), ($col_m * 100), ($col_y * 100), ($col_k * 100)); $color_cmd = sprintf('/CS%d CS %F SCN', $this->spot_colors[$color_name]['i'], (1 - $col_t)); $this->_out($color_cmd); } break; } case 'Y': case 'N': case 'V': case 'L': case 'C': { if ($skip) { break; } $line[($len - 1)] = strtolower($cmd); $this->_out($line); break; } case 'b': case 'B': { $this->_out($cmd . '*'); break; } case 'f': case 'F': { if ($u > 0) { $isU = false; $max = min(($i + 5), $cnt); for ($j = ($i + 1); $j < $max; ++$j) { $isU = ($isU OR (($lines[$j] == 'U') OR ($lines[$j] == '*U'))); } if ($isU) { $this->_out('f*'); } } else { $this->_out('f*'); } break; } case '*u': { ++$u; break; } case '*U': { --$u; break; } } } // restore previous graphic state $this->_out($this->epsmarker.'Q'); if (!empty($border)) { $bx = $this->x; $by = $this->y; $this->x = $ximg; if ($this->rtl) { $this->x += $w; } $this->y = $y; $this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true); $this->x = $bx; $this->y = $by; } if ($link) { $this->Link($ximg, $y, $w, $h, $link, 0); } // set pointer to align the next text/objects switch($align) { case 'T':{ $this->y = $y; $this->x = $this->img_rb_x; break; } case 'M':{ $this->y = $y + round($h/2); $this->x = $this->img_rb_x; break; } case 'B':{ $this->y = $this->img_rb_y; $this->x = $this->img_rb_x; break; } case 'N':{ $this->SetY($this->img_rb_y); break; } default:{ break; } } $this->endlinex = $this->img_rb_x; } /** * Set document barcode. * @param $bc (string) barcode * @public */ public function setBarcode($bc='') { $this->barcode = $bc; } /** * Get current barcode. * @return string * @public * @since 4.0.012 (2008-07-24) */ public function getBarcode() { return $this->barcode; } /** * Print a Linear Barcode. * @param $code (string) code to print * @param $type (string) type of barcode (see tcpdf_barcodes_1d.php for supported formats). * @param $x (int) x position in user units (empty string = current x position) * @param $y (int) y position in user units (empty string = current y position) * @param $w (int) width in user units (empty string = remaining page width) * @param $h (int) height in user units (empty string = remaining page height) * @param $xres (float) width of the smallest bar in user units (empty string = default value = 0.4mm) * @param $style (array) array of options: * @param $align (string) Indicates the alignment of the pointer next to barcode insertion relative to barcode height. The value can be: * @author Nicola Asuni * @since 3.1.000 (2008-06-09) * @public */ public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres='', $style='', $align='') { if (TCPDF_STATIC::empty_string(trim($code))) { return; } require_once(dirname(__FILE__).'/tcpdf_barcodes_1d.php'); // save current graphic settings $gvars = $this->getGraphicVars(); // create new barcode object $barcodeobj = new TCPDFBarcode($code, $type); $arrcode = $barcodeobj->getBarcodeArray(); if (($arrcode === false) OR empty($arrcode) OR ($arrcode['maxw'] == 0)) { $this->Error('Error in 1D barcode string'); } // set default values if (!isset($style['position'])) { $style['position'] = ''; } elseif ($style['position'] == 'S') { // keep this for backward compatibility $style['position'] = ''; $style['stretch'] = true; } if (!isset($style['fitwidth'])) { if (!isset($style['stretch'])) { $style['fitwidth'] = true; } else { $style['fitwidth'] = false; } } if ($style['fitwidth']) { // disable stretch $style['stretch'] = false; } if (!isset($style['stretch'])) { if (($w === '') OR ($w <= 0)) { $style['stretch'] = false; } else { $style['stretch'] = true; } } if (!isset($style['fgcolor'])) { $style['fgcolor'] = array(0,0,0); // default black } if (!isset($style['bgcolor'])) { $style['bgcolor'] = false; // default transparent } if (!isset($style['border'])) { $style['border'] = false; } $fontsize = 0; if (!isset($style['text'])) { $style['text'] = false; } if ($style['text'] AND isset($style['font'])) { if (isset($style['fontsize'])) { $fontsize = $style['fontsize']; } $this->SetFont($style['font'], '', $fontsize); } if (!isset($style['stretchtext'])) { $style['stretchtext'] = 4; } if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); if (($w === '') OR ($w <= 0)) { if ($this->rtl) { $w = $x - $this->lMargin; } else { $w = $this->w - $this->rMargin - $x; } } // padding if (!isset($style['padding'])) { $padding = 0; } elseif ($style['padding'] === 'auto') { $padding = 10 * ($w / ($arrcode['maxw'] + 20)); } else { $padding = floatval($style['padding']); } // horizontal padding if (!isset($style['hpadding'])) { $hpadding = $padding; } elseif ($style['hpadding'] === 'auto') { $hpadding = 10 * ($w / ($arrcode['maxw'] + 20)); } else { $hpadding = floatval($style['hpadding']); } // vertical padding if (!isset($style['vpadding'])) { $vpadding = $padding; } elseif ($style['vpadding'] === 'auto') { $vpadding = ($hpadding / 2); } else { $vpadding = floatval($style['vpadding']); } // calculate xres (single bar width) $max_xres = ($w - (2 * $hpadding)) / $arrcode['maxw']; if ($style['stretch']) { $xres = $max_xres; } else { if (TCPDF_STATIC::empty_string($xres)) { $xres = (0.141 * $this->k); // default bar width = 0.4 mm } if ($xres > $max_xres) { // correct xres to fit on $w $xres = $max_xres; } if ((isset($style['padding']) AND ($style['padding'] === 'auto')) OR (isset($style['hpadding']) AND ($style['hpadding'] === 'auto'))) { $hpadding = 10 * $xres; if (isset($style['vpadding']) AND ($style['vpadding'] === 'auto')) { $vpadding = ($hpadding / 2); } } } if ($style['fitwidth']) { $wold = $w; $w = (($arrcode['maxw'] * $xres) + (2 * $hpadding)); if (isset($style['cellfitalign'])) { switch ($style['cellfitalign']) { case 'L': { if ($this->rtl) { $x -= ($wold - $w); } break; } case 'R': { if (!$this->rtl) { $x += ($wold - $w); } break; } case 'C': { if ($this->rtl) { $x -= (($wold - $w) / 2); } else { $x += (($wold - $w) / 2); } break; } default : { break; } } } } $text_height = ($this->cell_height_ratio * $fontsize / $this->k); // height if (($h === '') OR ($h <= 0)) { // set default height $h = (($arrcode['maxw'] * $xres) / 3) + (2 * $vpadding) + $text_height; } $barh = $h - $text_height - (2 * $vpadding); if ($barh <=0) { // try to reduce font or padding to fit barcode on available height if ($text_height > $h) { $fontsize = (($h * $this->k) / (4 * $this->cell_height_ratio)); $text_height = ($this->cell_height_ratio * $fontsize / $this->k); $this->SetFont($style['font'], '', $fontsize); } if ($vpadding > 0) { $vpadding = (($h - $text_height) / 4); } $barh = $h - $text_height - (2 * $vpadding); } // fit the barcode on available space list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, false); // set alignment $this->img_rb_y = $y + $h; // set alignment if ($this->rtl) { if ($style['position'] == 'L') { $xpos = $this->lMargin; } elseif ($style['position'] == 'C') { $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($style['position'] == 'R') { $xpos = $this->w - $this->rMargin - $w; } else { $xpos = $x - $w; } $this->img_rb_x = $xpos; } else { if ($style['position'] == 'L') { $xpos = $this->lMargin; } elseif ($style['position'] == 'C') { $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($style['position'] == 'R') { $xpos = $this->w - $this->rMargin - $w; } else { $xpos = $x; } $this->img_rb_x = $xpos + $w; } $xpos_rect = $xpos; if (!isset($style['align'])) { $style['align'] = 'C'; } switch ($style['align']) { case 'L': { $xpos = $xpos_rect + $hpadding; break; } case 'R': { $xpos = $xpos_rect + ($w - ($arrcode['maxw'] * $xres)) - $hpadding; break; } case 'C': default : { $xpos = $xpos_rect + (($w - ($arrcode['maxw'] * $xres)) / 2); break; } } $xpos_text = $xpos; // barcode is always printed in LTR direction $tempRTL = $this->rtl; $this->rtl = false; // print background color if ($style['bgcolor']) { $this->Rect($xpos_rect, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']); } elseif ($style['border']) { $this->Rect($xpos_rect, $y, $w, $h, 'D'); } // set foreground color $this->SetDrawColorArray($style['fgcolor']); $this->SetTextColorArray($style['fgcolor']); // print bars foreach ($arrcode['bcode'] as $k => $v) { $bw = ($v['w'] * $xres); if ($v['t']) { // draw a vertical bar $ypos = $y + $vpadding + ($v['p'] * $barh / $arrcode['maxh']); $this->Rect($xpos, $ypos, $bw, ($v['h'] * $barh / $arrcode['maxh']), 'F', array(), $style['fgcolor']); } $xpos += $bw; } // print text if ($style['text']) { if (isset($style['label']) AND !TCPDF_STATIC::empty_string($style['label'])) { $label = $style['label']; } else { $label = $code; } $txtwidth = ($arrcode['maxw'] * $xres); if ($this->GetStringWidth($label) > $txtwidth) { $style['stretchtext'] = 2; } // print text $this->x = $xpos_text; $this->y = $y + $vpadding + $barh; $cellpadding = $this->cell_padding; $this->SetCellPadding(0); $this->Cell($txtwidth, '', $label, 0, 0, 'C', false, '', $style['stretchtext'], false, 'T', 'T'); $this->cell_padding = $cellpadding; } // restore original direction $this->rtl = $tempRTL; // restore previous settings $this->setGraphicVars($gvars); // set pointer to align the next text/objects switch($align) { case 'T':{ $this->y = $y; $this->x = $this->img_rb_x; break; } case 'M':{ $this->y = $y + round($h / 2); $this->x = $this->img_rb_x; break; } case 'B':{ $this->y = $this->img_rb_y; $this->x = $this->img_rb_x; break; } case 'N':{ $this->SetY($this->img_rb_y); break; } default:{ break; } } $this->endlinex = $this->img_rb_x; } /** * Print 2D Barcode. * @param $code (string) code to print * @param $type (string) type of barcode (see tcpdf_barcodes_2d.php for supported formats). * @param $x (int) x position in user units * @param $y (int) y position in user units * @param $w (int) width in user units * @param $h (int) height in user units * @param $style (array) array of options: * @param $align (string) Indicates the alignment of the pointer next to barcode insertion relative to barcode height. The value can be: * @param $distort (boolean) if true distort the barcode to fit width and height, otherwise preserve aspect ratio * @author Nicola Asuni * @since 4.5.037 (2009-04-07) * @public */ public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style='', $align='', $distort=false) { if (TCPDF_STATIC::empty_string(trim($code))) { return; } require_once(dirname(__FILE__).'/tcpdf_barcodes_2d.php'); // save current graphic settings $gvars = $this->getGraphicVars(); // create new barcode object $barcodeobj = new TCPDF2DBarcode($code, $type); $arrcode = $barcodeobj->getBarcodeArray(); if (($arrcode === false) OR empty($arrcode) OR !isset($arrcode['num_rows']) OR ($arrcode['num_rows'] == 0) OR !isset($arrcode['num_cols']) OR ($arrcode['num_cols'] == 0)) { $this->Error('Error in 2D barcode string'); } // set default values if (!isset($style['position'])) { $style['position'] = ''; } if (!isset($style['fgcolor'])) { $style['fgcolor'] = array(0,0,0); // default black } if (!isset($style['bgcolor'])) { $style['bgcolor'] = false; // default transparent } if (!isset($style['border'])) { $style['border'] = false; } // padding if (!isset($style['padding'])) { $style['padding'] = 0; } elseif ($style['padding'] === 'auto') { $style['padding'] = 4; } if (!isset($style['hpadding'])) { $style['hpadding'] = $style['padding']; } elseif ($style['hpadding'] === 'auto') { $style['hpadding'] = 4; } if (!isset($style['vpadding'])) { $style['vpadding'] = $style['padding']; } elseif ($style['vpadding'] === 'auto') { $style['vpadding'] = 4; } $hpad = (2 * $style['hpadding']); $vpad = (2 * $style['vpadding']); // cell (module) dimension if (!isset($style['module_width'])) { $style['module_width'] = 1; // width of a single module in points } if (!isset($style['module_height'])) { $style['module_height'] = 1; // height of a single module in points } if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); // number of barcode columns and rows $rows = $arrcode['num_rows']; $cols = $arrcode['num_cols']; // module width and height $mw = $style['module_width']; $mh = $style['module_height']; if (($mw == 0) OR ($mh == 0)) { $this->Error('Error in 2D barcode string'); } // get max dimensions if ($this->rtl) { $maxw = $x - $this->lMargin; } else { $maxw = $this->w - $this->rMargin - $x; } $maxh = ($this->h - $this->tMargin - $this->bMargin); $ratioHW = ((($rows * $mh) + $hpad) / (($cols * $mw) + $vpad)); $ratioWH = ((($cols * $mw) + $vpad) / (($rows * $mh) + $hpad)); if (!$distort) { if (($maxw * $ratioHW) > $maxh) { $maxw = $maxh * $ratioWH; } if (($maxh * $ratioWH) > $maxw) { $maxh = $maxw * $ratioHW; } } // set maximum dimesions if ($w > $maxw) { $w = $maxw; } if ($h > $maxh) { $h = $maxh; } // set dimensions if ((($w === '') OR ($w <= 0)) AND (($h === '') OR ($h <= 0))) { $w = ($cols + $hpad) * ($mw / $this->k); $h = ($rows + $vpad) * ($mh / $this->k); } elseif (($w === '') OR ($w <= 0)) { $w = $h * $ratioWH; } elseif (($h === '') OR ($h <= 0)) { $h = $w * $ratioHW; } // barcode size (excluding padding) $bw = ($w * $cols) / ($cols + $hpad); $bh = ($h * $rows) / ($rows + $vpad); // dimension of single barcode cell unit $cw = $bw / $cols; $ch = $bh / $rows; if (!$distort) { if (($cw / $ch) > ($mw / $mh)) { // correct horizontal distortion $cw = $ch * $mw / $mh; $bw = $cw * $cols; $style['hpadding'] = ($w - $bw) / (2 * $cw); } else { // correct vertical distortion $ch = $cw * $mh / $mw; $bh = $ch * $rows; $style['vpadding'] = ($h - $bh) / (2 * $ch); } } // fit the barcode on available space list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, false); // set alignment $this->img_rb_y = $y + $h; // set alignment if ($this->rtl) { if ($style['position'] == 'L') { $xpos = $this->lMargin; } elseif ($style['position'] == 'C') { $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($style['position'] == 'R') { $xpos = $this->w - $this->rMargin - $w; } else { $xpos = $x - $w; } $this->img_rb_x = $xpos; } else { if ($style['position'] == 'L') { $xpos = $this->lMargin; } elseif ($style['position'] == 'C') { $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($style['position'] == 'R') { $xpos = $this->w - $this->rMargin - $w; } else { $xpos = $x; } $this->img_rb_x = $xpos + $w; } $xstart = $xpos + ($style['hpadding'] * $cw); $ystart = $y + ($style['vpadding'] * $ch); // barcode is always printed in LTR direction $tempRTL = $this->rtl; $this->rtl = false; // print background color if ($style['bgcolor']) { $this->Rect($xpos, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']); } elseif ($style['border']) { $this->Rect($xpos, $y, $w, $h, 'D'); } // set foreground color $this->SetDrawColorArray($style['fgcolor']); // print barcode cells // for each row for ($r = 0; $r < $rows; ++$r) { $xr = $xstart; // for each column for ($c = 0; $c < $cols; ++$c) { if ($arrcode['bcode'][$r][$c] == 1) { // draw a single barcode cell $this->Rect($xr, $ystart, $cw, $ch, 'F', array(), $style['fgcolor']); } $xr += $cw; } $ystart += $ch; } // restore original direction $this->rtl = $tempRTL; // restore previous settings $this->setGraphicVars($gvars); // set pointer to align the next text/objects switch($align) { case 'T':{ $this->y = $y; $this->x = $this->img_rb_x; break; } case 'M':{ $this->y = $y + round($h/2); $this->x = $this->img_rb_x; break; } case 'B':{ $this->y = $this->img_rb_y; $this->x = $this->img_rb_x; break; } case 'N':{ $this->SetY($this->img_rb_y); break; } default:{ break; } } $this->endlinex = $this->img_rb_x; } /** * Returns an array containing current margins: * * @return array containing all margins measures * @public * @since 3.2.000 (2008-06-23) */ public function getMargins() { $ret = array( 'left' => $this->lMargin, 'right' => $this->rMargin, 'top' => $this->tMargin, 'bottom' => $this->bMargin, 'header' => $this->header_margin, 'footer' => $this->footer_margin, 'cell' => $this->cell_padding, 'padding_left' => $this->cell_padding['L'], 'padding_top' => $this->cell_padding['T'], 'padding_right' => $this->cell_padding['R'], 'padding_bottom' => $this->cell_padding['B'] ); return $ret; } /** * Returns an array containing original margins: * * @return array containing all margins measures * @public * @since 4.0.012 (2008-07-24) */ public function getOriginalMargins() { $ret = array( 'left' => $this->original_lMargin, 'right' => $this->original_rMargin ); return $ret; } /** * Returns the current font size. * @return current font size * @public * @since 3.2.000 (2008-06-23) */ public function getFontSize() { return $this->FontSize; } /** * Returns the current font size in points unit. * @return current font size in points unit * @public * @since 3.2.000 (2008-06-23) */ public function getFontSizePt() { return $this->FontSizePt; } /** * Returns the current font family name. * @return string current font family name * @public * @since 4.3.008 (2008-12-05) */ public function getFontFamily() { return $this->FontFamily; } /** * Returns the current font style. * @return string current font style * @public * @since 4.3.008 (2008-12-05) */ public function getFontStyle() { return $this->FontStyle; } /** * Cleanup HTML code (requires HTML Tidy library). * @param $html (string) htmlcode to fix * @param $default_css (string) CSS commands to add * @param $tagvs (array) parameters for setHtmlVSpace method * @param $tidy_options (array) options for tidy_parse_string function * @return string XHTML code cleaned up * @author Nicola Asuni * @public * @since 5.9.017 (2010-11-16) * @see setHtmlVSpace() */ public function fixHTMLCode($html, $default_css='', $tagvs='', $tidy_options='') { return TCPDF_STATIC::fixHTMLCode($html, $default_css, $tagvs, $tidy_options, $this->tagvspaces); } /** * Returns the border width from CSS property * @param $width (string) border width * @return int with in user units * @protected * @since 5.7.000 (2010-08-02) */ protected function getCSSBorderWidth($width) { if ($width == 'thin') { $width = (2 / $this->k); } elseif ($width == 'medium') { $width = (4 / $this->k); } elseif ($width == 'thick') { $width = (6 / $this->k); } else { $width = $this->getHTMLUnitToUnits($width, 1, 'px', false); } return $width; } /** * Returns the border dash style from CSS property * @param $style (string) border style to convert * @return int sash style (return -1 in case of none or hidden border) * @protected * @since 5.7.000 (2010-08-02) */ protected function getCSSBorderDashStyle($style) { switch (strtolower($style)) { case 'none': case 'hidden': { $dash = -1; break; } case 'dotted': { $dash = 1; break; } case 'dashed': { $dash = 3; break; } case 'double': case 'groove': case 'ridge': case 'inset': case 'outset': case 'solid': default: { $dash = 0; break; } } return $dash; } /** * Returns the border style array from CSS border properties * @param $cssborder (string) border properties * @return array containing border properties * @protected * @since 5.7.000 (2010-08-02) */ protected function getCSSBorderStyle($cssborder) { $bprop = preg_split('/[\s]+/', trim($cssborder)); $border = array(); // value to be returned switch (count($bprop)) { case 3: { $width = $bprop[0]; $style = $bprop[1]; $color = $bprop[2]; break; } case 2: { $width = 'medium'; $style = $bprop[0]; $color = $bprop[1]; break; } case 1: { $width = 'medium'; $style = $bprop[0]; $color = 'black'; break; } default: { $width = 'medium'; $style = 'solid'; $color = 'black'; break; } } if ($style == 'none') { return array(); } $border['cap'] = 'square'; $border['join'] = 'miter'; $border['dash'] = $this->getCSSBorderDashStyle($style); if ($border['dash'] < 0) { return array(); } $border['width'] = $this->getCSSBorderWidth($width); $border['color'] = TCPDF_COLORS::convertHTMLColorToDec($color, $this->spot_colors); return $border; } /** * Get the internal Cell padding from CSS attribute. * @param $csspadding (string) padding properties * @param $width (float) width of the containing element * @return array of cell paddings * @public * @since 5.9.000 (2010-10-04) */ public function getCSSPadding($csspadding, $width=0) { $padding = preg_split('/[\s]+/', trim($csspadding)); $cell_padding = array(); // value to be returned switch (count($padding)) { case 4: { $cell_padding['T'] = $padding[0]; $cell_padding['R'] = $padding[1]; $cell_padding['B'] = $padding[2]; $cell_padding['L'] = $padding[3]; break; } case 3: { $cell_padding['T'] = $padding[0]; $cell_padding['R'] = $padding[1]; $cell_padding['B'] = $padding[2]; $cell_padding['L'] = $padding[1]; break; } case 2: { $cell_padding['T'] = $padding[0]; $cell_padding['R'] = $padding[1]; $cell_padding['B'] = $padding[0]; $cell_padding['L'] = $padding[1]; break; } case 1: { $cell_padding['T'] = $padding[0]; $cell_padding['R'] = $padding[0]; $cell_padding['B'] = $padding[0]; $cell_padding['L'] = $padding[0]; break; } default: { return $this->cell_padding; } } if ($width == 0) { $width = $this->w - $this->lMargin - $this->rMargin; } $cell_padding['T'] = $this->getHTMLUnitToUnits($cell_padding['T'], $width, 'px', false); $cell_padding['R'] = $this->getHTMLUnitToUnits($cell_padding['R'], $width, 'px', false); $cell_padding['B'] = $this->getHTMLUnitToUnits($cell_padding['B'], $width, 'px', false); $cell_padding['L'] = $this->getHTMLUnitToUnits($cell_padding['L'], $width, 'px', false); return $cell_padding; } /** * Get the internal Cell margin from CSS attribute. * @param $cssmargin (string) margin properties * @param $width (float) width of the containing element * @return array of cell margins * @public * @since 5.9.000 (2010-10-04) */ public function getCSSMargin($cssmargin, $width=0) { $margin = preg_split('/[\s]+/', trim($cssmargin)); $cell_margin = array(); // value to be returned switch (count($margin)) { case 4: { $cell_margin['T'] = $margin[0]; $cell_margin['R'] = $margin[1]; $cell_margin['B'] = $margin[2]; $cell_margin['L'] = $margin[3]; break; } case 3: { $cell_margin['T'] = $margin[0]; $cell_margin['R'] = $margin[1]; $cell_margin['B'] = $margin[2]; $cell_margin['L'] = $margin[1]; break; } case 2: { $cell_margin['T'] = $margin[0]; $cell_margin['R'] = $margin[1]; $cell_margin['B'] = $margin[0]; $cell_margin['L'] = $margin[1]; break; } case 1: { $cell_margin['T'] = $margin[0]; $cell_margin['R'] = $margin[0]; $cell_margin['B'] = $margin[0]; $cell_margin['L'] = $margin[0]; break; } default: { return $this->cell_margin; } } if ($width == 0) { $width = $this->w - $this->lMargin - $this->rMargin; } $cell_margin['T'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['T']), $width, 'px', false); $cell_margin['R'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['R']), $width, 'px', false); $cell_margin['B'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['B']), $width, 'px', false); $cell_margin['L'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['L']), $width, 'px', false); return $cell_margin; } /** * Get the border-spacing from CSS attribute. * @param $cssbspace (string) border-spacing CSS properties * @param $width (float) width of the containing element * @return array of border spacings * @public * @since 5.9.010 (2010-10-27) */ public function getCSSBorderMargin($cssbspace, $width=0) { $space = preg_split('/[\s]+/', trim($cssbspace)); $border_spacing = array(); // value to be returned switch (count($space)) { case 2: { $border_spacing['H'] = $space[0]; $border_spacing['V'] = $space[1]; break; } case 1: { $border_spacing['H'] = $space[0]; $border_spacing['V'] = $space[0]; break; } default: { return array('H' => 0, 'V' => 0); } } if ($width == 0) { $width = $this->w - $this->lMargin - $this->rMargin; } $border_spacing['H'] = $this->getHTMLUnitToUnits($border_spacing['H'], $width, 'px', false); $border_spacing['V'] = $this->getHTMLUnitToUnits($border_spacing['V'], $width, 'px', false); return $border_spacing; } /** * Returns the letter-spacing value from CSS value * @param $spacing (string) letter-spacing value * @param $parent (float) font spacing (tracking) value of the parent element * @return float quantity to increases or decreases the space between characters in a text. * @protected * @since 5.9.000 (2010-10-02) */ protected function getCSSFontSpacing($spacing, $parent=0) { $val = 0; // value to be returned $spacing = trim($spacing); switch ($spacing) { case 'normal': { $val = 0; break; } case 'inherit': { if ($parent == 'normal') { $val = 0; } else { $val = $parent; } break; } default: { $val = $this->getHTMLUnitToUnits($spacing, 0, 'px', false); } } return $val; } /** * Returns the percentage of font stretching from CSS value * @param $stretch (string) stretch mode * @param $parent (float) stretch value of the parent element * @return float font stretching percentage * @protected * @since 5.9.000 (2010-10-02) */ protected function getCSSFontStretching($stretch, $parent=100) { $val = 100; // value to be returned $stretch = trim($stretch); switch ($stretch) { case 'ultra-condensed': { $val = 40; break; } case 'extra-condensed': { $val = 55; break; } case 'condensed': { $val = 70; break; } case 'semi-condensed': { $val = 85; break; } case 'normal': { $val = 100; break; } case 'semi-expanded': { $val = 115; break; } case 'expanded': { $val = 130; break; } case 'extra-expanded': { $val = 145; break; } case 'ultra-expanded': { $val = 160; break; } case 'wider': { $val = ($parent + 10); break; } case 'narrower': { $val = ($parent - 10); break; } case 'inherit': { if ($parent == 'normal') { $val = 100; } else { $val = $parent; } break; } default: { $val = $this->getHTMLUnitToUnits($stretch, 100, '%', false); } } return $val; } /** * Convert HTML string containing font size value to points * @param $val (string) String containing font size value and unit. * @param $refsize (float) Reference font size in points. * @param $parent_size (float) Parent font size in points. * @param $defaultunit (string) Default unit (can be one of the following: %, em, ex, px, in, mm, pc, pt). * @return float value in points * @public */ public function getHTMLFontUnits($val, $refsize=12, $parent_size=12, $defaultunit='pt') { $refsize = TCPDF_FONTS::getFontRefSize($refsize); $parent_size = TCPDF_FONTS::getFontRefSize($parent_size, $refsize); switch ($val) { case 'xx-small': { $size = ($refsize - 4); break; } case 'x-small': { $size = ($refsize - 3); break; } case 'small': { $size = ($refsize - 2); break; } case 'medium': { $size = $refsize; break; } case 'large': { $size = ($refsize + 2); break; } case 'x-large': { $size = ($refsize + 4); break; } case 'xx-large': { $size = ($refsize + 6); break; } case 'smaller': { $size = ($parent_size - 3); break; } case 'larger': { $size = ($parent_size + 3); break; } default: { $size = $this->getHTMLUnitToUnits($val, $parent_size, $defaultunit, true); } } return $size; } /** * Returns the HTML DOM array. * @param $html (string) html code * @return array * @protected * @since 3.2.000 (2008-06-20) */ protected function getHtmlDomArray($html) { // array of CSS styles ( selector => properties). $css = array(); // get CSS array defined at previous call $matches = array(); if (preg_match_all('/([^\<]*)<\/cssarray>/isU', $html, $matches) > 0) { if (isset($matches[1][0])) { $css = array_merge($css, unserialize($this->unhtmlentities($matches[1][0]))); } $html = preg_replace('/(.*?)<\/cssarray>/isU', '', $html); } // extract external CSS files $matches = array(); if (preg_match_all('/]*)>/isU', $html, $matches) > 0) { foreach ($matches[1] as $key => $link) { $type = array(); if (preg_match('/type[\s]*=[\s]*"text\/css"/', $link, $type)) { $type = array(); preg_match('/media[\s]*=[\s]*"([^"]*)"/', $link, $type); // get 'all' and 'print' media, other media types are discarded // (all, braille, embossed, handheld, print, projection, screen, speech, tty, tv) if (empty($type) OR (isset($type[1]) AND (($type[1] == 'all') OR ($type[1] == 'print')))) { $type = array(); if (preg_match('/href[\s]*=[\s]*"([^"]*)"/', $link, $type) > 0) { // read CSS data file $cssdata = file_get_contents(trim($type[1])); $css = array_merge($css, TCPDF_STATIC::extractCSSproperties($cssdata)); } } } } } // extract style tags $matches = array(); if (preg_match_all('/]*)>([^\<]*)<\/style>/isU', $html, $matches) > 0) { foreach ($matches[1] as $key => $media) { $type = array(); preg_match('/media[\s]*=[\s]*"([^"]*)"/', $media, $type); // get 'all' and 'print' media, other media types are discarded // (all, braille, embossed, handheld, print, projection, screen, speech, tty, tv) if (empty($type) OR (isset($type[1]) AND (($type[1] == 'all') OR ($type[1] == 'print')))) { $cssdata = $matches[2][$key]; $css = array_merge($css, TCPDF_STATIC::extractCSSproperties($cssdata)); } } } // create a special tag to contain the CSS array (used for table content) $csstagarray = ''.htmlentities(serialize($css)).''; // remove head and style blocks $html = preg_replace('/]*)>(.*?)<\/head>/siU', '', $html); $html = preg_replace('/]*)>([^\<]*)<\/style>/isU', '', $html); // define block tags $blocktags = array('blockquote','br','dd','dl','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','pre','ul','tcpdf','table','tr','td'); // define self-closing tags $selfclosingtags = array('area','base','basefont','br','hr','input','img','link','meta'); // remove all unsupported tags (the line below lists all supported tags) $html = strip_tags($html, '




    1. ', $offset)) !== false) {
      			$html_a = substr($html, 0, $offset);
      			$html_b = substr($html, $offset, ($pos - $offset + 11));
      			while (preg_match("']*)>(.*?)\n(.*?)'si", $html_b)) {
      				// preserve newlines on 'si", "\\2\\3", $html_b);
      				$html_b = preg_replace("']*)>(.*?)[\"](.*?)'si", "\\2''\\3", $html_b);
      			}
      			$html = $html_a.$html_b.substr($html, $pos + 11);
      			$offset = strlen($html_a.$html_b);
      		}
      		$html = preg_replace('/([\s]*)', $html);
      		$offset = 0;
      		while (($offset < strlen($html)) AND ($pos = strpos($html, '', $offset)) !== false) {
      			$html_a = substr($html, 0, $offset);
      			$html_b = substr($html, $offset, ($pos - $offset + 9));
      			while (preg_match("']*)>(.*?)'si", $html_b)) {
      				$html_b = preg_replace("']*)>(.*?)'si", "\\2#!TaB!#\\4#!NwL!#", $html_b);
      				$html_b = preg_replace("']*)>(.*?)'si", "\\2#!NwL!#", $html_b);
      			}
      			$html = $html_a.$html_b.substr($html, $pos + 9);
      			$offset = strlen($html_a.$html_b);
      		}
      		if (preg_match("']*)>'si", "'si", "\" />", $html);
      		}
      		$html = str_replace("\n", ' ', $html);
      		// restore textarea newlines
      		$html = str_replace('', "\n", $html);
      		// remove extra spaces from code
      		$html = preg_replace('/[\s]+<\/(table|tr|ul|ol|dl)>/', '', $html);
      		$html = preg_replace('/'.$this->re_space['p'].'+<\/(td|th|li|dt|dd)>/'.$this->re_space['m'], '', $html);
      		$html = preg_replace('/[\s]+<(tr|td|th|li|dt|dd)/', '<\\1', $html);
      		$html = preg_replace('/'.$this->re_space['p'].'+<(ul|ol|dl|br)/'.$this->re_space['m'], '<\\1', $html);
      		$html = preg_replace('/<\/(table|tr|td|th|blockquote|dd|dt|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|ul|p)>[\s]+<', $html);
      		$html = preg_replace('/<\/(td|th)>/', '', $html);
      		$html = preg_replace('/<\/table>([\s]*)/', '', $html);
      		$html = preg_replace('/'.$this->re_space['p'].'+re_space['m'], chr(32).']*)>[\s]+([^\<])/xi', ' \\2', $html);
      		$html = preg_replace('/]*)>/xi', '', $html);
      		$html = preg_replace('/]*)>([^\<]*)<\/textarea>/xi', '', $html);
      		$html = preg_replace('/]*)><\/li>/', ' ', $html);
      		$html = preg_replace('/]*)>'.$this->re_space['p'].'*re_space['m'], ' \/]*)>[\s]/', '<\\1> ', $html); // preserve some spaces
      		$html = preg_replace('/[\s]<\/([^\>]*)>/', ' ', $html); // preserve some spaces
      		$html = preg_replace('//', '', $html); // fix sub/sup alignment
      		$html = preg_replace('/'.$this->re_space['p'].'+/'.$this->re_space['m'], chr(32), $html); // replace multiple spaces with a single space
      		// trim string
      		$html = $this->stringTrim($html);
      		// fix first image tag alignment
      		$html = preg_replace('/^
      FontFamily; $dom[$key]['fontstyle'] = $this->FontStyle; $dom[$key]['fontsize'] = $this->FontSizePt; $dom[$key]['font-stretch'] = $this->font_stretching; $dom[$key]['letter-spacing'] = $this->font_spacing; $dom[$key]['stroke'] = $this->textstrokewidth; $dom[$key]['fill'] = (($this->textrendermode % 2) == 0); $dom[$key]['clip'] = ($this->textrendermode > 3); $dom[$key]['line-height'] = $this->cell_height_ratio; $dom[$key]['bgcolor'] = false; $dom[$key]['fgcolor'] = $this->fgcolor; // color $dom[$key]['strokecolor'] = $this->strokecolor; $dom[$key]['align'] = ''; $dom[$key]['listtype'] = ''; $dom[$key]['text-indent'] = 0; $dom[$key]['border'] = array(); $dom[$key]['dir'] = $this->rtl?'rtl':'ltr'; $thead = false; // true when we are inside the THEAD tag ++$key; $level = array(); array_push($level, 0); // root while ($elkey < $maxel) { $dom[$key] = array(); $element = $a[$elkey]; $dom[$key]['elkey'] = $elkey; if (preg_match($tagpattern, $element)) { // html tag $element = substr($element, 1, -1); // get tag name preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag); $tagname = strtolower($tag[1]); // check if we are inside a table header if ($tagname == 'thead') { if ($element{0} == '/') { $thead = false; } else { $thead = true; } ++$elkey; continue; } $dom[$key]['tag'] = true; $dom[$key]['value'] = $tagname; if (in_array($dom[$key]['value'], $blocktags)) { $dom[$key]['block'] = true; } else { $dom[$key]['block'] = false; } if ($element{0} == '/') { // *** closing html tag $dom[$key]['opening'] = false; $dom[$key]['parent'] = end($level); array_pop($level); $dom[$key]['hide'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['hide']; $dom[$key]['fontname'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontname']; $dom[$key]['fontstyle'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontstyle']; $dom[$key]['fontsize'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontsize']; $dom[$key]['font-stretch'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['font-stretch']; $dom[$key]['letter-spacing'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['letter-spacing']; $dom[$key]['stroke'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['stroke']; $dom[$key]['fill'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fill']; $dom[$key]['clip'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['clip']; $dom[$key]['line-height'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['line-height']; $dom[$key]['bgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['bgcolor']; $dom[$key]['fgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fgcolor']; $dom[$key]['strokecolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['strokecolor']; $dom[$key]['align'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['align']; $dom[$key]['dir'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['dir']; if (isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'])) { $dom[$key]['listtype'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype']; } // set the number of columns in table tag if (($dom[$key]['value'] == 'tr') AND (!isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['cols']))) { $dom[($dom[($dom[$key]['parent'])]['parent'])]['cols'] = $dom[($dom[$key]['parent'])]['cols']; } if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) { $dom[($dom[$key]['parent'])]['content'] = $csstagarray; for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) { $dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']]; } $key = $i; // mark nested tables $dom[($dom[$key]['parent'])]['content'] = str_replace('', '', $dom[($dom[$key]['parent'])]['content']); $dom[($dom[$key]['parent'])]['content'] = str_replace('', '', $dom[($dom[$key]['parent'])]['content']); } // store header rows on a new table if (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['thead'] === true)) { if (TCPDF_STATIC::empty_string($dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'])) { $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] = $csstagarray.$a[$dom[($dom[($dom[$key]['parent'])]['parent'])]['elkey']]; } for ($i = $dom[$key]['parent']; $i <= $key; ++$i) { $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] .= $a[$dom[$i]['elkey']]; } if (!isset($dom[($dom[$key]['parent'])]['attribute'])) { $dom[($dom[$key]['parent'])]['attribute'] = array(); } // header elements must be always contained in a single page $dom[($dom[$key]['parent'])]['attribute']['nobr'] = 'true'; } if (($dom[$key]['value'] == 'table') AND (!TCPDF_STATIC::empty_string($dom[($dom[$key]['parent'])]['thead']))) { // remove the nobr attributes from the table header $dom[($dom[$key]['parent'])]['thead'] = str_replace(' nobr="true"', '', $dom[($dom[$key]['parent'])]['thead']); $dom[($dom[$key]['parent'])]['thead'] .= ''; } } else { // *** opening or self-closing html tag $dom[$key]['opening'] = true; $dom[$key]['parent'] = end($level); if ((substr($element, -1, 1) == '/') OR (in_array($dom[$key]['value'], $selfclosingtags))) { // self-closing tag $dom[$key]['self'] = true; } else { // opening tag array_push($level, $key); $dom[$key]['self'] = false; } // copy some values from parent $parentkey = 0; if ($key > 0) { $parentkey = $dom[$key]['parent']; $dom[$key]['hide'] = $dom[$parentkey]['hide']; $dom[$key]['fontname'] = $dom[$parentkey]['fontname']; $dom[$key]['fontstyle'] = $dom[$parentkey]['fontstyle']; $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize']; $dom[$key]['font-stretch'] = $dom[$parentkey]['font-stretch']; $dom[$key]['letter-spacing'] = $dom[$parentkey]['letter-spacing']; $dom[$key]['stroke'] = $dom[$parentkey]['stroke']; $dom[$key]['fill'] = $dom[$parentkey]['fill']; $dom[$key]['clip'] = $dom[$parentkey]['clip']; $dom[$key]['line-height'] = $dom[$parentkey]['line-height']; $dom[$key]['bgcolor'] = $dom[$parentkey]['bgcolor']; $dom[$key]['fgcolor'] = $dom[$parentkey]['fgcolor']; $dom[$key]['strokecolor'] = $dom[$parentkey]['strokecolor']; $dom[$key]['align'] = $dom[$parentkey]['align']; $dom[$key]['listtype'] = $dom[$parentkey]['listtype']; $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent']; $dom[$key]['border'] = array(); $dom[$key]['dir'] = $dom[$parentkey]['dir']; } // get attributes preg_match_all('/([^=\s]*)[\s]*=[\s]*"([^"]*)"/', $element, $attr_array, PREG_PATTERN_ORDER); $dom[$key]['attribute'] = array(); // reset attribute array while (list($id, $name) = each($attr_array[1])) { $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id]; } if (!empty($css)) { // merge CSS style to current style list($dom[$key]['csssel'], $dom[$key]['cssdata']) = TCPDF_STATIC::getCSSdataArray($dom, $key, $css); $dom[$key]['attribute']['style'] = TCPDF_STATIC::getTagStyleFromCSSarray($dom[$key]['cssdata']); } // split style attributes if (isset($dom[$key]['attribute']['style']) AND !empty($dom[$key]['attribute']['style'])) { // get style attributes preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER); $dom[$key]['style'] = array(); // reset style attribute array while (list($id, $name) = each($style_array[1])) { // in case of duplicate attribute the last replace the previous $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]); } // --- get some style attributes --- // text direction if (isset($dom[$key]['style']['direction'])) { $dom[$key]['dir'] = $dom[$key]['style']['direction']; } // display if (isset($dom[$key]['style']['display'])) { $dom[$key]['hide'] = (trim(strtolower($dom[$key]['style']['display'])) == 'none'); } // font family if (isset($dom[$key]['style']['font-family'])) { $dom[$key]['fontname'] = $this->getFontFamilyName($dom[$key]['style']['font-family']); } // list-style-type if (isset($dom[$key]['style']['list-style-type'])) { $dom[$key]['listtype'] = trim(strtolower($dom[$key]['style']['list-style-type'])); if ($dom[$key]['listtype'] == 'inherit') { $dom[$key]['listtype'] = $dom[$parentkey]['listtype']; } } // text-indent if (isset($dom[$key]['style']['text-indent'])) { $dom[$key]['text-indent'] = $this->getHTMLUnitToUnits($dom[$key]['style']['text-indent']); if ($dom[$key]['text-indent'] == 'inherit') { $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent']; } } // font size if (isset($dom[$key]['style']['font-size'])) { $fsize = trim($dom[$key]['style']['font-size']); $dom[$key]['fontsize'] = $this->getHTMLFontUnits($fsize, $dom[0]['fontsize'], $dom[$parentkey]['fontsize'], 'pt'); } // font-stretch if (isset($dom[$key]['style']['font-stretch'])) { $dom[$key]['font-stretch'] = $this->getCSSFontStretching($dom[$key]['style']['font-stretch'], $dom[$parentkey]['font-stretch']); } // letter-spacing if (isset($dom[$key]['style']['letter-spacing'])) { $dom[$key]['letter-spacing'] = $this->getCSSFontSpacing($dom[$key]['style']['letter-spacing'], $dom[$parentkey]['letter-spacing']); } // line-height if (isset($dom[$key]['style']['line-height'])) { $lineheight = trim($dom[$key]['style']['line-height']); switch ($lineheight) { // A normal line height. This is default case 'normal': { $dom[$key]['line-height'] = $dom[0]['line-height']; break; } default: { if (is_numeric($lineheight)) { $lineheight = $lineheight * 100; } $dom[$key]['line-height'] = $this->getHTMLUnitToUnits($lineheight, 1, '%', true); } } } // font style if (isset($dom[$key]['style']['font-weight'])) { if (strtolower($dom[$key]['style']['font-weight']{0}) == 'n') { if (strpos($dom[$key]['fontstyle'], 'B') !== false) { $dom[$key]['fontstyle'] = str_replace('B', '', $dom[$key]['fontstyle']); } } elseif (strtolower($dom[$key]['style']['font-weight']{0}) == 'b') { $dom[$key]['fontstyle'] .= 'B'; } } if (isset($dom[$key]['style']['font-style']) AND (strtolower($dom[$key]['style']['font-style']{0}) == 'i')) { $dom[$key]['fontstyle'] .= 'I'; } // font color if (isset($dom[$key]['style']['color']) AND (!TCPDF_STATIC::empty_string($dom[$key]['style']['color']))) { $dom[$key]['fgcolor'] = TCPDF_COLORS::convertHTMLColorToDec($dom[$key]['style']['color'], $this->spot_colors); } elseif ($dom[$key]['value'] == 'a') { $dom[$key]['fgcolor'] = $this->htmlLinkColorArray; } // background color if (isset($dom[$key]['style']['background-color']) AND (!TCPDF_STATIC::empty_string($dom[$key]['style']['background-color']))) { $dom[$key]['bgcolor'] = TCPDF_COLORS::convertHTMLColorToDec($dom[$key]['style']['background-color'], $this->spot_colors); } // text-decoration if (isset($dom[$key]['style']['text-decoration'])) { $decors = explode(' ', strtolower($dom[$key]['style']['text-decoration'])); foreach ($decors as $dec) { $dec = trim($dec); if (!TCPDF_STATIC::empty_string($dec)) { if ($dec{0} == 'u') { // underline $dom[$key]['fontstyle'] .= 'U'; } elseif ($dec{0} == 'l') { // line-trough $dom[$key]['fontstyle'] .= 'D'; } elseif ($dec{0} == 'o') { // overline $dom[$key]['fontstyle'] .= 'O'; } } } } elseif ($dom[$key]['value'] == 'a') { $dom[$key]['fontstyle'] = $this->htmlLinkFontStyle; } // check for width attribute if (isset($dom[$key]['style']['width'])) { $dom[$key]['width'] = $dom[$key]['style']['width']; } // check for height attribute if (isset($dom[$key]['style']['height'])) { $dom[$key]['height'] = $dom[$key]['style']['height']; } // check for text alignment if (isset($dom[$key]['style']['text-align'])) { $dom[$key]['align'] = strtoupper($dom[$key]['style']['text-align']{0}); } // check for CSS border properties if (isset($dom[$key]['style']['border'])) { $borderstyle = $this->getCSSBorderStyle($dom[$key]['style']['border']); if (!empty($borderstyle)) { $dom[$key]['border']['LTRB'] = $borderstyle; } } if (isset($dom[$key]['style']['border-color'])) { $brd_colors = preg_split('/[\s]+/', trim($dom[$key]['style']['border-color'])); if (isset($brd_colors[3])) { $dom[$key]['border']['L']['color'] = TCPDF_COLORS::convertHTMLColorToDec($brd_colors[3], $this->spot_colors); } if (isset($brd_colors[1])) { $dom[$key]['border']['R']['color'] = TCPDF_COLORS::convertHTMLColorToDec($brd_colors[1], $this->spot_colors); } if (isset($brd_colors[0])) { $dom[$key]['border']['T']['color'] = TCPDF_COLORS::convertHTMLColorToDec($brd_colors[0], $this->spot_colors); } if (isset($brd_colors[2])) { $dom[$key]['border']['B']['color'] = TCPDF_COLORS::convertHTMLColorToDec($brd_colors[2], $this->spot_colors); } } if (isset($dom[$key]['style']['border-width'])) { $brd_widths = preg_split('/[\s]+/', trim($dom[$key]['style']['border-width'])); if (isset($brd_widths[3])) { $dom[$key]['border']['L']['width'] = $this->getCSSBorderWidth($brd_widths[3]); } if (isset($brd_widths[1])) { $dom[$key]['border']['R']['width'] = $this->getCSSBorderWidth($brd_widths[1]); } if (isset($brd_widths[0])) { $dom[$key]['border']['T']['width'] = $this->getCSSBorderWidth($brd_widths[0]); } if (isset($brd_widths[2])) { $dom[$key]['border']['B']['width'] = $this->getCSSBorderWidth($brd_widths[2]); } } if (isset($dom[$key]['style']['border-style'])) { $brd_styles = preg_split('/[\s]+/', trim($dom[$key]['style']['border-style'])); if (isset($brd_styles[3]) AND ($brd_styles[3]!='none')) { $dom[$key]['border']['L']['cap'] = 'square'; $dom[$key]['border']['L']['join'] = 'miter'; $dom[$key]['border']['L']['dash'] = $this->getCSSBorderDashStyle($brd_styles[3]); if ($dom[$key]['border']['L']['dash'] < 0) { $dom[$key]['border']['L'] = array(); } } if (isset($brd_styles[1])) { $dom[$key]['border']['R']['cap'] = 'square'; $dom[$key]['border']['R']['join'] = 'miter'; $dom[$key]['border']['R']['dash'] = $this->getCSSBorderDashStyle($brd_styles[1]); if ($dom[$key]['border']['R']['dash'] < 0) { $dom[$key]['border']['R'] = array(); } } if (isset($brd_styles[0])) { $dom[$key]['border']['T']['cap'] = 'square'; $dom[$key]['border']['T']['join'] = 'miter'; $dom[$key]['border']['T']['dash'] = $this->getCSSBorderDashStyle($brd_styles[0]); if ($dom[$key]['border']['T']['dash'] < 0) { $dom[$key]['border']['T'] = array(); } } if (isset($brd_styles[2])) { $dom[$key]['border']['B']['cap'] = 'square'; $dom[$key]['border']['B']['join'] = 'miter'; $dom[$key]['border']['B']['dash'] = $this->getCSSBorderDashStyle($brd_styles[2]); if ($dom[$key]['border']['B']['dash'] < 0) { $dom[$key]['border']['B'] = array(); } } } $cellside = array('L' => 'left', 'R' => 'right', 'T' => 'top', 'B' => 'bottom'); foreach ($cellside as $bsk => $bsv) { if (isset($dom[$key]['style']['border-'.$bsv])) { $borderstyle = $this->getCSSBorderStyle($dom[$key]['style']['border-'.$bsv]); if (!empty($borderstyle)) { $dom[$key]['border'][$bsk] = $borderstyle; } } if (isset($dom[$key]['style']['border-'.$bsv.'-color'])) { $dom[$key]['border'][$bsk]['color'] = TCPDF_COLORS::convertHTMLColorToDec($dom[$key]['style']['border-'.$bsv.'-color'], $this->spot_colors); } if (isset($dom[$key]['style']['border-'.$bsv.'-width'])) { $dom[$key]['border'][$bsk]['width'] = $this->getCSSBorderWidth($dom[$key]['style']['border-'.$bsv.'-width']); } if (isset($dom[$key]['style']['border-'.$bsv.'-style'])) { $dom[$key]['border'][$bsk]['dash'] = $this->getCSSBorderDashStyle($dom[$key]['style']['border-'.$bsv.'-style']); if ($dom[$key]['border'][$bsk]['dash'] < 0) { $dom[$key]['border'][$bsk] = array(); } } } // check for CSS padding properties if (isset($dom[$key]['style']['padding'])) { $dom[$key]['padding'] = $this->getCSSPadding($dom[$key]['style']['padding']); } else { $dom[$key]['padding'] = $this->cell_padding; } foreach ($cellside as $psk => $psv) { if (isset($dom[$key]['style']['padding-'.$psv])) { $dom[$key]['padding'][$psk] = $this->getHTMLUnitToUnits($dom[$key]['style']['padding-'.$psv], 0, 'px', false); } } // check for CSS margin properties if (isset($dom[$key]['style']['margin'])) { $dom[$key]['margin'] = $this->getCSSMargin($dom[$key]['style']['margin']); } else { $dom[$key]['margin'] = $this->cell_margin; } foreach ($cellside as $psk => $psv) { if (isset($dom[$key]['style']['margin-'.$psv])) { $dom[$key]['margin'][$psk] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $dom[$key]['style']['margin-'.$psv]), 0, 'px', false); } } // check for CSS border-spacing properties if (isset($dom[$key]['style']['border-spacing'])) { $dom[$key]['border-spacing'] = $this->getCSSBorderMargin($dom[$key]['style']['border-spacing']); } // page-break-inside if (isset($dom[$key]['style']['page-break-inside']) AND ($dom[$key]['style']['page-break-inside'] == 'avoid')) { $dom[$key]['attribute']['nobr'] = 'true'; } // page-break-before if (isset($dom[$key]['style']['page-break-before'])) { if ($dom[$key]['style']['page-break-before'] == 'always') { $dom[$key]['attribute']['pagebreak'] = 'true'; } elseif ($dom[$key]['style']['page-break-before'] == 'left') { $dom[$key]['attribute']['pagebreak'] = 'left'; } elseif ($dom[$key]['style']['page-break-before'] == 'right') { $dom[$key]['attribute']['pagebreak'] = 'right'; } } // page-break-after if (isset($dom[$key]['style']['page-break-after'])) { if ($dom[$key]['style']['page-break-after'] == 'always') { $dom[$key]['attribute']['pagebreakafter'] = 'true'; } elseif ($dom[$key]['style']['page-break-after'] == 'left') { $dom[$key]['attribute']['pagebreakafter'] = 'left'; } elseif ($dom[$key]['style']['page-break-after'] == 'right') { $dom[$key]['attribute']['pagebreakafter'] = 'right'; } } } if (isset($dom[$key]['attribute']['display'])) { $dom[$key]['hide'] = (trim(strtolower($dom[$key]['attribute']['display'])) == 'none'); } if (isset($dom[$key]['attribute']['border']) AND ($dom[$key]['attribute']['border'] != 0)) { $borderstyle = $this->getCSSBorderStyle($dom[$key]['attribute']['border'].' solid black'); if (!empty($borderstyle)) { $dom[$key]['border']['LTRB'] = $borderstyle; } } // check for font tag if ($dom[$key]['value'] == 'font') { // font family if (isset($dom[$key]['attribute']['face'])) { $dom[$key]['fontname'] = $this->getFontFamilyName($dom[$key]['attribute']['face']); } // font size if (isset($dom[$key]['attribute']['size'])) { if ($key > 0) { if ($dom[$key]['attribute']['size']{0} == '+') { $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] + intval(substr($dom[$key]['attribute']['size'], 1)); } elseif ($dom[$key]['attribute']['size']{0} == '-') { $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] - intval(substr($dom[$key]['attribute']['size'], 1)); } else { $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']); } } else { $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']); } } } // force natural alignment for lists if ((($dom[$key]['value'] == 'ul') OR ($dom[$key]['value'] == 'ol') OR ($dom[$key]['value'] == 'dl')) AND (!isset($dom[$key]['align']) OR TCPDF_STATIC::empty_string($dom[$key]['align']) OR ($dom[$key]['align'] != 'J'))) { if ($this->rtl) { $dom[$key]['align'] = 'R'; } else { $dom[$key]['align'] = 'L'; } } if (($dom[$key]['value'] == 'small') OR ($dom[$key]['value'] == 'sup') OR ($dom[$key]['value'] == 'sub')) { if (!isset($dom[$key]['attribute']['size']) AND !isset($dom[$key]['style']['font-size'])) { $dom[$key]['fontsize'] = $dom[$key]['fontsize'] * K_SMALL_RATIO; } } if (($dom[$key]['value'] == 'strong') OR ($dom[$key]['value'] == 'b')) { $dom[$key]['fontstyle'] .= 'B'; } if (($dom[$key]['value'] == 'em') OR ($dom[$key]['value'] == 'i')) { $dom[$key]['fontstyle'] .= 'I'; } if ($dom[$key]['value'] == 'u') { $dom[$key]['fontstyle'] .= 'U'; } if (($dom[$key]['value'] == 'del') OR ($dom[$key]['value'] == 's') OR ($dom[$key]['value'] == 'strike')) { $dom[$key]['fontstyle'] .= 'D'; } if (!isset($dom[$key]['style']['text-decoration']) AND ($dom[$key]['value'] == 'a')) { $dom[$key]['fontstyle'] = $this->htmlLinkFontStyle; } if (($dom[$key]['value'] == 'pre') OR ($dom[$key]['value'] == 'tt')) { $dom[$key]['fontname'] = $this->default_monospaced_font; } if (($dom[$key]['value']{0} == 'h') AND (intval($dom[$key]['value']{1}) > 0) AND (intval($dom[$key]['value']{1}) < 7)) { // headings h1, h2, h3, h4, h5, h6 if (!isset($dom[$key]['attribute']['size']) AND !isset($dom[$key]['style']['font-size'])) { $headsize = (4 - intval($dom[$key]['value']{1})) * 2; $dom[$key]['fontsize'] = $dom[0]['fontsize'] + $headsize; } if (!isset($dom[$key]['style']['font-weight'])) { $dom[$key]['fontstyle'] .= 'B'; } } if (($dom[$key]['value'] == 'table')) { $dom[$key]['rows'] = 0; // number of rows $dom[$key]['trids'] = array(); // IDs of TR elements $dom[$key]['thead'] = ''; // table header rows } if (($dom[$key]['value'] == 'tr')) { $dom[$key]['cols'] = 0; if ($thead) { $dom[$key]['thead'] = true; // rows on thead block are printed as a separate table } else { $dom[$key]['thead'] = false; // store the number of rows on table element ++$dom[($dom[$key]['parent'])]['rows']; // store the TR elements IDs on table element array_push($dom[($dom[$key]['parent'])]['trids'], $key); } } if (($dom[$key]['value'] == 'th') OR ($dom[$key]['value'] == 'td')) { if (isset($dom[$key]['attribute']['colspan'])) { $colspan = intval($dom[$key]['attribute']['colspan']); } else { $colspan = 1; } $dom[$key]['attribute']['colspan'] = $colspan; $dom[($dom[$key]['parent'])]['cols'] += $colspan; } // text direction if (isset($dom[$key]['attribute']['dir'])) { $dom[$key]['dir'] = $dom[$key]['attribute']['dir']; } // set foreground color attribute if (isset($dom[$key]['attribute']['color']) AND (!TCPDF_STATIC::empty_string($dom[$key]['attribute']['color']))) { $dom[$key]['fgcolor'] = TCPDF_COLORS::convertHTMLColorToDec($dom[$key]['attribute']['color'], $this->spot_colors); } elseif (!isset($dom[$key]['style']['color']) AND ($dom[$key]['value'] == 'a')) { $dom[$key]['fgcolor'] = $this->htmlLinkColorArray; } // set background color attribute if (isset($dom[$key]['attribute']['bgcolor']) AND (!TCPDF_STATIC::empty_string($dom[$key]['attribute']['bgcolor']))) { $dom[$key]['bgcolor'] = TCPDF_COLORS::convertHTMLColorToDec($dom[$key]['attribute']['bgcolor'], $this->spot_colors); } // set stroke color attribute if (isset($dom[$key]['attribute']['strokecolor']) AND (!TCPDF_STATIC::empty_string($dom[$key]['attribute']['strokecolor']))) { $dom[$key]['strokecolor'] = TCPDF_COLORS::convertHTMLColorToDec($dom[$key]['attribute']['strokecolor'], $this->spot_colors); } // check for width attribute if (isset($dom[$key]['attribute']['width'])) { $dom[$key]['width'] = $dom[$key]['attribute']['width']; } // check for height attribute if (isset($dom[$key]['attribute']['height'])) { $dom[$key]['height'] = $dom[$key]['attribute']['height']; } // check for text alignment if (isset($dom[$key]['attribute']['align']) AND (!TCPDF_STATIC::empty_string($dom[$key]['attribute']['align'])) AND ($dom[$key]['value'] !== 'img')) { $dom[$key]['align'] = strtoupper($dom[$key]['attribute']['align']{0}); } // check for text rendering mode (the following attributes do not exist in HTML) if (isset($dom[$key]['attribute']['stroke'])) { // font stroke width $dom[$key]['stroke'] = $this->getHTMLUnitToUnits($dom[$key]['attribute']['stroke'], $dom[$key]['fontsize'], 'pt', true); } if (isset($dom[$key]['attribute']['fill'])) { // font fill if ($dom[$key]['attribute']['fill'] == 'true') { $dom[$key]['fill'] = true; } else { $dom[$key]['fill'] = false; } } if (isset($dom[$key]['attribute']['clip'])) { // clipping mode if ($dom[$key]['attribute']['clip'] == 'true') { $dom[$key]['clip'] = true; } else { $dom[$key]['clip'] = false; } } } // end opening tag } else { // text $dom[$key]['tag'] = false; $dom[$key]['block'] = false; //$element = str_replace(' ', TCPDF_FONTS::unichr(160, $this->isunicode), $element); $dom[$key]['value'] = stripslashes($this->unhtmlentities($element)); $dom[$key]['parent'] = end($level); $dom[$key]['dir'] = $dom[$dom[$key]['parent']]['dir']; } ++$elkey; ++$key; } return $dom; } /** * Returns the string used to find spaces * @return string * @protected * @author Nicola Asuni * @since 4.8.024 (2010-01-15) */ protected function getSpaceString() { $spacestr = chr(32); if ($this->isUnicodeFont()) { $spacestr = chr(0).chr(32); } return $spacestr; } /** * Serialize an array of parameters to be used with TCPDF tag in HTML code. * @param $pararray (array) parameters array * @return sting containing serialized data * @since 4.9.006 (2010-04-02) * @public * @deprecated */ public function serializeTCPDFtagParameters($pararray) { return TCPDF_STATIC::serializeTCPDFtagParameters($pararray); } /** * Prints a cell (rectangular area) with optional borders, background color and html text string. * The upper-left corner of the cell corresponds to the current position. After the call, the current position moves to the right or to the next line.
      * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting. * IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting. * Supported tags are: a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, tcpdf, td, th, thead, tr, tt, u, ul * NOTE: all the HTML attributes must be enclosed in double-quote. * @param $w (float) Cell width. If 0, the cell extends up to the right margin. * @param $h (float) Cell minimum height. The cell extends automatically if needed. * @param $x (float) upper-left corner X coordinate * @param $y (float) upper-left corner Y coordinate * @param $html (string) html text to print. Default value: empty string. * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:
      • 0: no border (default)
      • 1: frame
      or a string containing some or all of the following characters (in any order):
      • L: left
      • T: top
      • R: right
      • B: bottom
      or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $ln (int) Indicates where the current position should go after the call. Possible values are:
      • 0: to the right (or left for RTL language)
      • 1: to the beginning of the next line
      • 2: below
      Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0. * @param $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false). * @param $reseth (boolean) if true reset the last cell height (default true). * @param $align (string) Allows to center or align the text. Possible values are:
      • L : left align
      • C : center
      • R : right align
      • '' : empty string : left for LTR or right for RTL
      * @param $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width. * @see Multicell(), writeHTML() * @public */ public function writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=false, $reseth=true, $align='', $autopadding=true) { return $this->MultiCell($w, $h, $html, $border, $align, $fill, $ln, $x, $y, $reseth, 0, true, $autopadding, 0, 'T', false); } /** * Allows to preserve some HTML formatting (limited support).
      * IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting. * Supported tags are: a, b, blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table, tcpdf, td, th, thead, tr, tt, u, ul * NOTE: all the HTML attributes must be enclosed in double-quote. * @param $html (string) text to display * @param $ln (boolean) if true add a new line after text (default = true) * @param $fill (boolean) Indicates if the background must be painted (true) or transparent (false). * @param $reseth (boolean) if true reset the last cell height (default false). * @param $cell (boolean) if true add the current left (or right for RTL) padding to each Write (default false). * @param $align (string) Allows to center or align the text. Possible values are:
      • L : left align
      • C : center
      • R : right align
      • '' : empty string : left for LTR or right for RTL
      * @public */ public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') { $gvars = $this->getGraphicVars(); // store current values $prev_cell_margin = $this->cell_margin; $prev_cell_padding = $this->cell_padding; $prevPage = $this->page; $prevlMargin = $this->lMargin; $prevrMargin = $this->rMargin; $curfontname = $this->FontFamily; $curfontstyle = $this->FontStyle; $curfontsize = $this->FontSizePt; $curfontascent = $this->getFontAscent($curfontname, $curfontstyle, $curfontsize); $curfontdescent = $this->getFontDescent($curfontname, $curfontstyle, $curfontsize); $curfontstretcing = $this->font_stretching; $curfonttracking = $this->font_spacing; $this->newline = true; $newline = true; $startlinepage = $this->page; $minstartliney = $this->y; $maxbottomliney = 0; $startlinex = $this->x; $startliney = $this->y; $yshift = 0; $loop = 0; $curpos = 0; $this_method_vars = array(); $undo = false; $fontaligned = false; $reverse_dir = false; // true when the text direction is reversed $this->premode = false; if ($this->inxobj) { // we are inside an XObject template $pask = count($this->xobjects[$this->xobjid]['annotations']); } elseif (isset($this->PageAnnots[$this->page])) { $pask = count($this->PageAnnots[$this->page]); } else { $pask = 0; } if ($this->inxobj) { // we are inside an XObject template $startlinepos = strlen($this->xobjects[$this->xobjid]['outdata']); } elseif (!$this->InFooter) { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $startlinepos = $this->footerpos[$this->page]; } else { // we are inside the footer $startlinepos = $this->pagelen[$this->page]; } $lalign = $align; $plalign = $align; if ($this->rtl) { $w = $this->x - $this->lMargin; } else { $w = $this->w - $this->rMargin - $this->x; } $w -= ($this->cell_padding['L'] + $this->cell_padding['R']); if ($cell) { if ($this->rtl) { $this->x -= $this->cell_padding['R']; $this->lMargin += $this->cell_padding['R']; } else { $this->x += $this->cell_padding['L']; $this->rMargin += $this->cell_padding['L']; } } if ($this->customlistindent >= 0) { $this->listindent = $this->customlistindent; } else { $this->listindent = $this->GetStringWidth('000000'); } $this->listindentlevel = 0; // save previous states $prev_cell_height_ratio = $this->cell_height_ratio; $prev_listnum = $this->listnum; $prev_listordered = $this->listordered; $prev_listcount = $this->listcount; $prev_lispacer = $this->lispacer; $this->listnum = 0; $this->listordered = array(); $this->listcount = array(); $this->lispacer = ''; if ((TCPDF_STATIC::empty_string($this->lasth)) OR ($reseth)) { // reset row height $this->resetLastH(); } $dom = $this->getHtmlDomArray($html); $maxel = count($dom); $key = 0; $hidden_node_key = -1; while ($key < $maxel) { if ($dom[$key]['tag']) { if ($dom[$key]['opening']) { if (($hidden_node_key <= 0) AND $dom[$key]['hide']) { // store the node key $hidden_node_key = $key; } } elseif (($hidden_node_key > 0) AND ($dom[$key]['parent'] == $hidden_node_key)) { // we have reached the closing tag of the hidden node $hidden_node_key = 0; } } if ($hidden_node_key >= 0) { // skip this node ++$key; if ($hidden_node_key == 0) { // reset hidden mode $hidden_node_key = -1; } continue; } if ($dom[$key]['tag'] AND isset($dom[$key]['attribute']['pagebreak'])) { // check for pagebreak if (($dom[$key]['attribute']['pagebreak'] == 'true') OR ($dom[$key]['attribute']['pagebreak'] == 'left') OR ($dom[$key]['attribute']['pagebreak'] == 'right')) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); $this->htmlvspace = ($this->PageBreakTrigger + 1); } if ((($dom[$key]['attribute']['pagebreak'] == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0)))) OR (($dom[$key]['attribute']['pagebreak'] == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); $this->htmlvspace = ($this->PageBreakTrigger + 1); } } if ($dom[$key]['tag'] AND $dom[$key]['opening'] AND isset($dom[$key]['attribute']['nobr']) AND ($dom[$key]['attribute']['nobr'] == 'true')) { if (isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) { $dom[$key]['attribute']['nobr'] = false; } else { // store current object $this->startTransaction(); // save this method vars $this_method_vars['html'] = $html; $this_method_vars['ln'] = $ln; $this_method_vars['fill'] = $fill; $this_method_vars['reseth'] = $reseth; $this_method_vars['cell'] = $cell; $this_method_vars['align'] = $align; $this_method_vars['gvars'] = $gvars; $this_method_vars['prevPage'] = $prevPage; $this_method_vars['prev_cell_margin'] = $prev_cell_margin; $this_method_vars['prev_cell_padding'] = $prev_cell_padding; $this_method_vars['prevlMargin'] = $prevlMargin; $this_method_vars['prevrMargin'] = $prevrMargin; $this_method_vars['curfontname'] = $curfontname; $this_method_vars['curfontstyle'] = $curfontstyle; $this_method_vars['curfontsize'] = $curfontsize; $this_method_vars['curfontascent'] = $curfontascent; $this_method_vars['curfontdescent'] = $curfontdescent; $this_method_vars['curfontstretcing'] = $curfontstretcing; $this_method_vars['curfonttracking'] = $curfonttracking; $this_method_vars['minstartliney'] = $minstartliney; $this_method_vars['maxbottomliney'] = $maxbottomliney; $this_method_vars['yshift'] = $yshift; $this_method_vars['startlinepage'] = $startlinepage; $this_method_vars['startlinepos'] = $startlinepos; $this_method_vars['startlinex'] = $startlinex; $this_method_vars['startliney'] = $startliney; $this_method_vars['newline'] = $newline; $this_method_vars['loop'] = $loop; $this_method_vars['curpos'] = $curpos; $this_method_vars['pask'] = $pask; $this_method_vars['lalign'] = $lalign; $this_method_vars['plalign'] = $plalign; $this_method_vars['w'] = $w; $this_method_vars['prev_cell_height_ratio'] = $prev_cell_height_ratio; $this_method_vars['prev_listnum'] = $prev_listnum; $this_method_vars['prev_listordered'] = $prev_listordered; $this_method_vars['prev_listcount'] = $prev_listcount; $this_method_vars['prev_lispacer'] = $prev_lispacer; $this_method_vars['fontaligned'] = $fontaligned; $this_method_vars['key'] = $key; $this_method_vars['dom'] = $dom; } } // print THEAD block if (($dom[$key]['value'] == 'tr') AND isset($dom[$key]['thead']) AND $dom[$key]['thead']) { if (isset($dom[$key]['parent']) AND isset($dom[$dom[$key]['parent']]['thead']) AND !TCPDF_STATIC::empty_string($dom[$dom[$key]['parent']]['thead'])) { $this->inthead = true; // print table header (thead) $this->writeHTML($this->thead, false, false, false, false, ''); // check if we are on a new page or on a new column if (($this->y < $this->start_transaction_y) OR ($this->checkPageBreak($this->lasth, '', false))) { // we are on a new page or on a new column and the total object height is less than the available vertical space. // restore previous object $this->rollbackTransaction(true); // restore previous values foreach ($this_method_vars as $vkey => $vval) { $$vkey = $vval; } // disable table header $tmp_thead = $this->thead; $this->thead = ''; // add a page (or trig AcceptPageBreak() for multicolumn mode) $pre_y = $this->y; if ((!$this->checkPageBreak($this->PageBreakTrigger + 1)) AND ($this->y < $pre_y)) { // fix for multicolumn mode $startliney = $this->y; } $this->start_transaction_page = $this->page; $this->start_transaction_y = $this->y; // restore table header $this->thead = $tmp_thead; // fix table border properties if (isset($dom[$dom[$key]['parent']]['attribute']['cellspacing'])) { $tmp_cellspacing = $this->getHTMLUnitToUnits($dom[$dom[$key]['parent']]['attribute']['cellspacing'], 1, 'px'); } elseif (isset($dom[$dom[$key]['parent']]['border-spacing'])) { $tmp_cellspacing = $dom[$dom[$key]['parent']]['border-spacing']['V']; } else { $tmp_cellspacing = 0; } $dom[$dom[$key]['parent']]['borderposition']['page'] = $this->page; $dom[$dom[$key]['parent']]['borderposition']['column'] = $this->current_column; $dom[$dom[$key]['parent']]['borderposition']['y'] = $this->y + $tmp_cellspacing; $xoffset = ($this->x - $dom[$dom[$key]['parent']]['borderposition']['x']); $dom[$dom[$key]['parent']]['borderposition']['x'] += $xoffset; $dom[$dom[$key]['parent']]['borderposition']['xmax'] += $xoffset; // print table header (thead) $this->writeHTML($this->thead, false, false, false, false, ''); } } // move $key index forward to skip THEAD block while ( ($key < $maxel) AND (!( ($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'tr') AND (!isset($dom[$key]['thead']) OR !$dom[$key]['thead'])) OR ($dom[$key]['tag'] AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == 'table'))) )) { ++$key; } } if ($dom[$key]['tag'] OR ($key == 0)) { if ((($dom[$key]['value'] == 'table') OR ($dom[$key]['value'] == 'tr')) AND (isset($dom[$key]['align']))) { $dom[$key]['align'] = ($this->rtl) ? 'R' : 'L'; } // vertically align image in line if ((!$this->newline) AND ($dom[$key]['value'] == 'img') AND (isset($dom[$key]['height'])) AND ($dom[$key]['height'] > 0)) { // get image height $imgh = $this->getHTMLUnitToUnits($dom[$key]['height'], $this->lasth, 'px'); $autolinebreak = false; if (isset($dom[$key]['width']) AND ($dom[$key]['width'] > 0)) { $imgw = $this->getHTMLUnitToUnits($dom[$key]['width'], 1, 'px', false); if (($imgw <= ($this->w - $this->lMargin - $this->rMargin - $this->cell_padding['L'] - $this->cell_padding['R'])) AND ((($this->rtl) AND (($this->x - $imgw) < ($this->lMargin + $this->cell_padding['L']))) OR ((!$this->rtl) AND (($this->x + $imgw) > ($this->w - $this->rMargin - $this->cell_padding['R']))))) { // add automatic line break $autolinebreak = true; $this->Ln('', $cell); if ((!$dom[($key-1)]['tag']) AND ($dom[($key-1)]['value'] == ' ')) { // go back to evaluate this line break --$key; } } } if (!$autolinebreak) { if ($this->inPageBody()) { $pre_y = $this->y; // check for page break if ((!$this->checkPageBreak($imgh)) AND ($this->y < $pre_y)) { // fix for multicolumn mode $startliney = $this->y; } } if ($this->page > $startlinepage) { // fix line splitted over two pages if (isset($this->footerlen[$startlinepage])) { $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; } // line to be moved one page forward $pagebuff = $this->getPageBuffer($startlinepage); $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos)); $tstart = substr($pagebuff, 0, $startlinepos); $tend = substr($this->getPageBuffer($startlinepage), $curpos); // remove line from previous page $this->setPageBuffer($startlinepage, $tstart.''.$tend); $pagebuff = $this->getPageBuffer($this->page); $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]); $tend = substr($pagebuff, $this->cntmrk[$this->page]); // add line start to current page $yshift = ($minstartliney - $this->y); if ($fontaligned) { $yshift += ($curfontsize / $this->k); } $try = sprintf('1 0 0 1 0 %F cm', ($yshift * $this->k)); $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { $next_pask = count($this->PageAnnots[$this->page]); } else { $next_pask = 0; } if (isset($this->PageAnnots[$startlinepage])) { foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][] = $pac; unset($this->PageAnnots[$startlinepage][$pak]); $npak = count($this->PageAnnots[$this->page]) - 1; $this->PageAnnots[$this->page][$npak]['y'] -= $yshift; } } } $pask = $next_pask; $startlinepos = $this->cntmrk[$this->page]; $startlinepage = $this->page; $startliney = $this->y; $this->newline = false; } $this->y += ((($curfontsize * $this->cell_height_ratio / $this->k) + $curfontascent - $curfontdescent) / 2) - $imgh; $minstartliney = min($this->y, $minstartliney); $maxbottomliney = ($startliney + ($this->FontSize * $this->cell_height_ratio)); } } elseif (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize']) OR isset($dom[$key]['line-height'])) { // account for different font size $pfontname = $curfontname; $pfontstyle = $curfontstyle; $pfontsize = $curfontsize; $fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : $curfontname; $fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : $curfontstyle; $fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : $curfontsize; $fontascent = $this->getFontAscent($fontname, $fontstyle, $fontsize); $fontdescent = $this->getFontDescent($fontname, $fontstyle, $fontsize); if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize) OR ($this->cell_height_ratio != $dom[$key]['line-height']) OR ($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'li')) ) { if (($key < ($maxel - 1)) AND ( ($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'li')) OR ($this->cell_height_ratio != $dom[$key]['line-height']) OR (!$this->newline AND is_numeric($fontsize) AND is_numeric($curfontsize) AND ($fontsize >= 0) AND ($curfontsize >= 0) AND ($fontsize != $curfontsize)) )) { if ($this->page > $startlinepage) { // fix lines splitted over two pages if (isset($this->footerlen[$startlinepage])) { $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; } // line to be moved one page forward $pagebuff = $this->getPageBuffer($startlinepage); $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos)); $tstart = substr($pagebuff, 0, $startlinepos); $tend = substr($this->getPageBuffer($startlinepage), $curpos); // remove line start from previous page $this->setPageBuffer($startlinepage, $tstart.''.$tend); $pagebuff = $this->getPageBuffer($this->page); $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]); $tend = substr($pagebuff, $this->cntmrk[$this->page]); // add line start to current page $yshift = ($minstartliney - $this->y); $try = sprintf('1 0 0 1 0 %F cm', ($yshift * $this->k)); $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { $next_pask = count($this->PageAnnots[$this->page]); } else { $next_pask = 0; } if (isset($this->PageAnnots[$startlinepage])) { foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][] = $pac; unset($this->PageAnnots[$startlinepage][$pak]); $npak = count($this->PageAnnots[$this->page]) - 1; $this->PageAnnots[$this->page][$npak]['y'] -= $yshift; } } } $pask = $next_pask; $startlinepos = $this->cntmrk[$this->page]; $startlinepage = $this->page; $startliney = $this->y; } if (!isset($dom[$key]['line-height'])) { $dom[$key]['line-height'] = $this->cell_height_ratio; } if (!$dom[$key]['block']) { if (!(isset($dom[($key + 1)]) AND $dom[($key + 1)]['tag'] AND (!$dom[($key + 1)]['opening']) AND ($dom[($key + 1)]['value'] != 'li') AND $dom[$key]['tag'] AND (!$dom[$key]['opening']))) { $this->y += (((($curfontsize * $this->cell_height_ratio) - ($fontsize * $dom[$key]['line-height'])) / $this->k) + $curfontascent - $fontascent - $curfontdescent + $fontdescent) / 2; } if (($dom[$key]['value'] != 'sup') AND ($dom[$key]['value'] != 'sub')) { $current_line_align_data = array($key, $minstartliney, $maxbottomliney); if (isset($line_align_data) AND (($line_align_data[0] == ($key - 1)) OR (($line_align_data[0] == ($key - 2)) AND (isset($dom[($key - 1)])) AND (preg_match('/^([\s]+)$/', $dom[($key - 1)]['value']) > 0)))) { $minstartliney = min($this->y, $line_align_data[1]); $maxbottomliney = max(($this->y + (($fontsize * $this->cell_height_ratio) / $this->k)), $line_align_data[2]); } else { $minstartliney = min($this->y, $minstartliney); $maxbottomliney = max(($this->y + (($fontsize * $this->cell_height_ratio) / $this->k)), $maxbottomliney); } $line_align_data = $current_line_align_data; } } $this->cell_height_ratio = $dom[$key]['line-height']; $fontaligned = true; } $this->SetFont($fontname, $fontstyle, $fontsize); // reset row height $this->resetLastH(); $curfontname = $fontname; $curfontstyle = $fontstyle; $curfontsize = $fontsize; $curfontascent = $fontascent; $curfontdescent = $fontdescent; } } // set text rendering mode $textstroke = isset($dom[$key]['stroke']) ? $dom[$key]['stroke'] : $this->textstrokewidth; $textfill = isset($dom[$key]['fill']) ? $dom[$key]['fill'] : (($this->textrendermode % 2) == 0); $textclip = isset($dom[$key]['clip']) ? $dom[$key]['clip'] : ($this->textrendermode > 3); $this->setTextRenderingMode($textstroke, $textfill, $textclip); if (isset($dom[$key]['font-stretch']) AND ($dom[$key]['font-stretch'] !== false)) { $this->setFontStretching($dom[$key]['font-stretch']); } if (isset($dom[$key]['letter-spacing']) AND ($dom[$key]['letter-spacing'] !== false)) { $this->setFontSpacing($dom[$key]['letter-spacing']); } if (($plalign == 'J') AND $dom[$key]['block']) { $plalign = ''; } // get current position on page buffer $curpos = $this->pagelen[$startlinepage]; if (isset($dom[$key]['bgcolor']) AND ($dom[$key]['bgcolor'] !== false)) { $this->SetFillColorArray($dom[$key]['bgcolor']); $wfill = true; } else { $wfill = $fill | false; } if (isset($dom[$key]['fgcolor']) AND ($dom[$key]['fgcolor'] !== false)) { $this->SetTextColorArray($dom[$key]['fgcolor']); } if (isset($dom[$key]['strokecolor']) AND ($dom[$key]['strokecolor'] !== false)) { $this->SetDrawColorArray($dom[$key]['strokecolor']); } if (isset($dom[$key]['align'])) { $lalign = $dom[$key]['align']; } if (TCPDF_STATIC::empty_string($lalign)) { $lalign = $align; } } // align lines if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) { $newline = true; $fontaligned = false; // we are at the beginning of a new line if (isset($startlinex)) { $yshift = ($minstartliney - $startliney); if (($yshift > 0) OR ($this->page > $startlinepage)) { $yshift = 0; } $t_x = 0; // the last line must be shifted to be aligned as requested $linew = abs($this->endlinex - $startlinex); if ($this->inxobj) { // we are inside an XObject template $pstart = substr($this->xobjects[$this->xobjid]['outdata'], 0, $startlinepos); if (isset($opentagpos)) { $midpos = $opentagpos; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->xobjects[$this->xobjid]['outdata'], $midpos); } else { $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos); $pend = ''; } } else { $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = min($opentagpos, $this->footerpos[$startlinepage]); } elseif (isset($opentagpos)) { $midpos = $opentagpos; } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = $this->footerpos[$startlinepage]; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->getPageBuffer($startlinepage), $midpos); } else { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos); $pend = ''; } } if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl)))))) { // calculate shifting amount $tw = $w; if (($plalign == 'J') AND $this->isRTLTextDir() AND ($this->num_columns > 1)) { $tw += $this->cell_padding['R']; } if ($this->lMargin != $prevlMargin) { $tw += ($prevlMargin - $this->lMargin); } if ($this->rMargin != $prevrMargin) { $tw += ($prevrMargin - $this->rMargin); } $one_space_width = $this->GetStringWidth(chr(32)); $no = 0; // number of spaces on a line contained on a single block if ($this->isRTLTextDir()) { // RTL // remove left space if exist $pos1 = TCPDF_STATIC::revstrpos($pmid, '[('); if ($pos1 > 0) { $pos1 = intval($pos1); if ($this->isUnicodeFont()) { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, '[('.chr(0).chr(32))); $spacelen = 2; } else { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, '[('.chr(32))); $spacelen = 1; } if ($pos1 == $pos2) { $pmid = substr($pmid, 0, ($pos1 + 2)).substr($pmid, ($pos1 + 2 + $spacelen)); if (substr($pmid, $pos1, 4) == '[()]') { $linew -= $one_space_width; } elseif ($pos1 == strpos($pmid, '[(')) { $no = 1; } } } } else { // LTR // remove right space if exist $pos1 = TCPDF_STATIC::revstrpos($pmid, ')]'); if ($pos1 > 0) { $pos1 = intval($pos1); if ($this->isUnicodeFont()) { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, chr(0).chr(32).')]')) + 2; $spacelen = 2; } else { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, chr(32).')]')) + 1; $spacelen = 1; } if ($pos1 == $pos2) { $pmid = substr($pmid, 0, ($pos1 - $spacelen)).substr($pmid, $pos1); $linew -= $one_space_width; } } } $mdiff = ($tw - $linew); if ($plalign == 'C') { if ($this->rtl) { $t_x = -($mdiff / 2); } else { $t_x = ($mdiff / 2); } } elseif ($plalign == 'R') { // right alignment on LTR document $t_x = $mdiff; } elseif ($plalign == 'L') { // left alignment on RTL document $t_x = -$mdiff; } elseif (($plalign == 'J') AND ($plalign == $lalign)) { // Justification if ($this->isRTLTextDir()) { // align text on the left $t_x = -$mdiff; } $ns = 0; // number of spaces $pmidtemp = $pmid; // escape special characters $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp); $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp); // search spaces if (preg_match_all('/\[\(([^\)]*)\)\]/x', $pmidtemp, $lnstring, PREG_PATTERN_ORDER)) { $spacestr = $this->getSpaceString(); $maxkk = count($lnstring[1]) - 1; for ($kk=0; $kk <= $maxkk; ++$kk) { // restore special characters $lnstring[1][$kk] = str_replace('#!#OP#!#', '(', $lnstring[1][$kk]); $lnstring[1][$kk] = str_replace('#!#CP#!#', ')', $lnstring[1][$kk]); // store number of spaces on the strings $lnstring[2][$kk] = substr_count($lnstring[1][$kk], $spacestr); // count total spaces on line $ns += $lnstring[2][$kk]; $lnstring[3][$kk] = $ns; } if ($ns == 0) { $ns = 1; } // calculate additional space to add to each existing space $spacewidth = ($mdiff / ($ns - $no)) * $this->k; $spacewidthu = -1000 * ($mdiff + (($ns + $no) * $one_space_width)) / $ns / $this->FontSize; if ($this->font_spacing != 0) { // fixed spacing mode $osw = -1000 * $this->font_spacing / $this->FontSize; $spacewidthu += $osw; } $nsmax = $ns; $ns = 0; reset($lnstring); $offset = 0; $strcount = 0; $prev_epsposbeg = 0; $textpos = 0; if ($this->isRTLTextDir()) { $textpos = $this->wPt; } global $spacew; while (preg_match('/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x', $pmid, $strpiece, PREG_OFFSET_CAPTURE, $offset) == 1) { // check if we are inside a string section '[( ... )]' $stroffset = strpos($pmid, '[(', $offset); if (($stroffset !== false) AND ($stroffset <= $strpiece[2][1])) { // set offset to the end of string section $offset = strpos($pmid, ')]', $stroffset); while (($offset !== false) AND ($pmid[($offset - 1)] == '\\')) { $offset = strpos($pmid, ')]', ($offset + 1)); } if ($offset === false) { $this->Error('HTML Justification: malformed PDF code.'); } continue; } if ($this->isRTLTextDir()) { $spacew = ($spacewidth * ($nsmax - $ns)); } else { $spacew = ($spacewidth * $ns); } $offset = $strpiece[2][1] + strlen($strpiece[2][0]); $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, $offset); $epsposend = strpos($pmid, $this->epsmarker.'Q', $offset) + strlen($this->epsmarker.'Q'); if ((($epsposbeg > 0) AND ($epsposend > 0) AND ($offset > $epsposbeg) AND ($offset < $epsposend)) OR (($epsposbeg === false) AND ($epsposend > 0) AND ($offset < $epsposend))) { // shift EPS images $trx = sprintf('1 0 0 1 %F 0 cm', $spacew); $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, ($prev_epsposbeg - 6)); $pmid_b = substr($pmid, 0, $epsposbeg); $pmid_m = substr($pmid, $epsposbeg, ($epsposend - $epsposbeg)); $pmid_e = substr($pmid, $epsposend); $pmid = $pmid_b."\nq\n".$trx."\n".$pmid_m."\nQ\n".$pmid_e; $offset = $epsposend; continue; } $prev_epsposbeg = $epsposbeg; $currentxpos = 0; // shift blocks of code switch ($strpiece[2][0]) { case 'Td': case 'cm': case 'm': case 'l': { // get current X position preg_match('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches); $currentxpos = $xmatches[1]; $textpos = $currentxpos; if (($strcount <= $maxkk) AND ($strpiece[2][0] == 'Td')) { $ns = $lnstring[3][$strcount]; if ($this->isRTLTextDir()) { $spacew = ($spacewidth * ($nsmax - $ns)); } ++$strcount; } // justify block $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', create_function('$matches', 'global $spacew; $newx = sprintf("%F",(floatval($matches[1]) + $spacew)); return "".$newx." ".$matches[2]." x*#!#*x".$matches[3].$matches[4];'), $pmid, 1); break; } case 're': { // justify block if (!TCPDF_STATIC::empty_string($this->lispacer)) { $this->lispacer = ''; continue; } preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x', $pmid, $xmatches); $currentxpos = $xmatches[1]; global $x_diff, $w_diff; $x_diff = 0; $w_diff = 0; if ($this->isRTLTextDir()) { // RTL if ($currentxpos < $textpos) { $x_diff = ($spacewidth * ($nsmax - $lnstring[3][$strcount])); $w_diff = ($spacewidth * $lnstring[2][$strcount]); } else { if ($strcount > 0) { $x_diff = ($spacewidth * ($nsmax - $lnstring[3][($strcount - 1)])); $w_diff = ($spacewidth * $lnstring[2][($strcount - 1)]); } } } else { // LTR if ($currentxpos > $textpos) { if ($strcount > 0) { $x_diff = ($spacewidth * $lnstring[3][($strcount - 1)]); } $w_diff = ($spacewidth * $lnstring[2][$strcount]); } else { if ($strcount > 1) { $x_diff = ($spacewidth * $lnstring[3][($strcount - 2)]); } if ($strcount > 0) { $w_diff = ($spacewidth * $lnstring[2][($strcount - 1)]); } } } $pmid = preg_replace_callback('/('.$xmatches[1].')[\s]('.$xmatches[2].')[\s]('.$xmatches[3].')[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x', create_function('$matches', 'global $x_diff, $w_diff; $newx = sprintf("%F",(floatval($matches[1]) + $x_diff)); $neww = sprintf("%F",(floatval($matches[3]) + $w_diff)); return "".$newx." ".$matches[2]." ".$neww." ".$matches[4]." x*#!#*x".$matches[5].$matches[6];'), $pmid, 1); break; } case 'c': { // get current X position preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](c)([\s]*)/x', $pmid, $xmatches); $currentxpos = $xmatches[1]; // justify block $pmid = preg_replace_callback('/('.$xmatches[1].')[\s]('.$xmatches[2].')[\s]('.$xmatches[3].')[\s]('.$xmatches[4].')[\s]('.$xmatches[5].')[\s]('.$strpiece[1][0].')[\s](c)([\s]*)/x', create_function('$matches', 'global $spacew; $newx1 = sprintf("%F",(floatval($matches[1]) + $spacew)); $newx2 = sprintf("%F",(floatval($matches[3]) + $spacew)); $newx3 = sprintf("%F",(floatval($matches[5]) + $spacew)); return "".$newx1." ".$matches[2]." ".$newx2." ".$matches[4]." ".$newx3." ".$matches[6]." x*#!#*x".$matches[7].$matches[8];'), $pmid, 1); break; } } // shift the annotations and links $cxpos = ($currentxpos / $this->k); $lmpos = ($this->lMargin + $this->cell_padding['L'] + $this->feps); if ($this->inxobj) { // we are inside an XObject template foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) { if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) { if ($cxpos > $lmpos) { $this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += ($spacew / $this->k); $this->xobjects[$this->xobjid]['annotations'][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k); } else { $this->xobjects[$this->xobjid]['annotations'][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k); } break; } } } elseif (isset($this->PageAnnots[$this->page])) { foreach ($this->PageAnnots[$this->page] as $pak => $pac) { if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) { if ($cxpos > $lmpos) { $this->PageAnnots[$this->page][$pak]['x'] += ($spacew / $this->k); $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k); } else { $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k); } break; } } } } // end of while // remove markers $pmid = str_replace('x*#!#*x', '', $pmid); if ($this->isUnicodeFont()) { // multibyte characters $spacew = $spacewidthu; if ($this->font_stretching != 100) { // word spacing is affected by stretching $spacew /= ($this->font_stretching / 100); } $pmidtemp = $pmid; // escape special characters $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp); $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp); $pmid = preg_replace_callback("/\[\(([^\)]*)\)\]/x", create_function('$matches', 'global $spacew; $matches[1] = str_replace("#!#OP#!#", "(", $matches[1]); $matches[1] = str_replace("#!#CP#!#", ")", $matches[1]); return "[(".str_replace(chr(0).chr(32), ") ".sprintf("%F", $spacew)." (", $matches[1]).")]";'), $pmidtemp); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['outdata'] = $pstart."\n".$pmid."\n".$pend; } else { $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\n".$pend); } $endlinepos = strlen($pstart."\n".$pmid."\n"); } else { // non-unicode (single-byte characters) if ($this->font_stretching != 100) { // word spacing (Tw) is affected by stretching $spacewidth /= ($this->font_stretching / 100); } $rs = sprintf('%F Tw', $spacewidth); $pmid = preg_replace("/\[\(/x", $rs.' [(', $pmid); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['outdata'] = $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend; } else { $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend); } $endlinepos = strlen($pstart."\n".$pmid."\nBT 0 Tw ET\n"); } } } // end of J } // end if $startlinex if (($t_x != 0) OR ($yshift < 0)) { // shift the line $trx = sprintf('1 0 0 1 %F %F cm', ($t_x * $this->k), ($yshift * $this->k)); $pstart .= "\nq\n".$trx."\n".$pmid."\nQ\n"; $endlinepos = strlen($pstart); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['outdata'] = $pstart.$pend; foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) { if ($pak >= $pask) { $this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += $t_x; $this->xobjects[$this->xobjid]['annotations'][$pak]['y'] -= $yshift; } } } else { $this->setPageBuffer($startlinepage, $pstart.$pend); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { foreach ($this->PageAnnots[$this->page] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][$pak]['x'] += $t_x; $this->PageAnnots[$this->page][$pak]['y'] -= $yshift; } } } } $this->y -= $yshift; } } $pbrk = $this->checkPageBreak($this->lasth); $this->newline = false; $startlinex = $this->x; $startliney = $this->y; if ($dom[$dom[$key]['parent']]['value'] == 'sup') { $startliney -= ((0.3 * $this->FontSizePt) / $this->k); } elseif ($dom[$dom[$key]['parent']]['value'] == 'sub') { $startliney -= (($this->FontSizePt / 0.7) / $this->k); } else { $minstartliney = $startliney; $maxbottomliney = ($this->y + (($fontsize * $this->cell_height_ratio) / $this->k)); } $startlinepage = $this->page; if (isset($endlinepos) AND (!$pbrk)) { $startlinepos = $endlinepos; } else { if ($this->inxobj) { // we are inside an XObject template $startlinepos = strlen($this->xobjects[$this->xobjid]['outdata']); } elseif (!$this->InFooter) { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $startlinepos = $this->footerpos[$this->page]; } else { $startlinepos = $this->pagelen[$this->page]; } } unset($endlinepos); $plalign = $lalign; if (isset($this->PageAnnots[$this->page])) { $pask = count($this->PageAnnots[$this->page]); } else { $pask = 0; } if (!($dom[$key]['tag'] AND !$dom[$key]['opening'] AND ($dom[$key]['value'] == 'table') AND (isset($this->emptypagemrk[$this->page])) AND ($this->emptypagemrk[$this->page] == $this->pagelen[$this->page]))) { $this->SetFont($fontname, $fontstyle, $fontsize); if ($wfill) { $this->SetFillColorArray($this->bgcolor); } } } // end newline if (isset($opentagpos)) { unset($opentagpos); } if ($dom[$key]['tag']) { if ($dom[$key]['opening']) { // get text indentation (if any) if (isset($dom[$key]['text-indent']) AND $dom[$key]['block']) { $this->textindent = $dom[$key]['text-indent']; $this->newline = true; } // table if ($dom[$key]['value'] == 'table') { // available page width if ($this->rtl) { $wtmp = $this->x - $this->lMargin; } else { $wtmp = $this->w - $this->rMargin - $this->x; } // get cell spacing if (isset($dom[$key]['attribute']['cellspacing'])) { $clsp = $this->getHTMLUnitToUnits($dom[$key]['attribute']['cellspacing'], 1, 'px'); $cellspacing = array('H' => $clsp, 'V' => $clsp); } elseif (isset($dom[$key]['border-spacing'])) { $cellspacing = $dom[$key]['border-spacing']; } else { $cellspacing = array('H' => 0, 'V' => 0); } // table width if (isset($dom[$key]['width'])) { $table_width = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px'); } else { $table_width = $wtmp; } $table_width -= (2 * $cellspacing['H']); if (!$this->inthead) { $this->y += $cellspacing['V']; } if ($this->rtl) { $cellspacingx = -$cellspacing['H']; } else { $cellspacingx = $cellspacing['H']; } // total table width without cellspaces $table_columns_width = ($table_width - ($cellspacing['H'] * ($dom[$key]['cols'] - 1))); // minimum column width $table_min_column_width = ($table_columns_width / $dom[$key]['cols']); // array of custom column widths $table_colwidths = array_fill(0, $dom[$key]['cols'], $table_min_column_width); } // table row if ($dom[$key]['value'] == 'tr') { // reset column counter $colid = 0; } // table cell if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) { $trid = $dom[$key]['parent']; $table_el = $dom[$trid]['parent']; if (!isset($dom[$table_el]['cols'])) { $dom[$table_el]['cols'] = $dom[$trid]['cols']; } // store border info $tdborder = 0; if (isset($dom[$key]['border']) AND !empty($dom[$key]['border'])) { $tdborder = $dom[$key]['border']; } $colspan = $dom[$key]['attribute']['colspan']; $old_cell_padding = $this->cell_padding; if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) { $crclpd = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'], 1, 'px'); $current_cell_padding = array('L' => $crclpd, 'T' => $crclpd, 'R' => $crclpd, 'B' => $crclpd); } elseif (isset($dom[($dom[$trid]['parent'])]['padding'])) { $current_cell_padding = $dom[($dom[$trid]['parent'])]['padding']; } else { $current_cell_padding = array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0); } $this->cell_padding = $current_cell_padding; if (isset($dom[$key]['height'])) { // minimum cell height $cellh = $this->getHTMLUnitToUnits($dom[$key]['height'], 0, 'px'); } else { $cellh = 0; } if (isset($dom[$key]['content'])) { $cell_content = stripslashes($dom[$key]['content']); } else { $cell_content = ' '; } $tagtype = $dom[$key]['value']; $parentid = $key; while (($key < $maxel) AND (!(($dom[$key]['tag']) AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == $tagtype) AND ($dom[$key]['parent'] == $parentid)))) { // move $key index forward ++$key; } if (!isset($dom[$trid]['startpage'])) { $dom[$trid]['startpage'] = $this->page; } else { $this->setPage($dom[$trid]['startpage']); } if (!isset($dom[$trid]['startcolumn'])) { $dom[$trid]['startcolumn'] = $this->current_column; } elseif ($this->current_column != $dom[$trid]['startcolumn']) { $tmpx = $this->x; $this->selectColumn($dom[$trid]['startcolumn']); $this->x = $tmpx; } if (!isset($dom[$trid]['starty'])) { $dom[$trid]['starty'] = $this->y; } else { $this->y = $dom[$trid]['starty']; } if (!isset($dom[$trid]['startx'])) { $dom[$trid]['startx'] = $this->x; $this->x += $cellspacingx; } else { $this->x += ($cellspacingx / 2); } if (isset($dom[$parentid]['attribute']['rowspan'])) { $rowspan = intval($dom[$parentid]['attribute']['rowspan']); } else { $rowspan = 1; } // skip row-spanned cells started on the previous rows if (isset($dom[$table_el]['rowspans'])) { $rsk = 0; $rskmax = count($dom[$table_el]['rowspans']); while ($rsk < $rskmax) { $trwsp = $dom[$table_el]['rowspans'][$rsk]; $rsstartx = $trwsp['startx']; $rsendx = $trwsp['endx']; // account for margin changes if ($trwsp['startpage'] < $this->page) { if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$trwsp['startpage']]['orm'])) { $dl = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$trwsp['startpage']]['orm']); $rsstartx -= $dl; $rsendx -= $dl; } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$trwsp['startpage']]['olm'])) { $dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$trwsp['startpage']]['olm']); $rsstartx += $dl; $rsendx += $dl; } } if (($trwsp['rowspan'] > 0) AND ($rsstartx > ($this->x - $cellspacing['H'] - $current_cell_padding['L'] - $this->feps)) AND ($rsstartx < ($this->x + $cellspacing['H'] + $current_cell_padding['R'] + $this->feps)) AND (($trwsp['starty'] < ($this->y - $this->feps)) OR ($trwsp['startpage'] < $this->page) OR ($trwsp['startcolumn'] < $this->current_column))) { // set the starting X position of the current cell $this->x = $rsendx + $cellspacingx; // increment column indicator $colid += $trwsp['colspan']; if (($trwsp['rowspan'] == 1) AND (isset($dom[$trid]['endy'])) AND (isset($dom[$trid]['endpage'])) AND (isset($dom[$trid]['endcolumn'])) AND ($trwsp['endpage'] == $dom[$trid]['endpage']) AND ($trwsp['endcolumn'] == $dom[$trid]['endcolumn'])) { // set ending Y position for row $dom[$table_el]['rowspans'][$rsk]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']); $dom[$trid]['endy'] = $dom[$table_el]['rowspans'][$rsk]['endy']; } $rsk = 0; } else { ++$rsk; } } } if (isset($dom[$parentid]['width'])) { // user specified width $cellw = $this->getHTMLUnitToUnits($dom[$parentid]['width'], $table_columns_width, 'px'); $tmpcw = ($cellw / $colspan); for ($i = 0; $i < $colspan; ++$i) { $table_colwidths[($colid + $i)] = $tmpcw; } } else { // inherit column width $cellw = 0; for ($i = 0; $i < $colspan; ++$i) { $cellw += $table_colwidths[($colid + $i)]; } } $cellw += (($colspan - 1) * $cellspacing['H']); // increment column indicator $colid += $colspan; // add rowspan information to table element if ($rowspan > 1) { $trsid = array_push($dom[$table_el]['rowspans'], array('trid' => $trid, 'rowspan' => $rowspan, 'mrowspan' => $rowspan, 'colspan' => $colspan, 'startpage' => $this->page, 'startcolumn' => $this->current_column, 'startx' => $this->x, 'starty' => $this->y)); } $cellid = array_push($dom[$trid]['cellpos'], array('startx' => $this->x)); if ($rowspan > 1) { $dom[$trid]['cellpos'][($cellid - 1)]['rowspanid'] = ($trsid - 1); } // push background colors if (isset($dom[$parentid]['bgcolor']) AND ($dom[$parentid]['bgcolor'] !== false)) { $dom[$trid]['cellpos'][($cellid - 1)]['bgcolor'] = $dom[$parentid]['bgcolor']; } // store border info if (isset($tdborder) AND !empty($tdborder)) { $dom[$trid]['cellpos'][($cellid - 1)]['border'] = $tdborder; } $prevLastH = $this->lasth; // store some info for multicolumn mode if ($this->rtl) { $this->colxshift['x'] = $this->w - $this->x - $this->rMargin; } else { $this->colxshift['x'] = $this->x - $this->lMargin; } $this->colxshift['s'] = $cellspacing; $this->colxshift['p'] = $current_cell_padding; // ****** write the cell content ****** $this->MultiCell($cellw, $cellh, $cell_content, false, $lalign, false, 2, '', '', true, 0, true, true, 0, 'T', false); // restore some values $this->colxshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0)); $this->lasth = $prevLastH; $this->cell_padding = $old_cell_padding; $dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x; // update the end of row position if ($rowspan <= 1) { if (isset($dom[$trid]['endy'])) { if (($this->page == $dom[$trid]['endpage']) AND ($this->current_column == $dom[$trid]['endcolumn'])) { $dom[$trid]['endy'] = max($this->y, $dom[$trid]['endy']); } elseif (($this->page > $dom[$trid]['endpage']) OR ($this->current_column > $dom[$trid]['endcolumn'])) { $dom[$trid]['endy'] = $this->y; } } else { $dom[$trid]['endy'] = $this->y; } if (isset($dom[$trid]['endpage'])) { $dom[$trid]['endpage'] = max($this->page, $dom[$trid]['endpage']); } else { $dom[$trid]['endpage'] = $this->page; } if (isset($dom[$trid]['endcolumn'])) { $dom[$trid]['endcolumn'] = max($this->current_column, $dom[$trid]['endcolumn']); } else { $dom[$trid]['endcolumn'] = $this->current_column; } } else { // account for row-spanned cells $dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x; $dom[$table_el]['rowspans'][($trsid - 1)]['endy'] = $this->y; $dom[$table_el]['rowspans'][($trsid - 1)]['endpage'] = $this->page; $dom[$table_el]['rowspans'][($trsid - 1)]['endcolumn'] = $this->current_column; } if (isset($dom[$table_el]['rowspans'])) { // update endy and endpage on rowspanned cells foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($trwsp['rowspan'] > 0) { if (isset($dom[$trid]['endpage'])) { if (($trwsp['endpage'] == $dom[$trid]['endpage']) AND ($trwsp['endcolumn'] == $dom[$trid]['endcolumn'])) { $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']); } elseif (($trwsp['endpage'] < $dom[$trid]['endpage']) OR ($trwsp['endcolumn'] < $dom[$trid]['endcolumn'])) { $dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy']; $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage']; $dom[$table_el]['rowspans'][$k]['endcolumn'] = $dom[$trid]['endcolumn']; } else { $dom[$trid]['endy'] = $this->pagedim[$dom[$trid]['endpage']]['hk'] - $this->pagedim[$dom[$trid]['endpage']]['bm']; } } } } } $this->x += ($cellspacingx / 2); } else { // opening tag (or self-closing tag) if (!isset($opentagpos)) { if ($this->inxobj) { // we are inside an XObject template $opentagpos = strlen($this->xobjects[$this->xobjid]['outdata']); } elseif (!$this->InFooter) { if (isset($this->footerlen[$this->page])) { $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page]; } else { $this->footerpos[$this->page] = $this->pagelen[$this->page]; } $opentagpos = $this->footerpos[$this->page]; } } $dom = $this->openHTMLTagHandler($dom, $key, $cell); } } else { // closing tag $prev_numpages = $this->numpages; $old_bordermrk = $this->bordermrk[$this->page]; $dom = $this->closeHTMLTagHandler($dom, $key, $cell, $maxbottomliney); if ($this->bordermrk[$this->page] > $old_bordermrk) { $startlinepos += ($this->bordermrk[$this->page] - $old_bordermrk); } if ($prev_numpages > $this->numpages) { $startlinepage = $this->page; } } } elseif (strlen($dom[$key]['value']) > 0) { // print list-item if (!TCPDF_STATIC::empty_string($this->lispacer) AND ($this->lispacer != '^')) { $this->SetFont($pfontname, $pfontstyle, $pfontsize); $this->resetLastH(); $minstartliney = $this->y; $maxbottomliney = ($startliney + ($this->FontSize * $this->cell_height_ratio)); $this->putHtmlListBullet($this->listnum, $this->lispacer, $pfontsize); $this->SetFont($curfontname, $curfontstyle, $curfontsize); $this->resetLastH(); if (is_numeric($pfontsize) AND ($pfontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($pfontsize != $curfontsize)) { $pfontascent = $this->getFontAscent($pfontname, $pfontstyle, $pfontsize); $pfontdescent = $this->getFontDescent($pfontname, $pfontstyle, $pfontsize); $this->y += ((($pfontsize - $curfontsize) * $this->cell_height_ratio / $this->k) + $pfontascent - $curfontascent - $pfontdescent + $curfontdescent) / 2; $minstartliney = min($this->y, $minstartliney); $maxbottomliney = max(($this->y + (($pfontsize * $this->cell_height_ratio) / $this->k)), $maxbottomliney); } } // text $this->htmlvspace = 0; if ((!$this->premode) AND $this->isRTLTextDir()) { // reverse spaces order $lsp = ''; // left spaces $rsp = ''; // right spaces if (preg_match('/^('.$this->re_space['p'].'+)/'.$this->re_space['m'], $dom[$key]['value'], $matches)) { $lsp = $matches[1]; } if (preg_match('/('.$this->re_space['p'].'+)$/'.$this->re_space['m'], $dom[$key]['value'], $matches)) { $rsp = $matches[1]; } $dom[$key]['value'] = $rsp.$this->stringTrim($dom[$key]['value']).$lsp; } if ($newline) { if (!$this->premode) { $prelen = strlen($dom[$key]['value']); if ($this->isRTLTextDir()) { // right trim except non-breaking space $dom[$key]['value'] = $this->stringRightTrim($dom[$key]['value']); } else { // left trim except non-breaking space $dom[$key]['value'] = $this->stringLeftTrim($dom[$key]['value']); } $postlen = strlen($dom[$key]['value']); if (($postlen == 0) AND ($prelen > 0)) { $dom[$key]['trimmed_space'] = true; } } $newline = false; $firstblock = true; } else { $firstblock = false; // replace empty multiple spaces string with a single space $dom[$key]['value'] = preg_replace('/^'.$this->re_space['p'].'+$/'.$this->re_space['m'], chr(32), $dom[$key]['value']); } $strrest = ''; if ($this->rtl) { $this->x -= $this->textindent; } else { $this->x += $this->textindent; } if (!isset($dom[$key]['trimmed_space']) OR !$dom[$key]['trimmed_space']) { $strlinelen = $this->GetStringWidth($dom[$key]['value']); if (!empty($this->HREF) AND (isset($this->HREF['url']))) { // HTML Link $hrefcolor = ''; if (isset($dom[($dom[$key]['parent'])]['fgcolor']) AND ($dom[($dom[$key]['parent'])]['fgcolor'] !== false)) { $hrefcolor = $dom[($dom[$key]['parent'])]['fgcolor']; } $hrefstyle = -1; if (isset($dom[($dom[$key]['parent'])]['fontstyle']) AND ($dom[($dom[$key]['parent'])]['fontstyle'] !== false)) { $hrefstyle = $dom[($dom[$key]['parent'])]['fontstyle']; } $strrest = $this->addHtmlLink($this->HREF['url'], $dom[$key]['value'], $wfill, true, $hrefcolor, $hrefstyle, true); } else { $wadj = 0; // space to leave for block continuity if ($this->rtl) { $cwa = ($this->x - $this->lMargin); } else { $cwa = ($this->w - $this->rMargin - $this->x); } if (($strlinelen < $cwa) AND (isset($dom[($key + 1)])) AND ($dom[($key + 1)]['tag']) AND (!$dom[($key + 1)]['block'])) { // check the next text blocks for continuity $nkey = ($key + 1); $write_block = true; $same_textdir = true; $tmp_fontname = $this->FontFamily; $tmp_fontstyle = $this->FontStyle; $tmp_fontsize = $this->FontSizePt; while ($write_block AND isset($dom[$nkey])) { if ($dom[$nkey]['tag']) { if ($dom[$nkey]['block']) { // end of block $write_block = false; } $tmp_fontname = isset($dom[$nkey]['fontname']) ? $dom[$nkey]['fontname'] : $this->FontFamily; $tmp_fontstyle = isset($dom[$nkey]['fontstyle']) ? $dom[$nkey]['fontstyle'] : $this->FontStyle; $tmp_fontsize = isset($dom[$nkey]['fontsize']) ? $dom[$nkey]['fontsize'] : $this->FontSizePt; $same_textdir = ($dom[$nkey]['dir'] == $dom[$key]['dir']); } else { $nextstr = preg_split('/'.$this->re_space['p'].'+/'.$this->re_space['m'], $dom[$nkey]['value']); if (isset($nextstr[0]) AND $same_textdir) { $wadj += $this->GetStringWidth($nextstr[0], $tmp_fontname, $tmp_fontstyle, $tmp_fontsize); if (isset($nextstr[1])) { $write_block = false; } } } ++$nkey; } } if (($wadj > 0) AND (($strlinelen + $wadj) >= $cwa)) { $wadj = 0; $nextstr = preg_split('/'.$this->re_space['p'].'/'.$this->re_space['m'], $dom[$key]['value']); $numblks = count($nextstr); if ($numblks > 1) { // try to split on blank spaces $wadj = ($cwa - $strlinelen + $this->GetStringWidth($nextstr[($numblks - 1)])); } else { // set the entire block on new line $wadj = $this->GetStringWidth($nextstr[0]); } } // check for reversed text direction if (($wadj > 0) AND (($this->rtl AND ($this->tmprtl === 'L')) OR (!$this->rtl AND ($this->tmprtl === 'R')))) { // LTR text on RTL direction or RTL text on LTR direction $reverse_dir = true; $this->rtl = !$this->rtl; $revshift = ($strlinelen + $wadj + 0.000001); // add little quantity for rounding problems if ($this->rtl) { $this->x += $revshift; } else { $this->x -= $revshift; } $xws = $this->x; } // ****** write only until the end of the line and get the rest ****** $strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, '', false, 0, true, $firstblock, 0, $wadj); // restore default direction if ($reverse_dir AND ($wadj == 0)) { $this->x = $xws; $this->rtl = !$this->rtl; $reverse_dir = false; } } } $this->textindent = 0; if (strlen($strrest) > 0) { // store the remaining string on the previous $key position $this->newline = true; if ($strrest == $dom[$key]['value']) { // used to avoid infinite loop ++$loop; } else { $loop = 0; } $dom[$key]['value'] = $strrest; if ($cell) { if ($this->rtl) { $this->x -= $this->cell_padding['R']; } else { $this->x += $this->cell_padding['L']; } } if ($loop < 3) { --$key; } } else { $loop = 0; // add the positive font spacing of the last character (if any) if ($this->font_spacing > 0) { if ($this->rtl) { $this->x -= $this->font_spacing; } else { $this->x += $this->font_spacing; } } } } ++$key; if (isset($dom[$key]['tag']) AND $dom[$key]['tag'] AND (!isset($dom[$key]['opening']) OR !$dom[$key]['opening']) AND isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) { // check if we are on a new page or on a new column if ((!$undo) AND (($this->y < $this->start_transaction_y) OR (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['endy'] < $this->start_transaction_y)))) { // we are on a new page or on a new column and the total object height is less than the available vertical space. // restore previous object $this->rollbackTransaction(true); // restore previous values foreach ($this_method_vars as $vkey => $vval) { $$vkey = $vval; } // add a page (or trig AcceptPageBreak() for multicolumn mode) $pre_y = $this->y; if ((!$this->checkPageBreak($this->PageBreakTrigger + 1)) AND ($this->y < $pre_y)) { $startliney = $this->y; } $undo = true; // avoid infinite loop } else { $undo = false; } } } // end for each $key // align the last line if (isset($startlinex)) { $yshift = ($minstartliney - $startliney); if (($yshift > 0) OR ($this->page > $startlinepage)) { $yshift = 0; } $t_x = 0; // the last line must be shifted to be aligned as requested $linew = abs($this->endlinex - $startlinex); if ($this->inxobj) { // we are inside an XObject template $pstart = substr($this->xobjects[$this->xobjid]['outdata'], 0, $startlinepos); if (isset($opentagpos)) { $midpos = $opentagpos; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->xobjects[$this->xobjid]['outdata'], $midpos); } else { $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos); $pend = ''; } } else { $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos); if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = min($opentagpos, $this->footerpos[$startlinepage]); } elseif (isset($opentagpos)) { $midpos = $opentagpos; } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) { $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage]; $midpos = $this->footerpos[$startlinepage]; } else { $midpos = 0; } if ($midpos > 0) { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos)); $pend = substr($this->getPageBuffer($startlinepage), $midpos); } else { $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos); $pend = ''; } } if ((isset($plalign) AND ((($plalign == 'C') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl)))))) { // calculate shifting amount $tw = $w; if ($this->lMargin != $prevlMargin) { $tw += ($prevlMargin - $this->lMargin); } if ($this->rMargin != $prevrMargin) { $tw += ($prevrMargin - $this->rMargin); } $one_space_width = $this->GetStringWidth(chr(32)); $no = 0; // number of spaces on a line contained on a single block if ($this->isRTLTextDir()) { // RTL // remove left space if exist $pos1 = TCPDF_STATIC::revstrpos($pmid, '[('); if ($pos1 > 0) { $pos1 = intval($pos1); if ($this->isUnicodeFont()) { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, '[('.chr(0).chr(32))); $spacelen = 2; } else { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, '[('.chr(32))); $spacelen = 1; } if ($pos1 == $pos2) { $pmid = substr($pmid, 0, ($pos1 + 2)).substr($pmid, ($pos1 + 2 + $spacelen)); if (substr($pmid, $pos1, 4) == '[()]') { $linew -= $one_space_width; } elseif ($pos1 == strpos($pmid, '[(')) { $no = 1; } } } } else { // LTR // remove right space if exist $pos1 = TCPDF_STATIC::revstrpos($pmid, ')]'); if ($pos1 > 0) { $pos1 = intval($pos1); if ($this->isUnicodeFont()) { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, chr(0).chr(32).')]')) + 2; $spacelen = 2; } else { $pos2 = intval(TCPDF_STATIC::revstrpos($pmid, chr(32).')]')) + 1; $spacelen = 1; } if ($pos1 == $pos2) { $pmid = substr($pmid, 0, ($pos1 - $spacelen)).substr($pmid, $pos1); $linew -= $one_space_width; } } } $mdiff = ($tw - $linew); if ($plalign == 'C') { if ($this->rtl) { $t_x = -($mdiff / 2); } else { $t_x = ($mdiff / 2); } } elseif ($plalign == 'R') { // right alignment on LTR document $t_x = $mdiff; } elseif ($plalign == 'L') { // left alignment on RTL document $t_x = -$mdiff; } } // end if startlinex if (($t_x != 0) OR ($yshift < 0)) { // shift the line $trx = sprintf('1 0 0 1 %F %F cm', ($t_x * $this->k), ($yshift * $this->k)); $pstart .= "\nq\n".$trx."\n".$pmid."\nQ\n"; $endlinepos = strlen($pstart); if ($this->inxobj) { // we are inside an XObject template $this->xobjects[$this->xobjid]['outdata'] = $pstart.$pend; foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) { if ($pak >= $pask) { $this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += $t_x; $this->xobjects[$this->xobjid]['annotations'][$pak]['y'] -= $yshift; } } } else { $this->setPageBuffer($startlinepage, $pstart.$pend); // shift the annotations and links if (isset($this->PageAnnots[$this->page])) { foreach ($this->PageAnnots[$this->page] as $pak => $pac) { if ($pak >= $pask) { $this->PageAnnots[$this->page][$pak]['x'] += $t_x; $this->PageAnnots[$this->page][$pak]['y'] -= $yshift; } } } } $this->y -= $yshift; $yshift = 0; } } // restore previous values $this->setGraphicVars($gvars); if ($this->num_columns > 1) { $this->selectColumn(); } elseif ($this->page > $prevPage) { $this->lMargin = $this->pagedim[$this->page]['olm']; $this->rMargin = $this->pagedim[$this->page]['orm']; } // restore previous list state $this->cell_height_ratio = $prev_cell_height_ratio; $this->listnum = $prev_listnum; $this->listordered = $prev_listordered; $this->listcount = $prev_listcount; $this->lispacer = $prev_lispacer; if ($ln AND (!($cell AND ($dom[$key-1]['value'] == 'table')))) { $this->Ln($this->lasth); if ($this->y < $maxbottomliney) { $this->y = $maxbottomliney; } } unset($dom); } /** * Process opening tags. * @param $dom (array) html dom array * @param $key (int) current element id * @param $cell (boolean) if true add the default left (or right if RTL) padding to each new line (default false). * @return $dom array * @protected */ protected function openHTMLTagHandler($dom, $key, $cell) { $tag = $dom[$key]; $parent = $dom[($dom[$key]['parent'])]; $firsttag = ($key == 1); // check for text direction attribute if (isset($tag['dir'])) { $this->setTempRTL($tag['dir']); } else { $this->tmprtl = false; } if ($tag['block']) { $hbz = 0; // distance from y to line bottom $hb = 0; // vertical space between block tags // calculate vertical space for block tags if (isset($this->tagvspaces[$tag['value']][0]['h']) AND ($this->tagvspaces[$tag['value']][0]['h'] >= 0)) { $cur_h = $this->tagvspaces[$tag['value']][0]['h']; } elseif (isset($tag['fontsize'])) { $cur_h = ($tag['fontsize'] / $this->k) * $this->cell_height_ratio; } else { $cur_h = $this->FontSize * $this->cell_height_ratio; } if (isset($this->tagvspaces[$tag['value']][0]['n'])) { $n = $this->tagvspaces[$tag['value']][0]['n']; } elseif (preg_match('/[h][0-9]/', $tag['value']) > 0) { $n = 0.6; } else { $n = 1; } if ((!isset($this->tagvspaces[$tag['value']])) AND (in_array($tag['value'], array('div', 'dt', 'dd', 'li', 'br')))) { $hb = 0; } else { $hb = ($n * $cur_h); } if (($this->htmlvspace <= 0) AND ($n > 0)) { if (isset($parent['fontsize'])) { $hbz = (($parent['fontsize'] / $this->k) * $this->cell_height_ratio); } else { $hbz = $this->FontSize * $this->cell_height_ratio; } } if (isset($dom[($key - 1)]) AND ($dom[($key - 1)]['value'] == 'table')) { // fix vertical space after table $hbz = 0; } } // Opening tag switch($tag['value']) { case 'table': { $cp = 0; $cs = 0; $dom[$key]['rowspans'] = array(); if (!isset($dom[$key]['attribute']['nested']) OR ($dom[$key]['attribute']['nested'] != 'true')) { $this->htmlvspace = 0; // set table header if (!TCPDF_STATIC::empty_string($dom[$key]['thead'])) { // set table header $this->thead = $dom[$key]['thead']; if (!isset($this->theadMargins) OR (empty($this->theadMargins))) { $this->theadMargins = array(); $this->theadMargins['cell_padding'] = $this->cell_padding; $this->theadMargins['lmargin'] = $this->lMargin; $this->theadMargins['rmargin'] = $this->rMargin; $this->theadMargins['page'] = $this->page; $this->theadMargins['cell'] = $cell; } } } // store current margins and page $dom[$key]['old_cell_padding'] = $this->cell_padding; if (isset($tag['attribute']['cellpadding'])) { $pad = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px'); $this->SetCellPadding($pad); } elseif (isset($tag['padding'])) { $this->cell_padding = $tag['padding']; } if (isset($tag['attribute']['cellspacing'])) { $cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px'); } elseif (isset($tag['border-spacing'])) { $cs = $tag['border-spacing']['V']; } $prev_y = $this->y; if ($this->checkPageBreak(((2 * $cp) + (2 * $cs) + $this->lasth), '', false) OR ($this->y < $prev_y)) { $this->inthead = true; // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); } break; } case 'tr': { // array of columns positions $dom[$key]['cellpos'] = array(); break; } case 'hr': { if ((isset($tag['height'])) AND ($tag['height'] != '')) { $hrHeight = $this->getHTMLUnitToUnits($tag['height'], 1, 'px'); } else { $hrHeight = $this->GetLineWidth(); } $this->addHTMLVertSpace($hbz, ($hrHeight / 2), $cell, $firsttag); $x = $this->GetX(); $y = $this->GetY(); $wtmp = $this->w - $this->lMargin - $this->rMargin; if ($cell) { $wtmp -= ($this->cell_padding['L'] + $this->cell_padding['R']); } if ((isset($tag['width'])) AND ($tag['width'] != '')) { $hrWidth = $this->getHTMLUnitToUnits($tag['width'], $wtmp, 'px'); } else { $hrWidth = $wtmp; } $prevlinewidth = $this->GetLineWidth(); $this->SetLineWidth($hrHeight); $this->Line($x, $y, $x + $hrWidth, $y); $this->SetLineWidth($prevlinewidth); $this->addHTMLVertSpace(($hrHeight / 2), 0, $cell, !isset($dom[($key + 1)])); break; } case 'a': { if (array_key_exists('href', $tag['attribute'])) { $this->HREF['url'] = $tag['attribute']['href']; } break; } case 'img': { if (isset($tag['attribute']['src'])) { if ($tag['attribute']['src']{0} === '@') { // data stream $tag['attribute']['src'] = '@'.base64_decode(substr($tag['attribute']['src'], 1)); $type = ''; } else { // check for images without protocol if (preg_match('%^/{2}%', $tag['attribute']['src'])) { $tag['attribute']['src'] = 'http:'.$tag['attribute']['src']; } // replace relative path with real server path if (($tag['attribute']['src'][0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { $findroot = strpos($tag['attribute']['src'], $_SERVER['DOCUMENT_ROOT']); if (($findroot === false) OR ($findroot > 1)) { if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') { $tag['attribute']['src'] = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$tag['attribute']['src']; } else { $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src']; } } } $tag['attribute']['src'] = htmlspecialchars_decode(urldecode($tag['attribute']['src'])); $type = TCPDF_IMAGES::getImageFileType($tag['attribute']['src']); $testscrtype = @parse_url($tag['attribute']['src']); if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) { // convert URL to server path $tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']); } } if (!isset($tag['width'])) { $tag['width'] = 0; } if (!isset($tag['height'])) { $tag['height'] = 0; } //if (!isset($tag['attribute']['align'])) { // the only alignment supported is "bottom" // further development is required for other modes. $tag['attribute']['align'] = 'bottom'; //} switch($tag['attribute']['align']) { case 'top': { $align = 'T'; break; } case 'middle': { $align = 'M'; break; } case 'bottom': { $align = 'B'; break; } default: { $align = 'B'; break; } } $prevy = $this->y; $xpos = $this->x; $imglink = ''; if (isset($this->HREF['url']) AND !TCPDF_STATIC::empty_string($this->HREF['url'])) { $imglink = $this->HREF['url']; if ($imglink{0} == '#') { // convert url to internal link $lnkdata = explode(',', $imglink); if (isset($lnkdata[0])) { $page = intval(substr($lnkdata[0], 1)); if (empty($page) OR ($page <= 0)) { $page = $this->page; } if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) { $lnky = floatval($lnkdata[1]); } else { $lnky = 0; } $imglink = $this->AddLink(); $this->SetLink($imglink, $lnky, $page); } } } $border = 0; if (isset($tag['border']) AND !empty($tag['border'])) { // currently only support 1 (frame) or a combination of 'LTRB' $border = $tag['border']; } $iw = ''; if (isset($tag['width'])) { $iw = $this->getHTMLUnitToUnits($tag['width'], 1, 'px', false); } $ih = ''; if (isset($tag['height'])) { $ih = $this->getHTMLUnitToUnits($tag['height'], 1, 'px', false); } if (($type == 'eps') OR ($type == 'ai')) { $this->ImageEps($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, true, $align, '', $border, true); } elseif ($type == 'svg') { $this->ImageSVG($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, $align, '', $border, true); } else { $this->Image($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border, false, false, true); } switch($align) { case 'T': { $this->y = $prevy; break; } case 'M': { $this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ; break; } case 'B': { $this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k); break; } } } break; } case 'dl': { ++$this->listnum; if ($this->listnum == 1) { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); } else { $this->addHTMLVertSpace(0, 0, $cell, $firsttag); } break; } case 'dt': { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } case 'dd': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } ++$this->listindentlevel; $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } case 'ul': case 'ol': { ++$this->listnum; if ($tag['value'] == 'ol') { $this->listordered[$this->listnum] = true; } else { $this->listordered[$this->listnum] = false; } if (isset($tag['attribute']['start'])) { $this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1; } else { $this->listcount[$this->listnum] = 0; } if ($this->rtl) { $this->rMargin += $this->listindent; $this->x -= $this->listindent; } else { $this->lMargin += $this->listindent; $this->x += $this->listindent; } ++$this->listindentlevel; if ($this->listnum == 1) { if ($key > 1) { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); } } else { $this->addHTMLVertSpace(0, 0, $cell, $firsttag); } break; } case 'li': { if ($key > 2) { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); } if ($this->listordered[$this->listnum]) { // ordered item if (isset($parent['attribute']['type']) AND !TCPDF_STATIC::empty_string($parent['attribute']['type'])) { $this->lispacer = $parent['attribute']['type']; } elseif (isset($parent['listtype']) AND !TCPDF_STATIC::empty_string($parent['listtype'])) { $this->lispacer = $parent['listtype']; } elseif (isset($this->lisymbol) AND !TCPDF_STATIC::empty_string($this->lisymbol)) { $this->lispacer = $this->lisymbol; } else { $this->lispacer = '#'; } ++$this->listcount[$this->listnum]; if (isset($tag['attribute']['value'])) { $this->listcount[$this->listnum] = intval($tag['attribute']['value']); } } else { // unordered item if (isset($parent['attribute']['type']) AND !TCPDF_STATIC::empty_string($parent['attribute']['type'])) { $this->lispacer = $parent['attribute']['type']; } elseif (isset($parent['listtype']) AND !TCPDF_STATIC::empty_string($parent['listtype'])) { $this->lispacer = $parent['listtype']; } elseif (isset($this->lisymbol) AND !TCPDF_STATIC::empty_string($this->lisymbol)) { $this->lispacer = $this->lisymbol; } else { $this->lispacer = '!'; } } break; } case 'blockquote': { if ($this->rtl) { $this->rMargin += $this->listindent; } else { $this->lMargin += $this->listindent; } ++$this->listindentlevel; $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } case 'br': { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } case 'div': { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } case 'p': { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } case 'pre': { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); $this->premode = true; break; } case 'sup': { $this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k)); break; } case 'sub': { $this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k)); break; } case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': { $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag); break; } // Form fields (since 4.8.000 - 2009-09-07) case 'form': { if (isset($tag['attribute']['action'])) { $this->form_action = $tag['attribute']['action']; } else { $this->form_action = K_PATH_URL.$_SERVER['SCRIPT_NAME']; } if (isset($tag['attribute']['enctype'])) { $this->form_enctype = $tag['attribute']['enctype']; } else { $this->form_enctype = 'application/x-www-form-urlencoded'; } if (isset($tag['attribute']['method'])) { $this->form_mode = $tag['attribute']['method']; } else { $this->form_mode = 'post'; } break; } case 'input': { if (isset($tag['attribute']['name']) AND !TCPDF_STATIC::empty_string($tag['attribute']['name'])) { $name = $tag['attribute']['name']; } else { break; } $prop = array(); $opt = array(); if (isset($tag['attribute']['readonly']) AND !TCPDF_STATIC::empty_string($tag['attribute']['readonly'])) { $prop['readonly'] = true; } if (isset($tag['attribute']['value']) AND !TCPDF_STATIC::empty_string($tag['attribute']['value'])) { $value = $tag['attribute']['value']; } if (isset($tag['attribute']['maxlength']) AND !TCPDF_STATIC::empty_string($tag['attribute']['maxlength'])) { $opt['maxlen'] = intval($tag['attribute']['maxlength']); } $h = $this->FontSize * $this->cell_height_ratio; if (isset($tag['attribute']['size']) AND !TCPDF_STATIC::empty_string($tag['attribute']['size'])) { $w = intval($tag['attribute']['size']) * $this->GetStringWidth(chr(32)) * 2; } else { $w = $h; } if (isset($tag['attribute']['checked']) AND (($tag['attribute']['checked'] == 'checked') OR ($tag['attribute']['checked'] == 'true'))) { $checked = true; } else { $checked = false; } if (isset($tag['align'])) { switch ($tag['align']) { case 'C': { $opt['q'] = 1; break; } case 'R': { $opt['q'] = 2; break; } case 'L': default: { break; } } } switch ($tag['attribute']['type']) { case 'text': { if (isset($value)) { $opt['v'] = $value; } $this->TextField($name, $w, $h, $prop, $opt, '', '', false); break; } case 'password': { if (isset($value)) { $opt['v'] = $value; } $prop['password'] = 'true'; $this->TextField($name, $w, $h, $prop, $opt, '', '', false); break; } case 'checkbox': { if (!isset($value)) { break; } $this->CheckBox($name, $w, $checked, $prop, $opt, $value, '', '', false); break; } case 'radio': { if (!isset($value)) { break; } $this->RadioButton($name, $w, $prop, $opt, $value, $checked, '', '', false); break; } case 'submit': { if (!isset($value)) { $value = 'submit'; } $w = $this->GetStringWidth($value) * 1.5; $h *= 1.6; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); $action = array(); $action['S'] = 'SubmitForm'; $action['F'] = $this->form_action; if ($this->form_enctype != 'FDF') { $action['Flags'] = array('ExportFormat'); } if ($this->form_mode == 'get') { $action['Flags'] = array('GetMethod'); } $this->Button($name, $w, $h, $value, $action, $prop, $opt, '', '', false); break; } case 'reset': { if (!isset($value)) { $value = 'reset'; } $w = $this->GetStringWidth($value) * 1.5; $h *= 1.6; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); $this->Button($name, $w, $h, $value, array('S'=>'ResetForm'), $prop, $opt, '', '', false); break; } case 'file': { $prop['fileSelect'] = 'true'; $this->TextField($name, $w, $h, $prop, $opt, '', '', false); if (!isset($value)) { $value = '*'; } $w = $this->GetStringWidth($value) * 2; $h *= 1.2; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); $jsaction = 'var f=this.getField(\''.$name.'\'); f.browseForFileToSubmit();'; $this->Button('FB_'.$name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false); break; } case 'hidden': { if (isset($value)) { $opt['v'] = $value; } $opt['f'] = array('invisible', 'hidden'); $this->TextField($name, 0, 0, $prop, $opt, '', '', false); break; } case 'image': { // THIS TYPE MUST BE FIXED if (isset($tag['attribute']['src']) AND !TCPDF_STATIC::empty_string($tag['attribute']['src'])) { $img = $tag['attribute']['src']; } else { break; } $value = 'img'; //$opt['mk'] = array('i'=>$img, 'tp'=>1, 'if'=>array('sw'=>'A', 's'=>'A', 'fb'=>false)); if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) { $jsaction = $tag['attribute']['onclick']; } else { $jsaction = ''; } $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false); break; } case 'button': { if (!isset($value)) { $value = ' '; } $w = $this->GetStringWidth($value) * 1.5; $h *= 1.6; $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255)); if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) { $jsaction = $tag['attribute']['onclick']; } else { $jsaction = ''; } $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false); break; } } break; } case 'textarea': { $prop = array(); $opt = array(); if (isset($tag['attribute']['readonly']) AND !TCPDF_STATIC::empty_string($tag['attribute']['readonly'])) { $prop['readonly'] = true; } if (isset($tag['attribute']['name']) AND !TCPDF_STATIC::empty_string($tag['attribute']['name'])) { $name = $tag['attribute']['name']; } else { break; } if (isset($tag['attribute']['value']) AND !TCPDF_STATIC::empty_string($tag['attribute']['value'])) { $opt['v'] = $tag['attribute']['value']; } if (isset($tag['attribute']['cols']) AND !TCPDF_STATIC::empty_string($tag['attribute']['cols'])) { $w = intval($tag['attribute']['cols']) * $this->GetStringWidth(chr(32)) * 2; } else { $w = 40; } if (isset($tag['attribute']['rows']) AND !TCPDF_STATIC::empty_string($tag['attribute']['rows'])) { $h = intval($tag['attribute']['rows']) * $this->FontSize * $this->cell_height_ratio; } else { $h = 10; } $prop['multiline'] = 'true'; $this->TextField($name, $w, $h, $prop, $opt, '', '', false); break; } case 'select': { $h = $this->FontSize * $this->cell_height_ratio; if (isset($tag['attribute']['size']) AND !TCPDF_STATIC::empty_string($tag['attribute']['size'])) { $h *= ($tag['attribute']['size'] + 1); } $prop = array(); $opt = array(); if (isset($tag['attribute']['name']) AND !TCPDF_STATIC::empty_string($tag['attribute']['name'])) { $name = $tag['attribute']['name']; } else { break; } $w = 0; if (isset($tag['attribute']['opt']) AND !TCPDF_STATIC::empty_string($tag['attribute']['opt'])) { $options = explode('#!NwL!#', $tag['attribute']['opt']); $values = array(); foreach ($options as $val) { if (strpos($val, '#!TaB!#') !== false) { $opts = explode('#!TaB!#', $val); $values[] = $opts; $w = max($w, $this->GetStringWidth($opts[1])); } else { $values[] = $val; $w = max($w, $this->GetStringWidth($val)); } } } else { break; } $w *= 2; if (isset($tag['attribute']['multiple']) AND ($tag['attribute']['multiple']='multiple')) { $prop['multipleSelection'] = 'true'; $this->ListBox($name, $w, $h, $values, $prop, $opt, '', '', false); } else { $this->ComboBox($name, $w, $h, $values, $prop, $opt, '', '', false); } break; } case 'tcpdf': { if (defined('K_TCPDF_CALLS_IN_HTML') AND (K_TCPDF_CALLS_IN_HTML === true)) { // Special tag used to call TCPDF methods if (isset($tag['attribute']['method'])) { $tcpdf_method = $tag['attribute']['method']; if (method_exists($this, $tcpdf_method)) { if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) { $params = unserialize(urldecode($tag['attribute']['params'])); call_user_func_array(array($this, $tcpdf_method), $params); } else { $this->$tcpdf_method(); } $this->newline = true; } } } break; } default: { break; } } // define tags that support borders and background colors $bordertags = array('blockquote','br','dd','dl','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','pre','ul','tcpdf','table'); if (in_array($tag['value'], $bordertags)) { // set border $dom[$key]['borderposition'] = $this->getBorderStartPosition(); } if ($dom[$key]['self'] AND isset($dom[$key]['attribute']['pagebreakafter'])) { $pba = $dom[$key]['attribute']['pagebreakafter']; // check for pagebreak if (($pba == 'true') OR ($pba == 'left') OR ($pba == 'right')) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); } if ((($pba == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0)))) OR (($pba == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); } } return $dom; } /** * Process closing tags. * @param $dom (array) html dom array * @param $key (int) current element id * @param $cell (boolean) if true add the default left (or right if RTL) padding to each new line (default false). * @param $maxbottomliney (int) maximum y value of current line * @return $dom array * @protected */ protected function closeHTMLTagHandler($dom, $key, $cell, $maxbottomliney=0) { $tag = $dom[$key]; $parent = $dom[($dom[$key]['parent'])]; $lasttag = ((!isset($dom[($key + 1)])) OR ((!isset($dom[($key + 2)])) AND ($dom[($key + 1)]['value'] == 'marker'))); $in_table_head = false; // maximum x position (used to draw borders) if ($this->rtl) { $xmax = $this->w; } else { $xmax = 0; } if ($tag['block']) { $hbz = 0; // distance from y to line bottom $hb = 0; // vertical space between block tags // calculate vertical space for block tags if (isset($this->tagvspaces[$tag['value']][1]['h']) AND ($this->tagvspaces[$tag['value']][1]['h'] >= 0)) { $pre_h = $this->tagvspaces[$tag['value']][1]['h']; } elseif (isset($parent['fontsize'])) { $pre_h = (($parent['fontsize'] / $this->k) * $this->cell_height_ratio); } else { $pre_h = $this->FontSize * $this->cell_height_ratio; } if (isset($this->tagvspaces[$tag['value']][1]['n'])) { $n = $this->tagvspaces[$tag['value']][1]['n']; } elseif (preg_match('/[h][0-9]/', $tag['value']) > 0) { $n = 0.6; } else { $n = 1; } if ((!isset($this->tagvspaces[$tag['value']])) AND ($tag['value'] == 'div')) { $hb = 0; } else { $hb = ($n * $pre_h); } if ($maxbottomliney > $this->PageBreakTrigger) { $hbz = ($this->FontSize * $this->cell_height_ratio); } elseif ($this->y < $maxbottomliney) { $hbz = ($maxbottomliney - $this->y); } } // Closing tag switch($tag['value']) { case 'tr': { $table_el = $dom[($dom[$key]['parent'])]['parent']; if (!isset($parent['endy'])) { $dom[($dom[$key]['parent'])]['endy'] = $this->y; $parent['endy'] = $this->y; } if (!isset($parent['endpage'])) { $dom[($dom[$key]['parent'])]['endpage'] = $this->page; $parent['endpage'] = $this->page; } if (!isset($parent['endcolumn'])) { $dom[($dom[$key]['parent'])]['endcolumn'] = $this->current_column; $parent['endcolumn'] = $this->current_column; } // update row-spanned cells if (isset($dom[$table_el]['rowspans'])) { foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { $dom[$table_el]['rowspans'][$k]['rowspan'] -= 1; if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) { if (($dom[$table_el]['rowspans'][$k]['endpage'] == $parent['endpage']) AND ($dom[$table_el]['rowspans'][$k]['endcolumn'] == $parent['endcolumn'])) { $dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $parent['endy']); } elseif (($dom[$table_el]['rowspans'][$k]['endpage'] > $parent['endpage']) OR ($dom[$table_el]['rowspans'][$k]['endcolumn'] > $parent['endcolumn'])) { $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy']; $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage']; $dom[($dom[$key]['parent'])]['endcolumn'] = $dom[$table_el]['rowspans'][$k]['endcolumn']; } } } // report new endy and endpage to the rowspanned cells foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) { $dom[$table_el]['rowspans'][$k]['endpage'] = max($dom[$table_el]['rowspans'][$k]['endpage'], $dom[($dom[$key]['parent'])]['endpage']); $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage']; $dom[$table_el]['rowspans'][$k]['endcolumn'] = max($dom[$table_el]['rowspans'][$k]['endcolumn'], $dom[($dom[$key]['parent'])]['endcolumn']); $dom[($dom[$key]['parent'])]['endcolumn'] = $dom[$table_el]['rowspans'][$k]['endcolumn']; $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']); $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy']; } } // update remaining rowspanned cells foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) { if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) { $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[($dom[$key]['parent'])]['endpage']; $dom[$table_el]['rowspans'][$k]['endcolumn'] = $dom[($dom[$key]['parent'])]['endcolumn']; $dom[$table_el]['rowspans'][$k]['endy'] = $dom[($dom[$key]['parent'])]['endy']; } } } $this->setPage($dom[($dom[$key]['parent'])]['endpage']); if ($this->num_columns > 1) { $this->selectColumn($dom[($dom[$key]['parent'])]['endcolumn']); } $this->y = $dom[($dom[$key]['parent'])]['endy']; if (isset($dom[$table_el]['attribute']['cellspacing'])) { $this->y += $this->getHTMLUnitToUnits($dom[$table_el]['attribute']['cellspacing'], 1, 'px'); } elseif (isset($dom[$table_el]['border-spacing'])) { $this->y += $dom[$table_el]['border-spacing']['V']; } $this->Ln(0, $cell); if ($this->current_column == $parent['startcolumn']) { $this->x = $parent['startx']; } // account for booklet mode if ($this->page > $parent['startpage']) { if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$parent['startpage']]['orm'])) { $this->x -= ($this->pagedim[$this->page]['orm'] - $this->pagedim[$parent['startpage']]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$parent['startpage']]['olm'])) { $this->x += ($this->pagedim[$this->page]['olm'] - $this->pagedim[$parent['startpage']]['olm']); } } break; } case 'tablehead': // closing tag used for the thead part $in_table_head = true; $this->inthead = false; case 'table': { $table_el = $parent; // set default border if (isset($table_el['attribute']['border']) AND ($table_el['attribute']['border'] > 0)) { // set default border $border = array('LTRB' => array('width' => $this->getCSSBorderWidth($table_el['attribute']['border']), 'cap'=>'square', 'join'=>'miter', 'dash'=> 0, 'color'=>array(0,0,0))); } else { $border = 0; } $default_border = $border; // fix bottom line alignment of last line before page break foreach ($dom[($dom[$key]['parent'])]['trids'] as $j => $trkey) { // update row-spanned cells if (isset($dom[($dom[$key]['parent'])]['rowspans'])) { foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) { if (isset($prevtrkey) AND ($trwsp['trid'] == $prevtrkey) AND ($trwsp['mrowspan'] > 0)) { $dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] = $trkey; } if ($dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] == $trkey) { $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] -= 1; } } } if (isset($prevtrkey) AND ($dom[$trkey]['startpage'] > $dom[$prevtrkey]['endpage'])) { $pgendy = $this->pagedim[$dom[$prevtrkey]['endpage']]['hk'] - $this->pagedim[$dom[$prevtrkey]['endpage']]['bm']; $dom[$prevtrkey]['endy'] = $pgendy; // update row-spanned cells if (isset($dom[($dom[$key]['parent'])]['rowspans'])) { foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) { if (($trwsp['trid'] == $trkey) AND ($trwsp['mrowspan'] > 1) AND ($trwsp['endpage'] == $dom[$prevtrkey]['endpage'])) { $dom[($dom[$key]['parent'])]['rowspans'][$k]['endy'] = $pgendy; $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] = -1; } } } } $prevtrkey = $trkey; $table_el = $dom[($dom[$key]['parent'])]; } // for each row if (count($table_el['trids']) > 0) { unset($xmax); } foreach ($table_el['trids'] as $j => $trkey) { $parent = $dom[$trkey]; if (!isset($xmax)) { $xmax = $parent['cellpos'][(count($parent['cellpos']) - 1)]['endx']; } // for each cell on the row foreach ($parent['cellpos'] as $k => $cellpos) { if (isset($cellpos['rowspanid']) AND ($cellpos['rowspanid'] >= 0)) { $cellpos['startx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['startx']; $cellpos['endx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['endx']; $endy = $table_el['rowspans'][($cellpos['rowspanid'])]['endy']; $startpage = $table_el['rowspans'][($cellpos['rowspanid'])]['startpage']; $endpage = $table_el['rowspans'][($cellpos['rowspanid'])]['endpage']; $startcolumn = $table_el['rowspans'][($cellpos['rowspanid'])]['startcolumn']; $endcolumn = $table_el['rowspans'][($cellpos['rowspanid'])]['endcolumn']; } else { $endy = $parent['endy']; $startpage = $parent['startpage']; $endpage = $parent['endpage']; $startcolumn = $parent['startcolumn']; $endcolumn = $parent['endcolumn']; } if ($this->num_columns == 0) { $this->num_columns = 1; } if (isset($cellpos['border'])) { $border = $cellpos['border']; } if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) { $this->SetFillColorArray($cellpos['bgcolor']); $fill = true; } else { $fill = false; } $x = $cellpos['startx']; $y = $parent['starty']; $starty = $y; $w = abs($cellpos['endx'] - $cellpos['startx']); // get border modes $border_start = TCPDF_STATIC::getBorderMode($border, $position='start', $this->opencell); $border_end = TCPDF_STATIC::getBorderMode($border, $position='end', $this->opencell); $border_middle = TCPDF_STATIC::getBorderMode($border, $position='middle', $this->opencell); // design borders around HTML cells. for ($page = $startpage; $page <= $endpage; ++$page) { // for each page $ccode = ''; $this->setPage($page); if ($this->num_columns < 2) { // single-column mode $this->x = $x; $this->y = $this->tMargin; } // account for margin changes if ($page > $startpage) { if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) { $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) { $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']); } } if ($startpage == $endpage) { // single page $deltacol = 0; $deltath = 0; for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column $this->selectColumn($column); if ($startcolumn == $endcolumn) { // single column $cborder = $border; $h = $endy - $parent['starty']; $this->y = $y; $this->x = $x; } elseif ($column == $startcolumn) { // first column $cborder = $border_start; $this->y = $starty; $this->x = $x; $h = $this->h - $this->y - $this->bMargin; if ($this->rtl) { $deltacol = $this->x + $this->rMargin - $this->w; } else { $deltacol = $this->x - $this->lMargin; } } elseif ($column == $endcolumn) { // end column $cborder = $border_end; if (isset($this->columns[$column]['th']['\''.$page.'\''])) { $this->y = $this->columns[$column]['th']['\''.$page.'\'']; } $this->x += $deltacol; $h = $endy - $this->y; } else { // middle column $cborder = $border_middle; if (isset($this->columns[$column]['th']['\''.$page.'\''])) { $this->y = $this->columns[$column]['th']['\''.$page.'\'']; } $this->x += $deltacol; $h = $this->h - $this->y - $this->bMargin; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } elseif ($page == $startpage) { // first page $deltacol = 0; $deltath = 0; for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column $this->selectColumn($column); if ($column == $startcolumn) { // first column $cborder = $border_start; $this->y = $starty; $this->x = $x; $h = $this->h - $this->y - $this->bMargin; if ($this->rtl) { $deltacol = $this->x + $this->rMargin - $this->w; } else { $deltacol = $this->x - $this->lMargin; } } else { // middle column $cborder = $border_middle; if (isset($this->columns[$column]['th']['\''.$page.'\''])) { $this->y = $this->columns[$column]['th']['\''.$page.'\'']; } $this->x += $deltacol; $h = $this->h - $this->y - $this->bMargin; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } elseif ($page == $endpage) { // last page $deltacol = 0; $deltath = 0; for ($column = 0; $column <= $endcolumn; ++$column) { // for each column $this->selectColumn($column); if ($column == $endcolumn) { // end column $cborder = $border_end; if (isset($this->columns[$column]['th']['\''.$page.'\''])) { $this->y = $this->columns[$column]['th']['\''.$page.'\'']; } $this->x += $deltacol; $h = $endy - $this->y; } else { // middle column $cborder = $border_middle; if (isset($this->columns[$column]['th']['\''.$page.'\''])) { $this->y = $this->columns[$column]['th']['\''.$page.'\'']; } $this->x += $deltacol; $h = $this->h - $this->y - $this->bMargin; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } else { // middle page $deltacol = 0; $deltath = 0; for ($column = 0; $column < $this->num_columns; ++$column) { // for each column $this->selectColumn($column); $cborder = $border_middle; if (isset($this->columns[$column]['th']['\''.$page.'\''])) { $this->y = $this->columns[$column]['th']['\''.$page.'\'']; } $this->x += $deltacol; $h = $this->h - $this->y - $this->bMargin; $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } if ($cborder OR $fill) { $offsetlen = strlen($ccode); // draw border and fill if ($this->inxobj) { // we are inside an XObject template if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) { $pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']); $pagemark = $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey]; $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey] += $offsetlen; } else { $pagemark = $this->xobjects[$this->xobjid]['intmrk']; $this->xobjects[$this->xobjid]['intmrk'] += $offsetlen; } $pagebuff = $this->xobjects[$this->xobjid]['outdata']; $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend; } else { // draw border and fill if (end($this->transfmrk[$this->page]) !== false) { $pagemarkkey = key($this->transfmrk[$this->page]); $pagemark = $this->transfmrk[$this->page][$pagemarkkey]; } elseif ($this->InFooter) { $pagemark = $this->footerpos[$this->page]; } else { $pagemark = $this->intmrk[$this->page]; } $pagebuff = $this->getPageBuffer($this->page); $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->setPageBuffer($this->page, $pstart.$ccode.$pend); } } } // end for each page // restore default border $border = $default_border; } // end for each cell on the row if (isset($table_el['attribute']['cellspacing'])) { $this->y += $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px'); } elseif (isset($table_el['border-spacing'])) { $this->y += $table_el['border-spacing']['V']; } $this->Ln(0, $cell); $this->x = $parent['startx']; if ($endpage > $startpage) { if (($this->rtl) AND ($this->pagedim[$endpage]['orm'] != $this->pagedim[$startpage]['orm'])) { $this->x += ($this->pagedim[$endpage]['orm'] - $this->pagedim[$startpage]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$endpage]['olm'] != $this->pagedim[$startpage]['olm'])) { $this->x += ($this->pagedim[$endpage]['olm'] - $this->pagedim[$startpage]['olm']); } } } if (!$in_table_head) { // we are not inside a thead section $this->cell_padding = $table_el['old_cell_padding']; // reset row height $this->resetLastH(); if (($this->page == ($this->numpages - 1)) AND ($this->pageopen[$this->numpages])) { $plendiff = ($this->pagelen[$this->numpages] - $this->emptypagemrk[$this->numpages]); if (($plendiff > 0) AND ($plendiff < 60)) { $pagediff = substr($this->getPageBuffer($this->numpages), $this->emptypagemrk[$this->numpages], $plendiff); if (substr($pagediff, 0, 5) == 'BT /F') { // the difference is only a font setting $plendiff = 0; } } if ($plendiff == 0) { // remove last blank page $this->deletePage($this->numpages); } } if (isset($this->theadMargins['top'])) { // restore top margin $this->tMargin = $this->theadMargins['top']; } if (!isset($table_el['attribute']['nested']) OR ($table_el['attribute']['nested'] != 'true')) { // reset main table header $this->thead = ''; $this->theadMargins = array(); $this->pagedim[$this->page]['tm'] = $this->tMargin; } } $parent = $table_el; break; } case 'a': { $this->HREF = ''; break; } case 'sup': { $this->SetXY($this->GetX(), $this->GetY() + ((0.7 * $parent['fontsize']) / $this->k)); break; } case 'sub': { $this->SetXY($this->GetX(), $this->GetY() - ((0.3 * $parent['fontsize']) / $this->k)); break; } case 'div': { $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); break; } case 'blockquote': { if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } --$this->listindentlevel; $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); break; } case 'p': { $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); break; } case 'pre': { $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); $this->premode = false; break; } case 'dl': { --$this->listnum; if ($this->listnum <= 0) { $this->listnum = 0; $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); } else { $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag); } $this->resetLastH(); break; } case 'dt': { $this->lispacer = ''; $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag); break; } case 'dd': { $this->lispacer = ''; if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } --$this->listindentlevel; $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag); break; } case 'ul': case 'ol': { --$this->listnum; $this->lispacer = ''; if ($this->rtl) { $this->rMargin -= $this->listindent; } else { $this->lMargin -= $this->listindent; } --$this->listindentlevel; if ($this->listnum <= 0) { $this->listnum = 0; $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); } else { $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag); } $this->resetLastH(); break; } case 'li': { $this->lispacer = ''; $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag); break; } case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': { $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag); break; } // Form fields (since 4.8.000 - 2009-09-07) case 'form': { $this->form_action = ''; $this->form_enctype = 'application/x-www-form-urlencoded'; break; } default : { break; } } // draw border and background (if any) $this->drawHTMLTagBorder($parent, $xmax); if (isset($dom[($dom[$key]['parent'])]['attribute']['pagebreakafter'])) { $pba = $dom[($dom[$key]['parent'])]['attribute']['pagebreakafter']; // check for pagebreak if (($pba == 'true') OR ($pba == 'left') OR ($pba == 'right')) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); } if ((($pba == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0)))) OR (($pba == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) { // add a page (or trig AcceptPageBreak() for multicolumn mode) $this->checkPageBreak($this->PageBreakTrigger + 1); } } $this->tmprtl = false; return $dom; } /** * Add vertical spaces if needed. * @param $hbz (string) Distance between current y and line bottom. * @param $hb (string) The height of the break. * @param $cell (boolean) if true add the default left (or right if RTL) padding to each new line (default false). * @param $firsttag (boolean) set to true when the tag is the first. * @param $lasttag (boolean) set to true when the tag is the last. * @protected */ protected function addHTMLVertSpace($hbz=0, $hb=0, $cell=false, $firsttag=false, $lasttag=false) { if ($firsttag) { $this->Ln(0, $cell); $this->htmlvspace = 0; return; } if ($lasttag) { $this->Ln($hbz, $cell); $this->htmlvspace = 0; return; } if ($hb < $this->htmlvspace) { $hd = 0; } else { $hd = $hb - $this->htmlvspace; $this->htmlvspace = $hb; } $this->Ln(($hbz + $hd), $cell); } /** * Return the starting coordinates to draw an html border * @return array containing top-left border coordinates * @protected * @since 5.7.000 (2010-08-03) */ protected function getBorderStartPosition() { if ($this->rtl) { $xmax = $this->lMargin; } else { $xmax = $this->w - $this->rMargin; } return array('page' => $this->page, 'column' => $this->current_column, 'x' => $this->x, 'y' => $this->y, 'xmax' => $xmax); } /** * Draw an HTML block border and fill * @param $tag (array) array of tag properties. * @param $xmax (int) end X coordinate for border. * @protected * @since 5.7.000 (2010-08-03) */ protected function drawHTMLTagBorder($tag, $xmax) { if (!isset($tag['borderposition'])) { // nothing to draw return; } $prev_x = $this->x; $prev_y = $this->y; $prev_lasth = $this->lasth; $border = 0; $fill = false; $this->lasth = 0; if (isset($tag['border']) AND !empty($tag['border'])) { // get border style $border = $tag['border']; if (!TCPDF_STATIC::empty_string($this->thead) AND (!$this->inthead)) { // border for table header $border = TCPDF_STATIC::getBorderMode($border, $position='middle', $this->opencell); } } if (isset($tag['bgcolor']) AND ($tag['bgcolor'] !== false)) { // get background color $old_bgcolor = $this->bgcolor; $this->SetFillColorArray($tag['bgcolor']); $fill = true; } if (!$border AND !$fill) { // nothing to draw return; } if (isset($tag['attribute']['cellspacing'])) { $clsp = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px'); $cellspacing = array('H' => $clsp, 'V' => $clsp); } elseif (isset($tag['border-spacing'])) { $cellspacing = $tag['border-spacing']; } else { $cellspacing = array('H' => 0, 'V' => 0); } if (($tag['value'] != 'table') AND (is_array($border)) AND (!empty($border))) { // draw the border externally respect the sqare edge. $border['mode'] = 'ext'; } if ($this->rtl) { if ($xmax >= $tag['borderposition']['x']) { $xmax = $tag['borderposition']['xmax']; } $w = ($tag['borderposition']['x'] - $xmax); } else { if ($xmax <= $tag['borderposition']['x']) { $xmax = $tag['borderposition']['xmax']; } $w = ($xmax - $tag['borderposition']['x']); } if ($w <= 0) { return; } $w += $cellspacing['H']; $startpage = $tag['borderposition']['page']; $startcolumn = $tag['borderposition']['column']; $x = $tag['borderposition']['x']; $y = $tag['borderposition']['y']; $endpage = $this->page; $starty = $tag['borderposition']['y'] - $cellspacing['V']; $currentY = $this->y; $this->x = $x; // get latest column $endcolumn = $this->current_column; if ($this->num_columns == 0) { $this->num_columns = 1; } // get border modes $border_start = TCPDF_STATIC::getBorderMode($border, $position='start', $this->opencell); $border_end = TCPDF_STATIC::getBorderMode($border, $position='end', $this->opencell); $border_middle = TCPDF_STATIC::getBorderMode($border, $position='middle', $this->opencell); // temporary disable page regions $temp_page_regions = $this->page_regions; $this->page_regions = array(); // design borders around HTML cells. for ($page = $startpage; $page <= $endpage; ++$page) { // for each page $ccode = ''; $this->setPage($page); if ($this->num_columns < 2) { // single-column mode $this->x = $x; $this->y = $this->tMargin; } // account for margin changes if ($page > $startpage) { if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) { $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']); } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) { $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']); } } if ($startpage == $endpage) { // single page for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column $this->selectColumn($column); if ($startcolumn == $endcolumn) { // single column $cborder = $border; $h = ($currentY - $y) + $cellspacing['V']; $this->y = $starty; } elseif ($column == $startcolumn) { // first column $cborder = $border_start; $this->y = $starty; $h = $this->h - $this->y - $this->bMargin; } elseif ($column == $endcolumn) { // end column $cborder = $border_end; $h = $currentY - $this->y; } else { // middle column $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } elseif ($page == $startpage) { // first page for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column $this->selectColumn($column); if ($column == $startcolumn) { // first column $cborder = $border_start; $this->y = $starty; $h = $this->h - $this->y - $this->bMargin; } else { // middle column $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } elseif ($page == $endpage) { // last page for ($column = 0; $column <= $endcolumn; ++$column) { // for each column $this->selectColumn($column); if ($column == $endcolumn) { // end column $cborder = $border_end; $h = $currentY - $this->y; } else { // middle column $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; } $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } else { // middle page for ($column = 0; $column < $this->num_columns; ++$column) { // for each column $this->selectColumn($column); $cborder = $border_middle; $h = $this->h - $this->y - $this->bMargin; $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n"; } // end for each column } if ($cborder OR $fill) { $offsetlen = strlen($ccode); // draw border and fill if ($this->inxobj) { // we are inside an XObject template if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) { $pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']); $pagemark = $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey]; $this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey] += $offsetlen; } else { $pagemark = $this->xobjects[$this->xobjid]['intmrk']; $this->xobjects[$this->xobjid]['intmrk'] += $offsetlen; } $pagebuff = $this->xobjects[$this->xobjid]['outdata']; $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend; } else { if (end($this->transfmrk[$this->page]) !== false) { $pagemarkkey = key($this->transfmrk[$this->page]); $pagemark = $this->transfmrk[$this->page][$pagemarkkey]; } elseif ($this->InFooter) { $pagemark = $this->footerpos[$this->page]; } else { $pagemark = $this->intmrk[$this->page]; } $pagebuff = $this->getPageBuffer($this->page); $pstart = substr($pagebuff, 0, $pagemark); $pend = substr($pagebuff, $pagemark); $this->setPageBuffer($this->page, $pstart.$ccode.$pend); $this->bordermrk[$this->page] += $offsetlen; $this->cntmrk[$this->page] += $offsetlen; } } } // end for each page // restore page regions $this->page_regions = $temp_page_regions; if (isset($old_bgcolor)) { // restore background color $this->SetFillColorArray($old_bgcolor); } // restore pointer position $this->x = $prev_x; $this->y = $prev_y; $this->lasth = $prev_lasth; } /** * Set the default bullet to be used as LI bullet symbol * @param $symbol (string) character or string to be used (legal values are: '' = automatic, '!' = auto bullet, '#' = auto numbering, 'disc', 'disc', 'circle', 'square', '1', 'decimal', 'decimal-leading-zero', 'i', 'lower-roman', 'I', 'upper-roman', 'a', 'lower-alpha', 'lower-latin', 'A', 'upper-alpha', 'upper-latin', 'lower-greek', 'img|type|width|height|image.ext') * @public * @since 4.0.028 (2008-09-26) */ public function setLIsymbol($symbol='!') { // check for custom image symbol if (substr($symbol, 0, 4) == 'img|') { $this->lisymbol = $symbol; return; } $symbol = strtolower($symbol); switch ($symbol) { case '!' : case '#' : case 'disc' : case 'circle' : case 'square' : case '1': case 'decimal': case 'decimal-leading-zero': case 'i': case 'lower-roman': case 'I': case 'upper-roman': case 'a': case 'lower-alpha': case 'lower-latin': case 'A': case 'upper-alpha': case 'upper-latin': case 'lower-greek': { $this->lisymbol = $symbol; break; } default : { $this->lisymbol = ''; } } } /** * Set the booklet mode for double-sided pages. * @param $booklet (boolean) true set the booklet mode on, false otherwise. * @param $inner (float) Inner page margin. * @param $outer (float) Outer page margin. * @public * @since 4.2.000 (2008-10-29) */ public function SetBooklet($booklet=true, $inner=-1, $outer=-1) { $this->booklet = $booklet; if ($inner >= 0) { $this->lMargin = $inner; } if ($outer >= 0) { $this->rMargin = $outer; } } /** * Swap the left and right margins. * @param $reverse (boolean) if true swap left and right margins. * @protected * @since 4.2.000 (2008-10-29) */ protected function swapMargins($reverse=true) { if ($reverse) { // swap left and right margins $mtemp = $this->original_lMargin; $this->original_lMargin = $this->original_rMargin; $this->original_rMargin = $mtemp; $deltam = $this->original_lMargin - $this->original_rMargin; $this->lMargin += $deltam; $this->rMargin -= $deltam; } } /** * Set the vertical spaces for HTML tags. * The array must have the following structure (example): * $tagvs = array('h1' => array(0 => array('h' => '', 'n' => 2), 1 => array('h' => 1.3, 'n' => 1))); * The first array level contains the tag names, * the second level contains 0 for opening tags or 1 for closing tags, * the third level contains the vertical space unit (h) and the number spaces to add (n). * If the h parameter is not specified, default values are used. * @param $tagvs (array) array of tags and relative vertical spaces. * @public * @since 4.2.001 (2008-10-30) */ public function setHtmlVSpace($tagvs) { $this->tagvspaces = $tagvs; } /** * Set custom width for list indentation. * @param $width (float) width of the indentation. Use negative value to disable it. * @public * @since 4.2.007 (2008-11-12) */ public function setListIndentWidth($width) { return $this->customlistindent = floatval($width); } /** * Set the top/bottom cell sides to be open or closed when the cell cross the page. * @param $isopen (boolean) if true keeps the top/bottom border open for the cell sides that cross the page. * @public * @since 4.2.010 (2008-11-14) */ public function setOpenCell($isopen) { $this->opencell = $isopen; } /** * Set the color and font style for HTML links. * @param $color (array) RGB array of colors * @param $fontstyle (string) additional font styles to add * @public * @since 4.4.003 (2008-12-09) */ public function setHtmlLinksStyle($color=array(0,0,255), $fontstyle='U') { $this->htmlLinkColorArray = $color; $this->htmlLinkFontStyle = $fontstyle; } /** * Convert HTML string containing value and unit of measure to user's units or points. * @param $htmlval (string) String containing values and unit. * @param $refsize (string) Reference value in points. * @param $defaultunit (string) Default unit (can be one of the following: %, em, ex, px, in, mm, pc, pt). * @param $points (boolean) If true returns points, otherwise returns value in user's units. * @return float value in user's unit or point if $points=true * @public * @since 4.4.004 (2008-12-10) */ public function getHTMLUnitToUnits($htmlval, $refsize=1, $defaultunit='px', $points=false) { $supportedunits = array('%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt'); $retval = 0; $value = 0; $unit = 'px'; if ($points) { $k = 1; } else { $k = $this->k; } if (in_array($defaultunit, $supportedunits)) { $unit = $defaultunit; } if (is_numeric($htmlval)) { $value = floatval($htmlval); } elseif (preg_match('/([0-9\.\-\+]+)/', $htmlval, $mnum)) { $value = floatval($mnum[1]); if (preg_match('/([a-z%]+)/', $htmlval, $munit)) { if (in_array($munit[1], $supportedunits)) { $unit = $munit[1]; } } } switch ($unit) { // percentage case '%': { $retval = (($value * $refsize) / 100); break; } // relative-size case 'em': { $retval = ($value * $refsize); break; } // height of lower case 'x' (about half the font-size) case 'ex': { $retval = ($value * ($refsize / 2)); break; } // absolute-size case 'in': { $retval = (($value * $this->dpi) / $k); break; } // centimeters case 'cm': { $retval = (($value / 2.54 * $this->dpi) / $k); break; } // millimeters case 'mm': { $retval = (($value / 25.4 * $this->dpi) / $k); break; } // one pica is 12 points case 'pc': { $retval = (($value * 12) / $k); break; } // points case 'pt': { $retval = ($value / $k); break; } // pixels case 'px': { $retval = $this->pixelsToUnits($value); if ($points) { $retval *= $this->k; } break; } } return $retval; } /** * Output an HTML list bullet or ordered item symbol * @param $listdepth (int) list nesting level * @param $listtype (string) type of list * @param $size (float) current font size * @protected * @since 4.4.004 (2008-12-10) */ protected function putHtmlListBullet($listdepth, $listtype='', $size=10) { if ($this->state != 2) { return; } $size /= $this->k; $fill = ''; $bgcolor = $this->bgcolor; $color = $this->fgcolor; $strokecolor = $this->strokecolor; $width = 0; $textitem = ''; $tmpx = $this->x; $lspace = $this->GetStringWidth(' '); if ($listtype == '^') { // special symbol used for avoid justification of rect bullet $this->lispacer = ''; return; } elseif ($listtype == '!') { // set default list type for unordered list $deftypes = array('disc', 'circle', 'square'); $listtype = $deftypes[($listdepth - 1) % 3]; } elseif ($listtype == '#') { // set default list type for ordered list $listtype = 'decimal'; } elseif (substr($listtype, 0, 4) == 'img|') { // custom image type ('img|type|width|height|image.ext') $img = explode('|', $listtype); $listtype = 'img'; } switch ($listtype) { // unordered types case 'none': { break; } case 'disc': { $r = $size / 6; $lspace += (2 * $r); if ($this->rtl) { $this->x += $lspace; } else { $this->x -= $lspace; } $this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), $r, 0, 360, 'F', array(), $color, 8); break; } case 'circle': { $r = $size / 6; $lspace += (2 * $r); if ($this->rtl) { $this->x += $lspace; } else { $this->x -= $lspace; } $prev_line_style = $this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor; $new_line_style = array('width' => ($r / 3), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'phase' => 0, 'color'=>$color); $this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), ($r * (1 - (1/6))), 0, 360, 'D', $new_line_style, array(), 8); $this->_out($prev_line_style); // restore line settings break; } case 'square': { $l = $size / 3; $lspace += $l; if ($this->rtl) {; $this->x += $lspace; } else { $this->x -= $lspace; } $this->Rect($this->x, ($this->y + (($this->lasth - $l) / 2)), $l, $l, 'F', array(), $color); break; } case 'img': { // 1=>type, 2=>width, 3=>height, 4=>image.ext $lspace += $img[2]; if ($this->rtl) {; $this->x += $lspace; } else { $this->x -= $lspace; } $imgtype = strtolower($img[1]); $prev_y = $this->y; switch ($imgtype) { case 'svg': { $this->ImageSVG($img[4], $this->x, ($this->y + (($this->lasth - $img[3]) / 2)), $img[2], $img[3], '', 'T', '', 0, false); break; } case 'ai': case 'eps': { $this->ImageEps($img[4], $this->x, ($this->y + (($this->lasth - $img[3]) / 2)), $img[2], $img[3], '', true, 'T', '', 0, false); break; } default: { $this->Image($img[4], $this->x, ($this->y + (($this->lasth - $img[3]) / 2)), $img[2], $img[3], $img[1], '', 'T', false, 300, '', false, false, 0, false, false, false); break; } } $this->y = $prev_y; break; } // ordered types // $this->listcount[$this->listnum]; // $textitem case '1': case 'decimal': { $textitem = $this->listcount[$this->listnum]; break; } case 'decimal-leading-zero': { $textitem = sprintf('%02d', $this->listcount[$this->listnum]); break; } case 'i': case 'lower-roman': { $textitem = strtolower(TCPDF_STATIC::intToRoman($this->listcount[$this->listnum])); break; } case 'I': case 'upper-roman': { $textitem = TCPDF_STATIC::intToRoman($this->listcount[$this->listnum]); break; } case 'a': case 'lower-alpha': case 'lower-latin': { $textitem = chr(97 + $this->listcount[$this->listnum] - 1); break; } case 'A': case 'upper-alpha': case 'upper-latin': { $textitem = chr(65 + $this->listcount[$this->listnum] - 1); break; } case 'lower-greek': { $textitem = TCPDF_FONTS::unichr((945 + $this->listcount[$this->listnum] - 1), $this->isunicode); break; } /* // Types to be implemented (special handling) case 'hebrew': { break; } case 'armenian': { break; } case 'georgian': { break; } case 'cjk-ideographic': { break; } case 'hiragana': { break; } case 'katakana': { break; } case 'hiragana-iroha': { break; } case 'katakana-iroha': { break; } */ default: { $textitem = $this->listcount[$this->listnum]; } } if (!TCPDF_STATIC::empty_string($textitem)) { // Check whether we need a new page or new column $prev_y = $this->y; $h = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B']; if ($this->checkPageBreak($h) OR ($this->y < $prev_y)) { $tmpx = $this->x; } // print ordered item if ($this->rtl) { $textitem = '.'.$textitem; } else { $textitem = $textitem.'.'; } $lspace += $this->GetStringWidth($textitem); if ($this->rtl) { $this->x += $lspace; } else { $this->x -= $lspace; } $this->Write($this->lasth, $textitem, '', false, '', false, 0, false); } $this->x = $tmpx; $this->lispacer = '^'; // restore colors $this->SetFillColorArray($bgcolor); $this->SetDrawColorArray($strokecolor); $this->SettextColorArray($color); } /** * Returns current graphic variables as array. * @return array of graphic variables * @protected * @since 4.2.010 (2008-11-14) */ protected function getGraphicVars() { $grapvars = array( 'FontFamily' => $this->FontFamily, 'FontStyle' => $this->FontStyle, 'FontSizePt' => $this->FontSizePt, 'rMargin' => $this->rMargin, 'lMargin' => $this->lMargin, 'cell_padding' => $this->cell_padding, 'cell_margin' => $this->cell_margin, 'LineWidth' => $this->LineWidth, 'linestyleWidth' => $this->linestyleWidth, 'linestyleCap' => $this->linestyleCap, 'linestyleJoin' => $this->linestyleJoin, 'linestyleDash' => $this->linestyleDash, 'textrendermode' => $this->textrendermode, 'textstrokewidth' => $this->textstrokewidth, 'DrawColor' => $this->DrawColor, 'FillColor' => $this->FillColor, 'TextColor' => $this->TextColor, 'ColorFlag' => $this->ColorFlag, 'bgcolor' => $this->bgcolor, 'fgcolor' => $this->fgcolor, 'htmlvspace' => $this->htmlvspace, 'listindent' => $this->listindent, 'listindentlevel' => $this->listindentlevel, 'listnum' => $this->listnum, 'listordered' => $this->listordered, 'listcount' => $this->listcount, 'lispacer' => $this->lispacer, 'cell_height_ratio' => $this->cell_height_ratio, 'font_stretching' => $this->font_stretching, 'font_spacing' => $this->font_spacing, 'alpha' => $this->alpha, // extended 'lasth' => $this->lasth, 'tMargin' => $this->tMargin, 'bMargin' => $this->bMargin, 'AutoPageBreak' => $this->AutoPageBreak, 'PageBreakTrigger' => $this->PageBreakTrigger, 'x' => $this->x, 'y' => $this->y, 'w' => $this->w, 'h' => $this->h, 'wPt' => $this->wPt, 'hPt' => $this->hPt, 'fwPt' => $this->fwPt, 'fhPt' => $this->fhPt, 'page' => $this->page, 'current_column' => $this->current_column, 'num_columns' => $this->num_columns ); return $grapvars; } /** * Set graphic variables. * @param $gvars (array) array of graphic variablesto restore * @param $extended (boolean) if true restore extended graphic variables * @protected * @since 4.2.010 (2008-11-14) */ protected function setGraphicVars($gvars, $extended=false) { if ($this->state != 2) { return; } $this->FontFamily = $gvars['FontFamily']; $this->FontStyle = $gvars['FontStyle']; $this->FontSizePt = $gvars['FontSizePt']; $this->rMargin = $gvars['rMargin']; $this->lMargin = $gvars['lMargin']; $this->cell_padding = $gvars['cell_padding']; $this->cell_margin = $gvars['cell_margin']; $this->LineWidth = $gvars['LineWidth']; $this->linestyleWidth = $gvars['linestyleWidth']; $this->linestyleCap = $gvars['linestyleCap']; $this->linestyleJoin = $gvars['linestyleJoin']; $this->linestyleDash = $gvars['linestyleDash']; $this->textrendermode = $gvars['textrendermode']; $this->textstrokewidth = $gvars['textstrokewidth']; $this->DrawColor = $gvars['DrawColor']; $this->FillColor = $gvars['FillColor']; $this->TextColor = $gvars['TextColor']; $this->ColorFlag = $gvars['ColorFlag']; $this->bgcolor = $gvars['bgcolor']; $this->fgcolor = $gvars['fgcolor']; $this->htmlvspace = $gvars['htmlvspace']; $this->listindent = $gvars['listindent']; $this->listindentlevel = $gvars['listindentlevel']; $this->listnum = $gvars['listnum']; $this->listordered = $gvars['listordered']; $this->listcount = $gvars['listcount']; $this->lispacer = $gvars['lispacer']; $this->cell_height_ratio = $gvars['cell_height_ratio']; $this->font_stretching = $gvars['font_stretching']; $this->font_spacing = $gvars['font_spacing']; $this->alpha = $gvars['alpha']; if ($extended) { // restore extended values $this->lasth = $gvars['lasth']; $this->tMargin = $gvars['tMargin']; $this->bMargin = $gvars['bMargin']; $this->AutoPageBreak = $gvars['AutoPageBreak']; $this->PageBreakTrigger = $gvars['PageBreakTrigger']; $this->x = $gvars['x']; $this->y = $gvars['y']; $this->w = $gvars['w']; $this->h = $gvars['h']; $this->wPt = $gvars['wPt']; $this->hPt = $gvars['hPt']; $this->fwPt = $gvars['fwPt']; $this->fhPt = $gvars['fhPt']; $this->page = $gvars['page']; $this->current_column = $gvars['current_column']; $this->num_columns = $gvars['num_columns']; } $this->_out(''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor.''); if (!TCPDF_STATIC::empty_string($this->FontFamily)) { $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt); } } /** * Writes data to a temporary file on filesystem. * @param $filename (string) file name * @param $data (mixed) data to write on file * @param $append (boolean) if true append data, false replace. * @since 4.5.000 (2008-12-31) * @protected */ protected function writeDiskCache($filename, $data, $append=false) { if ($append) { $fmode = 'ab+'; } else { $fmode = 'wb+'; } $f = @fopen($filename, $fmode); if (!$f) { $this->Error('Unable to write cache file: '.$filename); } else { fwrite($f, $data); fclose($f); } // update file length (needed for transactions) if (!isset($this->cache_file_length['_'.$filename])) { $this->cache_file_length['_'.$filename] = strlen($data); } else { $this->cache_file_length['_'.$filename] += strlen($data); } } /** * Read data from a temporary file on filesystem. * @param $filename (string) file name * @return mixed retrieved data * @since 4.5.000 (2008-12-31) * @protected */ protected function readDiskCache($filename) { return file_get_contents($filename); } /** * Set buffer content (always append data). * @param $data (string) data * @protected * @since 4.5.000 (2009-01-02) */ protected function setBuffer($data) { $this->bufferlen += strlen($data); if ($this->diskcache) { if (!isset($this->buffer) OR TCPDF_STATIC::empty_string($this->buffer)) { $this->buffer = TCPDF_STATIC::getObjFilename('buffer'); } $this->writeDiskCache($this->buffer, $data, true); } else { $this->buffer .= $data; } } /** * Replace the buffer content * @param $data (string) data * @protected * @since 5.5.000 (2010-06-22) */ protected function replaceBuffer($data) { $this->bufferlen = strlen($data); if ($this->diskcache) { if (!isset($this->buffer) OR TCPDF_STATIC::empty_string($this->buffer)) { $this->buffer = TCPDF_STATIC::getObjFilename('buffer'); } $this->writeDiskCache($this->buffer, $data, false); } else { $this->buffer = $data; } } /** * Get buffer content. * @return string buffer content * @protected * @since 4.5.000 (2009-01-02) */ protected function getBuffer() { if ($this->diskcache) { return $this->readDiskCache($this->buffer); } else { return $this->buffer; } } /** * Set page buffer content. * @param $page (int) page number * @param $data (string) page data * @param $append (boolean) if true append data, false replace. * @protected * @since 4.5.000 (2008-12-31) */ protected function setPageBuffer($page, $data, $append=false) { if ($this->diskcache) { if (!isset($this->pages[$page])) { $this->pages[$page] = TCPDF_STATIC::getObjFilename('page'.$page); } $this->writeDiskCache($this->pages[$page], $data, $append); } else { if ($append) { $this->pages[$page] .= $data; } else { $this->pages[$page] = $data; } } if ($append AND isset($this->pagelen[$page])) { $this->pagelen[$page] += strlen($data); } else { $this->pagelen[$page] = strlen($data); } } /** * Get page buffer content. * @param $page (int) page number * @return string page buffer content or false in case of error * @protected * @since 4.5.000 (2008-12-31) */ protected function getPageBuffer($page) { if ($this->diskcache) { return $this->readDiskCache($this->pages[$page]); } elseif (isset($this->pages[$page])) { return $this->pages[$page]; } return false; } /** * Set image buffer content. * @param $image (string) image key * @param $data (array) image data * @return int image index number * @protected * @since 4.5.000 (2008-12-31) */ protected function setImageBuffer($image, $data) { if (($data['i'] = array_search($image, $this->imagekeys)) === FALSE) { $this->imagekeys[$this->numimages] = $image; $data['i'] = $this->numimages; ++$this->numimages; } if ($this->diskcache) { if (!isset($this->images[$image])) { $this->images[$image] = TCPDF_STATIC::getObjFilename('image'.$image); } $this->writeDiskCache($this->images[$image], serialize($data)); } else { $this->images[$image] = $data; } return $data['i']; } /** * Set image buffer content for a specified sub-key. * @param $image (string) image key * @param $key (string) image sub-key * @param $data (array) image data * @protected * @since 4.5.000 (2008-12-31) */ protected function setImageSubBuffer($image, $key, $data) { if (!isset($this->images[$image])) { $this->setImageBuffer($image, array()); } if ($this->diskcache) { $tmpimg = $this->getImageBuffer($image); $tmpimg[$key] = $data; $this->writeDiskCache($this->images[$image], serialize($tmpimg)); } else { $this->images[$image][$key] = $data; } } /** * Get image buffer content. * @param $image (string) image key * @return string image buffer content or false in case of error * @protected * @since 4.5.000 (2008-12-31) */ protected function getImageBuffer($image) { if ($this->diskcache AND isset($this->images[$image])) { return unserialize($this->readDiskCache($this->images[$image])); } elseif (isset($this->images[$image])) { return $this->images[$image]; } return false; } /** * Set font buffer content. * @param $font (string) font key * @param $data (array) font data * @protected * @since 4.5.000 (2009-01-02) */ protected function setFontBuffer($font, $data) { if ($this->diskcache) { if (!isset($this->fonts[$font])) { $this->fonts[$font] = TCPDF_STATIC::getObjFilename('font'); } $this->writeDiskCache($this->fonts[$font], serialize($data)); } else { $this->fonts[$font] = $data; } if (!in_array($font, $this->fontkeys)) { $this->fontkeys[] = $font; // store object ID for current font ++$this->n; $this->font_obj_ids[$font] = $this->n; $this->setFontSubBuffer($font, 'n', $this->n); } } /** * Set font buffer content. * @param $font (string) font key * @param $key (string) font sub-key * @param $data (array) font data * @protected * @since 4.5.000 (2009-01-02) */ protected function setFontSubBuffer($font, $key, $data) { if (!isset($this->fonts[$font])) { $this->setFontBuffer($font, array()); } if ($this->diskcache) { $tmpfont = $this->getFontBuffer($font); $tmpfont[$key] = $data; $this->writeDiskCache($this->fonts[$font], serialize($tmpfont)); } else { $this->fonts[$font][$key] = $data; } } /** * Get font buffer content. * @param $font (string) font key * @return string font buffer content or false in case of error * @protected * @since 4.5.000 (2009-01-02) */ protected function getFontBuffer($font) { if ($this->diskcache AND isset($this->fonts[$font])) { return unserialize($this->readDiskCache($this->fonts[$font])); } elseif (isset($this->fonts[$font])) { return $this->fonts[$font]; } return false; } /** * Move a page to a previous position. * @param $frompage (int) number of the source page * @param $topage (int) number of the destination page (must be less than $frompage) * @return true in case of success, false in case of error. * @public * @since 4.5.000 (2009-01-02) */ public function movePage($frompage, $topage) { if (($frompage > $this->numpages) OR ($frompage <= $topage)) { return false; } if ($frompage == $this->page) { // close the page before moving it $this->endPage(); } // move all page-related states $tmppage = $this->getPageBuffer($frompage); $tmppagedim = $this->pagedim[$frompage]; $tmppagelen = $this->pagelen[$frompage]; $tmpintmrk = $this->intmrk[$frompage]; $tmpbordermrk = $this->bordermrk[$frompage]; $tmpcntmrk = $this->cntmrk[$frompage]; $tmppageobjects = $this->pageobjects[$frompage]; if (isset($this->footerpos[$frompage])) { $tmpfooterpos = $this->footerpos[$frompage]; } if (isset($this->footerlen[$frompage])) { $tmpfooterlen = $this->footerlen[$frompage]; } if (isset($this->transfmrk[$frompage])) { $tmptransfmrk = $this->transfmrk[$frompage]; } if (isset($this->PageAnnots[$frompage])) { $tmpannots = $this->PageAnnots[$frompage]; } if (isset($this->newpagegroup) AND !empty($this->newpagegroup)) { for ($i = $frompage; $i > $topage; --$i) { if (isset($this->newpagegroup[$i]) AND (($i + $this->pagegroups[$this->newpagegroup[$i]]) > $frompage)) { --$this->pagegroups[$this->newpagegroup[$i]]; break; } } for ($i = $topage; $i > 0; --$i) { if (isset($this->newpagegroup[$i]) AND (($i + $this->pagegroups[$this->newpagegroup[$i]]) > $topage)) { ++$this->pagegroups[$this->newpagegroup[$i]]; break; } } } for ($i = $frompage; $i > $topage; --$i) { $j = $i - 1; // shift pages down $this->setPageBuffer($i, $this->getPageBuffer($j)); $this->pagedim[$i] = $this->pagedim[$j]; $this->pagelen[$i] = $this->pagelen[$j]; $this->intmrk[$i] = $this->intmrk[$j]; $this->bordermrk[$i] = $this->bordermrk[$j]; $this->cntmrk[$i] = $this->cntmrk[$j]; $this->pageobjects[$i] = $this->pageobjects[$j]; if (isset($this->footerpos[$j])) { $this->footerpos[$i] = $this->footerpos[$j]; } elseif (isset($this->footerpos[$i])) { unset($this->footerpos[$i]); } if (isset($this->footerlen[$j])) { $this->footerlen[$i] = $this->footerlen[$j]; } elseif (isset($this->footerlen[$i])) { unset($this->footerlen[$i]); } if (isset($this->transfmrk[$j])) { $this->transfmrk[$i] = $this->transfmrk[$j]; } elseif (isset($this->transfmrk[$i])) { unset($this->transfmrk[$i]); } if (isset($this->PageAnnots[$j])) { $this->PageAnnots[$i] = $this->PageAnnots[$j]; } elseif (isset($this->PageAnnots[$i])) { unset($this->PageAnnots[$i]); } if (isset($this->newpagegroup[$j])) { $this->newpagegroup[$i] = $this->newpagegroup[$j]; unset($this->newpagegroup[$j]); } if ($this->currpagegroup == $j) { $this->currpagegroup = $i; } } $this->setPageBuffer($topage, $tmppage); $this->pagedim[$topage] = $tmppagedim; $this->pagelen[$topage] = $tmppagelen; $this->intmrk[$topage] = $tmpintmrk; $this->bordermrk[$topage] = $tmpbordermrk; $this->cntmrk[$topage] = $tmpcntmrk; $this->pageobjects[$topage] = $tmppageobjects; if (isset($tmpfooterpos)) { $this->footerpos[$topage] = $tmpfooterpos; } elseif (isset($this->footerpos[$topage])) { unset($this->footerpos[$topage]); } if (isset($tmpfooterlen)) { $this->footerlen[$topage] = $tmpfooterlen; } elseif (isset($this->footerlen[$topage])) { unset($this->footerlen[$topage]); } if (isset($tmptransfmrk)) { $this->transfmrk[$topage] = $tmptransfmrk; } elseif (isset($this->transfmrk[$topage])) { unset($this->transfmrk[$topage]); } if (isset($tmpannots)) { $this->PageAnnots[$topage] = $tmpannots; } elseif (isset($this->PageAnnots[$topage])) { unset($this->PageAnnots[$topage]); } // adjust outlines $tmpoutlines = $this->outlines; foreach ($tmpoutlines as $key => $outline) { if (($outline['p'] >= $topage) AND ($outline['p'] < $frompage)) { $this->outlines[$key]['p'] = ($outline['p'] + 1); } elseif ($outline['p'] == $frompage) { $this->outlines[$key]['p'] = $topage; } } // adjust dests $tmpdests = $this->dests; foreach ($tmpdests as $key => $dest) { if (($dest['p'] >= $topage) AND ($dest['p'] < $frompage)) { $this->dests[$key]['p'] = ($dest['p'] + 1); } elseif ($dest['p'] == $frompage) { $this->dests[$key]['p'] = $topage; } } // adjust links $tmplinks = $this->links; foreach ($tmplinks as $key => $link) { if (($link[0] >= $topage) AND ($link[0] < $frompage)) { $this->links[$key][0] = ($link[0] + 1); } elseif ($link[0] == $frompage) { $this->links[$key][0] = $topage; } } // adjust javascript $tmpjavascript = $this->javascript; global $jfrompage, $jtopage; $jfrompage = $frompage; $jtopage = $topage; $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/', create_function('$matches', 'global $jfrompage, $jtopage; $pagenum = intval($matches[3]) + 1; if (($pagenum >= $jtopage) AND ($pagenum < $jfrompage)) { $newpage = ($pagenum + 1); } elseif ($pagenum == $jfrompage) { $newpage = $jtopage; } else { $newpage = $pagenum; } --$newpage; return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript); // return to last page $this->lastPage(true); return true; } /** * Remove the specified page. * @param $page (int) page to remove * @return true in case of success, false in case of error. * @public * @since 4.6.004 (2009-04-23) */ public function deletePage($page) { if (($page < 1) OR ($page > $this->numpages)) { return false; } // delete current page unset($this->pages[$page]); unset($this->pagedim[$page]); unset($this->pagelen[$page]); unset($this->intmrk[$page]); unset($this->bordermrk[$page]); unset($this->cntmrk[$page]); foreach ($this->pageobjects[$page] as $oid) { if (isset($this->offsets[$oid])){ unset($this->offsets[$oid]); } } unset($this->pageobjects[$page]); if (isset($this->footerpos[$page])) { unset($this->footerpos[$page]); } if (isset($this->footerlen[$page])) { unset($this->footerlen[$page]); } if (isset($this->transfmrk[$page])) { unset($this->transfmrk[$page]); } if (isset($this->PageAnnots[$page])) { unset($this->PageAnnots[$page]); } if (isset($this->newpagegroup) AND !empty($this->newpagegroup)) { for ($i = $page; $i > 0; --$i) { if (isset($this->newpagegroup[$i]) AND (($i + $this->pagegroups[$this->newpagegroup[$i]]) > $page)) { --$this->pagegroups[$this->newpagegroup[$i]]; break; } } } if (isset($this->pageopen[$page])) { unset($this->pageopen[$page]); } if ($page < $this->numpages) { // update remaining pages for ($i = $page; $i < $this->numpages; ++$i) { $j = $i + 1; // shift pages $this->setPageBuffer($i, $this->getPageBuffer($j)); $this->pagedim[$i] = $this->pagedim[$j]; $this->pagelen[$i] = $this->pagelen[$j]; $this->intmrk[$i] = $this->intmrk[$j]; $this->bordermrk[$i] = $this->bordermrk[$j]; $this->cntmrk[$i] = $this->cntmrk[$j]; $this->pageobjects[$i] = $this->pageobjects[$j]; if (isset($this->footerpos[$j])) { $this->footerpos[$i] = $this->footerpos[$j]; } elseif (isset($this->footerpos[$i])) { unset($this->footerpos[$i]); } if (isset($this->footerlen[$j])) { $this->footerlen[$i] = $this->footerlen[$j]; } elseif (isset($this->footerlen[$i])) { unset($this->footerlen[$i]); } if (isset($this->transfmrk[$j])) { $this->transfmrk[$i] = $this->transfmrk[$j]; } elseif (isset($this->transfmrk[$i])) { unset($this->transfmrk[$i]); } if (isset($this->PageAnnots[$j])) { $this->PageAnnots[$i] = $this->PageAnnots[$j]; } elseif (isset($this->PageAnnots[$i])) { unset($this->PageAnnots[$i]); } if (isset($this->newpagegroup[$j])) { $this->newpagegroup[$i] = $this->newpagegroup[$j]; unset($this->newpagegroup[$j]); } if ($this->currpagegroup == $j) { $this->currpagegroup = $i; } if (isset($this->pageopen[$j])) { $this->pageopen[$i] = $this->pageopen[$j]; } elseif (isset($this->pageopen[$i])) { unset($this->pageopen[$i]); } } // remove last page unset($this->pages[$this->numpages]); unset($this->pagedim[$this->numpages]); unset($this->pagelen[$this->numpages]); unset($this->intmrk[$this->numpages]); unset($this->bordermrk[$this->numpages]); unset($this->cntmrk[$this->numpages]); foreach ($this->pageobjects[$this->numpages] as $oid) { if (isset($this->offsets[$oid])){ unset($this->offsets[$oid]); } } unset($this->pageobjects[$this->numpages]); if (isset($this->footerpos[$this->numpages])) { unset($this->footerpos[$this->numpages]); } if (isset($this->footerlen[$this->numpages])) { unset($this->footerlen[$this->numpages]); } if (isset($this->transfmrk[$this->numpages])) { unset($this->transfmrk[$this->numpages]); } if (isset($this->PageAnnots[$this->numpages])) { unset($this->PageAnnots[$this->numpages]); } if (isset($this->newpagegroup[$this->numpages])) { unset($this->newpagegroup[$this->numpages]); } if ($this->currpagegroup == $this->numpages) { $this->currpagegroup = ($this->numpages - 1); } if (isset($this->pagegroups[$this->numpages])) { unset($this->pagegroups[$this->numpages]); } if (isset($this->pageopen[$this->numpages])) { unset($this->pageopen[$this->numpages]); } } --$this->numpages; $this->page = $this->numpages; // adjust outlines $tmpoutlines = $this->outlines; foreach ($tmpoutlines as $key => $outline) { if ($outline['p'] > $page) { $this->outlines[$key]['p'] = $outline['p'] - 1; } elseif ($outline['p'] == $page) { unset($this->outlines[$key]); } } // adjust dests $tmpdests = $this->dests; foreach ($tmpdests as $key => $dest) { if ($dest['p'] > $page) { $this->dests[$key]['p'] = $dest['p'] - 1; } elseif ($dest['p'] == $page) { unset($this->dests[$key]); } } // adjust links $tmplinks = $this->links; foreach ($tmplinks as $key => $link) { if ($link[0] > $page) { $this->links[$key][0] = $link[0] - 1; } elseif ($link[0] == $page) { unset($this->links[$key]); } } // adjust javascript $tmpjavascript = $this->javascript; global $jpage; $jpage = $page; $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/', create_function('$matches', 'global $jpage; $pagenum = intval($matches[3]) + 1; if ($pagenum >= $jpage) { $newpage = ($pagenum - 1); } elseif ($pagenum == $jpage) { $newpage = 1; } else { $newpage = $pagenum; } --$newpage; return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript); // return to last page $this->lastPage(true); return true; } /** * Clone the specified page to a new page. * @param $page (int) number of page to copy (0 = current page) * @return true in case of success, false in case of error. * @public * @since 4.9.015 (2010-04-20) */ public function copyPage($page=0) { if ($page == 0) { // default value $page = $this->page; } if (($page < 1) OR ($page > $this->numpages)) { return false; } // close the last page $this->endPage(); // copy all page-related states ++$this->numpages; $this->page = $this->numpages; $this->setPageBuffer($this->page, $this->getPageBuffer($page)); $this->pagedim[$this->page] = $this->pagedim[$page]; $this->pagelen[$this->page] = $this->pagelen[$page]; $this->intmrk[$this->page] = $this->intmrk[$page]; $this->bordermrk[$this->page] = $this->bordermrk[$page]; $this->cntmrk[$this->page] = $this->cntmrk[$page]; $this->pageobjects[$this->page] = $this->pageobjects[$page]; $this->pageopen[$this->page] = false; if (isset($this->footerpos[$page])) { $this->footerpos[$this->page] = $this->footerpos[$page]; } if (isset($this->footerlen[$page])) { $this->footerlen[$this->page] = $this->footerlen[$page]; } if (isset($this->transfmrk[$page])) { $this->transfmrk[$this->page] = $this->transfmrk[$page]; } if (isset($this->PageAnnots[$page])) { $this->PageAnnots[$this->page] = $this->PageAnnots[$page]; } if (isset($this->newpagegroup[$page])) { // start a new group $this->newpagegroup[$this->page] = sizeof($this->newpagegroup) + 1; $this->currpagegroup = $this->newpagegroup[$this->page]; $this->pagegroups[$this->currpagegroup] = 1; } elseif (isset($this->currpagegroup) AND ($this->currpagegroup > 0)) { ++$this->pagegroups[$this->currpagegroup]; } // copy outlines $tmpoutlines = $this->outlines; foreach ($tmpoutlines as $key => $outline) { if ($outline['p'] == $page) { $this->outlines[] = array('t' => $outline['t'], 'l' => $outline['l'], 'x' => $outline['x'], 'y' => $outline['y'], 'p' => $this->page, 's' => $outline['s'], 'c' => $outline['c']); } } // copy links $tmplinks = $this->links; foreach ($tmplinks as $key => $link) { if ($link[0] == $page) { $this->links[] = array($this->page, $link[1]); } } // return to last page $this->lastPage(true); return true; } /** * Output a Table of Content Index (TOC). * This method must be called after all Bookmarks were set. * Before calling this method you have to open the page using the addTOCPage() method. * After calling this method you have to call endTOCPage() to close the TOC page. * You can override this method to achieve different styles. * @param $page (int) page number where this TOC should be inserted (leave empty for current page). * @param $numbersfont (string) set the font for page numbers (please use monospaced font for better alignment). * @param $filler (string) string used to fill the space between text and page number. * @param $toc_name (string) name to use for TOC bookmark. * @param $style (string) Font style for title: B = Bold, I = Italic, BI = Bold + Italic. * @param $color (array) RGB color array for bookmark title (values from 0 to 255). * @public * @author Nicola Asuni * @since 4.5.000 (2009-01-02) * @see addTOCPage(), endTOCPage(), addHTMLTOC() */ public function addTOC($page='', $numbersfont='', $filler='.', $toc_name='TOC', $style='', $color=array(0,0,0)) { $fontsize = $this->FontSizePt; $fontfamily = $this->FontFamily; $fontstyle = $this->FontStyle; $w = $this->w - $this->lMargin - $this->rMargin; $spacer = $this->GetStringWidth(chr(32)) * 4; $lmargin = $this->lMargin; $rmargin = $this->rMargin; $x_start = $this->GetX(); $page_first = $this->page; $current_page = $this->page; $page_fill_start = false; $page_fill_end = false; $current_column = $this->current_column; if (TCPDF_STATIC::empty_string($numbersfont)) { $numbersfont = $this->default_monospaced_font; } if (TCPDF_STATIC::empty_string($filler)) { $filler = ' '; } if (TCPDF_STATIC::empty_string($page)) { $gap = ' '; } else { $gap = ''; if ($page < 1) { $page = 1; } } $this->SetFont($numbersfont, $fontstyle, $fontsize); $numwidth = $this->GetStringWidth('00000'); $maxpage = 0; //used for pages on attached documents foreach ($this->outlines as $key => $outline) { // check for extra pages (used for attachments) if (($this->page > $page_first) AND ($outline['p'] >= $this->numpages)) { $outline['p'] += ($this->page - $page_first); } if ($this->rtl) { $aligntext = 'R'; $alignnum = 'L'; } else { $aligntext = 'L'; $alignnum = 'R'; } if ($outline['l'] == 0) { $this->SetFont($fontfamily, $outline['s'].'B', $fontsize); } else { $this->SetFont($fontfamily, $outline['s'], $fontsize - $outline['l']); } $this->SetTextColorArray($outline['c']); // check for page break $this->checkPageBreak((2 * $this->FontSize * $this->cell_height_ratio)); // set margins and X position if (($this->page == $current_page) AND ($this->current_column == $current_column)) { $this->lMargin = $lmargin; $this->rMargin = $rmargin; } else { if ($this->current_column != $current_column) { if ($this->rtl) { $x_start = $this->w - $this->columns[$this->current_column]['x']; } else { $x_start = $this->columns[$this->current_column]['x']; } } $lmargin = $this->lMargin; $rmargin = $this->rMargin; $current_page = $this->page; $current_column = $this->current_column; } $this->SetX($x_start); $indent = ($spacer * $outline['l']); if ($this->rtl) { $this->x -= $indent; $this->rMargin = $this->w - $this->x; } else { $this->x += $indent; $this->lMargin = $this->x; } $link = $this->AddLink(); $this->SetLink($link, $outline['y'], $outline['p']); // write the text if ($this->rtl) { $txt = ' '.$outline['t']; } else { $txt = $outline['t'].' '; } $this->Write(0, $txt, $link, false, $aligntext, false, 0, false, false, 0, $numwidth, ''); if ($this->rtl) { $tw = $this->x - $this->lMargin; } else { $tw = $this->w - $this->rMargin - $this->x; } $this->SetFont($numbersfont, $fontstyle, $fontsize); if (TCPDF_STATIC::empty_string($page)) { $pagenum = $outline['p']; } else { // placemark to be replaced with the correct number $pagenum = '{#'.($outline['p']).'}'; if ($this->isUnicodeFont()) { $pagenum = '{'.$pagenum.'}'; } $maxpage = max($maxpage, $outline['p']); } $fw = ($tw - $this->GetStringWidth($pagenum.$filler)); $numfills = floor($fw / $this->GetStringWidth($filler)); if ($numfills > 0) { $rowfill = str_repeat($filler, $numfills); } else { $rowfill = ''; } if ($this->rtl) { $pagenum = $pagenum.$gap.$rowfill; } else { $pagenum = $rowfill.$gap.$pagenum; } // write the number $this->Cell($tw, 0, $pagenum, 0, 1, $alignnum, 0, $link, 0); } $page_last = $this->getPage(); $numpages = ($page_last - $page_first + 1); // account for booklet mode if ($this->booklet) { // check if a blank page is required before TOC $page_fill_start = ((($page_first % 2) == 0) XOR (($page % 2) == 0)); $page_fill_end = (!((($numpages % 2) == 0) XOR ($page_fill_start))); if ($page_fill_start) { // add a page at the end (to be moved before TOC) $this->addPage(); ++$page_last; ++$numpages; } if ($page_fill_end) { // add a page at the end $this->addPage(); ++$page_last; ++$numpages; } } $maxpage = max($maxpage, $page_last); if (!TCPDF_STATIC::empty_string($page)) { for ($p = $page_first; $p <= $page_last; ++$p) { // get page data $temppage = $this->getPageBuffer($p); for ($n = 1; $n <= $maxpage; ++$n) { // update page numbers $a = '{#'.$n.'}'; // get page number aliases $pnalias = $this->getInternalPageNumberAliases($a); // calculate replacement number if (($n >= $page) AND ($n <= $this->numpages)) { $np = $n + $numpages; } else { $np = $n; } $na = TCPDF_STATIC::formatTOCPageNumber(($this->starting_page_number + $np - 1)); $nu = TCPDF_FONTS::UTF8ToUTF16BE($na, false, $this->isunicode, $this->CurrentFont); // replace aliases with numbers foreach ($pnalias['u'] as $u) { $sfill = str_repeat($filler, max(0, (strlen($u) - strlen($nu.' ')))); if ($this->rtl) { $nr = $nu.TCPDF_FONTS::UTF8ToUTF16BE(' '.$sfill, false, $this->isunicode, $this->CurrentFont); } else { $nr = TCPDF_FONTS::UTF8ToUTF16BE($sfill.' ', false, $this->isunicode, $this->CurrentFont).$nu; } $temppage = str_replace($u, $nr, $temppage); } foreach ($pnalias['a'] as $a) { $sfill = str_repeat($filler, max(0, (strlen($a) - strlen($na.' ')))); if ($this->rtl) { $nr = $na.' '.$sfill; } else { $nr = $sfill.' '.$na; } $temppage = str_replace($a, $nr, $temppage); } } // save changes $this->setPageBuffer($p, $temppage); } // move pages $this->Bookmark($toc_name, 0, 0, $page_first, $style, $color); if ($page_fill_start) { $this->movePage($page_last, $page_first); } for ($i = 0; $i < $numpages; ++$i) { $this->movePage($page_last, $page); } } } /** * Output a Table Of Content Index (TOC) using HTML templates. * This method must be called after all Bookmarks were set. * Before calling this method you have to open the page using the addTOCPage() method. * After calling this method you have to call endTOCPage() to close the TOC page. * @param $page (int) page number where this TOC should be inserted (leave empty for current page). * @param $toc_name (string) name to use for TOC bookmark. * @param $templates (array) array of html templates. Use: "#TOC_DESCRIPTION#" for bookmark title, "#TOC_PAGE_NUMBER#" for page number. * @param $correct_align (boolean) if true correct the number alignment (numbers must be in monospaced font like courier and right aligned on LTR, or left aligned on RTL) * @param $style (string) Font style for title: B = Bold, I = Italic, BI = Bold + Italic. * @param $color (array) RGB color array for title (values from 0 to 255). * @public * @author Nicola Asuni * @since 5.0.001 (2010-05-06) * @see addTOCPage(), endTOCPage(), addTOC() */ public function addHTMLTOC($page='', $toc_name='TOC', $templates=array(), $correct_align=true, $style='', $color=array(0,0,0)) { $filler = ' '; $prev_htmlLinkColorArray = $this->htmlLinkColorArray; $prev_htmlLinkFontStyle = $this->htmlLinkFontStyle; // set new style for link $this->htmlLinkColorArray = array(); $this->htmlLinkFontStyle = ''; $page_first = $this->getPage(); $page_fill_start = false; $page_fill_end = false; // get the font type used for numbers in each template $current_font = $this->FontFamily; foreach ($templates as $level => $html) { $dom = $this->getHtmlDomArray($html); foreach ($dom as $key => $value) { if ($value['value'] == '#TOC_PAGE_NUMBER#') { $this->SetFont($dom[($key - 1)]['fontname']); $templates['F'.$level] = $this->isUnicodeFont(); } } } $this->SetFont($current_font); $maxpage = 0; //used for pages on attached documents foreach ($this->outlines as $key => $outline) { // get HTML template $row = $templates[$outline['l']]; if (TCPDF_STATIC::empty_string($page)) { $pagenum = $outline['p']; } else { // placemark to be replaced with the correct number $pagenum = '{#'.($outline['p']).'}'; if ($templates['F'.$outline['l']]) { $pagenum = '{'.$pagenum.'}'; } $maxpage = max($maxpage, $outline['p']); } // replace templates with current values $row = str_replace('#TOC_DESCRIPTION#', $outline['t'], $row); $row = str_replace('#TOC_PAGE_NUMBER#', $pagenum, $row); // add link to page $row = ''.$row.''; // write bookmark entry $this->writeHTML($row, false, false, true, false, ''); } // restore link styles $this->htmlLinkColorArray = $prev_htmlLinkColorArray; $this->htmlLinkFontStyle = $prev_htmlLinkFontStyle; // move TOC page and replace numbers $page_last = $this->getPage(); $numpages = ($page_last - $page_first + 1); // account for booklet mode if ($this->booklet) { // check if a blank page is required before TOC $page_fill_start = ((($page_first % 2) == 0) XOR (($page % 2) == 0)); $page_fill_end = (!((($numpages % 2) == 0) XOR ($page_fill_start))); if ($page_fill_start) { // add a page at the end (to be moved before TOC) $this->addPage(); ++$page_last; ++$numpages; } if ($page_fill_end) { // add a page at the end $this->addPage(); ++$page_last; ++$numpages; } } $maxpage = max($maxpage, $page_last); if (!TCPDF_STATIC::empty_string($page)) { for ($p = $page_first; $p <= $page_last; ++$p) { // get page data $temppage = $this->getPageBuffer($p); for ($n = 1; $n <= $maxpage; ++$n) { // update page numbers $a = '{#'.$n.'}'; // get page number aliases $pnalias = $this->getInternalPageNumberAliases($a); // calculate replacement number if ($n >= $page) { $np = $n + $numpages; } else { $np = $n; } $na = TCPDF_STATIC::formatTOCPageNumber(($this->starting_page_number + $np - 1)); $nu = TCPDF_FONTS::UTF8ToUTF16BE($na, false, $this->isunicode, $this->CurrentFont); // replace aliases with numbers foreach ($pnalias['u'] as $u) { if ($correct_align) { $sfill = str_repeat($filler, (strlen($u) - strlen($nu.' '))); if ($this->rtl) { $nr = $nu.TCPDF_FONTS::UTF8ToUTF16BE(' '.$sfill, false, $this->isunicode, $this->CurrentFont); } else { $nr = TCPDF_FONTS::UTF8ToUTF16BE($sfill.' ', false, $this->isunicode, $this->CurrentFont).$nu; } } else { $nr = $nu; } $temppage = str_replace($u, $nr, $temppage); } foreach ($pnalias['a'] as $a) { if ($correct_align) { $sfill = str_repeat($filler, (strlen($a) - strlen($na.' '))); if ($this->rtl) { $nr = $na.' '.$sfill; } else { $nr = $sfill.' '.$na; } } else { $nr = $na; } $temppage = str_replace($a, $nr, $temppage); } } // save changes $this->setPageBuffer($p, $temppage); } // move pages $this->Bookmark($toc_name, 0, 0, $page_first, $style, $color); if ($page_fill_start) { $this->movePage($page_last, $page_first); } for ($i = 0; $i < $numpages; ++$i) { $this->movePage($page_last, $page); } } } /** * Stores a copy of the current TCPDF object used for undo operation. * @public * @since 4.5.029 (2009-03-19) */ public function startTransaction() { if (isset($this->objcopy)) { // remove previous copy $this->commitTransaction(); } // record current page number and Y position $this->start_transaction_page = $this->page; $this->start_transaction_y = $this->y; // clone current object $this->objcopy = TCPDF_STATIC::objclone($this); } /** * Delete the copy of the current TCPDF object used for undo operation. * @public * @since 4.5.029 (2009-03-19) */ public function commitTransaction() { if (isset($this->objcopy)) { $this->objcopy->_destroy(true, true); unset($this->objcopy); } } /** * This method allows to undo the latest transaction by returning the latest saved TCPDF object with startTransaction(). * @param $self (boolean) if true restores current class object to previous state without the need of reassignment via the returned value. * @return TCPDF object. * @public * @since 4.5.029 (2009-03-19) */ public function rollbackTransaction($self=false) { if (isset($this->objcopy)) { if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) { // truncate files to previous values foreach ($this->objcopy->cache_file_length as $file => $length) { $file = substr($file, 1); $handle = fopen($file, 'r+'); ftruncate($handle, $length); } } $this->_destroy(true, true); if ($self) { $objvars = get_object_vars($this->objcopy); foreach ($objvars as $key => $value) { $this->$key = $value; } } return $this->objcopy; } return $this; } // --- MULTI COLUMNS METHODS ----------------------- /** * Set multiple columns of the same size * @param $numcols (int) number of columns (set to zero to disable columns mode) * @param $width (int) column width * @param $y (int) column starting Y position (leave empty for current Y position) * @public * @since 4.9.001 (2010-03-28) */ public function setEqualColumns($numcols=0, $width=0, $y='') { $this->columns = array(); if ($numcols < 2) { $numcols = 0; $this->columns = array(); } else { // maximum column width $maxwidth = ($this->w - $this->original_lMargin - $this->original_rMargin) / $numcols; if (($width == 0) OR ($width > $maxwidth)) { $width = $maxwidth; } if (TCPDF_STATIC::empty_string($y)) { $y = $this->y; } // space between columns $space = (($this->w - $this->original_lMargin - $this->original_rMargin - ($numcols * $width)) / ($numcols - 1)); // fill the columns array (with, space, starting Y position) for ($i = 0; $i < $numcols; ++$i) { $this->columns[$i] = array('w' => $width, 's' => $space, 'y' => $y); } } $this->num_columns = $numcols; $this->current_column = 0; $this->column_start_page = $this->page; $this->selectColumn(0); } /** * Remove columns and reset page margins. * @public * @since 5.9.072 (2011-04-26) */ public function resetColumns() { $this->lMargin = $this->original_lMargin; $this->rMargin = $this->original_rMargin; $this->setEqualColumns(); } /** * Set columns array. * Each column is represented by an array of arrays with the following keys: (w = width, s = space between columns, y = column top position). * @param $columns (array) * @public * @since 4.9.001 (2010-03-28) */ public function setColumnsArray($columns) { $this->columns = $columns; $this->num_columns = count($columns); $this->current_column = 0; $this->column_start_page = $this->page; $this->selectColumn(0); } /** * Set position at a given column * @param $col (int) column number (from 0 to getNumberOfColumns()-1); empty string = current column. * @public * @since 4.9.001 (2010-03-28) */ public function selectColumn($col='') { if (is_string($col)) { $col = $this->current_column; } elseif ($col >= $this->num_columns) { $col = 0; } $xshift = array('x' => 0, 's' => array('H' => 0, 'V' => 0), 'p' => array('L' => 0, 'T' => 0, 'R' => 0, 'B' => 0)); $enable_thead = false; if ($this->num_columns > 1) { if ($col != $this->current_column) { // move Y pointer at the top of the column if ($this->column_start_page == $this->page) { $this->y = $this->columns[$col]['y']; } else { $this->y = $this->tMargin; } // Avoid to write table headers more than once if (($this->page > $this->maxselcol['page']) OR (($this->page == $this->maxselcol['page']) AND ($col > $this->maxselcol['column']))) { $enable_thead = true; $this->maxselcol['page'] = $this->page; $this->maxselcol['column'] = $col; } } $xshift = $this->colxshift; // set X position of the current column by case $listindent = ($this->listindentlevel * $this->listindent); // calculate column X position $colpos = 0; for ($i = 0; $i < $col; ++$i) { $colpos += ($this->columns[$i]['w'] + $this->columns[$i]['s']); } if ($this->rtl) { $x = $this->w - $this->original_rMargin - $colpos; $this->rMargin = ($this->w - $x + $listindent); $this->lMargin = ($x - $this->columns[$col]['w']); $this->x = $x - $listindent; } else { $x = $this->original_lMargin + $colpos; $this->lMargin = ($x + $listindent); $this->rMargin = ($this->w - $x - $this->columns[$col]['w']); $this->x = $x + $listindent; } $this->columns[$col]['x'] = $x; } $this->current_column = $col; // fix for HTML mode $this->newline = true; // print HTML table header (if any) if ((!TCPDF_STATIC::empty_string($this->thead)) AND (!$this->inthead)) { if ($enable_thead) { // print table header $this->writeHTML($this->thead, false, false, false, false, ''); $this->y += $xshift['s']['V']; // store end of header position if (!isset($this->columns[$col]['th'])) { $this->columns[$col]['th'] = array(); } $this->columns[$col]['th']['\''.$this->page.'\''] = $this->y; $this->lasth = 0; } elseif (isset($this->columns[$col]['th']['\''.$this->page.'\''])) { $this->y = $this->columns[$col]['th']['\''.$this->page.'\'']; } } // account for an html table cell over multiple columns if ($this->rtl) { $this->rMargin += $xshift['x']; $this->x -= ($xshift['x'] + $xshift['p']['R']); } else { $this->lMargin += $xshift['x']; $this->x += $xshift['x'] + $xshift['p']['L']; } } /** * Return the current column number * @return int current column number * @public * @since 5.5.011 (2010-07-08) */ public function getColumn() { return $this->current_column; } /** * Return the current number of columns. * @return int number of columns * @public * @since 5.8.018 (2010-08-25) */ public function getNumberOfColumns() { return $this->num_columns; } /** * Set Text rendering mode. * @param $stroke (int) outline size in user units (0 = disable). * @param $fill (boolean) if true fills the text (default). * @param $clip (boolean) if true activate clipping mode * @public * @since 4.9.008 (2009-04-02) */ public function setTextRenderingMode($stroke=0, $fill=true, $clip=false) { // Ref.: PDF 32000-1:2008 - 9.3.6 Text Rendering Mode // convert text rendering parameters if ($stroke < 0) { $stroke = 0; } if ($fill === true) { if ($stroke > 0) { if ($clip === true) { // Fill, then stroke text and add to path for clipping $textrendermode = 6; } else { // Fill, then stroke text $textrendermode = 2; } $textstrokewidth = $stroke; } else { if ($clip === true) { // Fill text and add to path for clipping $textrendermode = 4; } else { // Fill text $textrendermode = 0; } } } else { if ($stroke > 0) { if ($clip === true) { // Stroke text and add to path for clipping $textrendermode = 5; } else { // Stroke text $textrendermode = 1; } $textstrokewidth = $stroke; } else { if ($clip === true) { // Add text to path for clipping $textrendermode = 7; } else { // Neither fill nor stroke text (invisible) $textrendermode = 3; } } } $this->textrendermode = $textrendermode; $this->textstrokewidth = $stroke; } /** * Set parameters for drop shadow effect for text. * @param $params (array) Array of parameters: enabled (boolean) set to true to enable shadow; depth_w (float) shadow width in user units; depth_h (float) shadow height in user units; color (array) shadow color or false to use the stroke color; opacity (float) Alpha value: real value from 0 (transparent) to 1 (opaque); blend_mode (string) blend mode, one of the following: Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity. * @since 5.9.174 (2012-07-25) * @public */ public function setTextShadow($params=array('enabled'=>false, 'depth_w'=>0, 'depth_h'=>0, 'color'=>false, 'opacity'=>1, 'blend_mode'=>'Normal')) { if (isset($params['enabled'])) { $this->txtshadow['enabled'] = $params['enabled']?true:false; } else { $this->txtshadow['enabled'] = false; } if (isset($params['depth_w'])) { $this->txtshadow['depth_w'] = floatval($params['depth_w']); } else { $this->txtshadow['depth_w'] = 0; } if (isset($params['depth_h'])) { $this->txtshadow['depth_h'] = floatval($params['depth_h']); } else { $this->txtshadow['depth_h'] = 0; } if (isset($params['color']) AND ($params['color'] !== false) AND is_array($params['color'])) { $this->txtshadow['color'] = $params['color']; } else { $this->txtshadow['color'] = $this->strokecolor; } if (isset($params['opacity'])) { $this->txtshadow['opacity'] = min(1, max(0, floatval($params['opacity']))); } else { $this->txtshadow['opacity'] = 1; } if (isset($params['blend_mode']) AND in_array($params['blend_mode'], array('Normal', 'Multiply', 'Screen', 'Overlay', 'Darken', 'Lighten', 'ColorDodge', 'ColorBurn', 'HardLight', 'SoftLight', 'Difference', 'Exclusion', 'Hue', 'Saturation', 'Color', 'Luminosity'))) { $this->txtshadow['blend_mode'] = $params['blend_mode']; } else { $this->txtshadow['blend_mode'] = 'Normal'; } if ((($this->txtshadow['depth_w'] == 0) AND ($this->txtshadow['depth_h'] == 0)) OR ($this->txtshadow['opacity'] == 0)) { $this->txtshadow['enabled'] = false; } } /** * Return the text shadow parameters array. * @return Array of parameters. * @since 5.9.174 (2012-07-25) * @public */ public function getTextShadow() { return $this->txtshadow; } /** * Returns an array of chars containing soft hyphens. * @param $word (array) array of chars * @param $patterns (array) Array of hypenation patterns. * @param $dictionary (array) Array of words to be returned without applying the hyphenation algoritm. * @param $leftmin (int) Minimum number of character to leave on the left of the word without applying the hyphens. * @param $rightmin (int) Minimum number of character to leave on the right of the word without applying the hyphens. * @param $charmin (int) Minimum word length to apply the hyphenation algoritm. * @param $charmax (int) Maximum length of broken piece of word. * @return array text with soft hyphens * @author Nicola Asuni * @since 4.9.012 (2010-04-12) * @protected */ protected function hyphenateWord($word, $patterns, $dictionary=array(), $leftmin=1, $rightmin=2, $charmin=1, $charmax=8) { $hyphenword = array(); // hyphens positions $numchars = count($word); if ($numchars <= $charmin) { return $word; } $word_string = TCPDF_FONTS::UTF8ArrSubString($word, '', '', $this->isunicode); // some words will be returned as-is $pattern = '/^([a-zA-Z0-9_\.\-]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/'; if (preg_match($pattern, $word_string) > 0) { // email return $word; } $pattern = '/(([a-zA-Z0-9\-]+\.)?)((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/'; if (preg_match($pattern, $word_string) > 0) { // URL return $word; } if (isset($dictionary[$word_string])) { return TCPDF_FONTS::UTF8StringToArray($dictionary[$word_string], $this->isunicode, $this->CurrentFont); } // suround word with '_' characters $tmpword = array_merge(array(95), $word, array(95)); $tmpnumchars = $numchars + 2; $maxpos = $tmpnumchars - $charmin; for ($pos = 0; $pos < $maxpos; ++$pos) { $imax = min(($tmpnumchars - $pos), $charmax); for ($i = $charmin; $i <= $imax; ++$i) { $subword = strtolower(TCPDF_FONTS::UTF8ArrSubString($tmpword, $pos, ($pos + $i), $this->isunicode)); if (isset($patterns[$subword])) { $pattern = TCPDF_FONTS::UTF8StringToArray($patterns[$subword], $this->isunicode, $this->CurrentFont); $pattern_length = count($pattern); $digits = 1; for ($j = 0; $j < $pattern_length; ++$j) { // check if $pattern[$j] is a number if (($pattern[$j] >= 48) AND ($pattern[$j] <= 57)) { if ($j == 0) { $zero = $pos - 1; } else { $zero = $pos + $j - $digits; } if (!isset($hyphenword[$zero]) OR ($hyphenword[$zero] != $pattern[$j])) { $hyphenword[$zero] = TCPDF_FONTS::unichr($pattern[$j], $this->isunicode); } ++$digits; } } } } } $inserted = 0; $maxpos = $numchars - $rightmin; for ($i = $leftmin; $i <= $maxpos; ++$i) { if (isset($hyphenword[$i]) AND (($hyphenword[$i] % 2) != 0)) { // 173 = soft hyphen character array_splice($word, $i + $inserted, 0, 173); ++$inserted; } } return $word; } /** * Returns text with soft hyphens. * @param $text (string) text to process * @param $patterns (mixed) Array of hypenation patterns or a TEX file containing hypenation patterns. TEX patterns can be downloaded from http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/ * @param $dictionary (array) Array of words to be returned without applying the hyphenation algoritm. * @param $leftmin (int) Minimum number of character to leave on the left of the word without applying the hyphens. * @param $rightmin (int) Minimum number of character to leave on the right of the word without applying the hyphens. * @param $charmin (int) Minimum word length to apply the hyphenation algoritm. * @param $charmax (int) Maximum length of broken piece of word. * @return array text with soft hyphens * @author Nicola Asuni * @since 4.9.012 (2010-04-12) * @public */ public function hyphenateText($text, $patterns, $dictionary=array(), $leftmin=1, $rightmin=2, $charmin=1, $charmax=8) { $text = $this->unhtmlentities($text); $word = array(); // last word $txtarr = array(); // text to be returned $intag = false; // true if we are inside an HTML tag if (!is_array($patterns)) { $patterns = TCPDF_STATIC::getHyphenPatternsFromTEX($patterns); } // get array of characters $unichars = TCPDF_FONTS::UTF8StringToArray($text, $this->isunicode, $this->CurrentFont); // for each char foreach ($unichars as $char) { if ((!$intag) AND TCPDF_FONT_DATA::$uni_type[$char] == 'L') { // letter character $word[] = $char; } else { // other type of character if (!TCPDF_STATIC::empty_string($word)) { // hypenate the word $txtarr = array_merge($txtarr, $this->hyphenateWord($word, $patterns, $dictionary, $leftmin, $rightmin, $charmin, $charmax)); $word = array(); } $txtarr[] = $char; if (chr($char) == '<') { // we are inside an HTML tag $intag = true; } elseif ($intag AND (chr($char) == '>')) { // end of HTML tag $intag = false; } } } if (!TCPDF_STATIC::empty_string($word)) { // hypenate the word $txtarr = array_merge($txtarr, $this->hyphenateWord($word, $patterns, $dictionary, $leftmin, $rightmin, $charmin, $charmax)); } // convert char array to string and return return TCPDF_FONTS::UTF8ArrSubString($txtarr, '', '', $this->isunicode); } /** * Enable/disable rasterization of vector images using ImageMagick library. * @param $mode (boolean) if true enable rasterization, false otherwise. * @public * @since 5.0.000 (2010-04-27) */ public function setRasterizeVectorImages($mode) { $this->rasterize_vector_images = $mode; } /** * Enable or disable default option for font subsetting. * @param $enable (boolean) if true enable font subsetting by default. * @author Nicola Asuni * @public * @since 5.3.002 (2010-06-07) */ public function setFontSubsetting($enable=true) { if ($this->pdfa_mode) { $this->font_subsetting = false; } else { $this->font_subsetting = $enable ? true : false; } } /** * Return the default option for font subsetting. * @return boolean default font subsetting state. * @author Nicola Asuni * @public * @since 5.3.002 (2010-06-07) */ public function getFontSubsetting() { return $this->font_subsetting; } /** * Left trim the input string * @param $str (string) string to trim * @param $replace (string) string that replace spaces. * @return left trimmed string * @author Nicola Asuni * @public * @since 5.8.000 (2010-08-11) */ public function stringLeftTrim($str, $replace='') { return preg_replace('/^'.$this->re_space['p'].'+/'.$this->re_space['m'], $replace, $str); } /** * Right trim the input string * @param $str (string) string to trim * @param $replace (string) string that replace spaces. * @return right trimmed string * @author Nicola Asuni * @public * @since 5.8.000 (2010-08-11) */ public function stringRightTrim($str, $replace='') { return preg_replace('/'.$this->re_space['p'].'+$/'.$this->re_space['m'], $replace, $str); } /** * Trim the input string * @param $str (string) string to trim * @param $replace (string) string that replace spaces. * @return trimmed string * @author Nicola Asuni * @public * @since 5.8.000 (2010-08-11) */ public function stringTrim($str, $replace='') { $str = $this->stringLeftTrim($str, $replace); $str = $this->stringRightTrim($str, $replace); return $str; } /** * Return true if the current font is unicode type. * @return true for unicode font, false otherwise. * @author Nicola Asuni * @public * @since 5.8.002 (2010-08-14) */ public function isUnicodeFont() { return (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0')); } /** * Return normalized font name * @param $fontfamily (string) property string containing font family names * @return string normalized font name * @author Nicola Asuni * @public * @since 5.8.004 (2010-08-17) */ public function getFontFamilyName($fontfamily) { // remove spaces and symbols $fontfamily = preg_replace('/[^a-z0-9_\,]/', '', strtolower($fontfamily)); // extract all font names $fontslist = preg_split('/[,]/', $fontfamily); // find first valid font name foreach ($fontslist as $font) { // replace font variations $font = preg_replace('/italic$/', 'I', $font); $font = preg_replace('/oblique$/', 'I', $font); $font = preg_replace('/bold([I]?)$/', 'B\\1', $font); // replace common family names and core fonts $pattern = array(); $replacement = array(); $pattern[] = '/^serif|^cursive|^fantasy|^timesnewroman/'; $replacement[] = 'times'; $pattern[] = '/^sansserif/'; $replacement[] = 'helvetica'; $pattern[] = '/^monospace/'; $replacement[] = 'courier'; $font = preg_replace($pattern, $replacement, $font); if (in_array(strtolower($font), $this->fontlist) OR in_array($font, $this->fontkeys)) { return $font; } } // return current font as default return $this->CurrentFont['fontkey']; } /** * Start a new XObject Template. * An XObject Template is a PDF block that is a self-contained description of any sequence of graphics objects (including path objects, text objects, and sampled images). * An XObject Template may be painted multiple times, either on several pages or at several locations on the same page and produces the same results each time, subject only to the graphics state at the time it is invoked. * Note: X,Y coordinates will be reset to 0,0. * @param $w (int) Template width in user units (empty string or zero = page width less margins). * @param $h (int) Template height in user units (empty string or zero = page height less margins). * @param $group (mixed) Set transparency group. Can be a boolean value or an array specifying optional parameters: 'CS' (solour space name), 'I' (boolean flag to indicate isolated group) and 'K' (boolean flag to indicate knockout group). * @return int the XObject Template ID in case of success or false in case of error. * @author Nicola Asuni * @public * @since 5.8.017 (2010-08-24) * @see endTemplate(), printTemplate() */ public function startTemplate($w=0, $h=0, $group=false) { if ($this->inxobj) { // we are already inside an XObject template return false; } $this->inxobj = true; ++$this->n; // XObject ID $this->xobjid = 'XT'.$this->n; // object ID $this->xobjects[$this->xobjid] = array('n' => $this->n); // store current graphic state $this->xobjects[$this->xobjid]['gvars'] = $this->getGraphicVars(); // initialize data $this->xobjects[$this->xobjid]['intmrk'] = 0; $this->xobjects[$this->xobjid]['transfmrk'] = array(); $this->xobjects[$this->xobjid]['outdata'] = ''; $this->xobjects[$this->xobjid]['xobjects'] = array(); $this->xobjects[$this->xobjid]['images'] = array(); $this->xobjects[$this->xobjid]['fonts'] = array(); $this->xobjects[$this->xobjid]['annotations'] = array(); $this->xobjects[$this->xobjid]['extgstates'] = array(); $this->xobjects[$this->xobjid]['gradients'] = array(); $this->xobjects[$this->xobjid]['spot_colors'] = array(); // set new environment $this->num_columns = 1; $this->current_column = 0; $this->SetAutoPageBreak(false); if (($w === '') OR ($w <= 0)) { $w = $this->w - $this->lMargin - $this->rMargin; } if (($h === '') OR ($h <= 0)) { $h = $this->h - $this->tMargin - $this->bMargin; } $this->xobjects[$this->xobjid]['x'] = 0; $this->xobjects[$this->xobjid]['y'] = 0; $this->xobjects[$this->xobjid]['w'] = $w; $this->xobjects[$this->xobjid]['h'] = $h; $this->w = $w; $this->h = $h; $this->wPt = $this->w * $this->k; $this->hPt = $this->h * $this->k; $this->fwPt = $this->wPt; $this->fhPt = $this->hPt; $this->x = 0; $this->y = 0; $this->lMargin = 0; $this->rMargin = 0; $this->tMargin = 0; $this->bMargin = 0; // set group mode $this->xobjects[$this->xobjid]['group'] = $group; return $this->xobjid; } /** * End the current XObject Template started with startTemplate() and restore the previous graphic state. * An XObject Template is a PDF block that is a self-contained description of any sequence of graphics objects (including path objects, text objects, and sampled images). * An XObject Template may be painted multiple times, either on several pages or at several locations on the same page and produces the same results each time, subject only to the graphics state at the time it is invoked. * @return int the XObject Template ID in case of success or false in case of error. * @author Nicola Asuni * @public * @since 5.8.017 (2010-08-24) * @see startTemplate(), printTemplate() */ public function endTemplate() { if (!$this->inxobj) { // we are not inside a template return false; } $this->inxobj = false; // restore previous graphic state $this->setGraphicVars($this->xobjects[$this->xobjid]['gvars'], true); return $this->xobjid; } /** * Print an XObject Template. * You can print an XObject Template inside the currently opened Template. * An XObject Template is a PDF block that is a self-contained description of any sequence of graphics objects (including path objects, text objects, and sampled images). * An XObject Template may be painted multiple times, either on several pages or at several locations on the same page and produces the same results each time, subject only to the graphics state at the time it is invoked. * @param $id (string) The ID of XObject Template to print. * @param $x (int) X position in user units (empty string = current x position) * @param $y (int) Y position in user units (empty string = current y position) * @param $w (int) Width in user units (zero = remaining page width) * @param $h (int) Height in user units (zero = remaining page height) * @param $align (string) Indicates the alignment of the pointer next to template insertion relative to template height. The value can be:
      • T: top-right for LTR or top-left for RTL
      • M: middle-right for LTR or middle-left for RTL
      • B: bottom-right for LTR or bottom-left for RTL
      • N: next line
      * @param $palign (string) Allows to center or align the template on the current line. Possible values are:
      • L : left align
      • C : center
      • R : right align
      • '' : empty string : left for LTR or right for RTL
      * @param $fitonpage (boolean) If true the template is resized to not exceed page dimensions. * @author Nicola Asuni * @public * @since 5.8.017 (2010-08-24) * @see startTemplate(), endTemplate() */ public function printTemplate($id, $x='', $y='', $w=0, $h=0, $align='', $palign='', $fitonpage=false) { if ($this->state != 2) { return; } if (!isset($this->xobjects[$id])) { $this->Error('The XObject Template \''.$id.'\' doesn\'t exist!'); } if ($this->inxobj) { if ($id == $this->xobjid) { // close current template $this->endTemplate(); } else { // use the template as resource for the template currently opened $this->xobjects[$this->xobjid]['xobjects'][$id] = $this->xobjects[$id]; } } // set default values if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); $ow = $this->xobjects[$id]['w']; $oh = $this->xobjects[$id]['h']; // calculate template width and height on document if (($w <= 0) AND ($h <= 0)) { $w = $ow; $h = $oh; } elseif ($w <= 0) { $w = $h * $ow / $oh; } elseif ($h <= 0) { $h = $w * $oh / $ow; } // fit the template on available space list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage); // set page alignment $rb_y = $y + $h; // set alignment if ($this->rtl) { if ($palign == 'L') { $xt = $this->lMargin; } elseif ($palign == 'C') { $xt = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $xt = $this->w - $this->rMargin - $w; } else { $xt = $x - $w; } $rb_x = $xt; } else { if ($palign == 'L') { $xt = $this->lMargin; } elseif ($palign == 'C') { $xt = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $xt = $this->w - $this->rMargin - $w; } else { $xt = $x; } $rb_x = $xt + $w; } // print XObject Template + Transformation matrix $this->StartTransform(); // translate and scale $sx = ($w / $this->xobjects[$id]['w']); $sy = ($h / $this->xobjects[$id]['h']); $tm = array(); $tm[0] = $sx; $tm[1] = 0; $tm[2] = 0; $tm[3] = $sy; $tm[4] = $xt * $this->k; $tm[5] = ($this->h - $h - $y) * $this->k; $this->Transform($tm); // set object $this->_out('/'.$id.' Do'); $this->StopTransform(); // add annotations if (!empty($this->xobjects[$id]['annotations'])) { foreach ($this->xobjects[$id]['annotations'] as $annot) { // transform original coordinates $coordlt = TCPDF_STATIC::getTransformationMatrixProduct($tm, array(1, 0, 0, 1, ($annot['x'] * $this->k), (-$annot['y'] * $this->k))); $ax = ($coordlt[4] / $this->k); $ay = ($this->h - $h - ($coordlt[5] / $this->k)); $coordrb = TCPDF_STATIC::getTransformationMatrixProduct($tm, array(1, 0, 0, 1, (($annot['x'] + $annot['w']) * $this->k), ((-$annot['y'] - $annot['h']) * $this->k))); $aw = ($coordrb[4] / $this->k) - $ax; $ah = ($this->h - $h - ($coordrb[5] / $this->k)) - $ay; $this->Annotation($ax, $ay, $aw, $ah, $annot['text'], $annot['opt'], $annot['spaces']); } } // set pointer to align the next text/objects switch($align) { case 'T': { $this->y = $y; $this->x = $rb_x; break; } case 'M': { $this->y = $y + round($h/2); $this->x = $rb_x; break; } case 'B': { $this->y = $rb_y; $this->x = $rb_x; break; } case 'N': { $this->SetY($rb_y); break; } default:{ break; } } } /** * Set the percentage of character stretching. * @param $perc (int) percentage of stretching (100 = no stretching) * @author Nicola Asuni * @public * @since 5.9.000 (2010-09-29) */ public function setFontStretching($perc=100) { $this->font_stretching = $perc; } /** * Get the percentage of character stretching. * @return float stretching value * @author Nicola Asuni * @public * @since 5.9.000 (2010-09-29) */ public function getFontStretching() { return $this->font_stretching; } /** * Set the amount to increase or decrease the space between characters in a text. * @param $spacing (float) amount to increase or decrease the space between characters in a text (0 = default spacing) * @author Nicola Asuni * @public * @since 5.9.000 (2010-09-29) */ public function setFontSpacing($spacing=0) { $this->font_spacing = $spacing; } /** * Get the amount to increase or decrease the space between characters in a text. * @return int font spacing (tracking) value * @author Nicola Asuni * @public * @since 5.9.000 (2010-09-29) */ public function getFontSpacing() { return $this->font_spacing; } /** * Return an array of no-write page regions * @return array of no-write page regions * @author Nicola Asuni * @public * @since 5.9.003 (2010-10-13) * @see setPageRegions(), addPageRegion() */ public function getPageRegions() { return $this->page_regions; } /** * Set no-write regions on page. * A no-write region is a portion of the page with a rectangular or trapezium shape that will not be covered when writing text or html code. * A region is always aligned on the left or right side of the page ad is defined using a vertical segment. * You can set multiple regions for the same page. * @param $regions (array) array of no-write regions. For each region you can define an array as follow: ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right). Omit this parameter to remove all regions. * @author Nicola Asuni * @public * @since 5.9.003 (2010-10-13) * @see addPageRegion(), getPageRegions() */ public function setPageRegions($regions=array()) { // empty current regions array $this->page_regions = array(); // add regions foreach ($regions as $data) { $this->addPageRegion($data); } } /** * Add a single no-write region on selected page. * A no-write region is a portion of the page with a rectangular or trapezium shape that will not be covered when writing text or html code. * A region is always aligned on the left or right side of the page ad is defined using a vertical segment. * You can set multiple regions for the same page. * @param $region (array) array of a single no-write region array: ('page' => page number or empy for current page, 'xt' => X top, 'yt' => Y top, 'xb' => X bottom, 'yb' => Y bottom, 'side' => page side 'L' = left or 'R' = right). * @author Nicola Asuni * @public * @since 5.9.003 (2010-10-13) * @see setPageRegions(), getPageRegions() */ public function addPageRegion($region) { if (!isset($region['page']) OR empty($region['page'])) { $region['page'] = $this->page; } if (isset($region['xt']) AND isset($region['xb']) AND ($region['xt'] > 0) AND ($region['xb'] > 0) AND isset($region['yt']) AND isset($region['yb']) AND ($region['yt'] >= 0) AND ($region['yt'] < $region['yb']) AND isset($region['side']) AND (($region['side'] == 'L') OR ($region['side'] == 'R'))) { $this->page_regions[] = $region; } } /** * Remove a single no-write region. * @param $key (int) region key * @author Nicola Asuni * @public * @since 5.9.003 (2010-10-13) * @see setPageRegions(), getPageRegions() */ public function removePageRegion($key) { if (isset($this->page_regions[$key])) { unset($this->page_regions[$key]); } } /** * Check page for no-write regions and adapt current coordinates and page margins if necessary. * A no-write region is a portion of the page with a rectangular or trapezium shape that will not be covered when writing text or html code. * A region is always aligned on the left or right side of the page ad is defined using a vertical segment. * @param $h (float) height of the text/image/object to print in user units * @param $x (float) current X coordinate in user units * @param $y (float) current Y coordinate in user units * @return array($x, $y) * @author Nicola Asuni * @protected * @since 5.9.003 (2010-10-13) */ protected function checkPageRegions($h, $x, $y) { // set default values if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } if (!$this->check_page_regions OR empty($this->page_regions)) { // no page regions defined return array($x, $y); } if (empty($h)) { $h = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B']; } // check for page break if ($this->checkPageBreak($h, $y)) { // the content will be printed on a new page $x = $this->x; $y = $this->y; } if ($this->num_columns > 1) { if ($this->rtl) { $this->lMargin = ($this->columns[$this->current_column]['x'] - $this->columns[$this->current_column]['w']); } else { $this->rMargin = ($this->w - $this->columns[$this->current_column]['x'] - $this->columns[$this->current_column]['w']); } } else { if ($this->rtl) { $this->lMargin = max($this->clMargin, $this->original_lMargin); } else { $this->rMargin = max($this->crMargin, $this->original_rMargin); } } // adjust coordinates and page margins foreach ($this->page_regions as $regid => $regdata) { if ($regdata['page'] == $this->page) { // check region boundaries if (($y > ($regdata['yt'] - $h)) AND ($y <= $regdata['yb'])) { // Y is inside the region $minv = ($regdata['xb'] - $regdata['xt']) / ($regdata['yb'] - $regdata['yt']); // inverse of angular coefficient $yt = max($y, $regdata['yt']); $yb = min(($yt + $h), $regdata['yb']); $xt = (($yt - $regdata['yt']) * $minv) + $regdata['xt']; $xb = (($yb - $regdata['yt']) * $minv) + $regdata['xt']; if ($regdata['side'] == 'L') { // left side $new_margin = max($xt, $xb); if ($this->lMargin < $new_margin) { if ($this->rtl) { // adjust left page margin $this->lMargin = max(0, $new_margin); } if ($x < $new_margin) { // adjust x position $x = $new_margin; if ($new_margin > ($this->w - $this->rMargin)) { // adjust y position $y = $regdata['yb'] - $h; } } } } elseif ($regdata['side'] == 'R') { // right side $new_margin = min($xt, $xb); if (($this->w - $this->rMargin) > $new_margin) { if (!$this->rtl) { // adjust right page margin $this->rMargin = max(0, ($this->w - $new_margin)); } if ($x > $new_margin) { // adjust x position $x = $new_margin; if ($new_margin > $this->lMargin) { // adjust y position $y = $regdata['yb'] - $h; } } } } } } } return array($x, $y); } // --- SVG METHODS --------------------------------------------------------- /** * Embedd a Scalable Vector Graphics (SVG) image. * NOTE: SVG standard is not yet fully implemented, use the setRasterizeVectorImages() method to enable/disable rasterization of vector images using ImageMagick library. * @param $file (string) Name of the SVG file or a '@' character followed by the SVG data string. * @param $x (float) Abscissa of the upper-left corner. * @param $y (float) Ordinate of the upper-left corner. * @param $w (float) Width of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $h (float) Height of the image in the page. If not specified or equal to zero, it is automatically calculated. * @param $link (mixed) URL or identifier returned by AddLink(). * @param $align (string) Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:
      • T: top-right for LTR or top-left for RTL
      • M: middle-right for LTR or middle-left for RTL
      • B: bottom-right for LTR or bottom-left for RTL
      • N: next line
      If the alignment is an empty string, then the pointer will be restored on the starting SVG position. * @param $palign (string) Allows to center or align the image on the current line. Possible values are:
      • L : left align
      • C : center
      • R : right align
      • '' : empty string : left for LTR or right for RTL
      * @param $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:
      • 0: no border (default)
      • 1: frame
      or a string containing some or all of the following characters (in any order):
      • L: left
      • T: top
      • R: right
      • B: bottom
      or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $fitonpage (boolean) if true the image is resized to not exceed page dimensions. * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @public */ public function ImageSVG($file, $x='', $y='', $w=0, $h=0, $link='', $align='', $palign='', $border=0, $fitonpage=false) { if ($this->state != 2) { return; } if ($this->rasterize_vector_images AND ($w > 0) AND ($h > 0)) { // convert SVG to raster image using GD or ImageMagick libraries return $this->Image($file, $x, $y, $w, $h, 'SVG', $link, $align, true, 300, $palign, false, false, $border, false, false, false); } if ($file{0} === '@') { // image from string $this->svgdir = ''; $svgdata = substr($file, 1); } else { // SVG file $this->svgdir = dirname($file); $svgdata = file_get_contents($file); } if ($svgdata === false) { $this->Error('SVG file not found: '.$file); } if ($x === '') { $x = $this->x; } if ($y === '') { $y = $this->y; } // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); $k = $this->k; $ox = 0; $oy = 0; $ow = $w; $oh = $h; $aspect_ratio_align = 'xMidYMid'; $aspect_ratio_ms = 'meet'; $regs = array(); // get original image width and height preg_match('/]*)>/si', $svgdata, $regs); if (isset($regs[1]) AND !empty($regs[1])) { $tmp = array(); if (preg_match('/[\s]+x[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) { $ox = $this->getHTMLUnitToUnits($tmp[1], 0, $this->svgunit, false); } $tmp = array(); if (preg_match('/[\s]+y[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) { $oy = $this->getHTMLUnitToUnits($tmp[1], 0, $this->svgunit, false); } $tmp = array(); if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) { $ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); } $tmp = array(); if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) { $oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); } $tmp = array(); $view_box = array(); if (preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.\-]+)[\s]+([0-9\.\-]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $regs[1], $tmp)) { if (count($tmp) == 5) { array_shift($tmp); foreach ($tmp as $key => $val) { $view_box[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false); } $ox = $view_box[0]; $oy = $view_box[1]; } // get aspect ratio $tmp = array(); if (preg_match('/[\s]+preserveAspectRatio[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) { $aspect_ratio = preg_split('/[\s]+/si', $tmp[1]); switch (count($aspect_ratio)) { case 3: { $aspect_ratio_align = $aspect_ratio[1]; $aspect_ratio_ms = $aspect_ratio[2]; break; } case 2: { $aspect_ratio_align = $aspect_ratio[0]; $aspect_ratio_ms = $aspect_ratio[1]; break; } case 1: { $aspect_ratio_align = $aspect_ratio[0]; $aspect_ratio_ms = 'meet'; break; } } } } } // calculate image width and height on document if (($w <= 0) AND ($h <= 0)) { // convert image size to document unit $w = $ow; $h = $oh; } elseif ($w <= 0) { $w = $h * $ow / $oh; } elseif ($h <= 0) { $h = $w * $oh / $ow; } // fit the image on available space list($w, $h, $x, $y) = $this->fitBlock($w, $h, $x, $y, $fitonpage); if ($this->rasterize_vector_images) { // convert SVG to raster image using GD or ImageMagick libraries return $this->Image($file, $x, $y, $w, $h, 'SVG', $link, $align, true, 300, $palign, false, false, $border, false, false, false); } // set alignment $this->img_rb_y = $y + $h; // set alignment if ($this->rtl) { if ($palign == 'L') { $ximg = $this->lMargin; } elseif ($palign == 'C') { $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $ximg = $this->w - $this->rMargin - $w; } else { $ximg = $x - $w; } $this->img_rb_x = $ximg; } else { if ($palign == 'L') { $ximg = $this->lMargin; } elseif ($palign == 'C') { $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2; } elseif ($palign == 'R') { $ximg = $this->w - $this->rMargin - $w; } else { $ximg = $x; } $this->img_rb_x = $ximg + $w; } // store current graphic vars $gvars = $this->getGraphicVars(); // store SVG position and scale factors $svgoffset_x = ($ximg - $ox) * $this->k; $svgoffset_y = -($y - $oy) * $this->k; if (isset($view_box[2]) AND ($view_box[2] > 0) AND ($view_box[3] > 0)) { $ow = $view_box[2]; $oh = $view_box[3]; } else { if ($ow <= 0) { $ow = $w; } if ($oh <= 0) { $oh = $h; } } $svgscale_x = $w / $ow; $svgscale_y = $h / $oh; // scaling and alignment if ($aspect_ratio_align != 'none') { // store current scaling values $svgscale_old_x = $svgscale_x; $svgscale_old_y = $svgscale_y; // force uniform scaling if ($aspect_ratio_ms == 'slice') { // the entire viewport is covered by the viewBox if ($svgscale_x > $svgscale_y) { $svgscale_y = $svgscale_x; } elseif ($svgscale_x < $svgscale_y) { $svgscale_x = $svgscale_y; } } else { // meet // the entire viewBox is visible within the viewport if ($svgscale_x < $svgscale_y) { $svgscale_y = $svgscale_x; } elseif ($svgscale_x > $svgscale_y) { $svgscale_x = $svgscale_y; } } // correct X alignment switch (substr($aspect_ratio_align, 1, 3)) { case 'Min': { // do nothing break; } case 'Max': { $svgoffset_x += (($w * $this->k) - ($ow * $this->k * $svgscale_x)); break; } default: case 'Mid': { $svgoffset_x += ((($w * $this->k) - ($ow * $this->k * $svgscale_x)) / 2); break; } } // correct Y alignment switch (substr($aspect_ratio_align, 5)) { case 'Min': { // do nothing break; } case 'Max': { $svgoffset_y -= (($h * $this->k) - ($oh * $this->k * $svgscale_y)); break; } default: case 'Mid': { $svgoffset_y -= ((($h * $this->k) - ($oh * $this->k * $svgscale_y)) / 2); break; } } } // store current page break mode $page_break_mode = $this->AutoPageBreak; $page_break_margin = $this->getBreakMargin(); $cell_padding = $this->cell_padding; $this->SetCellPadding(0); $this->SetAutoPageBreak(false); // save the current graphic state $this->_out('q'.$this->epsmarker); // set initial clipping mask $this->Rect($x, $y, $w, $h, 'CNZ', array(), array()); // scale and translate $e = $ox * $this->k * (1 - $svgscale_x); $f = ($this->h - $oy) * $this->k * (1 - $svgscale_y); $this->_out(sprintf('%F %F %F %F %F %F cm', $svgscale_x, 0, 0, $svgscale_y, ($e + $svgoffset_x), ($f + $svgoffset_y))); // creates a new XML parser to be used by the other XML functions $this->parser = xml_parser_create('UTF-8'); // the following function allows to use parser inside object xml_set_object($this->parser, $this); // disable case-folding for this XML parser xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); // sets the element handler functions for the XML parser xml_set_element_handler($this->parser, 'startSVGElementHandler', 'endSVGElementHandler'); // sets the character data handler function for the XML parser xml_set_character_data_handler($this->parser, 'segSVGContentHandler'); // start parsing an XML document if (!xml_parse($this->parser, $svgdata)) { $error_message = sprintf('SVG Error: %s at line %d', xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser)); $this->Error($error_message); } // free this XML parser xml_parser_free($this->parser); // restore previous graphic state $this->_out($this->epsmarker.'Q'); // restore graphic vars $this->setGraphicVars($gvars); $this->lasth = $gvars['lasth']; if (!empty($border)) { $bx = $this->x; $by = $this->y; $this->x = $ximg; if ($this->rtl) { $this->x += $w; } $this->y = $y; $this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true); $this->x = $bx; $this->y = $by; } if ($link) { $this->Link($ximg, $y, $w, $h, $link, 0); } // set pointer to align the next text/objects switch($align) { case 'T':{ $this->y = $y; $this->x = $this->img_rb_x; break; } case 'M':{ $this->y = $y + round($h/2); $this->x = $this->img_rb_x; break; } case 'B':{ $this->y = $this->img_rb_y; $this->x = $this->img_rb_x; break; } case 'N':{ $this->SetY($this->img_rb_y); break; } default:{ // restore pointer to starting position $this->x = $gvars['x']; $this->y = $gvars['y']; $this->page = $gvars['page']; $this->current_column = $gvars['current_column']; $this->tMargin = $gvars['tMargin']; $this->bMargin = $gvars['bMargin']; $this->w = $gvars['w']; $this->h = $gvars['h']; $this->wPt = $gvars['wPt']; $this->hPt = $gvars['hPt']; $this->fwPt = $gvars['fwPt']; $this->fhPt = $gvars['fhPt']; break; } } $this->endlinex = $this->img_rb_x; // restore page break $this->SetAutoPageBreak($page_break_mode, $page_break_margin); $this->cell_padding = $cell_padding; } /** * Convert SVG transformation matrix to PDF. * @param $tm (array) original SVG transformation matrix * @return array transformation matrix * @protected * @since 5.0.000 (2010-05-02) */ protected function convertSVGtMatrix($tm) { $a = $tm[0]; $b = -$tm[1]; $c = -$tm[2]; $d = $tm[3]; $e = $this->getHTMLUnitToUnits($tm[4], 1, $this->svgunit, false) * $this->k; $f = -$this->getHTMLUnitToUnits($tm[5], 1, $this->svgunit, false) * $this->k; $x = 0; $y = $this->h * $this->k; $e = ($x * (1 - $a)) - ($y * $c) + $e; $f = ($y * (1 - $d)) - ($x * $b) + $f; return array($a, $b, $c, $d, $e, $f); } /** * Apply SVG graphic transformation matrix. * @param $tm (array) original SVG transformation matrix * @protected * @since 5.0.000 (2010-05-02) */ protected function SVGTransform($tm) { $this->Transform($this->convertSVGtMatrix($tm)); } /** * Apply the requested SVG styles (*** TO BE COMPLETED ***) * @param $svgstyle (array) array of SVG styles to apply * @param $prevsvgstyle (array) array of previous SVG style * @param $x (int) X origin of the bounding box * @param $y (int) Y origin of the bounding box * @param $w (int) width of the bounding box * @param $h (int) height of the bounding box * @param $clip_function (string) clip function * @param $clip_params (array) array of parameters for clipping function * @return object style * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @protected */ protected function setSVGStyles($svgstyle, $prevsvgstyle, $x=0, $y=0, $w=1, $h=1, $clip_function='', $clip_params=array()) { if ($this->state != 2) { return; } $objstyle = ''; $minlen = (0.01 / $this->k); // minimum acceptable length (3 point) if (!isset($svgstyle['opacity'])) { return $objstyle; } // clip-path $regs = array(); if (preg_match('/url\([\s]*\#([^\)]*)\)/si', $svgstyle['clip-path'], $regs)) { $clip_path = $this->svgclippaths[$regs[1]]; foreach ($clip_path as $cp) { $this->startSVGElementHandler('clip-path', $cp['name'], $cp['attribs'], $cp['tm']); } } // opacity if ($svgstyle['opacity'] != 1) { $this->setAlpha($svgstyle['opacity'], 'Normal', $svgstyle['opacity'], false); } // color $fill_color = TCPDF_COLORS::convertHTMLColorToDec($svgstyle['color'], $this->spot_colors); $this->SetFillColorArray($fill_color); // text color $text_color = TCPDF_COLORS::convertHTMLColorToDec($svgstyle['text-color'], $this->spot_colors); $this->SetTextColorArray($text_color); // clip if (preg_match('/rect\(([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)\)/si', $svgstyle['clip'], $regs)) { $top = (isset($regs[1])?$this->getHTMLUnitToUnits($regs[1], 0, $this->svgunit, false):0); $right = (isset($regs[2])?$this->getHTMLUnitToUnits($regs[2], 0, $this->svgunit, false):0); $bottom = (isset($regs[3])?$this->getHTMLUnitToUnits($regs[3], 0, $this->svgunit, false):0); $left = (isset($regs[4])?$this->getHTMLUnitToUnits($regs[4], 0, $this->svgunit, false):0); $cx = $x + $left; $cy = $y + $top; $cw = $w - $left - $right; $ch = $h - $top - $bottom; if ($svgstyle['clip-rule'] == 'evenodd') { $clip_rule = 'CNZ'; } else { $clip_rule = 'CEO'; } $this->Rect($cx, $cy, $cw, $ch, $clip_rule, array(), array()); } // fill $regs = array(); if (preg_match('/url\([\s]*\#([^\)]*)\)/si', $svgstyle['fill'], $regs)) { // gradient $gradient = $this->svggradients[$regs[1]]; if (isset($gradient['xref'])) { // reference to another gradient definition $newgradient = $this->svggradients[$gradient['xref']]; $newgradient['coords'] = $gradient['coords']; $newgradient['mode'] = $gradient['mode']; $newgradient['gradientUnits'] = $gradient['gradientUnits']; if (isset($gradient['gradientTransform'])) { $newgradient['gradientTransform'] = $gradient['gradientTransform']; } $gradient = $newgradient; } //save current Graphic State $this->_out('q'); //set clipping area if (!empty($clip_function) AND method_exists($this, $clip_function)) { $bbox = call_user_func_array(array($this, $clip_function), $clip_params); if (is_array($bbox) AND (count($bbox) == 4)) { list($x, $y, $w, $h) = $bbox; } } if ($gradient['mode'] == 'measure') { if (isset($gradient['gradientTransform']) AND !empty($gradient['gradientTransform'])) { $gtm = $gradient['gradientTransform']; // apply transformation matrix $xa = ($gtm[0] * $gradient['coords'][0]) + ($gtm[2] * $gradient['coords'][1]) + $gtm[4]; $ya = ($gtm[1] * $gradient['coords'][0]) + ($gtm[3] * $gradient['coords'][1]) + $gtm[5]; $xb = ($gtm[0] * $gradient['coords'][2]) + ($gtm[2] * $gradient['coords'][3]) + $gtm[4]; $yb = ($gtm[1] * $gradient['coords'][2]) + ($gtm[3] * $gradient['coords'][3]) + $gtm[5]; if (isset($gradient['coords'][4])) { $gradient['coords'][4] = sqrt(pow(($gtm[0] * $gradient['coords'][4]), 2) + pow(($gtm[1] * $gradient['coords'][4]), 2)); } $gradient['coords'][0] = $xa; $gradient['coords'][1] = $ya; $gradient['coords'][2] = $xb; $gradient['coords'][3] = $yb; } // convert SVG coordinates to user units $gradient['coords'][0] = $this->getHTMLUnitToUnits($gradient['coords'][0], 0, $this->svgunit, false); $gradient['coords'][1] = $this->getHTMLUnitToUnits($gradient['coords'][1], 0, $this->svgunit, false); $gradient['coords'][2] = $this->getHTMLUnitToUnits($gradient['coords'][2], 0, $this->svgunit, false); $gradient['coords'][3] = $this->getHTMLUnitToUnits($gradient['coords'][3], 0, $this->svgunit, false); if (isset($gradient['coords'][4])) { $gradient['coords'][4] = $this->getHTMLUnitToUnits($gradient['coords'][4], 0, $this->svgunit, false); } if ($w <= $minlen) { $w = $minlen; } if ($h <= $minlen) { $h = $minlen; } // shift units if ($gradient['gradientUnits'] == 'objectBoundingBox') { // convert to SVG coordinate system $gradient['coords'][0] += $x; $gradient['coords'][1] += $y; $gradient['coords'][2] += $x; $gradient['coords'][3] += $y; } // calculate percentages $gradient['coords'][0] = (($gradient['coords'][0] - $x) / $w); $gradient['coords'][1] = (($gradient['coords'][1] - $y) / $h); $gradient['coords'][2] = (($gradient['coords'][2] - $x) / $w); $gradient['coords'][3] = (($gradient['coords'][3] - $y) / $h); if (isset($gradient['coords'][4])) { $gradient['coords'][4] /= $w; } } elseif ($gradient['mode'] == 'percentage') { foreach($gradient['coords'] as $key => $val) { $gradient['coords'][$key] = (intval($val) / 100); if ($val < 0) { $gradient['coords'][$key] = 0; } elseif ($val > 1) { $gradient['coords'][$key] = 1; } } } if (($gradient['type'] == 2) AND ($gradient['coords'][0] == $gradient['coords'][2]) AND ($gradient['coords'][1] == $gradient['coords'][3])) { // single color (no shading) $gradient['coords'][0] = 1; $gradient['coords'][1] = 0; $gradient['coords'][2] = 0.999; $gradient['coords'][3] = 0; } // swap Y coordinates $tmp = $gradient['coords'][1]; $gradient['coords'][1] = $gradient['coords'][3]; $gradient['coords'][3] = $tmp; // set transformation map for gradient if ($gradient['type'] == 3) { // circular gradient $cy = $this->h - $y - ($gradient['coords'][1] * ($w + $h)); $this->_out(sprintf('%F 0 0 %F %F %F cm', ($w * $this->k), ($w * $this->k), ($x * $this->k), ($cy * $this->k))); } else { $this->_out(sprintf('%F 0 0 %F %F %F cm', ($w * $this->k), ($h * $this->k), ($x * $this->k), (($this->h - ($y + $h)) * $this->k))); } if (count($gradient['stops']) > 1) { $this->Gradient($gradient['type'], $gradient['coords'], $gradient['stops'], array(), false); } } elseif ($svgstyle['fill'] != 'none') { $fill_color = TCPDF_COLORS::convertHTMLColorToDec($svgstyle['fill'], $this->spot_colors); if ($svgstyle['fill-opacity'] != 1) { $this->setAlpha($this->alpha['CA'], 'Normal', $svgstyle['fill-opacity'], false); } $this->SetFillColorArray($fill_color); if ($svgstyle['fill-rule'] == 'evenodd') { $objstyle .= 'F*'; } else { $objstyle .= 'F'; } } // stroke if ($svgstyle['stroke'] != 'none') { if ($svgstyle['stroke-opacity'] != 1) { $this->setAlpha($svgstyle['stroke-opacity'], 'Normal', $this->alpha['ca'], false); } $stroke_style = array( 'color' => TCPDF_COLORS::convertHTMLColorToDec($svgstyle['stroke'], $this->spot_colors), 'width' => $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false), 'cap' => $svgstyle['stroke-linecap'], 'join' => $svgstyle['stroke-linejoin'] ); if (isset($svgstyle['stroke-dasharray']) AND !empty($svgstyle['stroke-dasharray']) AND ($svgstyle['stroke-dasharray'] != 'none')) { $stroke_style['dash'] = $svgstyle['stroke-dasharray']; } $this->SetLineStyle($stroke_style); $objstyle .= 'D'; } // font $regs = array(); if (!empty($svgstyle['font'])) { if (preg_match('/font-family[\s]*:[\s]*([^\;\"]*)/si', $svgstyle['font'], $regs)) { $font_family = $this->getFontFamilyName($regs[1]); } else { $font_family = $svgstyle['font-family']; } if (preg_match('/font-size[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) { $font_size = trim($regs[1]); } else { $font_size = $svgstyle['font-size']; } if (preg_match('/font-style[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) { $font_style = trim($regs[1]); } else { $font_style = $svgstyle['font-style']; } if (preg_match('/font-weight[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) { $font_weight = trim($regs[1]); } else { $font_weight = $svgstyle['font-weight']; } if (preg_match('/font-stretch[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) { $font_stretch = trim($regs[1]); } else { $font_stretch = $svgstyle['font-stretch']; } if (preg_match('/letter-spacing[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) { $font_spacing = trim($regs[1]); } else { $font_spacing = $svgstyle['letter-spacing']; } } else { $font_family = $this->getFontFamilyName($svgstyle['font-family']); $font_size = $svgstyle['font-size']; $font_style = $svgstyle['font-style']; $font_weight = $svgstyle['font-weight']; $font_stretch = $svgstyle['font-stretch']; $font_spacing = $svgstyle['letter-spacing']; } $font_size = $this->getHTMLFontUnits($font_size, $this->svgstyles[0]['font-size'], $prevsvgstyle['font-size'], $this->svgunit); $font_stretch = $this->getCSSFontStretching($font_stretch, $svgstyle['font-stretch']); $font_spacing = $this->getCSSFontSpacing($font_spacing, $svgstyle['letter-spacing']); switch ($font_style) { case 'italic': { $font_style = 'I'; break; } case 'oblique': { $font_style = 'I'; break; } default: case 'normal': { $font_style = ''; break; } } switch ($font_weight) { case 'bold': case 'bolder': { $font_style .= 'B'; break; } } switch ($svgstyle['text-decoration']) { case 'underline': { $font_style .= 'U'; break; } case 'overline': { $font_style .= 'O'; break; } case 'line-through': { $font_style .= 'D'; break; } default: case 'none': { break; } } $this->SetFont($font_family, $font_style, $font_size); $this->setFontStretching($font_stretch); $this->setFontSpacing($font_spacing); return $objstyle; } /** * Draws an SVG path * @param $d (string) attribute d of the path SVG element * @param $style (string) Style of rendering. Possible values are: *
        *
      • D or empty string: Draw (default).
      • *
      • F: Fill.
      • *
      • F*: Fill using the even-odd rule to determine which regions lie inside the clipping path.
      • *
      • DF or FD: Draw and fill.
      • *
      • DF* or FD*: Draw and fill using the even-odd rule to determine which regions lie inside the clipping path.
      • *
      • CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).
      • *
      • CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).
      • *
      * @return array of container box measures (x, y, w, h) * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @protected */ protected function SVGPath($d, $style='') { if ($this->state != 2) { return; } // set fill/stroke style $op = TCPDF_STATIC::getPathPaintOperator($style, ''); if (empty($op)) { return; } $paths = array(); $d = preg_replace('/([0-9ACHLMQSTVZ])([\-\+])/si', '\\1 \\2', $d); preg_match_all('/([ACHLMQSTVZ])[\s]*([^ACHLMQSTVZ\"]*)/si', $d, $paths, PREG_SET_ORDER); $x = 0; $y = 0; $x1 = 0; $y1 = 0; $x2 = 0; $y2 = 0; $xmin = 2147483647; $xmax = 0; $ymin = 2147483647; $ymax = 0; $relcoord = false; $minlen = (0.01 / $this->k); // minimum acceptable length (3 point) $firstcmd = true; // used to print first point // draw curve pieces foreach ($paths as $key => $val) { // get curve type $cmd = trim($val[1]); if (strtolower($cmd) == $cmd) { // use relative coordinated instead of absolute $relcoord = true; $xoffset = $x; $yoffset = $y; } else { $relcoord = false; $xoffset = 0; $yoffset = 0; } $params = array(); if (isset($val[2])) { // get curve parameters $rawparams = preg_split('/([\,\s]+)/si', trim($val[2])); $params = array(); foreach ($rawparams as $ck => $cp) { $params[$ck] = $this->getHTMLUnitToUnits($cp, 0, $this->svgunit, false); if (abs($params[$ck]) < $minlen) { // aproximate little values to zero $params[$ck] = 0; } } } // store current origin point $x0 = $x; $y0 = $y; switch (strtoupper($cmd)) { case 'M': { // moveto foreach ($params as $ck => $cp) { if (($ck % 2) == 0) { $x = $cp + $xoffset; } else { $y = $cp + $yoffset; if ($firstcmd OR (abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) { if ($ck == 1) { $this->_outPoint($x, $y); $firstcmd = false; } else { $this->_outLine($x, $y); } $x0 = $x; $y0 = $y; } $xmin = min($xmin, $x); $ymin = min($ymin, $y); $xmax = max($xmax, $x); $ymax = max($ymax, $y); if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'L': { // lineto foreach ($params as $ck => $cp) { if (($ck % 2) == 0) { $x = $cp + $xoffset; } else { $y = $cp + $yoffset; if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) { $this->_outLine($x, $y); $x0 = $x; $y0 = $y; } $xmin = min($xmin, $x); $ymin = min($ymin, $y); $xmax = max($xmax, $x); $ymax = max($ymax, $y); if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'H': { // horizontal lineto foreach ($params as $ck => $cp) { $x = $cp + $xoffset; if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) { $this->_outLine($x, $y); $x0 = $x; $y0 = $y; } $xmin = min($xmin, $x); $xmax = max($xmax, $x); if ($relcoord) { $xoffset = $x; } } break; } case 'V': { // vertical lineto foreach ($params as $ck => $cp) { $y = $cp + $yoffset; if ((abs($x0 - $x) >= $minlen) OR (abs($y0 - $y) >= $minlen)) { $this->_outLine($x, $y); $x0 = $x; $y0 = $y; } $ymin = min($ymin, $y); $ymax = max($ymax, $y); if ($relcoord) { $yoffset = $y; } } break; } case 'C': { // curveto foreach ($params as $ck => $cp) { $params[$ck] = $cp; if ((($ck + 1) % 6) == 0) { $x1 = $params[($ck - 5)] + $xoffset; $y1 = $params[($ck - 4)] + $yoffset; $x2 = $params[($ck - 3)] + $xoffset; $y2 = $params[($ck - 2)] + $yoffset; $x = $params[($ck - 1)] + $xoffset; $y = $params[($ck)] + $yoffset; $this->_outCurve($x1, $y1, $x2, $y2, $x, $y); $xmin = min($xmin, $x, $x1, $x2); $ymin = min($ymin, $y, $y1, $y2); $xmax = max($xmax, $x, $x1, $x2); $ymax = max($ymax, $y, $y1, $y2); if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'S': { // shorthand/smooth curveto foreach ($params as $ck => $cp) { $params[$ck] = $cp; if ((($ck + 1) % 4) == 0) { if (($key > 0) AND ((strtoupper($paths[($key - 1)][1]) == 'C') OR (strtoupper($paths[($key - 1)][1]) == 'S'))) { $x1 = (2 * $x) - $x2; $y1 = (2 * $y) - $y2; } else { $x1 = $x; $y1 = $y; } $x2 = $params[($ck - 3)] + $xoffset; $y2 = $params[($ck - 2)] + $yoffset; $x = $params[($ck - 1)] + $xoffset; $y = $params[($ck)] + $yoffset; $this->_outCurve($x1, $y1, $x2, $y2, $x, $y); $xmin = min($xmin, $x, $x1, $x2); $ymin = min($ymin, $y, $y1, $y2); $xmax = max($xmax, $x, $x1, $x2); $ymax = max($ymax, $y, $y1, $y2); if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'Q': { // quadratic Bzier curveto foreach ($params as $ck => $cp) { $params[$ck] = $cp; if ((($ck + 1) % 4) == 0) { // convert quadratic points to cubic points $x1 = $params[($ck - 3)] + $xoffset; $y1 = $params[($ck - 2)] + $yoffset; $xa = ($x + (2 * $x1)) / 3; $ya = ($y + (2 * $y1)) / 3; $x = $params[($ck - 1)] + $xoffset; $y = $params[($ck)] + $yoffset; $xb = ($x + (2 * $x1)) / 3; $yb = ($y + (2 * $y1)) / 3; $this->_outCurve($xa, $ya, $xb, $yb, $x, $y); $xmin = min($xmin, $x, $xa, $xb); $ymin = min($ymin, $y, $ya, $yb); $xmax = max($xmax, $x, $xa, $xb); $ymax = max($ymax, $y, $ya, $yb); if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'T': { // shorthand/smooth quadratic Bzier curveto foreach ($params as $ck => $cp) { $params[$ck] = $cp; if (($ck % 2) != 0) { if (($key > 0) AND ((strtoupper($paths[($key - 1)][1]) == 'Q') OR (strtoupper($paths[($key - 1)][1]) == 'T'))) { $x1 = (2 * $x) - $x1; $y1 = (2 * $y) - $y1; } else { $x1 = $x; $y1 = $y; } // convert quadratic points to cubic points $xa = ($x + (2 * $x1)) / 3; $ya = ($y + (2 * $y1)) / 3; $x = $params[($ck - 1)] + $xoffset; $y = $params[($ck)] + $yoffset; $xb = ($x + (2 * $x1)) / 3; $yb = ($y + (2 * $y1)) / 3; $this->_outCurve($xa, $ya, $xb, $yb, $x, $y); $xmin = min($xmin, $x, $xa, $xb); $ymin = min($ymin, $y, $ya, $yb); $xmax = max($xmax, $x, $xa, $xb); $ymax = max($ymax, $y, $ya, $yb); if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'A': { // elliptical arc foreach ($params as $ck => $cp) { $params[$ck] = $cp; if ((($ck + 1) % 7) == 0) { $x0 = $x; $y0 = $y; $rx = abs($params[($ck - 6)]); $ry = abs($params[($ck - 5)]); $ang = -$rawparams[($ck - 4)]; $angle = deg2rad($ang); $fa = $rawparams[($ck - 3)]; // large-arc-flag $fs = $rawparams[($ck - 2)]; // sweep-flag $x = $params[($ck - 1)] + $xoffset; $y = $params[$ck] + $yoffset; if ((abs($x0 - $x) < $minlen) AND (abs($y0 - $y) < $minlen)) { // endpoints are almost identical $xmin = min($xmin, $x); $ymin = min($ymin, $y); $xmax = max($xmax, $x); $ymax = max($ymax, $y); } else { $cos_ang = cos($angle); $sin_ang = sin($angle); $a = (($x0 - $x) / 2); $b = (($y0 - $y) / 2); $xa = ($a * $cos_ang) - ($b * $sin_ang); $ya = ($a * $sin_ang) + ($b * $cos_ang); $rx2 = $rx * $rx; $ry2 = $ry * $ry; $xa2 = $xa * $xa; $ya2 = $ya * $ya; $delta = ($xa2 / $rx2) + ($ya2 / $ry2); if ($delta > 1) { $rx *= sqrt($delta); $ry *= sqrt($delta); $rx2 = $rx * $rx; $ry2 = $ry * $ry; } $numerator = (($rx2 * $ry2) - ($rx2 * $ya2) - ($ry2 * $xa2)); if ($numerator < 0) { $root = 0; } else { $root = sqrt($numerator / (($rx2 * $ya2) + ($ry2 * $xa2))); } if ($fa == $fs){ $root *= -1; } $cax = $root * (($rx * $ya) / $ry); $cay = -$root * (($ry * $xa) / $rx); // coordinates of ellipse center $cx = ($cax * $cos_ang) - ($cay * $sin_ang) + (($x0 + $x) / 2); $cy = ($cax * $sin_ang) + ($cay * $cos_ang) + (($y0 + $y) / 2); // get angles $angs = TCPDF_STATIC::getVectorsAngle(1, 0, (($xa - $cax) / $rx), (($cay - $ya) / $ry)); $dang = TCPDF_STATIC::getVectorsAngle((($xa - $cax) / $rx), (($ya - $cay) / $ry), ((-$xa - $cax) / $rx), ((-$ya - $cay) / $ry)); if (($fs == 0) AND ($dang > 0)) { $dang -= (2 * M_PI); } elseif (($fs == 1) AND ($dang < 0)) { $dang += (2 * M_PI); } $angf = $angs - $dang; if ((($fs == 0) AND ($angs > $angf)) OR (($fs == 1) AND ($angs < $angf))) { // reverse angles $tmp = $angs; $angs = $angf; $angf = $tmp; } $angs = round(rad2deg($angs), 6); $angf = round(rad2deg($angf), 6); // covent angles to positive values if (($angs < 0) AND ($angf < 0)) { $angs += 360; $angf += 360; } $pie = false; if (($key == 0) AND (isset($paths[($key + 1)][1])) AND (trim($paths[($key + 1)][1]) == 'z')) { $pie = true; } list($axmin, $aymin, $axmax, $aymax) = $this->_outellipticalarc($cx, $cy, $rx, $ry, $ang, $angs, $angf, $pie, 2, false, ($fs == 0), true); $xmin = min($xmin, $x, $axmin); $ymin = min($ymin, $y, $aymin); $xmax = max($xmax, $x, $axmax); $ymax = max($ymax, $y, $aymax); } if ($relcoord) { $xoffset = $x; $yoffset = $y; } } } break; } case 'Z': { $this->_out('h'); break; } } $firstcmd = false; } // end foreach if (!empty($op)) { $this->_out($op); } return array($xmin, $ymin, ($xmax - $xmin), ($ymax - $ymin)); } /** * Sets the opening SVG element handler function for the XML parser. (*** TO BE COMPLETED ***) * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler. * @param $name (string) The second parameter, name, contains the name of the element for which this handler is called. If case-folding is in effect for this parser, the element name will be in uppercase letters. * @param $attribs (array) The third parameter, attribs, contains an associative array with the element's attributes (if any). The keys of this array are the attribute names, the values are the attribute values. Attribute names are case-folded on the same criteria as element names. Attribute values are not case-folded. The original order of the attributes can be retrieved by walking through attribs the normal way, using each(). The first key in the array was the first attribute, and so on. * @param $ctm (array) tranformation matrix for clipping mode (starting transformation matrix). * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @protected */ protected function startSVGElementHandler($parser, $name, $attribs, $ctm=array()) { // check if we are in clip mode if ($this->svgclipmode) { $this->svgclippaths[$this->svgclipid][] = array('name' => $name, 'attribs' => $attribs, 'tm' => $this->svgcliptm[$this->svgclipid]); return; } if ($this->svgdefsmode AND !in_array($name, array('clipPath', 'linearGradient', 'radialGradient', 'stop'))) { if (!isset($attribs['id'])) { $attribs['id'] = 'DF_'.(count($this->svgdefs) + 1); } $this->svgdefs[$attribs['id']] = array('name' => $name, 'attribs' => $attribs); return; } $clipping = false; if ($parser == 'clip-path') { // set clipping mode $clipping = true; } // get styling properties $prev_svgstyle = $this->svgstyles[(count($this->svgstyles) - 1)]; // previous style $svgstyle = $this->svgstyles[0]; // set default style if ($clipping AND !isset($attribs['fill']) AND (!isset($attribs['style']) OR (!preg_match('/[;\"\s]{1}fill[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval)))) { // default fill attribute for clipping $attribs['fill'] = 'none'; } if (isset($attribs['style']) AND !TCPDF_STATIC::empty_string($attribs['style'])) { // fix style for regular expression $attribs['style'] = ';'.$attribs['style']; } foreach ($prev_svgstyle as $key => $val) { if (in_array($key, TCPDF_IMAGES::$svginheritprop)) { // inherit previous value $svgstyle[$key] = $val; } if (isset($attribs[$key]) AND !TCPDF_STATIC::empty_string($attribs[$key])) { // specific attribute settings if ($attribs[$key] == 'inherit') { $svgstyle[$key] = $val; } else { $svgstyle[$key] = $attribs[$key]; } } elseif (isset($attribs['style']) AND !TCPDF_STATIC::empty_string($attribs['style'])) { // CSS style syntax $attrval = array(); if (preg_match('/[;\"\s]{1}'.$key.'[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval) AND isset($attrval[1])) { if ($attrval[1] == 'inherit') { $svgstyle[$key] = $val; } else { $svgstyle[$key] = $attrval[1]; } } } } // transformation matrix if (!empty($ctm)) { $tm = $ctm; } else { //$tm = $this->svgstyles[(count($this->svgstyles) - 1)]['transfmatrix']; $tm = array(1,0,0,1,0,0); } if (isset($attribs['transform']) AND !empty($attribs['transform'])) { $tm = TCPDF_STATIC::getTransformationMatrixProduct($tm, TCPDF_STATIC::getSVGTransformMatrix($attribs['transform'])); } $svgstyle['transfmatrix'] = $tm; $invisible = false; if (($svgstyle['visibility'] == 'hidden') OR ($svgstyle['visibility'] == 'collapse') OR ($svgstyle['display'] == 'none')) { // the current graphics element is invisible (nothing is painted) $invisible = true; } // process tag switch($name) { case 'defs': { $this->svgdefsmode = true; break; } // clipPath case 'clipPath': { if ($invisible) { break; } $this->svgclipmode = true; if (!isset($attribs['id'])) { $attribs['id'] = 'CP_'.(count($this->svgcliptm) + 1); } $this->svgclipid = $attribs['id']; $this->svgclippaths[$this->svgclipid] = array(); $this->svgcliptm[$this->svgclipid] = $tm; break; } case 'svg': { // start of SVG object break; } case 'g': { // group together related graphics elements array_push($this->svgstyles, $svgstyle); $this->StartTransform(); $this->SVGTransform($tm); $this->setSVGStyles($svgstyle, $prev_svgstyle); break; } case 'linearGradient': { if ($this->pdfa_mode) { break; } if (!isset($attribs['id'])) { $attribs['id'] = 'GR_'.(count($this->svggradients) + 1); } $this->svggradientid = $attribs['id']; $this->svggradients[$this->svggradientid] = array(); $this->svggradients[$this->svggradientid]['type'] = 2; $this->svggradients[$this->svggradientid]['stops'] = array(); if (isset($attribs['gradientUnits'])) { $this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits']; } else { $this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox'; } //$attribs['spreadMethod'] if (((!isset($attribs['x1'])) AND (!isset($attribs['y1'])) AND (!isset($attribs['x2'])) AND (!isset($attribs['y2']))) OR ((isset($attribs['x1']) AND (substr($attribs['x1'], -1) == '%')) OR (isset($attribs['y1']) AND (substr($attribs['y1'], -1) == '%')) OR (isset($attribs['x2']) AND (substr($attribs['x2'], -1) == '%')) OR (isset($attribs['y2']) AND (substr($attribs['y2'], -1) == '%')))) { $this->svggradients[$this->svggradientid]['mode'] = 'percentage'; } else { $this->svggradients[$this->svggradientid]['mode'] = 'measure'; } $x1 = (isset($attribs['x1'])?$attribs['x1']:'0'); $y1 = (isset($attribs['y1'])?$attribs['y1']:'0'); $x2 = (isset($attribs['x2'])?$attribs['x2']:'100'); $y2 = (isset($attribs['y2'])?$attribs['y2']:'0'); if (isset($attribs['gradientTransform'])) { $this->svggradients[$this->svggradientid]['gradientTransform'] = TCPDF_STATIC::getSVGTransformMatrix($attribs['gradientTransform']); } $this->svggradients[$this->svggradientid]['coords'] = array($x1, $y1, $x2, $y2); if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) { // gradient is defined on another place $this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1); } break; } case 'radialGradient': { if ($this->pdfa_mode) { break; } if (!isset($attribs['id'])) { $attribs['id'] = 'GR_'.(count($this->svggradients) + 1); } $this->svggradientid = $attribs['id']; $this->svggradients[$this->svggradientid] = array(); $this->svggradients[$this->svggradientid]['type'] = 3; $this->svggradients[$this->svggradientid]['stops'] = array(); if (isset($attribs['gradientUnits'])) { $this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits']; } else { $this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox'; } //$attribs['spreadMethod'] if (((!isset($attribs['cx'])) AND (!isset($attribs['cy']))) OR ((isset($attribs['cx']) AND (substr($attribs['cx'], -1) == '%')) OR (isset($attribs['cy']) AND (substr($attribs['cy'], -1) == '%')) )) { $this->svggradients[$this->svggradientid]['mode'] = 'percentage'; } else { $this->svggradients[$this->svggradientid]['mode'] = 'measure'; } $cx = (isset($attribs['cx']) ? $attribs['cx'] : 0.5); $cy = (isset($attribs['cy']) ? $attribs['cy'] : 0.5); $fx = (isset($attribs['fx']) ? $attribs['fx'] : $cx); $fy = (isset($attribs['fy']) ? $attribs['fy'] : $cy); $r = (isset($attribs['r']) ? $attribs['r'] : 0.5); if (isset($attribs['gradientTransform'])) { $this->svggradients[$this->svggradientid]['gradientTransform'] = TCPDF_STATIC::getSVGTransformMatrix($attribs['gradientTransform']); } $this->svggradients[$this->svggradientid]['coords'] = array($cx, $cy, $fx, $fy, $r); if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) { // gradient is defined on another place $this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1); } break; } case 'stop': { // gradient stops if (substr($attribs['offset'], -1) == '%') { $offset = floatval(substr($attribs['offset'], -1)) / 100; } else { $offset = floatval($attribs['offset']); if ($offset > 1) { $offset /= 100; } } $stop_color = isset($svgstyle['stop-color'])?TCPDF_COLORS::convertHTMLColorToDec($svgstyle['stop-color'], $this->spot_colors):'black'; $opacity = isset($svgstyle['stop-opacity'])?$svgstyle['stop-opacity']:1; $this->svggradients[$this->svggradientid]['stops'][] = array('offset' => $offset, 'color' => $stop_color, 'opacity' => $opacity); break; } // paths case 'path': { if ($invisible) { break; } if (isset($attribs['d'])) { $d = trim($attribs['d']); if (!empty($d)) { if ($clipping) { $this->SVGTransform($tm); $this->SVGPath($d, 'CNZ'); } else { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, 0, 0, 1, 1, 'SVGPath', array($d, 'CNZ')); if (!empty($obstyle)) { $this->SVGPath($d, $obstyle); } $this->StopTransform(); } } } break; } // shapes case 'rect': { if ($invisible) { break; } $x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0); $y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0); $w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0); $h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0); $rx = (isset($attribs['rx'])?$this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false):0); $ry = (isset($attribs['ry'])?$this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false):$rx); if ($clipping) { $this->SVGTransform($tm); $this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ', array(), array()); } else { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'RoundedRectXY', array($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ')); if (!empty($obstyle)) { $this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', $obstyle, array(), array()); } $this->StopTransform(); } break; } case 'circle': { if ($invisible) { break; } $r = (isset($attribs['r']) ? $this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false) : 0); $cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0)); $cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0)); $x = ($cx - $r); $y = ($cy - $r); $w = (2 * $r); $h = $w; if ($clipping) { $this->SVGTransform($tm); $this->Circle($cx, $cy, $r, 0, 360, 'CNZ', array(), array(), 8); } else { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Circle', array($cx, $cy, $r, 0, 360, 'CNZ')); if (!empty($obstyle)) { $this->Circle($cx, $cy, $r, 0, 360, $obstyle, array(), array(), 8); } $this->StopTransform(); } break; } case 'ellipse': { if ($invisible) { break; } $rx = (isset($attribs['rx']) ? $this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false) : 0); $ry = (isset($attribs['ry']) ? $this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false) : 0); $cx = (isset($attribs['cx']) ? $this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false) : (isset($attribs['x']) ? $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false) : 0)); $cy = (isset($attribs['cy']) ? $this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false) : (isset($attribs['y']) ? $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false) : 0)); $x = ($cx - $rx); $y = ($cy - $ry); $w = (2 * $rx); $h = (2 * $ry); if ($clipping) { $this->SVGTransform($tm); $this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ', array(), array(), 8); } else { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Ellipse', array($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ')); if (!empty($obstyle)) { $this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, $obstyle, array(), array(), 8); } $this->StopTransform(); } break; } case 'line': { if ($invisible) { break; } $x1 = (isset($attribs['x1'])?$this->getHTMLUnitToUnits($attribs['x1'], 0, $this->svgunit, false):0); $y1 = (isset($attribs['y1'])?$this->getHTMLUnitToUnits($attribs['y1'], 0, $this->svgunit, false):0); $x2 = (isset($attribs['x2'])?$this->getHTMLUnitToUnits($attribs['x2'], 0, $this->svgunit, false):0); $y2 = (isset($attribs['y2'])?$this->getHTMLUnitToUnits($attribs['y2'], 0, $this->svgunit, false):0); $x = $x1; $y = $y1; $w = abs($x2 - $x1); $h = abs($y2 - $y1); if (!$clipping) { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Line', array($x1, $y1, $x2, $y2)); $this->Line($x1, $y1, $x2, $y2); $this->StopTransform(); } break; } case 'polyline': case 'polygon': { if ($invisible) { break; } $points = (isset($attribs['points'])?$attribs['points']:'0 0'); $points = trim($points); // note that point may use a complex syntax not covered here $points = preg_split('/[\,\s]+/si', $points); if (count($points) < 4) { break; } $p = array(); $xmin = 2147483647; $xmax = 0; $ymin = 2147483647; $ymax = 0; foreach ($points as $key => $val) { $p[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false); if (($key % 2) == 0) { // X coordinate $xmin = min($xmin, $p[$key]); $xmax = max($xmax, $p[$key]); } else { // Y coordinate $ymin = min($ymin, $p[$key]); $ymax = max($ymax, $p[$key]); } } $x = $xmin; $y = $ymin; $w = ($xmax - $xmin); $h = ($ymax - $ymin); if ($name == 'polyline') { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'PolyLine', array($p, 'CNZ')); if (!empty($obstyle)) { $this->PolyLine($p, $obstyle, array(), array()); } $this->StopTransform(); } else { // polygon if ($clipping) { $this->SVGTransform($tm); $this->Polygon($p, 'CNZ', array(), array(), true); } else { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Polygon', array($p, 'CNZ')); if (!empty($obstyle)) { $this->Polygon($p, $obstyle, array(), array(), true); } $this->StopTransform(); } } break; } // image case 'image': { if ($invisible) { break; } if (!isset($attribs['xlink:href']) OR empty($attribs['xlink:href'])) { break; } $x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0); $y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0); $w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0); $h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0); $img = $attribs['xlink:href']; if (!$clipping) { $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h); if (preg_match('/^data:image\/[^;]+;base64,/', $img, $m) > 0) { // embedded image encoded as base64 $img = '@'.base64_decode(substr($img, strlen($m[0]))); } else { // fix image path if (!TCPDF_STATIC::empty_string($this->svgdir) AND (($img{0} == '.') OR (basename($img) == $img))) { // replace relative path with full server path $img = $this->svgdir.'/'.$img; } if (($img[0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { $findroot = strpos($img, $_SERVER['DOCUMENT_ROOT']); if (($findroot === false) OR ($findroot > 1)) { if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') { $img = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$img; } else { $img = $_SERVER['DOCUMENT_ROOT'].$img; } } } $img = urldecode($img); $testscrtype = @parse_url($img); if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) { // convert URL to server path $img = str_replace(K_PATH_URL, K_PATH_MAIN, $img); } } // get image type $imgtype = TCPDF_IMAGES::getImageFileType($img); if (($imgtype == 'eps') OR ($imgtype == 'ai')) { $this->ImageEps($img, $x, $y, $w, $h); } elseif ($imgtype == 'svg') { $this->ImageSVG($img, $x, $y, $w, $h); } else { $this->Image($img, $x, $y, $w, $h); } $this->StopTransform(); } break; } // text case 'text': case 'tspan': { // only basic support - advanced features must be implemented $this->svgtextmode['invisible'] = $invisible; if ($invisible) { break; } array_push($this->svgstyles, $svgstyle); if (isset($attribs['x'])) { $x = $this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false); } elseif ($name == 'tspan') { $x = $this->x; } else { $x = 0; } if (isset($attribs['y'])) { $y = $this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false); } elseif ($name == 'tspan') { $y = $this->y; } else { $y = 0; } $svgstyle['text-color'] = $svgstyle['fill']; $this->svgtext = ''; if (isset($svgstyle['text-anchor'])) { $this->svgtextmode['text-anchor'] = $svgstyle['text-anchor']; } else { $this->svgtextmode['text-anchor'] = 'start'; } if (isset($svgstyle['direction'])) { if ($svgstyle['direction'] == 'rtl') { $this->svgtextmode['rtl'] = true; } else { $this->svgtextmode['rtl'] = false; } } else { $this->svgtextmode['rtl'] = false; } if (isset($svgstyle['stroke']) AND ($svgstyle['stroke'] != 'none') AND isset($svgstyle['stroke-width']) AND ($svgstyle['stroke-width'] > 0)) { $this->svgtextmode['stroke'] = $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false); } else { $this->svgtextmode['stroke'] = false; } $this->StartTransform(); $this->SVGTransform($tm); $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, 1, 1); $this->x = $x; $this->y = $y; break; } // use case 'use': { if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) { $svgdefid = substr($attribs['xlink:href'], 1); if (isset($this->svgdefs[$svgdefid])) { $use = $this->svgdefs[$svgdefid]; if (isset($attribs['xlink:href'])) { unset($attribs['xlink:href']); } if (isset($attribs['id'])) { unset($attribs['id']); } $attribs = array_merge($attribs, $use['attribs']); $this->startSVGElementHandler($parser, $use['name'], $attribs); } } break; } default: { break; } } // end of switch } /** * Sets the closing SVG element handler function for the XML parser. * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler. * @param $name (string) The second parameter, name, contains the name of the element for which this handler is called. If case-folding is in effect for this parser, the element name will be in uppercase letters. * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @protected */ protected function endSVGElementHandler($parser, $name) { switch($name) { case 'defs': { $this->svgdefsmode = false; break; } // clipPath case 'clipPath': { $this->svgclipmode = false; break; } case 'g': { // ungroup: remove last style from array array_pop($this->svgstyles); $this->StopTransform(); break; } case 'text': case 'tspan': { if ($this->svgtextmode['invisible']) { // This implementation must be fixed to following the rule: // If the 'visibility' property is set to hidden on a 'tspan', 'tref' or 'altGlyph' element, then the text is invisible but still takes up space in text layout calculations. break; } // print text $text = $this->svgtext; //$text = $this->stringTrim($text); $textlen = $this->GetStringWidth($text); if ($this->svgtextmode['text-anchor'] != 'start') { // check if string is RTL text if ($this->svgtextmode['text-anchor'] == 'end') { if ($this->svgtextmode['rtl']) { $this->x += $textlen; } else { $this->x -= $textlen; } } elseif ($this->svgtextmode['text-anchor'] == 'middle') { if ($this->svgtextmode['rtl']) { $this->x += ($textlen / 2); } else { $this->x -= ($textlen / 2); } } } $textrendermode = $this->textrendermode; $textstrokewidth = $this->textstrokewidth; $this->setTextRenderingMode($this->svgtextmode['stroke'], true, false); if ($name == 'text') { // store current coordinates $tmpx = $this->x; $tmpy = $this->y; } $this->Cell($textlen, 0, $text, 0, 0, '', false, '', 0, false, 'L', 'T'); if ($name == 'text') { // restore coordinates $this->x = $tmpx; $this->y = $tmpy; } // restore previous rendering mode $this->textrendermode = $textrendermode; $this->textstrokewidth = $textstrokewidth; $this->svgtext = ''; $this->StopTransform(); array_pop($this->svgstyles); break; } default: { break; } } } /** * Sets the character data handler function for the XML parser. * @param $parser (resource) The first parameter, parser, is a reference to the XML parser calling the handler. * @param $data (string) The second parameter, data, contains the character data as a string. * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @protected */ protected function segSVGContentHandler($parser, $data) { $this->svgtext .= $data; } // --- END SVG METHODS ----------------------------------------------------- } // END OF TCPDF CLASS //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/class.calendar.php000066400000000000000000000067461237252063700204740ustar00rootroot00000000000000 * @name calendar * @package Collabtive * @version 2.0 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class calendar { private $daysInMonth; private $daysLastMonth; private $weeksInMonth; private $firstDay; private $month; private $year; private $project; public $calendar; /** * Constructor * * @access protected */ function __construct() { $this->calendar = array(); } /** * Get the calendar array for a given month and year (and project) * * @param int $month Month without leading zero (e.g. 5 for March) * @param int $year Year in the format yyyy (e.g. 2008) * @param int $project Project ID (default: 0 => no project selected, so get the calendar for all projects) * @return array */ public function getCal($month, $year, $project = 0) { $this->month = $month; $this->year = $year; // get number of days in the given and the previous month $this->daysInMonth = date("t",mktime(0,0,0,$month,1,$year)); $this->daysLastMonth = date("t",mktime(0,0,0,$month-1,1,$year)); // get first day of the month $this->firstDay = date("w", mktime(0,0,0,$month,1,$year))-1; $tempDays = $this->firstDay + $this->daysInMonth; $this->weeksInMonth = ceil($tempDays/7); $this->project = $project; return $this->buildCal(); } /** * Populates the array of calendar information * * @return array */ private function buildCal() { $counter = 0; $ms = new milestone(); $tsk = new task(); for($j=0; $j<$this->weeksInMonth; $j++) { for($i=0; $i<7; $i++) { $counter++; $theday = $counter-$this->firstDay; if ($theday < 1) { $this->calendar[$j][$i]["val"] = $this->daysLastMonth+$theday; $this->calendar[$j][$i]["currmonth"] = 0; } elseif($theday > $this->daysInMonth) { $this->calendar[$j][$i]["val"] = $theday-$this->daysInMonth; $this->calendar[$j][$i]["currmonth"] = 0; } else { $miles = $ms->getTodayMilestones($this->month,$this->year,$theday,$this->project); $milesnum = count($miles); $tasks = $tsk->getTodayTasks($this->month,$this->year,$theday,$this->project); $tasksnum = count($tasks); $this->calendar[$j][$i] = array( "val" => $theday, "milestones" => $miles, "milesnum" => $milesnum, "tasks" => $tasks, "tasksnum" => $tasksnum, "currmonth" => 1 ); } } } return $this; } } ?> Collabtive-2.0/include/class.company.php000066400000000000000000000137331237252063700203630ustar00rootroot00000000000000mylog = new mylog; } /** * Add a company * * @param array $data * @return int $insid ID of the inserted company */ function add($data) { global $conn; $ins1Stmt = $conn->prepare("INSERT INTO company (`company`, `contact`, `email`, `phone`, `mobile`, `url`, `address`, `zip`, `city`, `country`, `state`, `desc`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"); $ins1 = $ins1Stmt->execute(array($data['company'], $data['contact'], $data['email'], $data['phone'], $data['mobile'], $data['url'], $data['address'], $data['zip'], $data['city'], $data['country'], $data['state'], $data['desc'])); $insid = $conn->lastInsertId(); if ($ins1) { return $insid; } else { return false; } } /** * Edit a company * * @param array $data Company data * @return bool */ function edit($data) { global $conn; $id = (int) $data['id']; $updStmt = $conn->prepare("UPDATE company SET `company`=?, `contact`=?, `email`=?, `phone`=?, `mobile`=?, `url`=?, `address`=?, `zip`=?, `city`=?, `country`=?, `state`=?, `desc`=? WHERE ID = ?"); $upd = $updStmt->execute(array($data['company'], $data['contact'], $data['email'], $data['phone'], $data['mobile'], $data['url'], $data['address'], $data['zip'], $data['city'], $data['country'], $data['state'], $data['desc'], $id)); if ($upd) { return true; } else { return false; } } /** * Delete a company and disconnect all assigned projects * * @param int $id Company ID * @return bool */ function del($id) { global $conn; $id = (int) $id; $del_assigns = $conn->query("DELETE FROM company_assigned WHERE customer = $id"); $del = $conn->query("DELETE FROM customer WHERE ID = $id"); if ($del) { return true; } else { return false; } } /** * Assign a company to a project * * @param int $task Company ID * @param int $id project ID * @return bool */ function assign($company, $id) { global $conn; $company = (int) $company; $id = (int) $id; $upd = $conn->query("INSERT INTO customers_assigned (customer, project) VALUES ($company, $id)"); if ($upd) { return true; } else { return false; } } /** * Disconnect a company from a user * * @param int $task Company ID * @param int $id User ID * @return bool */ function deassign($company, $id) { global $conn; $company = (int) $company; $id = (int) $id; $upd = $conn->query("DELETE FROM company_assigned WHERE user = $id AND company = $company"); if ($upd) { return true; } else { return false; } } /** * Get a company * * @param int $id Company ID * @return array $company Company */ function getCompany($id) { global $conn; $id = (int) $id; $sel = $conn->prepare("SELECT * FROM company WHERE ID = ?"); $selStmt = $sel->execute(array($id)); $company = $sel->fetch(); if (!empty($company)) { return $company; } else { return false; } } function getProjectCompany($project) { global $conn; $project = (int) $project; $sel = $conn->prepare("SELECT customer FROM customers_assigned WHERE project = ?"); $selStmt = $sel->execute(array($project)); $companyId = $sel->fetch(); $company = $this->getCompany($companyId); if (!empty($company)) { return $company; } else { return false; } } /** * Get a list of companies * * @param int $lim Maximum number of companies to return (default: 10) * @return array $companies List of companies */ function getCompanies($lim = 10) { global $conn; $lim = (int) $lim; $sel = $conn->prepare("SELECT * FROM company ORDER BY `company` ASC LIMIT $lim"); $selStmt = $sel->execute(); $companies = $sel->fetchAll(); if (!empty($companies)) { return $companies; } else { return false; } } /** * Get a list of all companies * * @return array $companies List of all companies */ function getAllCompanies() { global $conn; $sel = $conn->query("SELECT * FROM company"); $companies = array(); while ($company = $sel->fetch()) { array_push($companies, $company); } if (!empty($companies)) { return $companies; }else { return false; } } /** * Get a company including all of its members * * @param int $id Company ID * @return array $company Company including all of its members */ function getCompanyMembers($id) { global $conn; $id = (int) $id; $sel = $conn->query("SELECT user, company FROM company_assigned WHERE company = $id"); $staff = array(); $userobj = (object) new user(); $company = $this->getProfile($member[1]); while ($member = $sel->fetch()) { $user = $userobj->getProfile($member[0]); array_push($staff, $user); } $company["staff"] = $staff; if (!empty($company)) { return $company; }else { return false; } } } ?> Collabtive-2.0/include/class.datei.php000066400000000000000000000614421237252063700200030ustar00rootroot00000000000000 * @name datei * @package Collabtive * @version 2.0 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class datei { /** * Constructor * * @access protected */ function __construct() { // Initialize event log $this->mylog = new mylog; } // FOLDER METHODS /** * Create a new folder * * @param int $parent ID of the parent folder * @param int $project ID of the project the folder belongs to * @param string $folder Name of the new folder * @param string $desc Description of the new folder * @param strin $visible Visibility of the new folder * @return bool */ function addFolder($parent, $project, $folder, $desc) { global $conn; $project = (int) $project; $folderOrig = $folder; $thepath = $this->getAbsolutePathName($this->getFolder($parent)); //if its the root path, don't append any slashes if($thepath == "/") { $thepath = ""; } // Replace umlauts $folder = str_replace("ä", "ae" , $folder); $folder = str_replace("ö", "oe" , $folder); $folder = str_replace("ü", "ue" , $folder); $folder = str_replace("ß", "ss" , $folder); // Remove whitespace $folder = preg_replace("/\W/", "", $folder); $folder = preg_replace("/[^-_0-9a-zA-Z]/", "_", $folder); // Insert folder into database $insStmt = $conn->prepare("INSERT INTO projectfolders (parent, project, name, description) VALUES (?, ?, ?, ?)"); $ins = $insStmt->execute(array($parent, $project, $folder, $desc)); if ($ins) { // Create the folder //$makefolder = CL_ROOT . "/files/" . CL_CONFIG . "/$project/$folder/"; $makefolder = CL_ROOT . "/files/" . CL_CONFIG . "/$project" . $thepath . "/" . $folder . "/"; //echo "

      " . $makefolder . "
      " . $makefolder2; if (!file_exists($makefolder)) { if (mkdir($makefolder, 0777, true)) { // Folder created $this->mylog->add($folderOrig, 'folder', 1, $project); return true; } } else { // Folder already existed, return false return false; } } else { // Folder could not be created, return false return false; } } /** * Delete a folder * Deletes the given folder as well as all of its files and subfolders. * * @param int $id Folder ID * @param int $project Project ID * @return bool */ function deleteFolder($id, $project) { global $conn; $id = (int) $id; $project = (int) $project; $folder = $this->getFolder($id); $files = $this->getProjectFiles($project, 10000, $id); // Delete all files in the folder from database and filesystem if (!empty($files)) { foreach($files as $file) { $this->loeschen($file["ID"]); } } // Recursively delete any nested subfolders if (!empty($folder["subfolders"])) { foreach($folder["subfolders"] as $sub) { $this->deleteFolder($sub["ID"], $sub["project"]); } } $del = $conn->query("DELETE FROM projectfolders WHERE ID = $id"); if ($del) { // Remove directory $foldstr = CL_ROOT . "/files/" . CL_CONFIG . "/$project/" . $folder["name"] . "/"; delete_directory($foldstr); $this->mylog->add($folder["name"], 'folder', 3, $project); return true; } } /** * Get a folder * * @param int $id Folder ID * @return array $folder */ function getFolder($id) { global $conn; $id = (int) $id; $folder = $conn->query("SELECT * FROM projectfolders WHERE ID = $id LIMIT 1")->fetch(); if(!$folder) { return false; } $folder["subfolders"] = $this->getSubFolders($folder["ID"]); $folder["abspath"] = $this->getAbsolutePathName($folder); return $folder; } /** * Recursively get all subfolders of a folder * * @param int $parent ID of the parent folder * @return array $folders */ function getSubFolders($parent) { global $conn; $parent = (int) $parent; $sel = $conn->query("SELECT * FROM projectfolders WHERE parent = $parent ORDER BY ID ASC"); $folders = array(); while ($folder = $sel->fetch()) { $folder["subfolders"] = $this->getSubFolders($folder["ID"]); $folder["abspath"] = $this->getAbsolutePathName($folder); array_push($folders, $folder); } if (!empty($folders)) { return $folders; } else { return false; } } /** * Get all the folders in a project, starting from a given folder * * @param int $project Project ID * @param int $parent Parent folder ID (default: 0 => root folder) * @return array $folders */ function getProjectFolders($project, $parent = 0) { global $conn; $project = (int) $project; $sel = $conn->query("SELECT * FROM projectfolders WHERE project = $project AND parent = $parent ORDER BY ID ASC"); $folders = array(); while ($folder = $sel->fetch()) { $folder["subfolders"] = $this->getSubFolders($folder["ID"]); $folder["abspath"] = $this->getAbsolutePathName($folder); array_push($folders, $folder); } if (!empty($folders)) { return $folders; } else { return false; } } /** * Get all the folders in a project * * @param string $id project Project ID * @return array $folders */ function getAllProjectFolders($project) { global $conn; $project = (int) $project; $sel = $conn->query("SELECT * FROM projectfolders WHERE project = $project ORDER BY ID ASC"); $folders = array(); while ($folder = $sel->fetch()) { $folder["subfolders"] = $this->getSubFolders($folder["ID"]); $folder["abspath"] = $this->getAbsolutePathName($folder); array_push($folders, $folder); } if (!empty($folders)) { return $folders; } else { return false; } } /** * Get an absolute path name of a folder * Returns the absolute name (relative to the root directory of the project) of a folder. * * @param array $folder The folder to be inspected * @return string Absolute path/name of the folder */ function getAbsolutePathName($folder) { global $conn; if ($folder['parent'] == 0) { return "/" . $folder['name']; } else { $sel = $conn->query("SELECT * FROM projectfolders WHERE ID = " . $folder['parent']); $parent = $sel->fetch(); return $this->getAbsolutePathName($parent) . "/" . $folder['name']; } } // FILE METHODS /** * Upload a file * Does filename sanitizing as well as MIME-type determination * Also adds the file to the database using add_file() * * @param string $fname Name of the HTML form field POSTed from * @param string $ziel Destination directory * @param int $project Project ID of the associated project (default: 0 => root folder) * @param int $folder * @return bool */ function upload($fname, $ziel, $project, $folder = 0) { echo $fname . " " . $ziel . " " . $project; // Get data from form $name = $_FILES[$fname]['name']; $typ = $_FILES[$fname]['type']; $size = $_FILES[$fname]['size']; $tmp_name = $_FILES[$fname]['tmp_name']; $tstr = $fname . "-title"; $tastr = $fname . "-tags"; $title = $_POST[$tstr]; $error = $_FILES[$fname]['error']; $root = CL_ROOT; // If no filename is given, abort if (empty($name)) { return false; } $desc = $_POST['desc']; // Find the extension $teilnamen = explode(".", $name); $teile = count($teilnamen); $workteile = $teile - 1; $erweiterung = $teilnamen[$workteile]; $subname = ""; // If it is a PHP file, treat it as plain text so it is not executed when opened in the browser if (stristr($erweiterung, "php")) { $erweiterung = "txt"; $typ = "text/plain"; } // Reassemble the file name from the exploded array, without the extension for ($i = 0; $i < $workteile; $i++) { $subname .= $teilnamen[$i]; } // Create a random number $randval = mt_rand(1, 99999); // Only allow a-z, 0-9 in filenames, substitute other chars with _ $subname = str_replace("ä", "ae" , $subname); $subname = str_replace("Ä", "Ae" , $subname); $subname = str_replace("ö", "oe" , $subname); $subname = str_replace("Ö", "Oe" , $subname); $subname = str_replace("ü", "ue" , $subname); $subname = str_replace("Ü", "Ue" , $subname); $subname = str_replace("ß", "ss" , $subname); $subname = preg_replace("/[^-_0-9a-zA-Z]/", "_", $subname); // Remove whitespace $subname = preg_replace("/\W/", "", $subname); // If filename is longer than 200 chars, cut it if (strlen($subname) > 200) { $subname = substr($subname, 0, 200); } // Assemble the final filename from the original name plus the random value. // This is to ensure that files with the same name do not overwrite each other. $name = $subname . "_" . $randval . "." . $erweiterung; // Absolute file system path used to move the file to its final location $datei_final = $root . "/" . $ziel . "/" . $name; // Relative path used for display / URL construction in the file manager $datei_final2 = $ziel . "/" . $name; if (!file_exists($datei_final)) { if (move_uploaded_file($tmp_name, $datei_final)) { if ($project > 0) { // File did not already exist, was uploaded, and a project is set // Now add the file to the database, log the upload event and return the file ID chmod($datei_final, 0755); $fid = $this->add_file($name, $desc, $project, 0, $datei_final2, "$typ", $title, $folder, ""); if (!empty($title)) { $this->mylog->add($title, 'file', 1, $project); } else { $this->mylog->add($name, 'file', 1, $project); } //encrypt the uploaded file $this->encryptFile($datei_final); return $fid; } else { // No project means the file is not added to the database willfully. Return file name return $name; } } else { // File was not uploaded / error occured. Return false return false; } } else { // File already exists. Return false return false; } } /** * Upload a file * Does filename sanitizing as well as MIME-type determination * Also adds the file to the database using add_file() * * @param string $fname Name of the HTML form field POSTed from * @param string $ziel Destination directory * @param int $project Project ID of the associated project * @return bool */ function uploadAsync($name, $tmp_name, $typ, $size, $ziel, $project, $folder = 0) { $visible = ""; $visstr = ""; $root = CL_ROOT; if (empty($name)) { return false; } // Find the extension $teilnamen = explode(".", $name); $teile = count($teilnamen); $workteile = $teile - 1; $erweiterung = $teilnamen[$workteile]; $subname = ""; // If it is a PHP file, treat as plain text so it is not executed when opened in the browser if (stristr($erweiterung, "php")) { $erweiterung = "txt"; $typ = "text/plain"; } for ($i = 0; $i < $workteile; $i++) { $subname .= $teilnamen[$i]; } $randval = mt_rand(1, 99999); // Only allow a-z, 0-9 in filenames, substitute other chars with _ $subname = str_replace("ä", "ae" , $subname); $subname = str_replace("Ä", "Ae" , $subname); $subname = str_replace("ö", "oe" , $subname); $subname = str_replace("Ö", "Oe" , $subname); $subname = str_replace("ü", "ue" , $subname); $subname = str_replace("Ü", "Ue" , $subname); $subname = str_replace("ß", "ss" , $subname); $subname = preg_replace("/[^-_0-9a-zA-Z]/", "_", $subname); // Remove whitespace $subname = preg_replace("/\W/", "", $subname); // If filename is longer than 200 chars, cut it if (strlen($subname) > 200) { $subname = substr($subname, 0, 200); } $name = $subname . "_" . $randval . "." . $erweiterung; $datei_final = $root . "/" . $ziel . "/" . $name; $datei_final2 = $ziel . "/" . $name; if (!file_exists($datei_final)) { if (move_uploaded_file($tmp_name, $datei_final)) { if ($project > 0) { // File did not already exist, was uploaded, and a project is set // Now add the file to the database, log the upload event and return the file ID. if (!$title) { $title = $name; } chmod($datei_final, 0755); $fid = $this->add_file($name, $desc, $project, 0, $datei_final2, "$typ", $title, $folder, ""); if (!empty($title)) { $this->mylog->add($title, 'file', 1, $project); } else { $this->mylog->add($name, 'file', 1, $project); } //encrypt the uploaded file //$this->encryptFile($datei_final); return $fid; } else { // No project means the file is not added to the database wilfully. Return file name return $name; } } else { // File was not uploaded / error occured. Return false return false; } } else { // File already exists. Return false return false; } } /** * Edit a file * * @param int $id File ID * @param string $title Title of the file * @param string $desc Description text * @param string $tags Associated tags (not yet implemented) * @return bool */ function edit($id, $title, $desc, $tags) { global $conn; $id = (int) $id; // Get project for logging $proj = $conn->query("SELECT project FROM files WHERE ID = $id")->fetch(); $project = $proj[0]; $sql = $conn->prepare("UPDATE files SET `title` = ?, `desc` = ?, `tags` = ? WHERE id = ?"); $upd = $sql->execute(array($title, $desc, $tags, $id)); if ($sql) { $this->mylog->add($title, 'file' , 2, $project); return true; } else { return false; } } /** * Delete a file * * @param int $datei File ID * @return bool */ function loeschen($datei) { global $conn; $datei = (int) $datei; $thisfile = $conn->query("SELECT datei, name, project, title FROM files WHERE ID = $datei")->fetch(); if (!empty($thisfile)) { $fname = $thisfile[1]; $project = $thisfile[2]; $ftitle = $thisfile[3]; $thisfile = $thisfile[0]; $delfile = "./" . $thisfile; if (!file_exists($delfile)) { return false; } $del = $conn->query("DELETE FROM files WHERE ID = $datei"); // Delete attachments of the file (prevents abandoned objects in messages) $del2 = $conn->query("DELETE FROM files_attached WHERE file = $datei"); if ($del) { // Only remove the file from file system if deletion from database was successful if (unlink($delfile)) { if ($ftitle != "") { $this->mylog->add($ftitle, 'file', 3, $project); } else { $this->mylog->add($fname, 'file', 3, $project); } return true; } else { return false; } } } else { return false; } } /** * Return a file * * @param string $id File ID * @return array $file File details */ function getFile($id) { global $conn; $id = (int) $id; // Get the file from the database $file = $conn->query("SELECT * FROM files WHERE ID=$id")->fetch(); if (!empty($file)) { // Determine if there is a MIME-type icon corresponding to the file's MIME-type. If not, set 'none' $file['type'] = str_replace("/", "-", $file["type"]); // Get settings (needed to add a different MIME-type icon per theme for each file) $set = new settings(); $settings = $set->getSettings(); // Construct the path to the MIME-type icon $myfile = "./templates/" . $settings["template"] . "/theme/" . $settings["theme"] . "/images/files/" . $file['type'] . ".png"; if (!file_exists($myfile)) { $file['type'] = "none"; } // Determine if it is an image or text file or some other kind of file (required for lightbox) if (stristr($file['type'], "image")) { $file['imgfile'] = 1; } elseif (stristr($file['type'], "text")) { $file['imgfile'] = 0; } else { $file['imgfile'] = 0; } // Strip slashes from title, desc and tags $file["title"] = stripslashes($file["title"]); $file["desc"] = stripslashes($file["desc"]); $file["size"] = filesize(realpath($file["datei"])) / 1024; $file["size"] = round($file["size"]); $file["addedstr"] = date(CL_DATEFORMAT, $file["added"]); // Attach data about the user who uploaded the file $userobj = new user(); $file["userdata"] = $userobj->getProfile($file["user"]); return $file; } else { return false; } } /** * Move a file to another folder * * @param int $file File ID * @param int $folder Folder ID * @return bool */ function moveFile($file, $target) { global $conn; $file = (int) $file; $target = (int)$target; // Get the file $thefile = $this->getFile($file); // Get the target folder $thefolder = $this->getFolder($target); $abspath = $this->getAbsolutePathName($thefolder); if($abspath == "/") { $abspath = ""; } // Build file system paths //$targetstr = "files/" . CL_CONFIG . "/" . $thefile["project"] . "/" . $thefolder["name"] . "/" . $thefile["name"]; $targetstr = "files/" . CL_CONFIG . "/" . $thefile["project"] . $abspath . "/" . $thefile["name"]; $rootstr = CL_ROOT . "/" . $thefile["datei"]; // Update database $upd = $conn->query("UPDATE files SET datei = '$targetstr', folder = '$thefolder[ID]' WHERE ID = $thefile[ID]"); // Move the file physically return rename($rootstr, $targetstr); } /** * List all files associated to a given project * * @param string $id Project ID * @param int $lim Limit * @param int $folder Folder * @return array $files Found files */ function getProjectFiles($id, $lim = 5000, $folder = "") { global $conn; $id = (int) $id; $lim = (int) $lim; $folder = (int) $folder; // If folder is given, return files from this folder, otherwise return files from root folder if ($folder > 0) { $fold = "files/" . CL_CONFIG . "/$id/$folder/"; $sel = $conn->query("SELECT COUNT(*) FROM files WHERE project = $id AND folder = $folder ORDER BY ID DESC"); } else { $sel = $conn->query("SELECT COUNT(*) FROM files WHERE project = $id AND folder = 0 ORDER BY ID DESC"); } $num = $sel->fetch(); $num = $num[0]; // Set items per page SmartyPaginate::connect(); SmartyPaginate::setLimit($lim); SmartyPaginate::setTotal($num); $start = SmartyPaginate::getCurrentIndex(); $lim = SmartyPaginate::getLimit(); $files = array(); if ($folder > 0) { $sql = "SELECT ID FROM files WHERE project = $id AND folder = $folder ORDER BY ID DESC LIMIT $start,$lim"; $sel2 = $conn->query($sql); } else { $sel2 = $conn->query("SELECT ID FROM files WHERE project = $id AND folder = 0 ORDER BY ID DESC LIMIT $start,$lim"); } while ($file = $sel2->fetch()) { if (!empty($file)) { array_push($files, $this->getFile($file["ID"])); } } if (!empty($files)) { return $files; } else { return false; } } /** * List all files associated to a given project regardless of folder * * @param string $id Project ID * @return array $files Found files */ function getAllProjectFiles($id) { global $conn; $id = (int) $id; $files = array(); $sel2 = $conn->query("SELECT ID FROM files WHERE project = $id ORDER BY ID DESC"); while ($file = $sel2->fetch()) { if (!empty($file)) { array_push($files, $this->getFile($file["ID"])); } } if (!empty($files)) { return $files; } else { return false; } } /** * Seed the random number generator * * @return float $value Initial value */ private function make_seed() { list($usec, $sec) = explode(' ', microtime()); $value = (float) $sec + ((float) $usec * 100000); return $value; } /** * Add a file to the database * * @param string $name File name * @param string $desc Description * @param int $project ID of the associated project * @param int $milestone ID of the associated milestone * @param string $tags Tags for the file (not yet implemented) * @param string $datei File path * @param string $type MIME type * @param string $title Title of the file * @param int $ folder Optional parameter (holds ID of subfolder the file is uploaded to [0 = root directory]) * @return bool $insid */ function add_file($name, $desc, $project, $milestone, $datei, $type, $title = " ", $folder = 0, $visstr = "") { global $conn; if (!$desc) { $desc = " "; } $project = (int) $project; $milestone = (int) $milestone; $folder = (int) $folder; $userid = $_SESSION["userid"]; $now = time(); $insStmt = $conn->prepare("INSERT INTO files (`name`, `desc`, `project`, `milestone`, `user`, `added`, `datei`, `type`, `title`, `folder`, `visible`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $ins = $insStmt->execute(array($name, $desc, $project, $milestone, $userid, $now, $datei, $type, $title, $folder, $visstr)); if ($ins) { $insid = $conn->lastInsertId(); return $insid; } else { return false; } } function encryptFile($filename, $key) { include_once(CL_ROOT . "/include/phpseclib/Crypt/AES.php"); $cipher = new Crypt_AES(); // could use CRYPT_AES_MODE_CBC $cipher->setPassword($key); $plaintext = file_get_contents($filename); //echo $cipher->decrypt($cipher->encrypt($plaintext)); return file_put_contents($filename,$cipher->encrypt($plaintext)); } function decryptFile($filename, $key) { include_once(CL_ROOT . "/include/phpseclib/Crypt/AES.php"); $cipher = new Crypt_AES(); // could use CRYPT_AES_MODE_CBC $cipher->setPassword($key); $ciphertext = file_get_contents($filename); //echo $cipher->decrypt($cipher->encrypt($plaintext)); return $cipher->decrypt($ciphertext); } } ?> Collabtive-2.0/include/class.emailer.php000066400000000000000000000034101237252063700203220ustar00rootroot00000000000000 * @name emailer * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class emailer { private $from; private $mailsettings; function __construct($settings) { $this->mailsettings = $settings; } /** * Send an email to a member * * @param string $to Recipient's email address * @param string $subject Subjectline of the mail * @param string $text Textbody of the mail, HTML allowed * @return bool */ function send_mail($to, $subject, $text) { //create PHP Mailer object $mailer = (object) new PHPmailer(); //setup PHPMailer $mailer->From = $this->mailsettings["mailfrom"]; $mailer->Sender = $this->mailsettings["mailfrom"]; $mailer->FromName = $this->mailsettings["mailfromname"]; $mailer->AddAddress($to); $mailer->Subject = $subject; $mailer->Body = $text; //send mail as HTML $mailer->IsHTML(true); //set charset $mailer->CharSet = "utf-8"; //set mailing method... mail, smtp or sendmail $mailer->Mailer = $this->mailsettings["mailmethod"]; //if it's smtp , set the smtp server if($this->mailsettings["mailmethod"] == "smtp") { $mailer->Host = $this->mailsettings["mailhost"]; //setup SMTP auth if($this->mailsettings["mailuser"] and $this->mailsettings["mailpass"]) { $mailer->Username = $this->mailsettings["mailuser"]; $mailer->Password = $this->mailsettings["mailpass"]; $mailer->SMTPAuth = true; } } if ($mailer->Send()) { return true; } else { return false; } } } ?>Collabtive-2.0/include/class.hft_image.php000066400000000000000000000246361237252063700206440ustar00rootroot00000000000000clear(); // clear all. if(file_exists($file_original)) { $this->file_original = $file_original; $this->image_original = $this->imagecreatefromfile($file_original); if(!$this->image_original){ $this->error($ERR["IMAGE_NOT_CREATED_FROM_FILE"]." file=$file_original"); return false; } } else { $this->error($ERR["FILE_DOESNOT_EXSIT"]." file=$file_original"); } } function clear() { // clear all the class member variables $this->image_original = 0; $this->file_original = ""; $this->image_original_width = 0; $this->image_original_height = 0; $this->image_original_type_code = 0; $this->image_original_type_abbr = ""; $this->image_original_html_sizes= ""; $this->image_resized = 0; $this->file_resized = ""; $this->image_resized_width = 0; $this->image_resized_height = 0; $this->image_resized_type_code = -1; $this->image_resized_type_abbr = ""; $this->image_resized_html_sizes = ""; $this->set_parameters(); } function set_parameters($jpeg_quality="90", $use_gd2=true) { $this->jpeg_quality=$jpeg_quality; $this->use_gd2=$use_gd2; } function error($msg){ //error messages and debug info: // here you can implement your own error handling echo("
      $msg
      file=".__FILE__."
      "); } function imagecreatefromfile($img_file){ global $ERR; $img=0; $img_sz = getimagesize( $img_file ); ## returns array with some properties like dimensions and type; ####### Now create original image from uploaded file. Be carefull! GIF is often not supported, as far as I remember from GD 1.6 switch( $img_sz[2] ){ case 1: $img = $this->_imagecheckandcreate("ImageCreateFromGif", $img_file); $img_type = "GIF"; break; case 2: $img = $this->_imagecheckandcreate("ImageCreateFromJpeg", $img_file); $img_type = "JPG"; break; case 3: $img = $this->_imagecheckandcreate("ImageCreateFromPng", $img_file); $img_type = "PNG"; break; // would be nice if this function will be finally supported case 4: $img = $this->_imagecheckandcreate("ImageCreateFromSwf", $img_file); $img_type = "SWF"; break; default: $img = 0; $img_type = "UNKNOWN"; $this->error($ERR["IMG_NOT_SUPPORTED"]." $img_file"); break; }//case if($img){ $this->image_original_width=$img_sz[0]; $this->image_original_height=$img_sz[1]; $this->image_original_type_code=$img_sz[2]; $this->image_original_type_abbr=$img_type; $this->image_original_html_sizes=$img_sz[3]; }else { $this->clear(); } return $img; } function _imagecheckandcreate($function, $img_file) { //inner function used from imagecreatefromfile(). //Checks if the function exists and returns //created image or false global $ERR; if(function_exists($function)) { $img = $function($img_file); }else{ $img = false; $this->error($ERR["FUNCTION_DOESNOT_EXIST"]." ".$function); } return $img; } function resize($desired_width, $desired_height, $mode="0"){ //this is core function--it resizes created image //if any of parameters == "*" then no resizing on this parameter //>> mode = "+" then image is resized to cover the region specified by desired_width, _height //>> mode = "-" then image is resized to fit into the region specified by desired_width, _height // width-to-height ratio is all the time the same //>>mode=0 then image will be exactly resized to $desired_width _height. //geometrical distortion can occur in this case. // say u have picture 400x300 and there is circle on the picture //now u resized in mode=0 to 800x300 -- circle shape will be distorted and will look like ellipse. //GD2 provides much better quality but is not everywhere installed global $ERR; if($desired_width == "*" && $desired_height == "*"){ $this->image_resized = $this->image_original; Return true; } switch($mode) { case "-": case '+': //multipliers if($desired_width != "*") $mult_x = $desired_width / $this->image_original_width; if($desired_height != "*") $mult_y = $desired_height / $this->image_original_height; $ratio = $this->image_original_width / $this->image_original_height; if($desired_width == "*"){ $new_height = $desired_height; $new_width = $ratio * $desired_height; }elseif($desired_height == "*"){ $new_height = $desired_width / $ratio; $new_width = $desired_width; }else{ if($mode=="-"){ if( $this->image_original_height * $mult_x < $desired_height ){ //image must be smaller than given $desired_ region //test which multiplier gives us best result //$mult_x does the job $new_width = $desired_width; $new_height = $this->image_original_height * $mult_x; }else{ //$mult_y does the job $new_width = $this->image_original_width * $mult_y; $new_height = $desired_height; } }else{ //mode == "+" // cover the region //image must be bigger than given $desired_ region //test which multiplier gives us best result if( $this->image_original_height * $mult_x > $desired_height ){ //$mult_x does the job $new_width = $desired_width; $new_height = $this->image_original_height * $mult_x; }else{ //$mult_y does the job $new_width = $this->image_original_width * $mult_y; $new_height = $desired_height; } } } break; case '0': //fit the region exactly. if($desired_width == "*") $desired_width = $this->image_original_width; if($desired_height == "*") $desired_height = $this->image_original_height; $new_width = $desired_width; $new_height = $desired_height; break; default: $this->error($ERR["UNKNOWN_RESIZE_MODE"]." $mode"); break; } // OK here we have $new_width _height //create destination image checking for GD2 functions: if( $this->use_gd2 ){ if( function_exists("imagecreatetruecolor")){ $this->image_resized = imagecreatetruecolor($new_width, $new_height) or $this->error($ERR["GD2_NOT_CREATED"]); }else { $this->error($ERR["GD2_UNAVALABLE"]." ImageCreateTruecolor()"); } } else { $this->image_resized = imagecreate($new_width, $new_height) or $this->error($ERR["IMG_NOT_CREATED"]); } //Resize if( $this->use_gd2 ){ if( function_exists("imagecopyresampled")){ $res = imagecopyresampled($this->image_resized, $this->image_original, 0, 0, //dest coord 0, 0, //source coord $new_width, $new_height, //dest sizes $this->image_original_width, $this->image_original_height // src sizes ) or $this->error($ERR["GD2_NOT_RESIZED"]); }else { $this->error($ERR["GD2_UNAVALABLE"]." ImageCopyResampled()"); } } else { $res = imagecopyresized($this->image_resized, $this->image_original, 0, 0, //dest coord 0, 0, //source coord $new_width, $new_height, //dest sizes $this->image_original_width, $this->image_original_height // src sizes ) or $this->error($ERR["IMG_NOT_RESIZED"]); } } function output_original($destination_file, $image_type="JPG") { //outputs original image //if destination file is empty image will be output to browser // right now $image_type can be JPG or PNG return _output_image($destination_file, $image_type, $this->image_original); } function output_resized($destination_file, $image_type="JPG") { //if destination file is empty image will be output to browser // right now $image_type can be JPG or PNG $res = $this->_output_image($destination_file, $image_type, $this->image_resized); if(trim($destination_file)){ $sz=getimagesize($destination_file); $this->file_resized = $destination_file; $this->image_resized_width = $sz[0]; $this->image_resized_height = $sz[1]; $this->image_resized_type_code=$sz[2]; $this->image_resized_html_sizes=$sz[3]; //only jpeg and png are really supported, but I'd like to think of future switch($this->image_resized_html_sizes){ case 0: $this->image_resized_type_abbr = "GIF"; break; case 1: $this->image_resized_type_abbr = "JPG"; break; case 2: $this->image_resized_type_abbr = "PNG"; break; case 3: $this->image_resized_type_abbr = "SWF"; break; default: $this->image_resized_type_abbr = "UNKNOWN"; break; } } return $res; } function _output_image($destination_file, $image_type, $image){ //if destination file is empty image will be output to browser // right now $image_type can be JPEG or PNG global $ERR; $destination_file = trim($destination_file); if (empty($destination_file)) { $destination_file = NULL; } $res = false; if($image){ switch($image_type) { case 'JPEG': case 'JPG': $res = ImageJpeg($image, $destination_file, $this->jpeg_quality); break; case 'PNG': $res = Imagepng($image, $destination_file); break; default: $this->error($ERR["UNKNOWN_OUTPUT_FORMAT"]." $image_type"); break; } }else{ $this->error($ERR["NO_IMAGE_FOR_OUTPUT"]); } if(!$res) $this->error($ERR["UNABLE_TO_OUTPUT"]." $destination_file"); return $res; } } ?>Collabtive-2.0/include/class.ical.php000066400000000000000000007062331237252063700176310ustar00rootroot00000000000000= '5' ) && ( 'UTC' == date_default_timezone_get() )) { date_default_timezone_set( 'Europe/Stockholm' ); } /* version string, do NOT remove!! */ define( 'ICALCREATOR_VERSION', 'iCalcreator 2.2.6' ); /*********************************************************************************/ /*********************************************************************************/ /** * vcalendar class * * @author Kjell-Inge Gustafsson * @since 0.9.8 - 2006-11-27 */ class vcalendar { // calendar property variables var $calscale; var $method; var $prodid; var $version; var $xprop; // container for calendar components var $components; // component config variables var $unique_id; var $language; var $directory; var $filename; var $delimiter; var $nl; var $format; // component internal variables var $attributeDelimiter; var $valueInit; // component xCal declaration container var $xcaldecl; /* * constructor for calendar object * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-08 * @return void */ function vcalendar () { $this->_makeVersion(); $this->calscale = null; $this->method = null; $this->_makeUnique_id(); $this->prodid = null; $this->xprop = array(); /** * language = */ if( defined( 'ICAL_LANG' )) $this->setConfig( 'language', ICAL_LANG ); $this->setConfig( 'nl', "\n" ); $this->setConfig( 'format', 'iCal'); $this->directory = null; $this->filename = null; $this->setConfig( 'delimiter', DIRECTORY_SEPARATOR ); $this->xcaldecl = array(); $this->components = array(); } /*********************************************************************************/ /** * Property Name: CALSCALE */ /** * creates formatted output for calendar property calscale * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createCalscale() { if( !isset( $this->calscale )) return; switch( $this->format ) { case 'xcal': return ' calscale="'.$this->calscale.'"'.$this->nl; break; default: return 'CALSCALE:'.$this->calscale.$this->nl; break; } } /** * set calendar property calscale * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-13 * @param string $value * @return void */ function setCalscale( $value ) { $this->calscale = $value; } /*********************************************************************************/ /** * Property Name: METHOD */ /** * creates formatted output for calendar property method * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createMethod() { if( !isset( $this->method )) return; switch( $this->format ) { case 'xcal': return ' method="'.$this->method.'"'.$this->nl; break; default: return 'METHOD:'.$this->method.$this->nl; break; } } /** * set calendar property method * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-13 * @param string $method * @return void */ function setMethod( $method ) { $this->method = $method; } /*********************************************************************************/ /** * Property Name: PRODID * * The identifier is RECOMMENDED to be the identical syntax to the * [RFC 822] addr-spec. A good method to assure uniqueness is to put the * domain name or a domain literal IP address of the host on which.. . */ /** * creates formatted output for calendar property prodid * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createProdid() { if( !isset( $this->prodid )) $this->_makeProdid(); switch( $this->format ) { case 'xcal': return ' prodid="'.$this->prodid.'"'.$this->nl; break; default: return 'PRODID:'.$this->prodid.$this->nl; break; } } /** * make default value for calendar prodid * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function _makeProdid() { $this->prodid = '-//'.$this->unique_id.'//NONSGML '.ICALCREATOR_VERSION.'//'.strtoupper( $this->language ); } /** * Conformance: The property MUST be specified once in an iCalendar object. * Description: The vendor of the implementation SHOULD assure that this * is a globally unique identifier; using some technique such as an FPI * value, as defined in [ISO 9070]. */ /** * make default unique_id for calendar prodid * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function _makeUnique_id() { $this->unique_id = gethostbyname( $_SERVER['SERVER_NAME'] ); } /*********************************************************************************/ /** * Property Name: VERSION * * Description: A value of "2.0" corresponds to this memo. */ /** * creates formatted output for calendar property version * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createVersion() { if( !isset( $this->version )) $this->_makeVersion(); switch( $this->format ) { case 'xcal': return ' version="'.$this->version.'"'.$this->nl; break; default: return 'VERSION:'.$this->version.$this->nl; break; } } /** * set default calendar version * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function _makeVersion() { $this->version = '2.0'; } /** * set calendar version * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @param string version * @return void */ function setVersion( $version ) { $this->version = $version; } /*********************************************************************************/ /** * Property Name: x-prop */ /** * creates formatted output for calendar property x-prop, iCal format only * * @author Kjell-Inge Gustafsson * @since 2.0.7 - 2007-06-21 * @return string */ function createXprop() { if( 'xcal' == $this->format ) return false; if( 0 >= count( $this->xprop )) return; $xprop = null; $toolbox = new calendarComponent(); $toolbox->setConfig( 'language', $this->getConfig( 'language' )); $toolbox->setConfig( 'nl', $this->getConfig( 'nl' )); $toolbox->_createFormat( $this->getConfig( 'format' )); foreach( $this->xprop as $label => $xpropPart ) { $attributes = $toolbox->_createParams( $xpropPart['params'], array( 'LANGUAGE' )); if( is_array( $xpropPart['value'] )) $xpropPart['value'] = implode( ',', $xpropPart['value'] ); $xprop .= $toolbox->_createElement( strtoupper( $label ), $attributes, $xpropPart['value'] ); } return $xprop; } /** * set calendar property x-prop * * @author Kjell-Inge Gustafsson * @since 2.0.7 - 2007-06-21 * @param string $label * @param string $value * @param array $params optional * @return void */ function setXprop( $label, $value, $params=FALSE ) { if( empty( $label ) || empty( $value )) return; $xprop = array( 'value' => $value ); $toolbox = new calendarComponent(); $xprop['params'] = $toolbox->_setParams( $params ); $this->xprop[$label] = $xprop; } /*********************************************************************************/ /** * delete calendar property value * * @author Kjell-Inge Gustafsson * @since 2.1.2 - 2007-07-07 * @param string $propName * @param int @propix, optional, if specific property is wanted in case of multiply occurences * @return bool, if successfull delete */ function deleteProperty( $propName, $propix=FALSE ) { $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; if( !$propix ) $propix = ( isset( $this->propdelix[$propName] )) ? $this->propdelix[$propName] + 2 : 1; $this->propdelix[$propName] = --$propix; $return = FALSE; switch( $propName ) { case 'CALSCALE': $this->calscale = null; $return = TRUE; break; case 'METHOD': $this->method = null; $return = TRUE; break; default: if( $propName != 'X-PROP' ) { if( !isset( $this->xprop[$propName] )) return FALSE; $this->xprop[$propName] = null; $return = TRUE; } else { if( count( $this->xprop ) <= $propix ) return FALSE; $xpropno = 0; foreach( $this->xprop as $xpropkey => $xpropvalue ) { if( $propix == $xpropno ) { $this->xprop[$xpropkey] = null; $return = TRUE; break 2; } else $xpropno++; } } } return $return; } /** * get calendar property value/params * * @author Kjell-Inge Gustafsson * @since 2.0.8 - 2007-07-07 * @param string $propName, optional * @param int @propix, optional, if specific property is wanted in case of multiply occurences * @param bool $inclParam=FALSE * @return mixed */ function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE ) { $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; if( !$propix ) $propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1; $this->propix[$propName] = --$propix; switch( $propName ) { case 'CALSCALE': if( 0 < $propix ) return FALSE; return ( !empty( $this->calscale )) ? $this->calscale : null; break; case 'METHOD': if( 0 < $propix ) return FALSE; return ( !empty( $this->method )) ? $this->method : null; break; case 'PRODID': if( 0 < $propix ) return FALSE; if( empty( $this->prodid )) $this->_makeProdid(); return $this->prodid; break; case 'VERSION': if( 0 < $propix ) return FALSE; return ( !empty( $this->version )) ? $this->version : null; break; default: if( $propName != 'X-PROP' ) { if( !isset( $this->xprop[$propName] )) return FALSE; return ( $inclParam ) ? array( $propName, $this->xprop[$propName] ) : array( $propName, $this->xprop[$propName]['value'] ); } else { if( count( $this->xprop ) <= $propix ) return FALSE; $xpropno = 0; foreach( $this->xprop as $xpropkey => $xpropvalue ) { if( $propix == $xpropno ) return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] ) : array( $xpropkey, $this->xprop[$xpropkey]['value'] ); else $xpropno++; } return FALSE; // not found ?? } } return FALSE; } /** * general vcalendar property setting * * @author Kjell-Inge Gustafsson * @since 0.9.21 - 2007-04-15 * @param mixed $args variable number of function arguments, * first argument is ALWAYS component name! * @return void */ function setProperty () { $numargs = func_num_args(); if( 1 >= $numargs ) return FALSE; $arglist = func_get_args(); $arglist[0] = strtoupper( $arglist[0] ); for( $argix=$numargs; $argix < 3; $argix++ ) if( !isset( $arglist[$argix] )) $arglist[$argix] = null; switch( $arglist[0] ) { case 'CALSCALE': $this->setCalscale( $arglist[1] ); break; case 'METHOD': $this->setMethod( $arglist[1] ); break; case 'VERSION': $this->setVersion( $arglist[1] ); break; default: $this->setXprop( $arglist[0], $arglist[1], $arglist[2] ); break; } } /*********************************************************************************/ /** * get vcalendar config values or * calendar components * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-22 * @param string $config * @return value */ function getConfig( $config ) { switch( strtoupper( $config )) { case 'COMPSINFO': unset( $this->compix ); $info = array(); foreach( $this->components as $cix => $component ) { unset( $component->propix ); $info[$cix]['ordno'] = $cix + 1; $info[$cix]['type'] = $component->objName; $info[$cix]['uid'] = $component->getProperty( 'uid' ); $info[$cix]['props'] = $component->getConfig( 'propinfo' ); $info[$cix]['sub'] = $component->getConfig( 'compsinfo' ); } return $info; break; case 'DELIMITER': return $this->delimiter; break; case 'DIRECTORY': if( empty( $this->directory )) $this->directory = '.'; return $this->directory; break; case 'DIRFILE': return $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$this->getConfig( 'filename' ); break; case 'FILEINFO': return array( $this->getConfig( 'directory' ) , $this->getConfig( 'filename' ) , $this->getConfig( 'filesize' )); break; case 'FILENAME': if( empty( $this->filename )) { if( 'xcal' == $this->format ) $this->filename = date( 'YmdHis' ).'.xml'; // recommended xcs.. . else $this->filename = date( 'YmdHis' ).'.ics'; } return $this->filename; break; case 'FILESIZE': return filesize( $this->getConfig( 'dirfile' )); break; case 'FORMAT': return $this->format; break; case 'LANGUAGE': /* get language for calendar component as defined in [RFC 1766] */ return $this->language; break; case 'NL': case 'NEWLINECHAR': return $this->nl; break; case 'UNIQUE_ID': return $this->unique_id; break; } } /** * general vcalendar config setting * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-21 * @param string $config * @param string $value * @return void */ function setConfig( $config, $value ) { switch( strtoupper( $config )) { case 'DELIMITER': $this->delimiter = $value; break; case 'DIRECTORY': $value = trim( $value ); $nl = $this->getConfig('delimiter'); if( $nl == substr( $value, ( 0 - strlen( $nl )))) $value = substr( $value, 0, ( strlen( $value ) - strlen( $nl ))); if( @is_writable( $value )) { $this->directory = $value; return TRUE; } else return FALSE; break; case 'FILENAME': $value = trim( $value ); if( file_exists($this->getConfig('directory').$this->getConfig('delimiter').$value )) { if( is_readable($this->getConfig('directory').$this->getConfig('delimiter').$value ) && is_writable($this->getConfig('directory').$this->getConfig('delimiter').$value )) { $this->filename = $value; return TRUE; } else return FALSE; } elseif( @touch( $this->getConfig('directory').$this->getConfig('delimiter').$value )) { $this->filename = $value; return TRUE; } else return FALSE; break; case 'FORMAT': $value = trim( $value ); if( 'xcal' == strtolower( $value )) { $this->format = 'xcal'; $this->attributeDelimiter = $this->nl; $this->valueInit = null; } else { $this->format = null; $this->attributeDelimiter = ';'; $this->valueInit = ':'; } break; case 'LANGUAGE': // set language for calendar component as defined in [RFC 1766] $value = trim( $value ); $this->language = $value; break; case 'NL': case 'NEWLINECHAR': $this->nl = $value; break; case 'UNIQUE_ID': $value = trim( $value ); $this->unique_id = $value; break; } } /*********************************************************************************/ /** * validDate * * convert input parameters to (valid) iCalcreator date in array format (or FALSE) * if $utc=TRUE and $tz = utc offset ([[+/]-]HHmm) input (local) date array + UTC offset * returns ouput in UTC format date * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param mixed $tz optional * @param bool $utc optional * @return bool false / array $date */ function validDate( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $utc=FALSE ) { $input = array(); $toolbox = new calendarComponent(); $parno = null; if( is_array( $year ) && isset( $year['timestamp'] )) { $input = $toolbox->_date_time_string( date( 'Y-m-d H:i:s', $year['timestamp'] ), 6 ); $input['tz'] = ( isset( $year['tz'] )) ? $year['tz'] : null; $utc = ( TRUE === $month ) ? TRUE : FALSE; } elseif( is_array( $year ) && ( in_array( count( $year ), array( 3, 4, 6, 7 )))) { if( isset( $year['tz'] ) || ( 4 == count( $year )) || ( 7 == count( $year ))) $parno = 7; elseif( isset( $year['hour'] ) || isset( $year['min'] ) || isset( $year['sec'] ) || ( 6 == count( $year ))) $parno = 6; else $parno = 3; $input = $toolbox->_date_time_array( $year, $parno ); $utc = ( TRUE === $month ) ? TRUE : FALSE; } elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 $input = $toolbox->_date_time_string( $year ); $utc = ( TRUE === $month ) ? TRUE : FALSE; } elseif(( $year !== FALSE ) && ( $month !== FALSE ) && ( $day !== FALSE )) { if(( 0 > (int) $year ) || (2100 < (int) $year )) return FALSE; $month = (int) $month; if(( 1 > $month ) || ( 12 < $month )) return FALSE; $day = (int) $day; if(( 1 > $day ) || ( 31 < $day )) return FALSE; $input['year'] = $year; $input['month'] = $month; $input['day'] = $day; if(( $hour !== FALSE ) || ( $min !== FALSE ) || ( $sec !== FALSE )) { $parno = 6; if( $hour !== FALSE ) $input['hour'] = $hour; if( $min !== FALSE ) $input['min'] = $min; if( $sec !== FALSE ) $input['sec'] = $sec; } if( $tz !== FALSE ) { $parno = 7; $input['tz'] = $tz; } elseif( !$parno ) $parno = 3; $input = $toolbox->_date_time_array( $input, $parno ); } else return FALSE; if( !checkdate ( $input['month'], $input['day'], $input['year'] )) return FALSE; if( isset( $input['hour'] ) && (( 0 > $input['hour'] ) || ( 23 < $input['hour'] ))) return FALSE; if( isset( $input['min'] ) && (( 0 > $input['min'] ) || ( 59 < $input['min'] ))) return FALSE; if( isset( $input['sec'] ) && (( 0 > $input['sec'] ) || ( 59 < $input['sec'] ))) return FALSE; if( isset( $input['tz'] ) && ( '' < trim ( $input['tz'] ))) { $input['tz'] = (string) trim( $input['tz'] ); if( ctype_digit( $input['tz']{1} )) { // only numeric tz=offset $offset = 0; if( ctype_digit( $input['tz']{0} )) $input['tz'] = '+'.$input['tz']; $offset = $toolbox->_tz2offset( $input['tz'] ); if( 0 != $offset) { if( !isset( $input['hour'] )) $input['hour'] = 0; if( !isset( $input['min'] )) $input['min'] = 0; if( !isset( $input['sec'] )) $input['sec'] = 0; $input = date('Y-m-d H:i:s\Z', mktime ( $input['hour'] , $input['min'] , $input['sec'] + $offset , $input['month'] , $input['day'] , $input['year'])); $parno = ( $utc ) ? 7 : 6 ; $input = $toolbox->_date_time_string( $input, $parno ); if( !$utc && isset( $input['tz'] ) && ( 'Z' == $input['tz'] )) unset( $input['tz'] ); } } } return $input; } /*********************************************************************************/ /** * add calendar component to container * * alias to setComponent * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-04-24 * @param object $component calendar component * @return void */ function addComponent( $component ) { $this->setComponent( $component ); } /** * delete calendar component from container * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-14 * @param mixed $arg1 ordno / component type / component uid * @param mixed $arg2 optional, ordno if arg1 = component type * @return void */ function deleteComponent( $arg1, $arg2=FALSE ) { $argType = $index = null; if ( ctype_digit( (string) $arg1 )) { $argType = 'INDEX'; $index = (int) $arg1 - 1; } elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { $argType = strtolower( $arg1 ); $index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 1; } $cix1dC = 0; foreach ( $this->components as $cix => $component) { unset( $component->propix ); if(( 'INDEX' == $argType ) && ( $index == $cix )) { unset( $this->components[$cix] ); return TRUE; } elseif( $argType == $component->objName ) { if( $index == $cix1dC ) { unset( $this->components[$cix] ); return TRUE; } $cix1dC++; } elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { unset( $this->components[$cix] ); return TRUE; } } return FALSE; } /** * get calendar component from container * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-20 * @param mixed $arg1 optional, ordno/component type/ component uid * @param mixed $arg2 optional, ordno if arg1 = component type * @return object */ function getComponent( $arg1=FALSE, $arg2=FALSE ) { $index = $argType = null; if ( !$arg1 ) { $argType = 'INDEX'; $index = $this->compix['INDEX'] = ( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1; } elseif ( ctype_digit( (string) $arg1 )) { $argType = 'INDEX'; $index = (int) $arg1; unset( $this->compix ); } elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { unset( $this->compix['INDEX'] ); $argType = strtolower( $arg1 ); if( !$arg2 ) $index = $this->compix[$argType] = ( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1; else $index = (int) $arg2; } $index -= 1; if( !empty( $index) && ( $index > end( array_keys( $this->components )))) return FALSE; $cix1gC = 0; foreach ( $this->components as $cix => $component) { unset( $component->propix ); if(( 'INDEX' == $argType ) && ( $index == $cix )) return $component; elseif( $argType == $component->objName ) { if( $index == $cix1gC ) return $component; $cix1gC++; } elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { unset( $component->propix ); return $component; } } /* not found.. . */ unset( $this->compix ); return false; } /** * add calendar component to container * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-20 * @param object $component calendar component * @param mixed $arg1 optional, ordno/component type/ component uid * @param mixed $arg2 optional, ordno if arg1 = component type * @return void */ function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) { if( '' >= $component->getConfig( 'language')) $component->setConfig( 'language' , $this->getConfig( 'language' )); $component->setConfig( 'nl' , $this->getConfig( 'nl' )); $component->setConfig( 'unique_id' , $this->getConfig( 'unique_id' )); $component->setConfig( 'format' , $this->getConfig( 'format' )); if( !in_array( $component->objName, array( 'valarm', 'vtimezone' ))) { unset( $component->propix ); /* make sure dtstamp and uid is set */ $dummy = $component->getProperty( 'dtstamp' ); $dummy = $component->getProperty( 'uid' ); } if( !$arg1 ) { $this->components[] = $component; return TRUE; } $argType = $index = null; if ( ctype_digit( (string) $arg1 )) { $argType = 'INDEX'; $index = (int) $arg1 - 1; } elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { $argType = strtolower( $arg1 ); $index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0; } $cix1sC = 0; foreach ( $this->components as $cix => $component2) { unset( $component2->propix ); if(( 'INDEX' == $argType ) && ( $index == $cix )) { $this->components[$cix] = $component; return TRUE; } elseif( $argType == $component2->objName ) { if( $index == $cix1sC ) { $this->components[$cix] = $component; return TRUE; } $cix1sC++; } elseif( !$argType && ( $arg1 == $component2->getProperty( 'uid' ))) { $this->components[$cix] = $component; return TRUE; } } /* not found.. . insert last in chain anyway .. .*/ $this->components[] = $component; } /** * sort iCal compoments, only local date sort * * @author Kjell-Inge Gustafsson * @since 2.1.1 - 2007-06-24 * @return void * */ function _cmpfcn( $a, $b ) { $c = ( !empty( $a->dtend['value'] )) ? $a->dtend['value'] : null; if( empty( $c ) && !empty( $a->due['value'] )) $c = $a->due['value']; if( empty( $c ) && !empty( $a->duration['value'] )) $c = $a->duration2date(); $d = ( !empty( $b->dtend['value'] )) ? $b->dtend['value'] : null; if( empty( $d ) && !empty( $b->due['value'] )) $d = $b->due['value']; if( empty( $d ) && !empty( $b->duration['value'] )) $d = $b->duration2date(); foreach( $this->_sortkeys as $key ) { if( !isset( $a->dtstart['value'][$key] )) return -1; elseif( !isset( $b->dtstart['value'][$key] )) return 1; elseif(( (int) $a->dtstart['value'][$key] ) < ( (int) $b->dtstart['value'][$key] )) return -1; elseif(( (int) $a->dtstart['value'][$key] ) > ( (int) $b->dtstart['value'][$key] )) return 1; elseif( !isset( $c[$key] )) return -1; elseif( !isset( $d[$key] )) return 1; elseif(( (int) $c[$key] ) < ( (int) $d[$key] )) return -1; elseif(( (int) $c[$key] ) > ( (int) $d[$key] )) return 1; } return 0; } function sort() { if( is_array( $this->components )) { $this->_sortkeys = array( 'year', 'month', 'day', 'hour', 'min', 'sec' ); usort( $this->components, array( $this, '_cmpfcn' )); } } /** * parse iCal file into vcalendar, components, properties and parameters * * @author Kjell-Inge Gustafsson * @since 2.2.1 - 2007-07-29 * @param string $filename optional filname (incl. opt. directory/path) * @return bool FALSE if error occurs during parsing * */ function parse( $filename=FALSE ) { if( !$filename ) $filename = $this->getConfig( 'dirfile' ); else { $filename2 = basename( $filename ); $directory = str_replace( $filename2, '', $filename ); if( $this->getConfig( 'delimiter' ) == substr( $directory, -1 )) $directory = substr( $directory, 0, strlen( $directory ) -1 ); $this->setConfig( 'filename', $filename2 ); if( !empty( $directory )) $this->setConfig( 'directory', $directory ); else $this->setConfig( 'directory', '.' ); } /* file error tests */ if( !is_file( $filename )) /* err 1 */ return FALSE; if( !is_readable( $filename )) return FALSE; /* err 2 */ if( !filesize( $filename )) return FALSE; /* err 3 */ $rows = file( $filename ); /* identify and remove BEGIN:VCALENDAR row */ if( 'BEGIN:VCALENDAR' != strtoupper( trim( $rows[0] ))) return FALSE; /* err 4a */ else { unset( $rows[0] ); $rows = array_values( $rows ); } /* identify and remove END:VCALENDAR row */ while( '' == trim( $rows[count( $rows ) - 1] )) { unset( $rows[count( $rows ) - 1] ); $rows = array_values( $rows ); } if( 'END:VCALENDAR' != strtoupper( trim( $rows[count( $rows ) - 1] ))) { return FALSE; /* err 4b */ } else { unset( $rows[count( $rows ) - 1] ); $rows = array_values( $rows ); } if( 1 > count( $rows )) return FALSE; /* err 5 */ $comp = $subcomp = null; $actcomp = & $this; $nl = $this->getConfig( 'nl' ); /* identify components and update unparsed data within component */ foreach( $rows as $line ) { if( '' == trim( $line )) continue; if( $nl == substr( $line, 0 - strlen( $nl ))) $line = substr( $line, 0, ( strlen( $line ) - strlen( $nl ))).'\n'; if( 'END:' == strtoupper( substr( $line, 0, 4 ))) { if( null != $subcomp ) { $comp->setComponent( $subcomp ); $subcomp = null; } else { $this->setComponent( $comp ); $comp = null; } $actcomp = null; continue; } // end - if ( 'END:' ==.. . elseif( 'BEGIN:' == strtoupper( substr( $line, 0, 6 ))) { $line = str_replace( '\n', '', $line ); $compname = trim (strtoupper( substr( $line, 6 ))); if( null != $comp ) { if( 'VALARM' == $compname ) $subcomp = new valarm(); elseif( 'STANDARD' == $compname ) $subcomp = new vtimezone( 'STANDARD' ); elseif( 'DAYLIGHT' == $compname ) $subcomp = new vtimezone( 'DAYLIGHT' ); else return FALSE; /* err 6 */ $actcomp = & $subcomp; } else { switch( $compname ) { case 'VALARM': $comp = new valarm(); break; case 'VEVENT': $comp = new vevent(); break; case 'VFREEBUSY'; $comp = new vfreebusy(); break; case 'VJOURNAL': $comp = new vjournal(); break; case 'VTODO': $comp = new vtodo(); break; case 'VTIMEZONE': $comp = new vtimezone(); break; default: return FALSE; // err 7 break; } // end - switch $actcomp = & $comp; } continue; } // end - elsif ( 'BEGIN:'.. . /* update selected component with unparsed data */ $actcomp->unparsed[] = $line; } // end - foreach( rows.. . /* parse data for calendar (this) object */ if( is_array( $this->unparsed ) && ( 0 < count( $this->unparsed ))) { /* concatenate property values spread over several lines */ $lastix = -1; $propnames = array( 'calscale','method','prodid','version','x-' ); $proprows = array(); foreach( $this->unparsed as $line ) { $newProp = FALSE; foreach ( $propnames as $propname ) { if( $propname == strtolower( substr( $line, 0, strlen( $propname )))) { $newProp = TRUE; break; } } if( $newProp ) { $newProp = FALSE; $lastix++; $proprows[$lastix] = $line; } else { /* remove line breaks */ if(( '\n' == substr( $proprows[$lastix], -2 )) && ( ' ' == substr( $line, 0, 1 ))) { $proprows[$lastix] = substr( $proprows[$lastix], 0, strlen( $proprows[$lastix] ) - 2 ); $line = substr( $line, 1 ); } $proprows[$lastix] .= $line; } } foreach( $proprows as $line ) { if( '\n' == substr( $line, -2 )) $line = substr( $line, 0, strlen( $line ) - 2 ); /* get propname */ $cix = $propname = null; for( $cix=0; $cix < strlen( $line ); $cix++ ) { if( in_array( $line{$cix}, array( ':', ';' ))) break; else $propname .= $line{$cix}; } /* ignore version/prodid properties */ if( in_array( strtoupper( $propname ), array( 'VERSION', 'PRODID' ))) continue; $line = substr( $line, $cix); /* separate attributes from value */ $attr = array(); $attrix = -1; $strlen = strlen( $line ); for( $cix=0; $cix < $strlen; $cix++ ) { if(( ':' == $line{$cix} ) && ( '://' != substr( $line, $cix, 3 )) && ( 'mailto:' != strtolower( substr( $line, $cix - 6, 7 )))) { $attrEnd = TRUE; if(( $cix < ( $strlen - 4 )) && ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr?? for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) { if( '://' == substr( $line, $c2ix - 2, 3 )) { $attrEnd = FALSE; break; // an URI with a portnr!! } } } if( $attrEnd) { $line = substr( $line, $cix + 1 ); break; } } if( ';' == $line{$cix} ) $attr[++$attrix] = null; else $attr[$attrix] .= $line{$cix}; } /* make attributes in array format */ $propattr = array(); foreach( $attr as $attribute ) { $attrsplit = explode( '=', $attribute, 2 ); if( 1 < count( $attrsplit )) $propattr[$attrsplit[0]] = $attrsplit[1]; else $propattr[] = $attribute; } /* update Property */ $this->setProperty( $propname, trim( $line ), $propattr ); } // end - foreach( $this->unparsed.. . } // end - if( is_array( $this->unparsed.. . /* parse Components */ if( is_array( $this->components ) && ( 0 < count( $this->components ))) { for( $six = 0; $six < count( $this->components ); $six++ ) $this->components[$six]->parse(); } } /*********************************************************************************/ /** * creates formatted output for calendar object instance * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-07 * @return string */ function createCalendar() { $calendarInit1 = $calendarInit2 = $calendarxCaldecl = $calendarStart = $calendar = null; switch( $this->format ) { case 'xcal': $calendarInit1 = ''.$this->nl. 'nl. '"http://www.ietf.org/internet-drafts/draft-ietf-calsch-many-xcal-01.txt"'; $calendarInit2 = '>'.$this->nl; $calendarStart = 'nl; break; } $calendarStart .= $this->createCalscale(); $calendarStart .= $this->createMethod(); $calendarStart .= $this->createProdid(); $calendarStart .= $this->createVersion(); switch( $this->format ) { case 'xcal': $nlstrlen = strlen( $this->nl ); if( $this->nl == substr( $calendarStart, ( 0 - $nlstrlen ))) $calendarStart = substr( $calendarStart, 0, ( strlen( $calendarStart ) - $nlstrlen )); $calendarStart .= '>'.$this->nl; break; default: break; } $calendar .= $this->createXprop(); foreach( $this->components as $component ) { if( '' >= $component->getConfig( 'language')) $component->setConfig( 'language', $this->getConfig( 'language' )); $component->setConfig( 'nl', $this->getConfig( 'nl' )); $component->setConfig( 'unique_id', $this->getConfig( 'unique_id' )); $component->setConfig( 'format', $this->getConfig( 'format' )); $calendar .= $component->createComponent( $this->xcaldecl ); } if(( 0 < count( $this->xcaldecl )) && ( 'xcal' == $this->format )) { // xCal only $calendarInit1 .= $this->nl.'['.$this->nl; $old_xcaldecl = array(); foreach( $this->xcaldecl as $declix => $declPart ) { if(( 0 < count( $old_xcaldecl)) && ( in_array( $declPart['uri'], $old_xcaldecl['uri'] )) && ( in_array( $declPart['external'], $old_xcaldecl['external'] ))) continue; // no duplicate uri and ext. references $calendarxCaldecl .= ' $declValue ) { switch( $declKey ) { // index case 'xmldecl': // no 1 $calendarxCaldecl .= $declValue.' '; break; case 'uri': // no 2 $calendarxCaldecl .= $declValue.' '; $old_xcaldecl['uri'][] = $declValue; break; case 'ref': // no 3 $calendarxCaldecl .= $declValue.' '; break; case 'external': // no 4 $calendarxCaldecl .= '"'.$declValue.'" '; $old_xcaldecl['external'][] = $declValue; break; case 'type': // no 5 $calendarxCaldecl .= $declValue.' '; break; case 'type2': // no 6 $calendarxCaldecl .= $declValue; break; } } $calendarxCaldecl .= '>'.$this->nl; } $calendarInit2 = ']'.$calendarInit2; } switch( $this->format ) { case 'xcal': $calendar .= ''.$this->nl; break; default: $calendar .= 'END:VCALENDAR'.$this->nl; break; } return $calendarInit1.$calendarxCaldecl.$calendarInit2.$calendarStart.$calendar; } /** * redirect file to user * * @author Kjell-Inge Gustafsson * @since 2.2.6 - 2007-08-01 * @return redirect */ function _redirectCalendar() { $dirfile = $this->getConfig( 'dirfile' ); // if( headers_sent( $filename, $linenum )) // die( "Headers already sent in $filename on line $linenum\n" ); if( 'xcal' == $this->format ) header( 'Content-Type: application/calendar+xml; charset=utf-8' ); else header( 'Content-Type: text/calendar; charset=utf-8' ); header( 'Content-Length: '.$this->getConfig( 'filesize' )); header( 'Content-Disposition: attachment; filename="'.basename( $dirfile ).'"' ); header( 'Cache-Control: max-age=10' ); $fp = fopen( $dirfile, 'r' ); fpassthru( $fp ); fclose( $fp ); die(); } /** * a HTTP redirect header is sent with saved calendar * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-07 * @param string $directory optional * @param string $filename optional * @param string $delimiter optional * @return redirect */ function returnCalendar( $directory=FALSE, $filename=FALSE, $delimiter=DIRECTORY_SEPARATOR ) { if( $this->saveCalendar ( $directory, $filename, $delimiter )) $this->_redirectCalendar (); } /** * save content in a file * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-06 * @param string $directory optional * @param string $filename optional * @param string $delimiter optional * @return bool */ function saveCalendar( $directory=FALSE, $filename=FALSE, $delimiter=DIRECTORY_SEPARATOR ) { if( $directory ) $this->setConfig( 'directory', $directory ); if( $filename ) $this->setConfig( 'filename', $filename ); if( $delimiter ) $this->setConfig( 'delimiter', $delimiter ); $dirfile = $this->getConfig( 'dirfile' ); $iCalFile = fopen( $dirfile, 'w' ); if ( $iCalFile ) { fputs( $iCalFile, $this->createCalendar() ); fclose( $iCalFile ); return TRUE; } else return FALSE; } /** * if recent version of file exists (max one hour), an HTTP redirect header is sent * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-15 * @param string $directory optional * @param string $filename optional * @param string $delimiter optional * @param int timeout optional, default 36001 * @return redirect/FALSE */ function useCachedCalendar( $directory=FALSE, $filename=FALSE, $delimiter=DIRECTORY_SEPARATOR, $timeout=3600) { if( $directory ) $this->setConfig( 'directory', $directory ); if( $filename ) $this->setConfig( 'filename', $filename ); if( $delimiter ) $this->setConfig( 'delimiter', $delimiter ); if( 0 >= $this->getConfig( 'filesize' )) return FALSE; $dirfile = $this->getConfig( 'dirfile' ); if( time() - filemtime( $dirfile ) < $timeout) $this->_redirectCalendar (); else return FALSE; } } /*********************************************************************************/ /*********************************************************************************/ /** * abstract class for calendar components * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-21 */ class calendarComponent { // component property variables var $action; var $attach; var $attendee; var $categories; var $comment; var $completed; var $contact; var $class; var $created; var $description; var $dtend; var $dtstart; var $dtstamp; var $due; var $duration; var $exdate; var $exrule; var $freebusy; var $geo; var $lastmodified; var $location; var $organizer; var $percentcomplete; var $priority; var $rdate; var $recurrenceid; var $relatedto; var $repeat; var $requeststatus; var $resources; var $rrule; var $sequence; var $status; var $summary; var $transp; var $trigger; var $tzid; var $tzname; var $tzoffsetfrom; var $tzoffsetto; var $tzurl; var $uid; var $url; var $xprop; // component subcomponents container var $components; // component config variables var $language; var $nl; var $unique_id; var $format; var $objName; // created automatically at instance creation // component internal variables var $componentStart1; var $componentStart2; var $componentEnd1; var $componentEnd2; var $elementStart1; var $elementStart2; var $elementEnd1; var $elementEnd2; var $intAttrDelimiter; var $attributeDelimiter; var $valueInit; // component xCal declaration container var $xcaldecl; /** * constructor for calendar component object * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-07-21 */ function calendarComponent() { $this->objName = ( isset( $this->timezonetype )) ? strtolower( $this->timezonetype ) : get_class ( $this ); $this->action = array(); $this->attach = array(); $this->attendee = array(); $this->categories = array(); $this->class = array(); $this->comment = array(); $this->completed = array(); $this->contact = array(); $this->created = array(); $this->description = array(); $this->dtend = array(); $this->dtstart = array(); $this->dtstamp = array(); $this->due = array(); $this->duration = array(); $this->exdate = array(); $this->exrule = array(); $this->freebusy = array(); $this->geo = array(); $this->lastmodified = array(); $this->location = array(); $this->organizer = array(); $this->percentcomplete = array(); $this->priority = array(); $this->rdate = array(); $this->recurrenceid = array(); $this->relatedto = array(); $this->repeat = array(); $this->requeststatus = array(); $this->resources = array(); $this->sequence = array(); $this->rrule = array(); $this->status = array(); $this->summary = array(); $this->transp = array(); $this->trigger = array(); $this->tzid = array(); $this->tzname = array(); $this->tzoffsetfrom = array(); $this->tzoffsetto = array(); $this->tzurl = array(); $this->uid = array(); $this->url = array(); $this->xprop = array(); $this->components = array(); $this->language = null; $this->nl = null; $this->unique_id = null; $this->xcaldecl = array(); $this->_makeDtstamp(); } /*********************************************************************************/ /** * Property Name: ACTION */ /** * creates formatted output for calendar component property action * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createAction() { if( !isset( $this->action['value'] )) return; $attributes = $this->_createParams( $this->action['params'] ); return $this->_createElement( 'ACTION', $attributes, $this->action['value'] ); } /** * set calendar component property action * * @author Kjell-Inge Gustafsson * @since 0.9.2 - 2006-11-16 * @param string $value "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE" * @param mixed $params * @return void */ function setAction( $value, $params=FALSE ) { $this->action['value'] = $value; $this->action['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: ATTACH */ /** * creates formatted output for calendar component property attach * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createAttach() { $cnt = count( $this->attach ); if( 0 >= $cnt ) return; $output = null; foreach( $this->attach as $attachPart ) { $attributes = $this->_createParams( $attachPart['params'] ); $output .= $this->_createElement( 'ATTACH', $attributes, $attachPart['value'] ); } return $output; } /** * set calendar component property attach * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-10 * @param string $value * @param string $params * @return void */ function setAttach( $value, $params=FALSE) { $attach = array(); $attach['value'] = $value ; $attach['params'] = $this->_setParams( $params ); $this->attach[] = $attach; } /*********************************************************************************/ /** * Property Name: ATTENDEE */ /** * creates formatted output for calendar component property attendee * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-20 * @return string */ function createAttendee() { $cnt = count( $this->attendee ); if( 0 >= $cnt ) return; $attendees = null; foreach( $this->attendee as $attendeePart ) { // start foreach 1 $attendee1 = $attendee2 = $attendeeLANG = $attendeeCN = null; foreach( $attendeePart as $paramlabel => $paramvalue ) { // start foreach 2 if( 'value' == $paramlabel ) { $attendee2 .= 'MAILTO:'.$paramvalue; } elseif(( 'params' == $paramlabel ) && ( is_array( $paramvalue ))) { // start elseif foreach( $paramvalue as $optparamlabel => $optparamvalue ) { // start foreach 3 $attendee11 = $attendee12 = null; if( is_int( $optparamlabel )) { $attendee1 .= $this->intAttrDelimiter.$optparamvalue; continue; } switch( $optparamlabel ) { // start switch case 'CUTYPE': case 'PARTSTAT': case 'ROLE': case 'RSVP': $attendee1 .= $this->intAttrDelimiter.$optparamlabel.'="'.$optparamvalue.'"'; break; case 'SENT-BY': $attendee1 .= $this->intAttrDelimiter.'SENT-BY="MAILTO:'.$optparamvalue.'"'; break; case 'MEMBER': $attendee11 = $this->intAttrDelimiter.'MEMBER='; case 'DELEGATED-TO': $attendee11 = ( !$attendee11 ) ? $this->intAttrDelimiter.'DELEGATED-TO=' : $attendee11; case 'DELEGATED-FROM': $attendee11 = ( !$attendee11 ) ? $this->intAttrDelimiter.'DELEGATED-FROM=' : $attendee11; foreach( $optparamvalue as $cix => $calUserAddress ) { $attendee12 .= ( $cix ) ? ',' : null; $attendee12 .= '"MAILTO:'.$calUserAddress.'"'; } $attendee1 .= $attendee11.$attendee12; break; case 'CN': $attendeeCN .= $this->intAttrDelimiter.'CN="'.$optparamvalue.'"'; break; case 'DIR': $attendee1 .= $this->intAttrDelimiter.'DIR="'.$optparamvalue.'"'; break; case 'LANGUAGE': $attendeeLANG .= $this->intAttrDelimiter.'LANGUAGE='.$optparamvalue; break; default: $attendee1 .= $this->intAttrDelimiter."$optparamlabel=$optparamvalue"; break; } // end switch } // end foreach 3 } // end elseif } // end foreach 2 $attendees .= $this->_createElement( 'ATTENDEE', $attendee1.$attendeeLANG.$attendeeCN, $attendee2 ); } // end foreach 1 return $attendees; } /** * set calendar component property attach * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-24 * @param string $value * @param array $params optional * @return void */ function setAttendee( $value, $params=FALSE ) { $value = str_replace ( 'MAILTO:', '', $value ); $value = str_replace ( 'mailto:', '', $value ); $attendee = array( 'value' => $value, 'params' => array() ); if( is_array($params )) { $optarrays = array(); foreach( $params as $optparamlabel => $optparamvalue ) { $optparamlabel = strtoupper( $optparamlabel ); switch( $optparamlabel ) { case 'MEMBER': case 'DELEGATED-TO': case 'DELEGATED-FROM': if( is_array( $optparamvalue )) { foreach( $optparamvalue as $part ) { $part = str_replace( 'MAILTO:', '', $part ); $part = str_replace( 'mailto:', '', $part ); if(( '"' == $part{0} ) && ( '"' == $part{strlen($part)-1} )) $part = substr( $part, 1, ( strlen($part)-2 )); $optarrays[$optparamlabel][] = $part; } } else { $part = str_replace( 'MAILTO:', '', $optparamvalue ); $part = str_replace( 'mailto:', '', $part ); if(( '"' == $part{0} ) && ( '"' == $part{strlen($part)-1} )) $part = substr( $part, 1, ( strlen($part)-2 )); $optarrays[$optparamlabel][] = $part; } break; default: if( 'SENT-BY' == $optparamlabel ) { $optparamvalue = str_replace( 'MAILTO:', '', $optparamvalue ); $optparamvalue = str_replace( 'mailto:', '', $optparamvalue ); } if(( '"' == substr( $optparamvalue, 0, 1 )) && ( '"' == substr( $optparamvalue, -1 ))) $optparamvalue = substr( $optparamvalue, 1, ( strlen( $optparamvalue ) - 2 )); $attendee['params'][$optparamlabel] = $optparamvalue; break; } // end switch( $optparamlabel.. . } // end foreach( $optparam.. . foreach( $optarrays as $optparamlabel => $optparams ) $attendee['params'][$optparamlabel] = $optparams; } // remove defaults if( isset( $attendee['params']['CUTYPE' ] ) && ( strtoupper( $attendee['params']['CUTYPE' ] ) == 'INDIVIDUAL' )) unset( $attendee['params']['CUTYPE' ] ); if( isset( $attendee['params']['PARTSTAT'] ) && ( strtoupper( $attendee['params']['PARTSTAT'] ) == 'NEEDS-ACTION' )) unset( $attendee['params']['PARTSTAT'] ); if( isset( $attendee['params']['ROLE'] ) && ( strtoupper( $attendee['params']['ROLE'] ) == 'REQ-PARTICIPANT' )) unset( $attendee['params']['ROLE'] ); if( isset( $attendee['params']['RSVP'] ) && ( strtoupper( $attendee['params']['RSVP'] ) == 'FALSE' )) unset( $attendee['params']['RSVP'] ); // check language setting if( isset( $attendee['params']['CN' ] )) { $lang = $this->getConfig( 'language' ); if( !isset( $attendee['params']['LANGUAGE' ] ) && !empty( $lang )) $attendee['params']['LANGUAGE' ] = $lang; } $this->attendee[] = $attendee; } /*********************************************************************************/ /** * Property Name: CATEGORIES */ /** * creates formatted output for calendar component property categories * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-18 * @return string */ function createCategories() { $cnt = count( $this->categories ); if( 0 >= $cnt ) return; $output = null; foreach( $this->categories as $category ) { $attributes = $this->_createParams( $category['params'], array( 'LANGUAGE' )); $output .= $this->_createElement( 'CATEGORIES', $attributes, $category['value'] ); } return $output; } /** * set calendar component property categories * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-18 * @param mixed $value * @param array $params optional * @return void */ function setCategories( $value, $params=FALSE ) { $category = array(); $value = ( is_array( $value )) ? implode( ',', $value ) : $value; $value = str_replace( ', ', ',', $value ); $value = str_replace( ' ,', ',', $value ); $category['value'] = $value; $category['params'] = $this->_setParams( $params ); $this->categories[] = $category; } /*********************************************************************************/ /** * Property Name: CLASS */ /** * creates formatted output for calendar component property class * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createClass() { $cnt = count( $this->class ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->class['params'] ); return $this->_createElement( 'CLASS', $attributes, $this->class['value'] ); } /** * set calendar component property class * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2003-03-18 * @param string $value "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token / x-name * @param array $params optional * @return void */ function setClass( $value, $params=FALSE ) { $this->class['value'] = $value; $this->class['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: COMMENT */ /** * creates formatted output for calendar component property comment * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createComment() { $cnt = count( $this->comment ); if( 0 >= $cnt ) return; $comment = null; foreach( $this->comment as $commentPart ) { $attributes = $this->_createParams( $commentPart['params'], array( 'ALTREP', 'LANGUAGE' )); $content = $this->_strrep( $commentPart['value'] ); $comment .= $this->_createElement( 'COMMENT', $attributes, $content ); } return $comment; } /** * set calendar component property comment * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param array $params optional * @return void */ function setComment( $value, $params=FALSE ) { $comment['value'] = $value; $comment['params'] = $this->_setParams( $params ); $this->comment[] = $comment; } /*********************************************************************************/ /** * Property Name: COMPLETED */ /** * creates formatted output for calendar component property completed * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createCompleted( ) { if( !isset( $this->completed['value']['year'] ) && !isset( $this->completed['value']['month'] ) && !isset( $this->completed['value']['day'] ) && !isset( $this->completed['value']['hour'] ) && !isset( $this->completed['value']['min'] ) && !isset( $this->completed['value']['sec'] )) return; $formatted = $this->_format_date_time( $this->completed['value'], 7 ); $attributes = $this->_createParams( $this->completed['params'] ); return $this->_createElement( 'COMPLETED', $attributes, $formatted ); } /** * set calendar component property completed * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-02 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return void */ function setCompleted( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { $this->completed = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); } /*********************************************************************************/ /** * Property Name: CONTACT */ /** * creates formatted output for calendar component property contact * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-24 * @return string */ function createContact() { $cnt = count( $this->contact ); if( 0 >= $cnt ) return; $output = null; foreach( $this->contact as $contact ) { $attributes = $this->_createParams( $contact['params'], array( 'ALTREP', 'LANGUAGE' )); $content = $this->_strrep( $contact['value'] ); $output .= $this->_createElement( 'CONTACT', $attributes, $content ); } return $output; } /** * set calendar component property contact * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-24 * @param string $value * @param array $params optional * @return void */ function setContact( $value, $params=FALSE ) { $contact['value'] = $value; $contact['params'] = $this->_setParams( $params ); if( isset( $contact['params']['ALTREP'] ) && ( '"' == substr( $contact['params']['ALTREP'], 0, 1 )) && ( '"' == substr( $contact['params']['ALTREP'], -1 ))) $contact['params']['ALTREP'] = substr( $contact['params']['ALTREP'], 1, ( strlen( $contact['params']['ALTREP'] ) - 2 )); $this->contact[] = $contact; } /*********************************************************************************/ /** * Property Name: CREATED */ /** * creates formatted output for calendar component property created * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createCreated() { if( !isset( $this->created['value']['year'] ) && !isset( $this->created['value']['month'] ) && !isset( $this->created['value']['day'] ) && !isset( $this->created['value']['hour'] ) && !isset( $this->created['value']['min'] ) && !isset( $this->created['value']['sec'] )) return; $formatted = $this->_format_date_time( $this->created['value'], 7 ); $attributes = $this->_createParams( $this->created['params'] ); return $this->_createElement( 'CREATED', $attributes, $formatted ); } /** * set calendar component property created * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-02 * @param mixed $year optional * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param mixed $params optional * @return void */ function setCreated( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { if( !isset( $year )) { $year = date('Ymd\THis', mktime ( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' ))); } $this->created = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); } /*********************************************************************************/ /** * Property Name: DESCRIPTION */ /** * creates formatted output for calendar component property description * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createDescription() { $cnt = count( $this->description ); if( 0 >= $cnt ) return; $descriptions = null; foreach( $this->description as $description ) { $attributes = $this->_createParams( $description['params'], array( 'ALTREP', 'LANGUAGE' )); $content = $this->_strrep( $description['value'] ); $descriptions .= $this->_createElement( 'DESCRIPTION', $attributes, $content ); } return $descriptions; } /** * set calendar component property description * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param array $params optional * @return void */ function setDescription( $value, $params=FALSE ) { $description['value'] = $value; $description['params'] = $this->_setParams( $params ); $this->description[] = $description; } /*********************************************************************************/ /** * Property Name: DTEND */ /** * creates formatted output for calendar component property dtend * * @author Kjell-Inge Gustafsson * @since 0.9.19 - 2007-03-27 * @return string */ function createDtend() { if( !isset( $this->dtend['value']['year'] ) && !isset( $this->dtend['value']['month'] ) && !isset( $this->dtend['value']['day'] ) && !isset( $this->dtend['value']['hour'] ) && !isset( $this->dtend['value']['min'] ) && !isset( $this->dtend['value']['sec'] )) return; $formatted = $this->_format_date_time( $this->dtend['value'] ); $attributes = $this->_createParams( $this->dtend['params'] ); return $this->_createElement( 'DTEND', $attributes, $formatted ); } /** * set calendar component property dtend * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param string $tz optional * @param array params optional * @return void */ function setDtend( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { $this->dtend = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); } /*********************************************************************************/ /** * Property Name: DTSTAMP */ /** * creates formatted output for calendar component property dtstamp * * @author Kjell-Inge Gustafsson * @since 2.2.4 - 2007-08-01 * @return string */ function createDtstamp() { if( !isset( $htis->dtstamp['value']['year'] ) && !isset( $this->dtstamp['value']['month'] ) && !isset( $this->dtstamp['value']['day'] ) && !isset( $this->dtstamp['value']['hour'] ) && !isset( $this->dtstamp['value']['min'] ) && !isset( $this->dtstamp['value']['sec'] )) $this->_makeDtstamp(); $formatted = $this->_format_date_time( $this->dtstamp['value'], 7 ); $attributes = $this->_createParams( $this->dtstamp['params'] ); return $this->_createElement( 'DTSTAMP', $attributes, $formatted ); } /** * computes datestamp for calendar component object instance dtstamp * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-13 * @return void */ function _makeDtstamp() { $this->dtstamp['value'] = array( 'year' => date( 'Y' ) , 'month' => date( 'm' ) , 'day' => date( 'd' ) , 'hour' => date( 'H' ) , 'min' => date( 'i' ) , 'sec' => date( 's' ) - date( 'Z' )); $this->dtstamp['params'] = null; } /** * set calendar component property dtstamp * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-02 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return void */ function setDtstamp( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { $this->dtstamp = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); } /*********************************************************************************/ /** * Property Name: DTSTART */ /** * creates formatted output for calendar component property dtstart * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @param bool $localtime optional, default FALSE * @return string */ function createDtstart( $localtime=FALSE ) { if( !isset( $this->dtstart['value']['year'] ) && !isset( $this->dtstart['value']['month'] ) && !isset( $this->dtstart['value']['day'] ) && !isset( $this->dtstart['value']['hour'] ) && !isset( $this->dtstart['value']['min'] ) && !isset( $this->dtstart['value']['sec'] )) return; if( $localtime ) unset( $this->dtstart['value']['tz'] ); $formatted = $this->_format_date_time( $this->dtstart['value'] ); $attributes = $this->_createParams( $this->dtstart['params'] ); return $this->_createElement( 'DTSTART', $attributes, $formatted ); } /** * set calendar component property dtstart * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param string $tz optional * @param array $params optional * @return void */ function setDtstart( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { $this->dtstart = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); } /*********************************************************************************/ /** * Property Name: DUE */ /** * creates formatted output for calendar component property due * * @author Kjell-Inge Gustafsson * @since 0.9.19 - 2007-03-27 * @return string */ function createDue() { if( !isset( $this->due['value']['year'] ) && !isset( $this->due['value']['month'] ) && !isset( $this->due['value']['day'] ) && !isset( $this->due['value']['hour'] ) && !isset( $this->due['value']['min'] ) && !isset( $this->due['value']['sec'] )) return; $formatted = $this->_format_date_time( $this->due['value'] ); $attributes = $this->_createParams( $this->due['params'] ); return $this->_createElement( 'DUE', $attributes, $formatted ); } /** * set calendar component property due * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return void */ function setDue( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { $this->due = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); } /*********************************************************************************/ /** * Property Name: DURATION */ /** * creates formatted output for calendar component property duration * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createDuration() { if( !isset( $this->duration['value']['week'] ) && !isset( $this->duration['value']['day'] ) && !isset( $this->duration['value']['hour'] ) && !isset( $this->duration['value']['min'] ) && !isset( $this->duration['value']['sec'] )) return; $attributes = $this->_createParams( $this->duration['params'] ); return $this->_createElement( 'DURATION', $attributes, $this->_format_duration( $this->duration['value'] )); } /** * set calendar component property duration * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param mixed $week * @param mixed $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return void */ function setDuration( $week=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { if( is_array( $week )) { $this->duration['value'] = $this->_duration_array( $week ); $this->duration['params'] = $this->_setParams( $day ); } elseif( is_string( $week ) && ( 3 <= strlen( trim( $week )))) { if( in_array( substr( $week,0, 1 ), array( '+', '-' ))) $week = substr( $week, 1 ); $this->duration['value'] = $this->_duration_string( $week ); $this->duration['params'] = $this->_setParams( $day ); } else { $this->duration['value'] = $this->_duration_array( array( $week, $day, $hour, $min, $sec )); $this->duration['params'] = $this->_setParams( $params ); } } /*********************************************************************************/ /** * Property Name: EXDATE */ /** * creates formatted output for calendar component property exdate * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createExdate() { $cnt = count( $this->exdate ); if( 0 >= $cnt ) return; $output = null; foreach( $this->exdate as $theExdate ) { $content = $attributes = null; foreach( $theExdate['value'] as $eix => $exdatePart ) { $formatted = $this->_format_date_time( $exdatePart ); if( isset( $theExdate['params']['TZID'] )) $formatted = str_replace( 'Z', '', $formatted); if( 0 < $eix ) { if( isset( $theExdate['value'][0]['tz'] ) && ( ctype_digit( substr( $theExdate['value'][0]['tz'], -4 )) || ( 'Z' == $theExdate['value'][0]['tz'] ))) { if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z'; } else $formatted = str_replace( 'Z', '', $formatted ); } if( 0 < $eix ) $content .= ','; $content .= $formatted; } $attributes .= $this->_createParams( $theExdate['params'] ); $output .= $this->_createElement( 'EXDATE', $attributes, $content ); } return $output; } /** * set calendar component property exdate * * @author Kjell-Inge Gustafsson * @since 2.0.5 - 2007-06-22 * @param array exdates * @param array $params optional * @return void */ function setExdate( $exdates, $params=FALSE ) { $exdate = array(); $exdate['params'] = $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' ) ); $parno = ( isset( $exdate['params']['TZID'] )) ? 6 : null; $parno = $this->_existRem( $exdate['params'], 'VALUE', 'DATE-TIME', 7, $parno ); if( !isset( $parno )) $parno = $this->_existRem( $exdate['params'], 'VALUE', 'DATE', 3 ); foreach( $exdates as $eix => $theExdate ) { if( is_array( $theExdate ) && ( in_array( count( $theExdate ), array( 3, 4, 6, 7 )))) { if( isset( $exdate['params']['TZID'] )) $theExdate['tz'] = $exdate['params']['TZID']; if( !isset( $parno )) { if( 4 < count( $theExdate )) $parno = 7; else $parno = 3; } $exdatea = $this->_date_time_array( $theExdate, $parno ); } elseif( is_array( $theExdate ) && isset( $theExdate['timestamp'] )) { if( isset( $exdate['params']['TZID'] )) $theExdate['tz'] = $exdate['params']['TZID']; $tz = ( isset( $theExdate['tz'] )) ? ' '.$theExdate['tz'] : null; if( !isset( $parno )) $parno = ( !empty( $tz )) ? 7 : 6; $exdatea = $this->_date_time_string( date( 'Y-m-d H:i:s', $theExdate['timestamp'] ).$tz, $parno ); } elseif( 8 <= strlen( trim( $theExdate ))) { // ex. 2006-08-03 10:12:18 $exdatea = $this->_date_time_string( $theExdate, $parno ); if( isset( $exdate['params']['TZID'] )) $exdatea['tz'] = $exdate['params']['TZID']; } if( !isset( $parno )) { $parno = count( $exdatea ); if( 6 == $parno ) $parno = 7; } if( isset( $exdatea['tz'] )) $exdatea['tz'] = (string) $exdatea['tz']; $exdate['value'][] = $exdatea; } if( 0 < count( $exdate['value'] )) { if( 3 == $parno ) { $exdate['params']['VALUE'] = 'DATE'; foreach( $exdate['value'] as $eix => $exdatea ) unset( $exdate['value'][$eix]['tz'] ); unset( $exdate['params']['TZID'] ); } if( !empty( $exdate['value'][0]['tz'] ) && ( $exdate['value'][0]['tz'] != 'Z' ) && ( !( in_array($exdate['value'][0]['tz']{0}, array( '+', '-' )) && ctype_digit( substr( $exdate['value'][0]['tz'], 1 ))) && !ctype_digit( $exdate['value'][0]['tz'] ) ) ) { $exdate['params']['TZID'] = $exdate['value'][0]['tz']; foreach( $exdate['value'] as $exix => $exdatea ) { if( !empty( $exdate['value'][0]['tz'] ) && ( $exdate['value'][0]['tz'] != 'Z' ) && ( !( in_array($exdate['value'][0]['tz']{0}, array( '+', '-' )) && ctype_digit( substr( $exdate['value'][0]['tz'], 1 ))) && !ctype_digit( $exdate['value'][0]['tz'] ) ) ) unset( $exdate['value'][$exix]['tz'] ); } } elseif( isset( $exdate['params']['TZID'] )) unset( $exdate['params']['TZID'] ); $this->exdate[] = $exdate; } } /*********************************************************************************/ /** * Property Name: EXRULE */ /** * creates formatted output for calendar component property exrule * * @author Kjell-Inge Gustafsson * @since 0.7.28 - 2006-09-13 * @return string */ function createExrule() { $cnt = count( $this->exrule ); if( 0 >= $cnt ) return; $exrule = 'EXRULE'; return $this->_format_recur( $exrule, $this->exrule ); } /** * set calendar component property exdate * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param array $exruleset * @param array $params optional * @return void */ function setExrule( $exruleset, $params=FALSE ) { $exrule = array(); foreach( $exruleset as $exrulelabel => $exrulevalue ) { $exrulelabel = strtoupper( $exrulelabel ); if( 'UNTIL' != $exrulelabel ) $exrule['value'][$exrulelabel] = $exrulevalue; elseif( is_array( $exrulevalue ) && (( 3 == count( $exrulevalue )) || ( 6 == count( $exrulevalue )) || ( 7 == count( $exrulevalue )) || ( array_key_exists( 'year', $exrulevalue )))) { $parno = ( 3 < count( $exrulevalue )) ? 7 : 3 ; $date = $this->_date_time_array( $exrulevalue, $parno ); if(( 3 < count( $date )) && !isset( $date['tz'] )) $date['tz'] = 'Z'; $exrule['value'][$exrulelabel] = $date; } elseif( is_array( $exrulevalue ) && isset( $exrulevalue['timestamp'] )) { $date = $this->_date_time_string( date( 'Y-m-d H:i:s', $exrulevalue['timestamp'] ), 6 ); $date['tz'] = 'Z'; $exrule['value'][$exrulelabel] = $date; } elseif( 8 <= strlen( trim( $exrulevalue ))) { // ex. 2006-08-03 10:12:18 $date = $this->_date_time_string( $exrulevalue ); if(( 3 < count( $date )) && !isset( $date['tz'] )) $date['tz'] = 'Z'; $exrule['value'][$exrulelabel] = $date; } } $exrule['params'] = $this->_setParams( $params ); $this->exrule[] = $exrule; } /*********************************************************************************/ /** * Property Name: FREEBUSY */ /** * creates formatted output for calendar component property freebusy * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-16 * @return string */ function createFreebusy() { $cnt = count( $this->freebusy ); if( 0 >= $cnt ) return; $output = null; foreach( $this->freebusy as $freebusyPart ) { $attributes = $content = null; if( isset( $freebusyPart['value']['fbtype'] )) { $attributes .= $this->intAttrDelimiter.'FBTYPE='.$freebusyPart['value']['fbtype']; unset( $freebusyPart['value']['fbtype'] ); $freebusyPart['value'] = array_values( $freebusyPart['value'] ); } else $attributes .= $this->intAttrDelimiter.'FBTYPE=BUSY'; $attributes .= $this->_createParams( $freebusyPart['params'] ); $fno = 1; $cnt = count( $freebusyPart['value']); foreach( $freebusyPart['value'] as $periodix => $freebusyPeriod ) { $formatted = $this->_format_date_time( $freebusyPeriod[0] ); $content .= $formatted; $content .= '/'; $cnt2 = count( $freebusyPeriod[1]); if( array_key_exists( 'year', $freebusyPeriod[1] )) // date-time $cnt2 = 7; elseif( array_key_exists( 'week', $freebusyPeriod[1] )) // duration $cnt2 = 5; if(( 7 == $cnt2 ) && // period= -> date-time isset( $freebusyPeriod[1]['year'] ) && isset( $freebusyPeriod[1]['month'] ) && isset( $freebusyPeriod[1]['day'] )) { $content .= $this->_format_date_time( $freebusyPeriod[1] ); } else { // period= -> dur-time $content .= $this->_format_duration( $freebusyPeriod[1] ); } if( $fno < $cnt ) $content .= ','; $fno++; } $output .= $this->_createElement( 'FREEBUSY', $attributes, $content ); } return $output; } /** * set calendar component property freebusy * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $fbType * @param array $fbValues * @param array $params optional * @return void */ function setFreebusy( $fbType, $fbValues, $params=FALSE ) { $fbType = strtoupper( $fbType ); if(( !in_array( $fbType, array( 'FREE', 'BUSY', 'BUSY-UNAVAILABLE', 'BUSY-TENTATIVE' ))) && ( 'X-' != substr( $fbType, 0, 2 ))) $fbType = 'BUSY'; $freebusy['value'] = array( 'fbtype' => $fbType ); foreach( $fbValues as $fbPeriod ) { // periods => period $freebusyPeriod = array(); foreach( $fbPeriod as $fbMember ) { // pairs => singlepart $freebusyPairMember = array(); if( is_array( $fbMember )) { $cnt = count( $fbMember ); if(( 6 == $cnt ) || ( 7 == $cnt ) || ( array_key_exists( 'year', $fbMember ))) { // date-time value $date = $this->_date_time_array( $fbMember, 7 ); $date['tz'] = ( !isset( $date['tz'] )) ? 'Z' : $date['tz']; $freebusyPairMember = $date; } elseif( array_key_exists( 'timestamp', $fbMember )) { // timestamp value $tz = ( isset( $fbMember['tz'] )) ? ' '.$fbMember['tz'] : null; $parno = ( !empty( $tz )) ? 7 : 6; $date = $this->_date_time_string( date( 'Y-m-d H:i:s', $fbMember['timestamp'] ).$tz, $parno ); $date['tz'] = ( !isset( $date['tz'] )) ? 'Z' : $date['tz']; $freebusyPairMember = $date; } else { // array format duration $freebusyPairMember = $this->_duration_array( $fbMember ); } } elseif(( 3 <= strlen( trim( $fbMember ))) && // string format duration ( in_array( $fbMember{0}, array( 'P', '+', '-' )))) { if( 'P' != $fbMember{0} ) $fbmember = substr( $fbMember, 1 ); $freebusyPairMember = $this->_duration_string( $fbMember ); } elseif( 8 <= strlen( trim( $fbMember ))) { // ex. 2006-08-03 10:12:18 $date = $this->_date_time_string( $fbMember, 7 ); $date['tz'] = ( !isset( $date['tz'] )) ? 'Z' : $date['tz']; $freebusyPairMember = $date; } $freebusyPeriod[] = $freebusyPairMember; } $freebusy['value'][] = $freebusyPeriod; } $freebusy['params'] = $this->_setParams( $params ); $this->freebusy[] = $freebusy; } /*********************************************************************************/ /** * Property Name: GEO */ /** * creates formatted output for calendar component property geo * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createGeo() { $cnt = count( $this->geo ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->geo['params'] ); $content = null; $content .= number_format( (float) $this->geo['value']['latitude'], 6, '.', ''); $content .= ';'; $content .= number_format( (float) $this->geo['value']['longitude'], 6, '.', ''); return $this->_createElement( 'GEO', $attributes, $content ); } /** * set calendar component property geo * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param float $latitude * @param float $longitude * @param array $params optional * @return void */ function setGeo( $latitude, $longitude, $params=FALSE ) { $this->geo['value']['latitude'] = $latitude; $this->geo['value']['longitude'] = $longitude; $this->geo['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: LAST-MODIFIED */ /** * creates formatted output for calendar component property last-modified * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createLastModified() { if( !isset( $this->lastmodified['value']['year'] ) && !isset( $this->lastmodified['value']['month'] ) && !isset( $this->lastmodified['value']['day'] ) && !isset( $this->lastmodified['value']['hour'] ) && !isset( $this->lastmodified['value']['min'] ) && !isset( $this->lastmodified['value']['sec'] )) return; $attributes = $this->_createParams( $this->lastmodified['params'] ); $formatted = $this->_format_date_time( $this->lastmodified['value'], 7 ); return $this->_createElement( 'LAST-MODIFIED', $attributes, $formatted ); } /** * set calendar component property completed * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-02 * @param mixed $year optional * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return void */ function setLastModified( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { if( !isset( $year )) { $year = date('Ymd\THis', mktime ( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' ))); } $this->lastmodified = $this->_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); } /*********************************************************************************/ /** * Property Name: LOCATION */ /** * creates formatted output for calendar component property location * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createLocation() { $cnt = count( $this->location ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->location['params'], array( 'ALTREP', 'LANGUAGE' )); $content = $this->_strrep( $this->location['value'] ); return $this->_createElement( 'LOCATION', $attributes, $content ); } /** * set calendar component property location ' * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param array params optional * @return void */ function setLocation( $value, $params=FALSE ) { $this->location['value'] = $value; $this->location['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: ORGANIZER */ /** * creates formatted output for calendar component property organizer * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createOrganizer() { $cnt = count( $this->organizer ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->organizer['params'] , array( 'CN', 'DIR', 'LANGUAGE', 'SENT-BY' )); $content = 'MAILTO:'.$this->organizer['value']; return $this->_createElement( 'ORGANIZER', $attributes, $content ); } /** * set calendar component property organizer * * @author Kjell-Inge Gustafsson * @since 2.0.9 - 2007-06-30 * @param string $value * @param array params optional * @return void */ function setOrganizer( $value, $params=FALSE ) { $value = str_replace ( 'MAILTO:', '', $value ); $value = str_replace ( 'mailto:', '', $value ); $this->organizer['value'] = $value; $this->organizer['params'] = $this->_setParams( $params ); if( isset($this->organizer['params']['SENT-BY'] )) { if( 'MAILTO' == strtoupper( substr( $this->organizer['params']['SENT-BY'], 0, 6 ))) $this->organizer['params']['SENT-BY'] = substr( $this->organizer['params']['SENT-BY'], 7 ); } } /*********************************************************************************/ /** * Property Name: PERCENT-COMPLETE */ /** * creates formatted output for calendar component property percent-complete * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createPercentComplete() { $cnt = count( $this->percentcomplete ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->percentcomplete['params'] ); return $this->_createElement( 'PERCENT-COMPLETE', $attributes, $this->percentcomplete['value'] ); } /** * set calendar component property percent-complete * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param int $value * @param array $params optional * @return void */ function setPercentComplete( $value, $params=FALSE ) { $this->percentcomplete['value'] = $value; $this->percentcomplete['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: PRIORITY */ /** * creates formatted output for calendar component property priority * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createPriority() { $cnt = count( $this->priority ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->priority['params'] ); return $this->_createElement( 'PRIORITY', $attributes, $this->priority['value'] ); } /** * set calendar component property priority * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param int $value * @param array $params optional * @return void */ function setPriority( $value, $params=FALSE ) { $this->priority['value'] = $value; $this->priority['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: RDATE */ /** * creates formatted output for calendar component property rdate * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-13 * @param bool $localtime optional, default FALSE * @return string */ function createRdate( $localtime=FALSE ) { $cnt = count( $this->rdate ); if( 0 >= $cnt ) return; $output = null; foreach( $this->rdate as $theRdate ) { $attributes = $this->_createParams( $theRdate['params'] ); $cnt = count( $theRdate['value'] ); $content = null; $rno = 1; foreach( $theRdate['value'] as $rpix =>$rdatePart ) { $contentPart = null; if( is_array( $rdatePart ) && ( 2 == count( $rdatePart )) && array_key_exists( '0', $rdatePart ) && array_key_exists( '1', $rdatePart )) { // PERIOD if( $localtime ) unset( $rdatePart[0]['tz'] ); $formatted = $this->_format_date_time( $rdatePart[0]); if( isset( $theRdate['params']['TZID'] )) $formatted = str_replace( 'Z', '', $formatted); if( 0 < $rpix ) { if( isset( $rdatePart[0]['tz'] ) && ( ctype_digit( substr( $rdatePart[0]['tz'], -4 )) || ( 'Z' == $rdatePart[0]['tz'] ))) { if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z'; } else $formatted = str_replace( 'Z', '', $formatted ); } $contentPart .= $formatted; if( 1 == $rno ) $attributes .= $this->intAttrDelimiter.'VALUE=PERIOD'; $contentPart .= '/'; $cnt2 = count( $rdatePart[1]); if( array_key_exists( 'year', $rdatePart[1] )) { if( array_key_exists( 'hour', $rdatePart[1] )) $cnt2 = 7; // date-time else $cnt2 = 3; // date } elseif( array_key_exists( 'week', $rdatePart[1] )) // duration $cnt2 = 5; if(( 7 == $cnt2 ) && // period= -> date-time isset( $rdatePart[1]['year'] ) && isset( $rdatePart[1]['month'] ) && isset( $rdatePart[1]['day'] )) { if( $localtime ) unset( $rdatePart[1]['tz'] ); $formatted = $this->_format_date_time( $rdatePart[1] ); if( isset( $theRdate['params']['TZID'] )) $formatted = str_replace( 'Z', '', $formatted); if( isset( $rdatePart[0]['tz'] ) && ( ctype_digit( substr( $rdatePart[0]['tz'], -4 )) || ( 'Z' == $rdatePart[0]['tz'] ))) { if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z'; } else $formatted = str_replace( 'Z', '', $formatted ); $contentPart .= $formatted; } else { // period= -> dur-time $contentPart .= $this->_format_duration( $rdatePart[1] ); } } // PERIOD end else { // single date start if( $localtime ) unset( $rdatePart['tz'] ); $formatted = $this->_format_date_time( $rdatePart); if( isset( $theRdate['params']['TZID'] )) $formatted = str_replace( 'Z', '', $formatted); if( 0 < $rpix ) { $firstPart = ( 2 == count( $theRdate['value'][0] )) ? $theRdate['value'][0][0] : $theRdate['value'][0]; if( isset( $firstPart['tz'] ) && ( ctype_digit( substr( $firstPart['tz'], -4 )) || ( 'Z' == $firstPart['tz'] ))) { if( 'Z' != substr( $formatted, -1 )) $formatted .= 'Z'; } else $formatted = str_replace( 'Z', '', $formatted ); } $contentPart .= $formatted; } $content .= $contentPart; if( $rno < $cnt ) $content .= ','; $rno++; } $output .= $this->_createElement( 'RDATE', $attributes, $content ); } return $output; } /** * set calendar component property rdate * * @author Kjell-Inge Gustafsson * @since 2.0.5 - 2007-06-22 * @param array $rdates * @param array $params optional * @return void */ function setRdate( $rdates, $params=FALSE ) { $input = array(); $input['params'] = $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' )); $this->_existRem( $input['params'], 'VALUE', 'PERIOD' ); $parno = ( isset( $input['params']['TZID'] )) ? 6 : null; $parno = ( !$parno ) ? $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7 ) : null; $parno = ( !$parno ) ? $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ) : 6; foreach( $rdates as $theRdate ) { // echo 'setRdate in '; print_r ( $theRdate ); echo "
      \n"; // test ## $inputa = null; if( is_array( $theRdate )) { if(( 2 == count( $theRdate )) && array_key_exists( '0', $theRdate ) && array_key_exists( '1', $theRdate ) && !array_key_exists( 'timestamp', $theRdate )) { // PERIOD foreach( $theRdate as $rix => $rPeriod ) { // echo 'setRdate i2 '; print_r ( $rPeriod ); echo "
      \n"; // test ## if( is_array( $rPeriod )) { if (( 1 == count( $rPeriod )) && ( 8 <= strlen( trim( $rPeriod[0] )))) { // text-date $inputab = $this->_date_time_string( $rPeriod[0], $parno ); $inputab['tz'] = ( isset( $input['params']['TZID'] )) ? $input['params']['TZID'] : ( isset( $inputab['tz'] )) ? $inputab['tz'] : null; $parno = ( !isset( $parno )) ? count( $inputab ) : $parno; if(( 7 == $parno ) && !isset( $inputab['tz'] )) $inputab['tz'] = 'Z'; if( isset( $inputab['tz'] )) $inputab['tz'] = (string) $inputab['tz']; $inputa[] = $inputab; } elseif (((3 == count( $rPeriod )) && ( $rix < 1 )) || ( 6 == count( $rPeriod )) || ( 7 == count( $rPeriod )) || ( array_key_exists( 'year', $rPeriod ))) { // date[-time] (only 1st rperiod) if( !isset( $parno ) && 3 < count( $rPeriod )) $parno = 7; $inputab = $this->_date_time_array( $rPeriod, $parno ); $inputab['tz'] = ( isset( $input['params']['TZID'] )) ? $input['params']['TZID'] : ( isset( $inputab['tz'] )) ? $inputab['tz'] : null; $parno = ( !isset( $parno )) ? count( $inputab ) : $parno; if(( 7 == $parno ) && !isset( $inputab['tz'] )) $inputab['tz'] = 'Z'; if( isset( $inputab['tz'] )) $inputab['tz'] = (string) $inputab['tz']; $inputa[] = $inputab; } elseif( isset( $rPeriod['timestamp'] )) { // timestamp $tz = ( isset( $rPeriod['tz'] )) ? ' '.$rPeriod['tz'] : null; $tz = ( isset( $input['params']['TZID'] )) ? ' '.$input['params']['TZID'] : $tz; if( !isset( $parno )) $parno = ( !empty( $tz )) ? 7 : 6; $inputab = $this->_date_time_string( date( 'Y-m-d H:i:s', $rPeriod['timestamp'] ).$tz, $parno ); if(( 7 == $parno ) && !isset( $inputab['tz'] )) $inputab['tz'] = 'Z'; if( isset( $inputab['tz'] )) $inputab['tz'] = (string) $inputab['tz']; $inputa[] = $inputab; } else { // array format duration $inputa[] = $this->_duration_array( $rPeriod ); } } elseif(( 3 <= strlen( trim( $rPeriod ))) && // string format duration ( in_array( $rPeriod{0}, array( 'P', '+', '-' )))) { if( 'P' != $rPeriod{0} ) $rPeriod = substr( $rPeriod, 1 ); $inputa[] = $this->_duration_string( $rPeriod ); } elseif( 8 <= strlen( trim( $rPeriod ))) { // ex. 2006-08-03 10:12:18 $inputab = $this->_date_time_string( $rPeriod, $parno ); $inputab['tz'] = ( isset( $input['params']['TZID'] )) ? (string) $input['params']['TZID'] : ( isset( $inputab['tz'] )) ? (string) $inputab['tz'] : null; $inputa[] = $inputab; $parno = ( !isset( $parno )) ? count( $inputab ) : $parno; } } } elseif ( array_key_exists( 'timestamp', $theRdate )) { // timestamp $tz = ( isset( $theRdate['tz'] )) ? ' '.$theRdate['tz'] : null; $tz = ( isset( $input['params']['TZID'] )) ? ' '.$input['params']['TZID'] : $tz; if( !isset( $parno )) $parno = ( !empty( $tz )) ? 7 : 6; $inputab = $this->_date_time_string( date( 'Y-m-d H:i:s', $theRdate['timestamp'] ).$tz, $parno ); if(( 7 == $parno ) && !isset( $inputab['tz'] )) $inputab['tz'] = 'Z'; if( isset( $inputab['tz'] )) $inputab['tz'] = (string) $inputab['tz']; $inputa = $inputab; } elseif (( in_array( count( $theRdate ), array( 3, 4, 6, 7 ))) || ( array_key_exists( 'year', $theRdate ))) { // date[-time] if( isset( $input['params']['TZID'] )) $theRdate['tz'] = $input['params']['TZID']; elseif( !isset( $theRdate['tz'] )) { if(( 7 == count( $theRdate )) && isset( $theRdate[6] )) { $theRdate['tz'] = $theRdate[6]; unset( $theRdate[6] ); } elseif(( 4 == count( $theRdate )) && isset( $theRdate[3] )) { $theRdate['tz'] = $theRdate[3]; unset( $theRdate[3] ); } } if( !isset( $parno ) && 3 < count( $theRdate )) $parno = ( isset( $theRdate['tz'] )) ? 7 : count( $theRdate ); elseif( !isset( $parno )) $parno = 3; $inputa = $this->_date_time_array( $theRdate, $parno ); if(( 7 == $parno ) && !isset( $inputa['tz'] )) $inputa['tz'] = 'Z'; if( isset( $inputa['tz'] )) $inputa['tz'] = (string) $inputa['tz']; } } elseif( 8 <= strlen( trim( $theRdate ))) { // ex. 2006-08-03 10:12:18 $inputa = $this->_date_time_string( $theRdate, $parno ); $inpute['tz'] = ( isset( $input['params']['TZID'] )) ? $input['params']['TZID'] : ( isset( $inpute['tz'] )) ? $inpute['tz'] : null; $parno = ( !isset( $parno )) ? count( $inputa ) : $parno; if(( 7 == $parno ) && !isset( $inputa['tz'] )) $inputa['tz'] = 'Z'; if( isset( $inputa['tz'] )) $inputa['tz'] = (string) $inputa['tz']; } $input['value'][] = $inputa; } if( 0 < count( $input['value'] )) { if( 3 == $parno ) { $input['params']['VALUE'] = 'DATE'; foreach( $input['value'] as $eix => $inputa ) unset( $input['value'][$eix]['tz'] ); unset( $input['params']['TZID'] ); } if( !empty( $input['value'][0]['tz'] ) && ( $input['value'][0]['tz'] != 'Z' ) && ( !( in_array($input['value'][0]['tz']{0}, array( '+', '-' )) && ctype_digit( substr( $input['value'][0]['tz'], 1 ))) && !ctype_digit( $input['value'][0]['tz'] ) ) ) { $input['params']['TZID'] = $input['value'][0]['tz']; foreach( $input['value'] as $eix => $inputa ) { if( !empty( $input['value'][0]['tz'] ) && ( $input['value'][0]['tz'] != 'Z' ) && ( !( in_array( $input['value'][0]['tz']{0}, array( '+', '-' )) && ctype_digit( substr( $input['value'][0]['tz'], 1 ))) && !ctype_digit( $input['value'][0]['tz'] ) ) ) unset( $input['value'][$eix]['tz'] ); } } elseif( isset( $input['params']['TZID'] )) unset( $input['params']['TZID'] ); $this->rdate[] = $input; } // echo 'setRdate ut '; print_r ( $this->rdate ); echo "
      \n"; // test ## } /*********************************************************************************/ /** * Property Name: RECURRENCE-ID */ /** * creates formatted output for calendar component property recurrence-id * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-26 * @return string */ function createRecurrenceid() { $cnt = count( $this->recurrenceid ); if( 0 >= $cnt ) return; $formatted = $this->_format_date_time( $this->recurrenceid['value'] ); $attributes = $this->_createParams( $this->recurrenceid['params'] ); return $this->_createElement( 'RECURRENCE-ID', $attributes, $formatted ); } /** * set calendar component property recurrence-id * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return void */ function setRecurrenceid( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { $this->recurrenceid = $this->_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params ); } /*********************************************************************************/ /** * Property Name: RELATED-TO */ /** * creates formatted output for calendar component property related-to * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-24 * @return string */ function createRelatedTo() { $cnt = count( $this->relatedto ); if( 0 >= $cnt ) return; $output = null; foreach( $this->relatedto as $relation ) { $attributes = $this->_createParams( $relation['params'] ); $content = '<'.$relation['value'].'>'; $output .= $this->_createElement( 'RELATED-TO', $attributes, $content ); } return $output; } /** * set calendar component property related-to * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-24 * @param float $relid * @param array $params optional * @return void */ function setRelatedTo( $relid, $params=FALSE ) { $relation = array(); if(( '<' == substr( $relid, 0, 1 )) && ( '>' == substr( $relid, -1 ))) $relid = substr( $relid, 1, ( strlen( $relid ) - 2 )); $relation['value'] = $relid; $relation['params'] = $this->_setParams( $params ); // remove default if( isset( $relation['params']['RELTYPE'] ) && ( strtoupper( $relation['params']['RELTYPE'] ) == 'PARENT' )) unset( $relation['params']['RELTYPE'] ); $this->relatedto[] = $relation; } /*********************************************************************************/ /** * Property Name: REPEAT */ /** * creates formatted output for calendar component property repeat * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createRepeat() { $cnt = count( $this->repeat ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->repeat['params'] ); return $this->_createElement( 'REPEAT', $attributes, $this->repeat['value'] ); } /** * set calendar component property transp * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param array $params optional * @return void */ function setRepeat( $value, $params=FALSE ) { $this->repeat['value'] = $value; $this->repeat['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: REQUEST-STATUS */ /** * creates formatted output for calendar component property request-status * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-16 * @return string */ function createRequestStatus() { $cnt = count( $this->requeststatus ); if( 0 >= $cnt ) return; $output = null; foreach( $this->requeststatus as $rstat ) { $attributes = $this->_createParams( $rstat['params'], array( 'LANGUAGE' )); $content = number_format( (float) $rstat['value']['statcode'], 2, '.', ''); $content .= ';'.$this->_strrep( $rstat['value']['text'] ); if( isset( $rstat['value']['extdata'] )) $content .= ';'.$this->_strrep( $rstat['value']['extdata'] ); $output .= $this->_createElement( 'REQUEST-STATUS', $attributes, $content ); } return $output; } /** * set calendar component property request-status * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-16 * @param float $statcode * @param string $text * @param string $extdata optional * @param array params optional * @return void */ function setRequestStatus( $statcode, $text, $extdata=FALSE, $params=FALSE ) { $input = array(); $input['value']['statcode'] = $statcode; $input['value']['text'] = $text; if( $extdata ) $input['value']['extdata'] = $extdata; $input['params'] = $this->_setParams( $params); $this->requeststatus[] = $input; } /*********************************************************************************/ /** * Property Name: RESOURCES */ /** * creates formatted output for calendar component property resources * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-19 * @return string */ function createResources() { if( 0 >= count( $this->resources )) return; $output = null; foreach( $this->resources as $resource ) { $attributes = $this->_createParams( $resource['params'], array( 'ALTREP', 'LANGUAGE' )); $output .= $this->_createElement( 'RESOURCES', $attributes, $resource['value'] ); } return $output; } /** * set calendar component property recources * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-19 * @param mixed $value * @param array params optional * @return void */ function setResources( $value, $params=FALSE ) { $input = array(); $value = ( is_array( $value )) ? implode( ',', $value ) : $value; $value = str_replace( ', ', ',', $value ); $value = str_replace( ' ,', ',', $value ); $input['value'] = $value; $input['params'] = $this->_setParams( $params ); $this->resources[] = $input; } /*********************************************************************************/ /** * Property Name: RRULE */ /** * creates formatted output for calendar component property rrule * * @author Kjell-Inge Gustafsson * @since 0.7.43 - 2006-09-15 * @return string */ function createRrule() { $cnt = count( $this->rrule ); if( 0 >= $cnt ) return; return $this->_format_recur( 'RRULE', $this->rrule ); } /** * set calendar component property rrule * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param array $rruleset * @param array $params optional * @return void */ function setRrule( $rruleset, $params=FALSE ) { $exrule = array(); foreach( $rruleset as $rrulelabel => $rrulevalue ) { $rrulelabel = strtoupper( $rrulelabel ); if( 'UNTIL' != $rrulelabel ) $rrule['value'][$rrulelabel] = $rrulevalue; elseif( is_array( $rrulevalue ) && (( 3 == count( $rrulevalue )) || ( 6 == count( $rrulevalue )) || ( 7 == count( $rrulevalue )) || ( array_key_exists( 'year', $rrulevalue )))) { $parno = ( 3 < count( $rrulevalue )) ? 7 : 3 ; // datetime / date $date = $this->_date_time_array( $rrulevalue, $parno ); if(( 3 < count( $date )) && !isset( $date['tz'] )) $date['tz'] = 'Z'; $rrule['value'][$rrulelabel] = $date; } elseif( is_array( $rrulevalue ) && isset( $rrulevalue['timestamp'] )) { $date = $this->_date_time_string( date( 'Y-m-d H:i:s', $rrulevalue['timestamp'] ), 6 ); $date['tz'] = 'Z'; $rrule['value'][$rrulelabel] = $date; } elseif( 8 <= strlen( trim( $rrulevalue ))) { // ex. 2006-08-03 10:12:18 $date = $this->_date_time_string( $rrulevalue ); if(( 3 < count( $date )) && !isset( $date['tz'] )) $date['tz'] = 'Z'; $rrule['value'][$rrulelabel] = $date; } } $rrule['params'] = $this->_setParams( $params ); $this->rrule[] = $rrule; } /*********************************************************************************/ /** * Property Name: SEQUENCE */ /** * creates formatted output for calendar component property sequence * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createSequence() { $cnt = count( $this->sequence ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->sequence['params'] ); return $this->_createElement( 'SEQUENCE', $attributes, $this->sequence['value'] ); } /** * set calendar component property sequence * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-04-25 * @param int $value optional * @param array $params optional * @return void */ function setSequence( $value=FALSE, $params=FALSE ) { if( !$value ) $value = $this->getProperty( 'sequence' ) + 1; $this->sequence['value'] = $value; $this->sequence['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: STATUS */ /** * creates formatted output for calendar component property status * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createStatus() { $cnt = count( $this->status ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->status['params'] ); return $this->_createElement( 'STATUS', $attributes, $this->status['value'] ); } /** * set calendar component property status * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param array $params optional * @return void */ function setStatus( $value, $params=FALSE ) { $this->status['value'] = $value; $this->status['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: SUMMARY */ /** * creates formatted output for calendar component property summary * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createSummary() { $cnt = count( $this->summary ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->summary['params'], array( 'ALTREP', 'LANGUAGE' )); $content = $this->_strrep( $this->summary['value'] ); return $this->_createElement( 'SUMMARY', $attributes, $content ); } /** * set calendar component property summary * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setSummary( $value, $params=FALSE ) { $this->summary['value'] = $value; $this->summary['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: TRANSP */ /** * creates formatted output for calendar component property transp * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createTransp() { $cnt = count( $this->transp ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->transp['params'] ); return $this->_createElement( 'TRANSP', $attributes, $this->transp['value'] ); } /** * set calendar component property transp * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setTransp( $value, $params=FALSE ) { $this->transp['value'] = $value; $this->transp['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: TRIGGER */ /** * creates formatted output for calendar component property trigger * * @author Kjell-Inge Gustafsson * @since 0.9.19 - 2007-03-27 * @return string */ function createTrigger() { $cnt = count( $this->trigger ); if( 0 >= $cnt ) return; $content = $attributes = null; if( isset( $this->trigger['value']['year'] ) && isset( $this->trigger['value']['month'] ) && isset( $this->trigger['value']['day'] )) $content .= $this->_format_date_time( $this->trigger['value'] ); else { if( TRUE !== $this->trigger['value']['relatedstart'] ) $attributes .= $this->intAttrDelimiter.'RELATED=END'; if( $this->trigger['value']['before'] ) $content .= '-'; $content .= $this->_format_duration( $this->trigger['value'] ); } $attributes .= $this->_createParams( $this->trigger['params'] ); return $this->_createElement( 'TRIGGER', $attributes, $content ); } /** * set calendar component property trigger * * @author Kjell-Inge Gustafsson * @since 2.1.1 - 2007-07-07 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $week optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param bool $relatedEnd optional * @param bool $after optional * @param string $tz optional * @param array $params optional * @return void * @toto fix is_int */ function setTrigger( $year=FALSE, $month=FALSE, $day=FALSE, $week=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $relatedEnd=FALSE, $after=FALSE, $tz=FALSE, $params=FALSE ) { if( is_array( $year ) && array_key_exists( 'timestamp', $year )) { // timestamp $params = $this->_setParams( $month ); $this->_existRem( $params, 'VALUE', 'DATE-TIME' ); if( isset( $params['TZID'] )) { $year['tz'] = $params['TZID']; unset( $params['TZID'] ); } $tz = ( isset( $year['tz'] )) ? ' '.$year['tz'] : null; $parno = ( isset( $tz )) ? 7 : 6; $date = $this->_date_time_string( date( 'Y-m-d H:i:s', $year['timestamp'] ).$tz, $parno ); foreach( $date as $k => $v ) $$k = $v; } elseif( is_array( $year )) { if( array_key_exists( 'year', $year ) && array_key_exists( 'month', $year ) && array_key_exists( 'day', $year )) { // date-time $params = $this->_setParams( $month ); if( isset( $params['TZID'] )) { $year['tz'] = $params['TZID']; unset( $params['TZID'] ); } } else { // duration $year = $this->_duration_array( $year ); $relatedEnd = $month; $after = $day; $params = $this->_setParams( $week ); } $this->_existRem( $params, 'VALUE', 'DATE-TIME' ); $this->_existRem( $params, 'VALUE', 'DURATION' ); $SSYY = ( array_key_exists( 'year', $year )) ? $year['year'] : null; $month = ( array_key_exists( 'month', $year )) ? $year['month'] : null; $day = ( array_key_exists( 'day', $year )) ? $year['day'] : null; $week = ( array_key_exists( 'week', $year )) ? $year['week'] : null; $hour = ( array_key_exists( 'hour', $year )) ? $year['hour'] : null; $min = ( array_key_exists( 'min', $year )) ? $year['min'] : null; $sec = ( array_key_exists( 'sec', $year )) ? $year['sec'] : null; $tz = ( array_key_exists( 'tz', $year )) ? $year['tz'] : null; $year = $SSYY; } elseif( is_string($year) && !ctype_digit( (string) $year )) { // duration or date in a string $params = $this->_setParams( $month ); unset( $month ); $this->_existRem( $params, 'VALUE', 'DATE-TIME' ); // ?? $this->_existRem( $params, 'VALUE', 'DURATION' ); if( in_array( $year{0}, array( 'P', '+', '-' ))) { // duration if( '-' == $year{0} ) $after = FALSE; elseif( '+' == $year{0} ) $after = TRUE; elseif( 'P' == $year{0} ) $after = TRUE; if( 'P' != $year{0} ) $year = substr( $year, 1 ); $date = $this->_duration_string( $year); } else { $date = $this->_date_time_string( $year, 7 ); // date if( isset( $params['TZID'] )) { $date['tz'] = $params['TZID']; unset( $params['TZID'] ); } } foreach( $date as $k => $v ) $$k = $v; } else $params = $this->_setParams( $params ); if( !empty( $year ) && !empty( $month ) && !empty( $day ) ) { // date $params['VALUE'] = 'DATE-TIME'; $this->trigger['value'] = array( 'year' => $year , 'month' => $month , 'day' => $day); $this->trigger['value']['hour'] = $hour; $this->trigger['value']['min'] = $min; $this->trigger['value']['sec'] = $sec; if( !empty( $tz )) $this->trigger['value']['tz'] = $tz; else $this->trigger['value']['tz'] = 'Z'; } else { // duration $this->_existRem( $params, 'VALUE', 'DURATION' ); if( $this->_existRem( $params, 'RELATED', 'END', TRUE )) $relatedEnd = TRUE; elseif( $this->_existRem( $params, 'RELATED', 'START', TRUE )) $relatedEnd = FALSE; if( !empty( $week )) { $this->trigger['value'] = array( 'week' => $week , 'relatedstart' => !$relatedEnd , 'before' => !$after ); } else { $this->trigger['value'] = array( 'day' => $day , 'hour' => $hour , 'min' => $min , 'sec' => $sec , 'relatedstart' => !$relatedEnd , 'before' => !$after ); } } if( !isset( $this->trigger['value'] )) return; $this->trigger['params'] = $params; } /*********************************************************************************/ /** * Property Name: TZID */ /** * creates formatted output for calendar component property tzid * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createTzid() { $cnt = count( $this->tzid ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->tzid['params'] ); return $this->_createElement( 'TZID', $attributes, $this->tzid['value'] ); } /** * set calendar component property tzid * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param array $params optional * @return void */ function setTzid( $value, $params=FALSE ) { $this->tzid['value'] = $value; if( !isset( $this->tzid['value'] )) return; $this->tzid['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * .. . * Property Name: TZNAME */ /** * creates formatted output for calendar component property tzname * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-24 * @return string */ function createTzname() { $cnt = count( $this->tzname ); if( 0 >= $cnt ) return; $output = null; foreach( $this->tzname as $theName ) { $attributes = $this->_createParams( $theName['params'], array( 'LANGUAGE' )); $output .= $this->_createElement( 'TZNAME', $attributes, $theName['value'] ); } return $output; } /** * set calendar component property tzname * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setTzname( $value, $params=FALSE ) { $input['value'] = $value; if( empty( $input['value'] )) return; $input['params'] = $this->_setParams( $params ); $this->tzname[] = $input; } /*********************************************************************************/ /** * Property Name: TZOFFSETFROM */ /** * creates formatted output for calendar component property tzoffsetfrom * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createTzoffsetfrom() { $cnt = count( $this->tzoffsetfrom ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->tzoffsetfrom['params'] ); return $this->_createElement( 'TZOFFSETFROM', $attributes, $this->tzoffsetfrom['value'] ); } /** * set calendar component property tzoffsetfrom * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-25 * @param string $value * @param string $params optional * @return void */ function setTzoffsetfrom( $value, $params=FALSE ) { $this->tzoffsetfrom['value'] = $value; if( empty( $this->tzoffsetfrom['value'] )) return; $this->tzoffsetfrom['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: TZOFFSETTO */ /** * creates formatted output for calendar component property tzoffsetto * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createTzoffsetto() { $cnt = count( $this->tzoffsetto ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->tzoffsetto['params'] ); return $this->_createElement( 'TZOFFSETTO', $attributes, $this->tzoffsetto['value'] ); } /** * set calendar component property tzoffsetto * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setTzoffsetto( $value, $params=FALSE ) { $this->tzoffsetto['value'] = $value; if( empty( $this->tzoffsetto['value'] )) return; $this->tzoffsetto['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: TZURL */ /** * creates formatted output for calendar component property tzurl * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createTzurl() { $cnt = count( $this->tzurl ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->tzurl['params'] ); return $this->_createElement( 'TZURL', $attributes, $this->tzurl['value'] ); } /** * set calendar component property tzurl * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setTzurl( $value, $params=FALSE ) { $this->tzurl['value'] = $value; if( empty( $this->tzurl['value'] )) return; $this->tzurl['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: UID */ /** * creates formatted output for calendar component property uid * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createUid() { $cnt = count( $this->uid ); if( 0 >= $cnt ) { $this->_makeuid(); } $attributes = $this->_createParams( $this->uid['params'] ); return $this->_createElement( 'UID', $attributes, $this->uid['value'] ); } /** * create an unique id for this calendar component object instance * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-04 * @return void */ function _makeUid() { $unique = null; $base = 'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPrRsStTuUvVxXuUvVwWzZ1234567890'; $start = 0; $end = strlen( $base ) - 1; $length = 10; $str = null; for( $p = 0; $p < $length; $p++ ) $unique .= $base{mt_rand( $start, $end )}; $this->uid['value'] = date('Ymd\THisT').'-'.$unique.'@'.$this->getConfig( 'unique_id' ); $this->uid['params'] = null; } /** * set calendar component property uid * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setUid( $value, $params=FALSE ) { $this->uid['value'] = $value; if( empty( $this->uid['value'] )) return; $this->uid['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: URL */ /** * creates formatted output for calendar component property url * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @return string */ function createUrl() { $cnt = count( $this->url ); if( 0 >= $cnt ) return; $attributes = $this->_createParams( $this->url['params'] ); return $this->_createElement( 'URL', $attributes, $this->url['value'] ); } /** * set calendar component property url * * @author Kjell-Inge Gustafsson * @since 0.9.18 - 2007-03-18 * @param string $value * @param string $params optional * @return void */ function setUrl( $value, $params=FALSE ) { $this->url['value'] = $value; if( empty( $this->url['value'] )) return; $this->url['params'] = $this->_setParams( $params ); } /*********************************************************************************/ /** * Property Name: x-prop */ /** * creates formatted output for calendar component property x-prop * * @author Kjell-Inge Gustafsson * @since 2.0.7 - 2007-06-21 * @return string */ function createXprop() { if( 0 >= count( $this->xprop )) return; $xprop = null; foreach( $this->xprop as $label => $xpropPart ) { $attributes = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' )); if( is_array( $xpropPart['value'] )) $xpropPart['value'] = implode( ',', $xpropPart['value'] ); $xprop .= $this->_createElement( strtoupper( $label ), $attributes, $xpropPart['value'] ); } return $xprop; } /** * set calendar component property x-prop * * @author Kjell-Inge Gustafsson * @since 2.0.7 - 2007-06-21 * @param string $label * @param mixed $value * @param array $params optional * @return void */ function setXprop( $label, $value, $params=FALSE ) { if( empty( $label ) || empty( $value )) return; $xprop = array( 'value' => $value ); $toolbox = new calendarComponent(); $xprop['params'] = $toolbox->_setParams( $params ); $this->xprop[$label] = $xprop; } /*********************************************************************************/ /*********************************************************************************/ /** * create element format parts * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2006-06-20 * @return string */ function _createFormat() { $objectname = null; switch( $this->format ) { case 'xcal': $objectname = ( isset( $this->timezonetype )) ? strtolower( $this->timezonetype ) : strtolower( $this->objName ); $this->componentStart1 = $this->elementStart1 = '<'; $this->componentStart2 = $this->elementStart2 = '>'; $this->componentEnd1 = $this->elementEnd1 = 'componentEnd2 = $this->elementEnd2 = '>'.$this->nl; $this->intAttrDelimiter = ''; $this->attributeDelimiter = $this->nl; $this->valueInit = null; break; default: $objectname = ( isset( $this->timezonetype )) ? strtoupper( $this->timezonetype ) : strtoupper( $this->objName ); $this->componentStart1 = 'BEGIN:'; $this->componentStart2 = null; $this->componentEnd1 = 'END:'; $this->componentEnd2 = $this->nl; $this->elementStart1 = null; $this->elementStart2 = null; $this->elementEnd1 = null; $this->elementEnd2 = $this->nl; $this->intAttrDelimiter = ''; $this->attributeDelimiter = ';'; $this->valueInit = ':'; break; } return $objectname; } /** * creates formatted output for calendar component property * * @author Kjell-Inge Gustafsson * @since 0.9.15 - 2007-01-08 * @param string $label property name * @param string $attributes property attributes * @param string $content property content (optional) * @return string */ function _createElement( $label, $attributes, $content=FALSE ) { $label = $this->_formatPropertyName( $label ); $output = $this->elementStart1.$label; $categoriesAttrLang = null; $attachInlineBinary = FALSE; $attachfmttype = null; if( !empty( $attributes )) { $attributes = trim( $attributes ); if ( 'xcal' == $this->format) { $attributes2 = explode( $this->intAttrDelimiter, $attributes ); $attributes = null; foreach( $attributes2 as $attribute ) { $attrKVarr = explode( '=', $attribute ); if( empty( $attrKVarr[0] )) continue; if( !isset( $attrKVarr[1] )) { $attrValue = $attrKVarr[0]; $attrKey = null; } elseif( 2 == count( $attrKVarr)) { $attrKey = strtolower( $attrKVarr[0] ); $attrValue = $attrKVarr[1]; } else { $attrKey = strtolower( $attrKVarr[0] ); unset( $attrKVarr[0] ); $attrValue = implode( '=', $attrKVarr ); } if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) { $attachInlineBinary = TRUE; if( 'fmttype' == $attrKey ) $attachfmttype = $attrKey.'='.$attrValue; continue; } elseif(( 'categories' == $label ) && ( 'language' == $attrKey )) $categoriesAttrLang = $attrKey.'='.$attrValue; else { $attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' '; $attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null; if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) { $attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 )); $attrValue = str_replace( '"', '', $attrValue ); } $attributes .= '"'.htmlspecialchars( $attrValue ).'"'; } } } else { $attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes ); } } if(((( 'attach' == $label ) && !$attachInlineBinary ) || ( in_array( $label, array( 'tzurl', 'url' )))) && ( 'xcal' == $this->format)) { $pos = strrpos($content, "/"); $docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content; $this->xcaldecl[] = array( 'xmldecl' => 'ENTITY' , 'uri' => $docname , 'ref' => 'SYSTEM' , 'external' => $content , 'type' => 'NDATA' , 'type2' => 'BINERY' ); $attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' '; $attributes .= 'uri="'.$docname.'"'; $content = null; if( 'attach' == $label ) { $attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes ); $content = $this->_createElement( 'extref', $attributes, null ); $attributes = null; } } elseif(( 'attach' == $label ) && $attachInlineBinary && ( 'xcal' == $this->format)) { $content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute } $output .= $attributes; if( !$content ) { switch( $this->format ) { case 'xcal': $output .= ' /'; $output .= $this->elementStart2; return $output; break; default: $output .= $this->elementStart2; return $this->_size75( $output ); break; } } $output .= $this->elementStart2; switch( $label ) { case 'categories': // case 'resources': ?? $output .= $this->nl; $items = explode(',', $content); $content = null; foreach( $items as $item ) $content .= $this->_createElement( 'item', $categoriesAttrLang, $item ); // max one attribute break; case 'geo': $output .= $this->nl; list($lat, $lon) = explode(';', $content); $content = null; $content .= $this->_createElement( 'lat', null, $lat ); $content .= $this->_createElement( 'lon', null, $lon ); break; default: break; } $output .= $this->valueInit.$content; switch( $this->format ) { case 'xcal': return $output.$this->elementEnd1.$label.$this->elementEnd2; break; default: return $this->_size75( $output ); break; } } /** * creates formatted output for calendar component property parameters * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-10 * @param array $params optional * @param array $ctrKeys optional * @return string */ function _createParams( $params=array(), $ctrKeys=array() ) { $attrLANG = $attr1 = $attr2 = null; $CNattrKey = ( in_array( 'CN', $ctrKeys )) ? TRUE : FALSE ; $LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ; $CNattrExist = $LANGattrExist = FALSE; if( is_array( $params )) { foreach( $params as $paramKey => $paramValue ) { if( is_int( $paramKey )) $attr2 .= $this->intAttrDelimiter.$paramValue; elseif(( 'LANGUAGE' == $paramKey ) && $LANGattrKey ) { $attrLANG .= $this->intAttrDelimiter."LANGUAGE=$paramValue"; $LANGattrExist = TRUE; } elseif(( 'CN' == $paramKey ) && $CNattrKey ) { $attr1 = $this->intAttrDelimiter.'CN="'.$paramValue.'"'; $CNattrExist = TRUE; } elseif(( 'ALTREP' == $paramKey ) && in_array( $paramKey, $ctrKeys )) $attr2 .= $this->intAttrDelimiter.'ALTREP="'.$paramValue.'"'; elseif(( 'DIR' == $paramKey ) && in_array( $paramKey, $ctrKeys )) $attr2 .= $this->intAttrDelimiter.'DIR="'.$paramValue.'"'; elseif(( 'SENT-BY' == $paramKey ) && in_array( $paramKey, $ctrKeys )) $attr2 .= $this->intAttrDelimiter.'SENT-BY="MAILTO:'.$paramValue.'"'; else $attr2 .= $this->intAttrDelimiter."$paramKey=$paramValue"; } } if( !$LANGattrExist ) { $lang = $this->getConfig( 'language' ); if(( $CNattrExist || $LANGattrKey ) && $lang ) $attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang; } return $attrLANG.$attr1.$attr2; } /** * convert date/datetime to timestamp * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param array $datetime datetime/(date) * @param string $tz timezone * @return timestamp */ function _date2timestamp( $datetime, $tz=null ) { $output = null; if( !isset( $datetime['hour'] )) $datetime['hour'] = '0'; if( !isset( $datetime['min'] )) $datetime['min'] = '0'; if( !isset( $datetime['sec'] )) $datetime['sec'] = '0'; foreach( $datetime as $dkey => $dvalue ) { if( 'tz' != $dkey ) $datetime[$dkey] = (integer) $dvalue; } if( $tz ) $datetime['tz'] = $tz; $offset = 0; if( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] ))) $offset = $this->_tz2offset( $datetime['tz'] ); $output = mktime( $datetime['hour'] , $datetime['min'] , $datetime['sec'] + $offset , $datetime['month'] , $datetime['day'] , $datetime['year'] ); return $output; } /** * ensures internal date-time/date format for input date-time/date in array format * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-15 * @param array $datetime * @param int $parno optional, default FALSE * @return array */ function _date_time_array( $datetime, $parno=FALSE ) { $output = array(); foreach( $datetime as $dateKey => $datePart ) { switch ( $dateKey ) { case '0': case 'year': $output['year'] = $datePart; break; case '1': case 'month': $output['month'] = $datePart; break; case '2': case 'day': $output['day'] = $datePart; break; } if( 3 != $parno ) { switch ( $dateKey ) { case '0': case '1': case '2': break; case '3': case 'hour': $output['hour'] = $datePart; break; case '4': case 'min' : $output['min'] = $datePart; break; case '5': case 'sec' : $output['sec'] = $datePart; break; case '6': case 'tz' : $output['tz'] = $datePart; break; } } } if( 3 != $parno ) { if( !isset( $output['hour'] )) $output['hour'] = 0; if( !isset( $output['min'] )) $output['min'] = 0; if( !isset( $output['sec'] )) $output['sec'] = 0; } return $output; } /** * ensures internal date-time/date format for input date-time/date in string fromat * * @author Kjell-Inge Gustafsson * @since 2.2.3 - 2007-07-29 * @param array $datetime * @param int $parno optional, default FALSE * @return array */ function _date_time_string( $datetime, $parno=FALSE ) { $datetime = (string) trim( $datetime ); $tz = null; $len = strlen( $datetime ) - 1; if( 'Z' == substr( $datetime, -1 )) { $tz = 'Z'; $datetime = trim( substr( $datetime, 0, $len )); } elseif( ( ctype_digit( substr( $datetime, -2, 2 ))) && // time or date ( '-' == substr( $datetime, -3, 1 )) || ( ':' == substr( $datetime, -3, 1 )) || ( '.' == substr( $datetime, -3, 1 ))) { $continue = TRUE; } elseif( ( ctype_digit( substr( $datetime, -4, 4 ))) && // 4 pos offset ( ' +' == substr( $datetime, -6, 2 )) || ( ' -' == substr( $datetime, -6, 2 ))) { $tz = substr( $datetime, -5, 5 ); $datetime = substr( $datetime, 0, ($len - 5)); } elseif( ( ctype_digit( substr( $datetime, -6, 6 ))) && // 6 pos offset ( ' +' == substr( $datetime, -8, 2 )) || ( ' -' == substr( $datetime, -8, 2 ))) { $tz = substr( $datetime, -7, 7 ); $datetime = substr( $datetime, 0, ($len - 7)); } elseif( ( 6 < $len ) && ( ctype_digit( substr( $datetime, -6, 6 )))) { $continue = TRUE; } elseif( 'T' == substr( $datetime, -7, 1 )) { $continue = TRUE; } else { // echo "_date_time_string 1: $datetime tz=$tz.
      \n"; // test ### $cx = $tx = 0; // 19970415T133000 US-Eastern for( $cx = -1; $cx > ( 9 - $len ); $cx-- ) { if(( ' ' == substr( $datetime, $cx, 1 )) || ctype_digit( substr( $datetime, $cx, 1 ))) break; // if exists, tz ends here.. . ? elseif( ctype_alpha( substr( $datetime, $cx, 1 )) || ( in_array( substr( $datetime, $cx, 1 ), array( '-', '/' )))) $tx--; // tz length counter } if( 0 > $tx ) { $tz = substr( $datetime, $tx ); $datetime = trim( substr( $datetime, 0, $len + $tx + 1 )); } } // echo "_date_time_string 1a: $datetime tz=$tz.
      \n"; // test ### if( 0 < substr_count( $datetime, '-' )) { $datetime = str_replace( '-', '/', $datetime ); // echo "_date_time_string 1b: $datetime tz=$tz.
      \n"; // test ### } elseif( ctype_digit( substr( $datetime, 0, 8 )) && ( 'T' == substr( $datetime, 8, 1 )) && ctype_digit( substr( $datetime, 9, 6 ))) $datetime = substr( $datetime, 0, 8 ).substr( $datetime, 9 ); $datestring = date( 'Y-m-d H:i:s', strtotime( $datetime )); // echo "_date_time_string 2: $datestring tz=$tz.
      \n"; // test ### $tz = trim( $tz ); $output = array(); $output['year'] = substr( $datestring, 0, 4 ); $output['month'] = substr( $datestring, 5, 2 ); $output['day'] = substr( $datestring, 8, 2 ); if(( 6 == $parno ) || ( 7 == $parno )) { $output['hour'] = substr( $datestring, 11, 2 ); $output['min'] = substr( $datestring, 14, 2 ); $output['sec'] = substr( $datestring, 17, 2 ); if( !empty( $tz )) $output['tz'] = $tz; } elseif( 3 != $parno ) { if(( '00' < substr( $datestring, 11, 2 )) || ( '00' < substr( $datestring, 14, 2 )) || ( '00' < substr( $datestring, 17, 2 ))) { $output['hour'] = substr( $datestring, 11, 2 ); $output['min'] = substr( $datestring, 14, 2 ); $output['sec'] = substr( $datestring, 17, 2 ); } if( !empty( $tz )) $output['tz'] = $tz; } return $output; } /** * ensures internal duration format for input in array format * * @author Kjell-Inge Gustafsson * @since 2.1.1 - 2007-06-24 * @param array $duration * @return array */ function _duration_array( $duration ) { $output = array(); if( is_array( $duration ) && ( 1 == count( $duration )) && isset( $duration['sec'] ) && ( 60 < $duration['sec'] )) { $durseconds = $duration['sec']; $output['week'] = floor( $durseconds / ( 60 * 60 * 24 * 7 )); $durseconds = $durseconds % ( 60 * 60 * 24 * 7 ); $output['day'] = floor( $durseconds / ( 60 * 60 * 24 )); $durseconds = $durseconds % ( 60 * 60 * 24 ); $output['hour'] = floor( $durseconds / ( 60 * 60 )); $durseconds = $durseconds % ( 60 * 60 ); $output['min'] = floor( $durseconds / ( 60 )); $output['sec'] = ( $durseconds % ( 60 )); } else { foreach( $duration as $durKey => $durValue ) { switch ( $durKey ) { case '0': case 'week': $output['week'] = $durValue; break; case '1': case 'day': $output['day'] = $durValue; break; case '2': case 'hour': $output['hour'] = $durValue; break; case '3': case 'min': $output['min'] = $durValue; break; case '4': case 'sec': $output['sec'] = $durValue; break; } } } if( isset( $output['week'] ) && ( 0 < $output['week'] )) return $output; elseif (( isset( $output['hour'] ) && ( 0 < $output['hour'] )) || ( isset( $output['min'] ) && ( 0 < $output['min'] )) || (isset( $output['sec'] ) && ( 0 < $output['sec'] ))) { if( !isset( $output['hour'] )) $output['hour'] = 0; if( !isset( $output['min'] )) $output['min'] = 0; if( !isset( $output['sec'] )) $output['sec'] = 0; } return $output; } /** * convert duration to date in array format based on dtstart value * * @author Kjell-Inge Gustafsson * @since 2.1.1 - 2007-06-24 * @return array */ function duration2date() { if( !isset( $this->dtstart['value'] ) || !isset( $this->duration['value'] )) return null; $d1 = $this->dtstart['value']; $dur = $this->duration['value']; $d1['hour'] = ( isset( $d1['hour'] )) ? $d1['hour'] : 0; $d1['min'] = ( isset( $d1['min'] )) ? $d1['min'] : 0; $d1['sec'] = ( isset( $d1['sec'] )) ? $d1['sec'] : 0; $dtend = mktime ( $d1['hour'] , $d1['min'] , $d1['sec'] , $d1['month'] , $d1['day'] , $d1['year'] ); if( isset( $dur['week'] )) $dtend += ( $dur['week'] * 7 * 24 * 60 * 60 ); if( isset( $dur['day'] )) $dtend += ( $dur['day'] * 24 * 60 * 60 ); if( isset( $dur['hour'] )) $dtend += ( $dur['hour'] * 60 *60 ); if( isset( $dur['min'] )) $dtend += ( $dur['min'] * 60 ); if( isset( $dur['sec'] )) $dtend += $dur['sec']; $dtend2 = array(); $dtend2['year'] = date('Y', $dtend ); $dtend2['month'] = date('m', $dtend ); $dtend2['day'] = date('d', $dtend ); $dtend2['hour'] = date('H', $dtend ); $dtend2['min'] = date('i', $dtend ); $dtend2['sec'] = date('s', $dtend ); if( isset( $d1['tz'] )) $dtend2['tz'] = $d1['tz']; return $dtend2; } /** * ensures internal duration format for input in string format * * @author Kjell-Inge Gustafsson * @since 2.0.5 - 2007-03-14 * @param string $duration * @return array */ function _duration_string( $duration ) { $duration = (string) trim( $duration ); while( 'P' != strtoupper( substr( $duration, 0, 1 ))) { if( 0 < strlen( $duration )) $duration = substr( $duration, 1 ); else return false; // no leading P !?!? } $duration = substr( $duration, 1 ); // skip P $duration = str_replace ( 't', 'T', $duration ); $duration = str_replace ( 'T', '', $duration ); $output = array(); $val = null; for( $ix=0; $ix < strlen( $duration ); $ix++ ) { switch( strtoupper( $duration{$ix} )) { case 'W': $output['week'] = $val; $val = null; break; case 'D': $output['day'] = $val; $val = null; break; case 'H': $output['hour'] = $val; $val = null; break; case 'M': $output['min'] = $val; $val = null; break; case 'S': $output['sec'] = $val; $val = null; break; default: if( !ctype_digit( $duration{$ix} )) return false; // unknown duration controll character !?!? else $val .= $duration{$ix}; } } return $this->_duration_array( $output ); } /** * if exist, remove key with expected value from array and return spec. value * * @author Kjell-Inge Gustafsson * @since 0.9.19 - 2007-03-18 * @param array $array * @param string $expkey * @param string $expval * @param int $hitval optional * @return int */ function _existRem( &$array, $expkey, $expval=FALSE, $hitval=null ) { if( !is_array( $array ) || ( 0 == count( $array ))) return null; if( !isset( $array[$expkey] )) return null; if( !$expval ) return $hitval; if( $expval != $array[$expkey] ) return null; unset( $array[$expkey] ); return $hitval; } /** * creates formatted output for calendar component property data value type date/date-time * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param array $datetime * @param int $parno, optional, default 6 * @return string */ function _format_date_time( $datetime, $parno=6 ) { if( !isset( $datetime['year'] ) && !isset( $datetime['month'] ) && !isset( $datetime['day'] ) && !isset( $datetime['hour'] ) && !isset( $datetime['min'] ) && !isset( $datetime['sec'] )) return ; $output = null; $output = date('Ymd', mktime ( 0, 0, 0 , (integer) $datetime['month'] , (integer) $datetime['day'] , (integer) $datetime['year'])); if( isset( $datetime['hour'] ) || isset( $datetime['min'] ) || isset( $datetime['sec'] ) || isset( $datetime['tz'] )) { if( isset( $datetime['tz'] ) && !isset( $datetime['hour'] )) $datetime['hour'] = '0'; if( isset( $datetime['hour'] ) && !isset( $datetime['min'] )) $datetime['min'] = '0'; if( isset( $datetime['hour'] ) && isset( $datetime['min'] ) && !isset( $datetime['sec'] )) $datetime['sec'] = '0'; foreach( $datetime as $dkey => $dvalue ) { if( 'tz' != $dkey ) $datetime[$dkey] = (integer) $dvalue; } $output .= date('\THis', mktime ( $datetime['hour'] , $datetime['min'] , $datetime['sec'] , $datetime['month'] , $datetime['day'] , $datetime['year'])); if( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] ))) { $datetime['tz'] = trim( $datetime['tz'] ); if( 'Z' == $datetime['tz'] ) $output .= 'Z'; $offset = 0; $offset = $this->_tz2offset( $datetime['tz'] ); if( 0 != $offset ) { $output = date('Ymd\THis\Z', mktime ( $datetime['hour'] , $datetime['min'] , $datetime['sec'] + $offset , $datetime['month'] , $datetime['day'] , $datetime['year'])); } } elseif( 7 == $parno ) $output .= 'Z'; } return $output; } /** * creates formatted output for calendar component property data value type duration * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-13 * @param array $duration ( week, day, hour, min, sec ) * @return string */ function _format_duration( $duration ) { if( !isset( $duration['week'] ) && !isset( $duration['day'] ) && !isset( $duration['hour'] ) && !isset( $duration['min'] ) && !isset( $duration['sec'] )) return; $output = 'P'; if( isset( $duration['week'] ) && ( 0 < $duration['week'] )) $output .= $duration['week'].'W'; else { if( isset($duration['day'] ) && ( 0 < $duration['day'] )) $output .= $duration['day'].'D'; if(( isset( $duration['hour']) && ( 0 < $duration['hour'] )) || ( isset( $duration['min']) && ( 0 < $duration['min'] )) || ( isset( $duration['sec']) && ( 0 < $duration['sec'] ))) { $output .= 'T'; if( 0 < $duration['hour'] ) { $output .= $duration['hour'].'H'; if( 0 < $duration['min'] ) { $output .= $duration['min'].'M'; if( 0 < $duration['sec'] ) $output .= $duration['sec'].'S'; } elseif( 0 < $duration['sec'] ) $output .= '0M'.$duration['sec'].'S'; } elseif( 0 < $duration['min'] ) { $output .= '0H'.$duration['min'].'M'; if( 0 < $duration['sec'] ) $output .= $duration['sec'].'S'; } elseif( 0 < $duration['sec'] ) $output .= '0H0M'.$duration['sec'].'S'; } } return $output; } /** * creates formatted output for calendar component property data value type recur * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @param array $recurlabel * @param array $recurdata * @return string */ function _format_recur ( $recurlabel, $recurdata ) { $recur = null; foreach( $recurdata as $therule ) { $attributes = ( isset( $therule['params'] )) ? $this->_createParams( $therule['params'] ) : null; $content1 = $content2 = null; foreach( $therule['value'] as $rulelabel => $rulevalue ) { switch( $rulelabel ) { case 'FREQ': { $content1 .= "FREQ=$rulevalue"; break; } case 'UNTIL': { $content2 .= ";UNTIL="; $content2 .= $this->_format_date_time( $rulevalue ); break; } case 'COUNT': case 'INTERVAL': case 'WKST': { $content2 .= ";$rulelabel=$rulevalue"; break; } case 'BYSECOND': case 'BYMINUTE': case 'BYHOUR': case 'BYMONTHDAY': case 'BYYEARDAY': case 'BYWEEKNO': case 'BYMONTH': case 'BYSETPOS': { $content2 .= ";$rulelabel="; if( is_array( $rulevalue )) { foreach( $rulevalue as $vix => $valuePart ) { $content2 .= ( $vix ) ? ',' : null; $content2 .= $valuePart; } } else $content2 .= $rulevalue; break; } case 'BYDAY': { $content2 .= ";$rulelabel="; $bydaycnt = 0; foreach( $rulevalue as $vix => $valuePart ) { $content21 = $content22 = null; if( is_array( $valuePart )) { $content2 .= ( $bydaycnt ) ? ',' : null; foreach( $valuePart as $vix2 => $valuePart2 ) { if( 'DAY' != strtoupper( $vix2 )) $content21 .= $valuePart2; else $content22 .= $valuePart2; } $content2 .= $content21.$content22; $bydaycnt++; } else { $content2 .= ( $bydaycnt ) ? ',' : null; if( 'DAY' != strtoupper( $vix )) $content21 .= $valuePart; else { $content22 .= $valuePart; $bydaycnt++; } $content2 .= $content21.$content22; } } break; } default: { $content2 .= ";$rulelabel=$rulevalue"; break; } } } $recur .= $this->_createElement( $recurlabel, $attributes, $content1.$content2 ); } return $recur; } /** * create property name case - lower/upper * * @author Kjell-Inge Gustafsson * @since 0.9.7 - 2006-11-20 * @param string $propertyName * @return string */ function _formatPropertyName( $propertyName ) { switch( $this->format ) { case 'xcal': return strtolower( $propertyName ); break; default: return strtoupper( $propertyName ); break; } } /** * convert format for input date to internal date with parameters * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-01 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return array */ function _setDate( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { $input = $parno = null; if( is_array( $year ) && ( in_array( count( $year ), array( 3, 4, 6, 7 )))) { $input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); if( isset( $input['params']['TZID'] )) $year['tz'] = $input['params']['TZID']; $hitval = ( !empty( $year['tz'] ) || !empty( $year[6] ) || ( 4 == count( $year ))) ? 7 : 6; $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval ); if( !isset( $parno )) $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ); if( !isset( $parno )) $parno = count( $year ); $input['value'] = $this->_date_time_array( $year, $parno ); } elseif( is_array( $year ) && isset( $year['timestamp'] )) { $input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); if( isset( $input['params']['TZID'] )) $year['tz'] = $input['params']['TZID']; $tz = ( isset( $year['tz'] )) ? ' '.$year['tz'] : null; $hitval = ( !empty( $tz )) ? 7 : 6; $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval ); if( !isset( $parno )) $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ); if( !isset( $parno )) $parno = $hitval; $input['value'] = $this->_date_time_string( date('Y-m-d H:i:s',$year['timestamp']).$tz,$parno ); } elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 $input['params'] = $this->_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7 ); if( !isset( $parno )) $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ); $input['value'] = $this->_date_time_string( $year, $parno ); if( isset( $input['params']['TZID'] )) $input['value']['tz'] = $input['params']['TZID']; } else { $input['params'] = $this->_setParams( $params, array( 'VALUE' => 'DATE-TIME' )); if( isset( $input['params']['TZID'] )) $tz = $input['params']['TZID']; $hitval = ( !empty( $tz )) ? 7 : null; $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval ); if( !isset( $parno )) $parno = $this->_existRem( $input['params'], 'VALUE', 'DATE', 3 ); $input['value'] = array( 'year' => $year, 'month' => $month, 'day' => $day ); if( 3 != $parno ) { $input['value']['hour'] = ( $hour ) ? $hour : '0'; $input['value']['min'] = ( $min ) ? $min : '0'; $input['value']['sec'] = ( $sec ) ? $sec : '0'; if( !empty( $tz )) $input['value']['tz'] = $tz; } } if( 3 == $parno ) { $input['params']['VALUE'] = 'DATE'; unset( $input['value']['tz'] ); unset( $input['params']['TZID'] ); } if( isset( $input['value']['tz'] )) $input['value']['tz'] = (string) $input['value']['tz']; if( !empty( $input['value']['tz'] ) && ( $input['value']['tz'] != 'Z' ) && ( !( in_array($input['value']['tz']{0}, array( '+', '-' )) && ctype_digit( substr( $input['value']['tz'], 1 ))) && !ctype_digit( $input['value']['tz'] ) ) ) { $input['params']['TZID'] = $input['value']['tz']; unset( $input['value']['tz'] ); } elseif( isset( $input['params']['TZID'] )) unset( $input['params']['TZID'] ); return $input; } /** * convert format for input date (UTC) to internal date with parameters * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-08-02 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return array */ function _setDate2( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { $input = null; if( is_array( $year ) && (( 6 == count( $year )) || ( array_key_exists( 'year', $year )))) { $input['value'] = $this->_date_time_array( $year, 7 ); $input['params'] = $this->_setParams( $month ); } elseif( is_array( $year ) && isset( $year['timestamp'] )) { $input['value'] = $this->_date_time_string( date( 'Y-m-d H:i:s', $year['timestamp'] ), 7 ); $input['params'] = $this->_setParams( $month ); } elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 $input['value'] = $this->_date_time_string( $year, 7 ); $input['params'] = $this->_setParams( $month ); } else { $input['value'] = array( 'year' => $year , 'month' => $month , 'day' => $day , 'hour' => $hour , 'min' => $min , 'sec' => $sec ); $input['params'] = $this->_setParams( $params ); } if( !isset( $input['value']['hour'] )) $input['value']['hour'] = 0; if( !isset( $input['value']['min'] )) $input['value']['min'] = 0; if( !isset( $input['value']['sec'] )) $input['value']['sec'] = 0; $input['value']['tz'] = 'Z'; return $input; } /** * set input (formatted) parameters- component property attributes * * default parameters can be set, if missing * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-05-01 * @param array $params * @param array $defaults * @return array */ function _setParams( $params, $defaults=FALSE ) { if( !is_array( $params)) $params = array(); $input = array(); foreach( $params as $paramKey => $paramValue ) { if( is_array( $paramValue )) { foreach( $paramValue as $pkey => $pValue ) { if(( '"' == substr( $pValue, 0, 1 )) && ( '"' == substr( $pValue, -1 ))) $paramValue[$pkey] = substr( $pValue, 1, ( strlen( $pValue ) - 2 )); } } elseif(( '"' == substr( $paramValue, 0, 1 )) && ( '"' == substr( $paramValue, -1 ))) $paramValue = substr( $paramValue, 1, ( strlen( $paramValue ) - 2 )); if( 'VALUE' == strtoupper( $paramKey )) $input['VALUE'] = strtoupper( $paramValue ); else $input[strtoupper( $paramKey )] = $paramValue; } if( is_array( $defaults )) { foreach( $defaults as $paramKey => $paramValue ) { if( !isset( $input[$paramKey] )) $input[$paramKey] = $paramValue; } } return (0 < count( $input )) ? $input : null; } /** * convert (numeric) tz to offset seconds * * @author Kjell-Inge Gustafsson * @since 2.2.2 - 2007-07-29 * @param string $offset * @return integer */ function _tz2offset( $tz ) { $tz = trim( (string) $tz ); $offset = 0; if(( 5 == strlen( $tz )) && ( '0000' <= substr( $tz, -4 )) && ( '9999' >= substr( $tz, -4 )) && (( '+' == substr( $tz, 0, 1 )) || ( '-' == substr( $tz, 0, 1 )))) { $hours2sec = substr( $tz, 1, 2 ) * 3600; $min2sec = substr( $tz, -2 ) * 60; $sign = substr( $tz, 0, 1 ); $offset = (int) ( $sign.'1' * ($hours2sec + $min2sec )); } elseif(( 7 == strlen( $tz )) && ( '000000' <= substr( $tz, -6 )) && ( '999999' >= substr( $tz, -6 )) && (( '+' == substr( $tz, 0, 1 )) || ( '-' == substr( $tz, 0, 1 )))) { $hours2sec = substr( $tz, 1, 2 ) * 3600; $min2sec = substr( $tz, 3, 2 ) * 60; $sec = substr( $tz, -2 ); $sign = substr( $tz, 0, 1 ); $offset = (int) ( $sign.'1' * ( $hours2sec + $min2sec + $sec )); } return $offset; } /*********************************************************************************/ /*********************************************************************************/ /** * get general component config variables or info about subcomponents * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-21 * @param string $config * @return value */ function getConfig( $config ) { switch( strtoupper( $config )) { case 'COMPSINFO': unset( $this->compix ); $info = array(); foreach( $this->components as $cix => $component ) { unset( $component->propix ); $info[$cix]['ordno'] = $cix + 1; $info[$cix]['type'] = $component->objName; $info[$cix]['uid'] = $component->getProperty( 'uid' ); $info[$cix]['props'] = $component->getConfig( 'propinfo' ); $info[$cix]['sub'] = $component->getConfig( 'compsinfo' ); } return $info; break; case 'FORMAT': return $this->format; break; case 'LANGUAGE': // get language for calendar component as defined in [RFC 1766] return $this->language; break; case 'NL': return $this->nl; break; case 'PROPINFO': $output = array(); if( 0 < count( $this->action )) $output['ACTION'] = count( $this->action ) / 2; if( 0 < count( $this->attach )) $output['ATTACH'] = count( $this->attach ); if( 0 < count( $this->attendee )) $output['ATTENDEE'] = count( $this->attendee ); if( 0 < count( $this->categories )) $output['CATEGORIES'] = count( $this->categories ); if( 0 < count( $this->class )) $output['CLASS'] = count( $this->class ) / 2; if( 0 < count( $this->comment )) $output['COMMENT'] = count( $this->comment ); if( 0 < count( $this->completed )) $output['COMPLETED'] = count( $this->completed ) / 2; if( 0 < count( $this->contact )) $output['CONTACT'] = count( $this->contact ); if( 0 < count( $this->created )) $output['CREATED'] = count( $this->created ) / 2; if( 0 < count( $this->description )) $output['DESCRIPTION'] = count( $this->description ); if( 0 < count( $this->dtend )) $output['DTEND'] = count( $this->dtend ) / 2; if( 0 < count( $this->dtstart )) $output['DTSTART'] = count( $this->dtstart ) / 2; if( 0 < count( $this->dtstamp )) $output['DTSTAMP'] = count( $this->dtstamp ) / 2; if( 0 < count( $this->due )) $output['DUE'] = count( $this->due ) / 2; if( 0 < count( $this->duration )) $output['DURATION'] = count( $this->duration ) / 2; if( 0 < count( $this->exdate )) $output['EXDATE'] = count( $this->exdate ); if( 0 < count( $this->exrule )) $output['EXRULE'] = count( $this->exrule ); if( 0 < count( $this->freebusy )) $output['FREEBUSY'] = count( $this->freebusy ); if( 0 < count( $this->geo )) $output['GEO'] = count( $this->geo ) / 2; if( 0 < count( $this->lastmodified )) $output['LAST-MODIFIED'] = count( $this->lastmodified ) / 2; if( 0 < count( $this->location )) $output['LOCATION'] = count( $this->location ) / 2; if( 0 < count( $this->organizer )) $output['ORGANIZER'] = count( $this->organizer ) / 2; if( 0 < count( $this->percentcomplete )) $output['PERCENT-COMPLETE'] = count( $this->percentcomplete ) / 2; if( 0 < count( $this->priority )) $output['PRIORITY'] = count( $this->priority ) / 2; if( 0 < count( $this->rdate )) $output['RDATE'] = count( $this->rdate ); if( 0 < count( $this->recurrenceid )) $output['RECURRENCE-ID'] = count( $this->recurrenceid ) / 2; if( 0 < count( $this->relatedto )) $output['RELATED-TO'] = count( $this->relatedto ); if( 0 < count( $this->repeat )) $output['REPEAT'] = count( $this->repeat ) / 2; if( 0 < count( $this->requeststatus )) $output['REQUEST-STATUS'] = count( $this->requeststatus ); if( 0 < count( $this->resources )) $output['RESOURCES'] = count( $this->resources ); if( 0 < count( $this->sequence )) $output['SEQUENCE'] = count( $this->sequence ) / 2; if( 0 < count( $this->rrule )) $output['RRULE'] = count( $this->rrule ); if( 0 < count( $this->status )) $output['STATUS'] = count( $this->status ) / 2; if( 0 < count( $this->summary )) $output['SUMMARY'] = count( $this->summary ) / 2; if( 0 < count( $this->transp )) $output['TRANSP'] = count( $this->transp ) / 2; if( 0 < count( $this->trigger )) $output['TRIGGER'] = count( $this->trigger ) / 2; if( 0 < count( $this->tzid )) $output['TZID'] = count( $this->tzid ) / 2; if( 0 < count( $this->tzname )) $output['TZNAME'] = count( $this->tzname ); if( 0 < count( $this->tzoffsetfrom )) $output['TZOFFSETTFROM'] = count( $this->tzoffsetfrom ) / 2; if( 0 < count( $this->tzoffsetto )) $output['TZOFFSETTO'] = count( $this->tzoffsetto ) / 2; if( 0 < count( $this->tzurl )) $output['TZURL'] = count( $this->tzurl ) / 2; if( !in_array( $this->objName, array( 'valarm', 'vtimezone' ))) { if( empty( $this->uid['value'] )) $this->_makeuid(); $output['UID'] = 1; } if( 0 < count( $this->url )) $output['URL'] = count( $this->url ) / 2; if( 0 < count( $this->xprop )) $output['X-PROP'] = count( $this->xprop ); return $output; break; case 'UNIQUE_ID': if( empty( $this->unique_id )) $this->unique_id = gethostbyname( $_SERVER['SERVER_NAME'] ); return $this->unique_id; break; } } /** * general component config setting * * @author Kjell-Inge Gustafsson * @since 2.0.3 - 2007-06-14 * @param string $config * @param string $value * @return void */ function setConfig( $config, $value ) { switch( strtoupper( $config )) { case 'FORMAT': $value = trim( $value ); $this->format = $value; break; case 'LANGUAGE': // set language for calendar component as defined in [RFC 1766] $value = trim( $value ); $this->language = $value; break; case 'NL': $this->nl = $value; break; case 'UNIQUE_ID': $value = trim( $value ); $this->unique_id = $value; break; } } /*********************************************************************************/ /** * delete component property value * * @author Kjell-Inge Gustafsson * @since 2.1.2 - 2007-07-07 * @param string $propName * @param int @propix, optional, if specific property is wanted in case of multiply occurences * @return bool, if successfull delete TRUE */ function deleteProperty( $propName, $propix=FALSE ) { $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; if( !$propix ) $propix = ( isset( $this->propdelix[$propName] )) ? $this->propdelix[$propName] + 2 : 1; $this->propdelix[$propName] = --$propix; $return = FALSE; switch( $propName ) { case 'ACTION': if(( 0 < $propix ) || !isset( $this->action['value'] )) return FALSE; $this->action = array(); return TRUE; break; case 'ATTACH': if( count( $this->attach ) <= $propix ) return FALSE; $this->attach[$propix] = null; return TRUE; break; case 'ATTENDEE': if( count( $this->attendee ) <= $propix ) return FALSE; $this->attendee[$propix] = null; return TRUE; break; case 'CATEGORIES': if( !isset( $this->categories[$propix])) return FALSE; $this->categories[$propix] = null; return TRUE; break; case 'CLASS': if(( 0 < $propix ) || !isset( $this->class['value'] )) return FALSE; $this->class = array(); return TRUE; break; case 'COMMENT': if( !isset( $this->comment[$propix])) return FALSE; $this->comment[$propix] = null; return TRUE; break; case 'COMPLETED': if(( 0 < $propix ) || !isset( $this->completed['value'] )) return FALSE; $this->completed = array(); return TRUE; break; case 'CONTACT': if( !isset( $this->contact[$propix])) return FALSE; $this->contact[$propix] = null; return TRUE; break; case 'CREATED': if(( 0 < $propix ) || !isset( $this->created['value'] )) return FALSE; $this->created = array(); return TRUE; break; case 'DESCRIPTION': if( !isset( $this->description[$propix])) return FALSE; $this->description[$propix] = null; return TRUE; break; case 'DTEND': if(( 0 < $propix ) || !isset( $this->dtend['value'] )) return FALSE; $this->dtend = array(); return TRUE; break; case 'DTSTAMP': if( in_array( $this->objName, array( 'valarm', 'vtimezone' ))) return FALSE; if(( 0 < $propix ) || !isset( $this->dtstamp['value'] )) return FALSE; $this->dtstamp = array(); return TRUE; break; case 'DTSTART': if(( 0 < $propix ) || !isset( $this->dtstart['value'] )) return FALSE; $this->dtstart = array(); return TRUE; break; case 'DUE': if(( 0 < $propix ) || !isset( $this->due['value'] )) return FALSE; $this->due = array(); return TRUE; break; case 'DURATION': if(( 0 < $propix ) || !isset( $this->duration['value'] )) return FALSE; $this->duration = array(); return TRUE; break; case 'EXDATE': if( !isset( $this->exdate[$propix])) return FALSE; $this->exdate[$propix] = null; return TRUE; break; case 'EXRULE': if( !isset( $this->exrule[$propix])) return FALSE; $this->exrule[$propix]['value']; return TRUE; break; case 'FREEBUSY': if( !isset( $this->freebusy[$propix])) return FALSE; $this->freebusy[$propix] = null; return TRUE; break; case 'GEO': if(( 0 < $propix ) || !isset( $this->geo['value'] )) return FALSE; $this->geo = array(); return TRUE; break; case 'LAST-MODIFIED': if(( 0 < $propix ) || !isset( $this->lastmodified['value'] )) return FALSE; $this->lastmodified = array(); return TRUE; break; case 'LOCATION': if(( 0 < $propix ) || !isset( $this->location['value'] )) return FALSE; $this->location = array(); return TRUE; break; case 'ORGANIZER': if(( 0 < $propix ) || !isset( $this->organizer['value'] )) return FALSE; $this->organizer = array(); return TRUE; break; case 'PERCENT-COMPLETE': if(( 0 < $propix ) || !isset( $this->percentcomplete['value'] )) return FALSE; $this->percentcomplete = array(); return TRUE; break; case 'PRIORITY': if(( 0 < $propix ) || !isset( $this->priority['value'] )) return FALSE; $this->priority = array(); return TRUE; break; case 'RDATE': if( !isset( $this->rdate[$propix])) return FALSE; $this->rdate[$propix] = null; return TRUE; break; case 'RECURRENCE-ID': if(( 0 < $propix ) || !isset( $this->recurrenceid['value'] )) return FALSE; $this->recurrenceid = array(); return TRUE; break; case 'RELATED-TO': if( !isset( $this->relatedto[$propix])) return FALSE; $this->relatedto[$propix] = null; return TRUE; break; case 'REPEAT': if(( 0 < $propix ) || !isset( $this->repeat['value'] )) return FALSE; $this->repeat = array(); return TRUE; break; case 'REQUEST-STATUS': if( !isset( $this->requeststatus[$propix])) return FALSE; $this->requeststatus[$propix] = null; return TRUE; break; case 'RESOURCES': if( !isset( $this->resources[$propix])) return FALSE; $this->resources[$propix] = null; return TRUE; break; case 'RRULE': if( !isset( $this->rrule[$propix])) return FALSE; $this->rrule[$propix] = null; return TRUE; break; case 'SEQUENCE': if(( 0 < $propix ) || !isset( $this->sequence['value'] )) return FALSE; $this->sequence = array(); return TRUE; break; case 'STATUS': if(( 0 < $propix ) || !isset( $this->status['value'] )) return FALSE; $this->status = array(); return TRUE; break; case 'SUMMARY': if(( 0 < $propix ) || !isset( $this->summary['value'] )) return FALSE; $this->summary = array(); return TRUE; break; case 'TRANSP': if(( 0 < $propix ) || !isset( $this->transp['value'] )) return FALSE; $this->transp = array(); return TRUE; break; case 'TRIGGER': if(( 0 < $propix ) || !isset( $this->trigger['value'] )) return FALSE; $this->trigger = array(); return TRUE; break; case 'TZID': if(( 0 < $propix ) || !isset( $this->tzid['value'] )) return FALSE; $this->tzid = array(); return TRUE; break; case 'TZNAME': if( !isset( $this->tzname[$propix])) return FALSE; $this->tzname[$propix] = null; return TRUE; break; case 'TZOFFSETFROM': if(( 0 < $propix ) || !isset( $this->tzoffsetfrom['value'] )) return FALSE; $this->tzoffsetfrom = array(); return TRUE; break; case 'TZOFFSETTO': if(( 0 < $propix ) || !isset( $this->tzoffsetto['value'] )) return FALSE; $this->tzoffsetto = array(); return TRUE; break; case 'TZURL': if(( 0 < $propix ) || !isset( $this->tzurl['value'] )) return FALSE; $this->tzurl = array(); return TRUE; break; case 'UID': if( in_array( $this->objName, array( 'valarm', 'vtimezone' ))) return FALSE; if(( 0 < $propix ) || !isset( $this->uid['value'] )) return FALSE; $this->uid = array(); return TRUE; break; case 'URL': if(( 0 < $propix ) || !isset( $this->url['value'] )) return FALSE; $this->url = array(); return TRUE; break; default: if( $propName != 'X-PROP' ) { if( !isset( $this->xprop[$propName] )) return FALSE; $this->xprop[$propName] = null; return TRUE; } else { if( count( $this->xprop ) <= $propix ) return FALSE; $xpropno = 0; foreach( $this->xprop as $xpropkey => $xpropvalue ) { if( $propix == $xpropno ) { $this->xprop[$xpropkey] = null; $return = TRUE; break 2; } else $xpropno++; } } } return $return; } /** * get component property value/params * * if property has multiply values, consequtive function calls are needed * * @author Kjell-Inge Gustafsson * @since 2.1.1 - 2007-07-07 * @param string $propName, optional * @param int @propix, optional, if specific property is wanted in case of multiply occurences * @param bool $inclParam=FALSE * @param bool $specform=FALSE * @return mixed */ function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE, $specform=FALSE ) { $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; if( !$propix ) $propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1; $this->propix[$propName] = --$propix; switch( $propName ) { case 'ACTION': if(( 0 < $propix ) || !isset( $this->action['value'] )) return FALSE; return ( $inclParam ) ? $this->action : $this->action['value']; break; case 'ATTACH': if( count( $this->attach ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->attach[$propix] : $this->attach[$propix]['value']; break; case 'ATTENDEE': if( count( $this->attendee ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->attendee[$propix] : $this->attendee[$propix]['value']; break; case 'CATEGORIES': if( count( $this->categories ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->categories[$propix] : $this->categories[$propix]['value']; break; case 'CLASS': if(( 0 < $propix ) || !isset( $this->class['value'] )) return FALSE; return ( $inclParam ) ? $this->class : $this->class['value']; break; case 'COMMENT': if( count( $this->comment ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->comment[$propix] : $this->comment[$propix]['value']; break; case 'COMPLETED': if(( 0 < $propix ) || !isset( $this->completed['value'] )) return FALSE; return ( $inclParam ) ? $this->completed : $this->completed['value']; break; case 'CONTACT': if( count( $this->contact ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->contact[$propix] : $this->contact[$propix]['value']; break; case 'CREATED': if(( 0 < $propix ) || !isset( $this->created['value'] )) return FALSE; return ( $inclParam ) ? $this->created : $this->created['value']; break; case 'DESCRIPTION': if( count( $this->description ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->description[$propix] : $this->description[$propix]['value']; break; case 'DTEND': if(( 0 < $propix ) || !isset( $this->dtend['value'] )) return FALSE; return ( $inclParam ) ? $this->dtend : $this->dtend['value']; break; case 'DTSTAMP': if( in_array( $this->objName, array( 'valarm', 'vtimezone' ))) return; if( 0 < $propix ) return null; if( !isset( $this->dtstamp['value'] )) $this->_makeDtstamp(); return ( $inclParam ) ? $this->dtstamp : $this->dtstamp['value']; break; case 'DTSTART': if(( 0 < $propix ) || !isset( $this->dtstart['value'] )) return FALSE; return ( $inclParam ) ? $this->dtstart : $this->dtstart['value']; break; case 'DUE': if(( 0 < $propix ) || !isset( $this->due['value'] )) return FALSE; return ( $inclParam ) ? $this->due : $this->due['value']; break; case 'DURATION': if(( 0 < $propix ) || !isset( $this->duration['value'] )) return FALSE; $value = ( $specform ) ? $this->duration2date() : $this->duration['value']; return ( $inclParam ) ? array( 'value' => $value, 'params' => $this->duration['params'] ) : $value; break; case 'EXDATE': if( count( $this->exdate ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->exdate[$propix] : $this->exdate[$propix]['value']; break; case 'EXRULE': if( count( $this->exrule ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->exrule[$propix] : $this->exrule[$propix]['value']; break; case 'FREEBUSY': if( count( $this->freebusy ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->freebusy[$propix] : $this->freebusy[$propix]['value']; break; case 'GEO': if(( 0 < $propix ) || !isset( $this->geo['value'] )) return FALSE; return ( $inclParam ) ? $this->geo : $this->geo['value']; break; case 'LAST-MODIFIED': if(( 0 < $propix ) || !isset( $this->lastmodified['value'] )) return FALSE; return ( $inclParam ) ? $this->lastmodified : $this->lastmodified['value']; break; case 'LOCATION': if(( 0 < $propix ) || !isset( $this->location['value'] )) return FALSE; return ( $inclParam ) ? $this->location : $this->location['value']; break; case 'ORGANIZER': if(( 0 < $propix ) || !isset( $this->organizer['value'] )) return FALSE; return ( $inclParam ) ? $this->organizer : $this->organizer['value']; break; case 'PERCENT-COMPLETE': if(( 0 < $propix ) || !isset( $this->percentcomplete['value'] )) return FALSE; return ( $inclParam ) ? $this->percentcomplete : $this->percentcomplete['value']; break; case 'PRIORITY': if(( 0 < $propix ) || !isset( $this->priority['value'] )) return FALSE; return ( $inclParam ) ? $this->priority : $this->priority['value']; break; case 'RDATE': if( count( $this->rdate ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->rdate[$propix] : $this->rdate[$propix]['value']; break; case 'RECURRENCE-ID': if(( 0 < $propix ) || !isset( $this->recurrenceid['value'] )) return FALSE; return ( $inclParam ) ? $this->recurrenceid : $this->recurrenceid['value']; break; case 'RELATED-TO': if( count( $this->relatedto ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->relatedto[$propix] : $this->relatedto[$propix]['value']; break; case 'REPEAT': if(( 0 < $propix ) || !isset( $this->repeat['value'] )) return FALSE; return ( $inclParam ) ? $this->repeat : $this->repeat['value']; break; case 'REQUEST-STATUS': if( count( $this->requeststatus ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->requeststatus[$propix] : $this->requeststatus[$propix]['value']; break; case 'RESOURCES': if( count( $this->resources ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->resources[$propix] : $this->resources[$propix]['value']; break; case 'RRULE': if( count( $this->rrule ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->rrule[$propix] : $this->rrule[$propix]['value']; break; case 'SEQUENCE': if(( 0 < $propix ) || !isset( $this->sequence['value'] )) return FALSE; return ( $inclParam ) ? $this->sequence : $this->sequence['value']; break; case 'STATUS': if(( 0 < $propix ) || !isset( $this->status['value'] )) return FALSE; return ( $inclParam ) ? $this->status : $this->status['value']; break; case 'SUMMARY': if(( 0 < $propix ) || !isset( $this->summary['value'] )) return FALSE; return ( $inclParam ) ? $this->summary : $this->summary['value']; break; case 'TRANSP': if(( 0 < $propix ) || !isset( $this->transp['value'] )) return FALSE; return ( $inclParam ) ? $this->transp : $this->transp['value']; break; case 'TRIGGER': if(( 0 < $propix ) || !isset( $this->trigger['value'] )) return FALSE; return ( $inclParam ) ? $this->trigger : $this->trigger['value']; break; case 'TZID': if(( 0 < $propix ) || !isset( $this->tzid['value'] )) return FALSE; return ( $inclParam ) ? $this->tzid : $this->tzid['value']; break; case 'TZNAME': if( count( $this->tzname ) <= $propix ) return FALSE; return ( $inclParam ) ? $this->tzname[$propix] : $this->tzname[$propix]['value']; break; case 'TZOFFSETFROM': if(( 0 < $propix ) || !isset( $this->tzoffsetfrom['value'] )) return FALSE; return ( $inclParam ) ? $this->tzoffsetfrom : $this->tzoffsetfrom['value']; break; case 'TZOFFSETTO': if(( 0 < $propix ) || !isset( $this->tzoffsetto['value'] )) return FALSE; return ( $inclParam ) ? $this->tzoffsetto : $this->tzoffsetto['value']; break; case 'TZURL': if(( 0 < $propix ) || !isset( $this->tzurl['value'] )) return FALSE; return ( $inclParam ) ? $this->tzurl : $this->tzurl['value']; break; case 'UID': if( in_array( $this->objName, array( 'valarm', 'vtimezone' ))) return; if( 0 < $propix ) return null; if( empty( $this->uid['value'] )) $this->_makeuid(); return ( $inclParam ) ? $this->uid : $this->uid['value']; break; case 'URL': if(( 0 < $propix ) || !isset( $this->url['value'] )) return FALSE; return ( $inclParam ) ? $this->url : $this->url['value']; break; default: if( $propName != 'X-PROP' ) { if( !isset( $this->xprop[$propName] )) return FALSE; return ( $inclParam ) ? array( $propName, $this->xprop[$propName] ) : array( $propName, $this->xprop[$propName]['value'] ); } else { if( count( $this->xprop ) <= $propix ) return FALSE; $xpropno = 0; foreach( $this->xprop as $xpropkey => $xpropvalue ) { if( $propix == $xpropno ) return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] ) : array( $xpropkey, $this->xprop[$xpropkey]['value'] ); else $xpropno++; } return FALSE; // not found ?? } } return FALSE; } /** * general component property setting * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-04-25 * @param mixed $args variable number of function arguments, * first argument is ALWAYS component name! * @return void */ function setProperty() { $numargs = func_num_args(); if( 1 > $numargs ) return FALSE; $arglist = func_get_args(); $arglist[0] = strtoupper( $arglist[0] ); for( $argix=$numargs; $argix < 12; $argix++ ) if( !isset( $arglist[$argix] )) $arglist[$argix] = null; switch( $arglist[0] ) { case 'ACTION': $this->setAction( $arglist[1], $arglist[2] ); break; case 'ATTACH': $this->setAttach( $arglist[1], $arglist[2] ); break; case 'ATTENDEE': $this->setAttendee( $arglist[1], $arglist[2] ); break; case 'CATEGORIES': $this->setCategories( $arglist[1], $arglist[2] ); break; case 'CLASS': $this->setClass( $arglist[1], $arglist[2] ); break; case 'COMMENT': $this->setComment( $arglist[1], $arglist[2] ); break; case 'COMPLETED': $this->setCompleted( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); break; case 'CONTACT': $this->setContact( $arglist[1], $arglist[2] ); break; case 'CREATED': $this->setCreated( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); break; case 'DESCRIPTION': $this->setDescription( $arglist[1], $arglist[2] ); break; case 'DTEND': $this->setDtend( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); break; case 'DTSTAMP': $this->setDtstamp( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); break; case 'DTSTART': $this->setDtstart( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); break; case 'DUE': $this->setDue( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); break; case 'DURATION': $this->setDuration( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6] ); break; case 'EXDATE': $this->setExdate( $arglist[1], $arglist[2] ); break; case 'EXRULE': $this->setExrule( $arglist[1], $arglist[2] ); break; case 'FREEBUSY': $this->setFreebusy( $arglist[1], $arglist[2], $arglist[3] ); break; case 'GEO': $this->setGeo( $arglist[1], $arglist[2], $arglist[3] ); break; case 'LAST-MODIFIED': $this->setLastModified( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); break; case 'LOCATION': $this->setLocation( $arglist[1], $arglist[2] ); break; case 'ORGANIZER': $this->setOrganizer( $arglist[1], $arglist[2] ); break; case 'PERCENT-COMPLETE': $this->setPercentComplete( $arglist[1], $arglist[2] ); break; case 'PRIORITY': $this->setPriority( $arglist[1], $arglist[2] ); break; case 'RDATE': $this->setRdate( $arglist[1], $arglist[2] ); break; case 'RECURRENCE-ID': $this->setRecurrenceid( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); break; case 'RELATED-TO': $this->setRelatedTo( $arglist[1], $arglist[2] ); break; case 'REPEAT': $this->setRepeat( $arglist[1], $arglist[2] ); break; case 'REQUEST-STATUS': $this->setRequestStatus( $arglist[1], $arglist[2], $arglist[3], $arglist[4] ); break; case 'RESOURCES': $this->setResources( $arglist[1], $arglist[2] ); break; case 'RRULE': $this->setRrule( $arglist[1], $arglist[2] ); break; case 'SEQUENCE': $this->setSequence( $arglist[1], $arglist[2] ); break; case 'STATUS': $this->setStatus( $arglist[1], $arglist[2] ); break; case 'SUMMARY': $this->setSummary( $arglist[1], $arglist[2] ); break; case 'TRANSP': $this->setTransp( $arglist[1], $arglist[2] ); break; case 'TRIGGER': $this->setTrigger( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8], $arglist[9], $arglist[10], $arglist[11] ); break; case 'TZID': $this->setTzid( $arglist[1], $arglist[2] ); break; case 'TZNAME': $this->setTzname( $arglist[1], $arglist[2] ); break; case 'TZOFFSETFROM': $this->setTzoffsetfrom( $arglist[1], $arglist[2] ); break; case 'TZOFFSETTO': $this->setTzoffsetto( $arglist[1], $arglist[2] ); break; case 'TZURL': $this->setTzurl( $arglist[1], $arglist[2] ); break; case 'UID': $this->setUid( $arglist[1], $arglist[2] ); break; case 'URL': $this->setUrl( $arglist[1], $arglist[2] ); break; default: $this->setXprop( $arglist[0], $arglist[1], $arglist[2] ); break; } } /*********************************************************************************/ /** * parse component unparsed data into properties * * @author Kjell-Inge Gustafsson * @since 2.2.1 - 2007-08-04 * @return bool FALSE if error occurs during parsing * */ function parse() { if( !isset( $this->unparsed ) || !is_array( $this->unparsed ) || ( 0 >= count( $this->unparsed ))) { unset( $this->unparsed ); return FALSE; } /* concatenate property values spread over several lines */ $lastix = -1; $propnames = array( 'action', 'attach', 'attendee', 'categories', 'comment', 'completed' , 'contact', 'class', 'created', 'description', 'dtend', 'dtstart' , 'dtstamp', 'due', 'duration', 'exdate', 'exrule', 'freebusy', 'geo' , 'last-modified', 'location', 'organizer', 'percent-complete' , 'priority', 'rdate', 'recurrence-id', 'related-to', 'repeat' , 'request-status', 'resources', 'rrule', 'sequence', 'status' , 'summary', 'transp', 'trigger', 'tzid', 'tzname', 'tzoffsetfrom' , 'tzoffsetto', 'tzurl', 'uid', 'url', 'x-' ); $proprows = array(); foreach( $this->unparsed as $line ) { $newProp = FALSE; foreach ( $propnames as $propname ) { if( $propname == strtolower( substr( $line, 0, strlen( $propname )))) { $newProp = TRUE; break; } } if( $newProp ) { $newProp = FALSE; $lastix++; $proprows[$lastix] = $line; } else { /* remove line breaks */ if(( '\n' == substr( $proprows[$lastix], -2 )) && ( ' ' == substr( $line, 0, 1 ))) { $proprows[$lastix] = substr( $proprows[$lastix], 0, strlen( $proprows[$lastix] ) - 2 ); $line = substr( $line, 1 ); } $proprows[$lastix] .= $line; } } /* parse each property 'line' */ foreach( $proprows as $line ) { $line = str_replace( "\n ", '', $line ); if( '\n' == substr( $line, -2 )) $line = substr( $line, 0, strlen( $line ) - 2 ); /* get propname, (problem with x-properties, otherwise in previous loop) */ $cix = $propname = null; for( $cix=0; $cix < strlen( $line ); $cix++ ) { if( in_array( $line{$cix}, array( ':', ';' ))) break; else $propname .= $line{$cix}; } /* rest of the line is opt.params and value */ $line = substr( $line, $cix); /* separate attributes from value */ $attr = array(); $attrix = -1; $strlen = strlen( $line ); for( $cix=0; $cix < $strlen; $cix++ ) { if(( ':' == $line{$cix} ) && ( '://' != substr( $line, $cix, 3 )) && ( 'mailto:' != strtolower( substr( $line, $cix - 6, 7 )))) { $attrEnd = TRUE; if(( $cix < ( $strlen - 4 )) && ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr?? for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) { if( '://' == substr( $line, $c2ix - 2, 3 )) { $attrEnd = FALSE; break; // an URI with a portnr!! } } } if( $attrEnd) { $line = substr( $line, $cix + 1 ); break; } } if( ';' == $line{$cix} ) $attr[++$attrix] = null; else $attr[$attrix] .= $line{$cix}; } /* make attributes in array format */ $propattr = array(); foreach( $attr as $attribute ) { $attrsplit = explode( '=', $attribute, 2 ); if( 1 < count( $attrsplit )) $propattr[$attrsplit[0]] = $attrsplit[1]; else $propattr[] = $attribute; } /* call setProperty( $propname.. . */ switch( $propname ) { case 'ATTENDEE': foreach( $propattr as $pix => $attr ) { $attr2 = explode( ',', $attr ); if( 1 < count( $attr2 )) $propattr[$pix] = $attr2; } $this->setProperty( $propname, $line, $propattr ); break; case 'COMMENT': case 'CONTACT': case 'DESCRIPTION': case 'LOCATION': case 'SUMMARY': $this->setProperty( $propname, $this->_strunrep( $line ), $propattr ); break; case 'REQUEST-STATUS': $values = explode( ';', $line ); if( !isset( $values[2] )) $values[2] = FALSE; $this->setProperty( $propname , $values[0] // statcode , $this->_strunrep( $values[1] ) // statdesc , $this->_strunrep( $values[2] ) // extdata , $propattr ); break; case 'FREEBUSY': $fbtype = $propattr['FBTYPE']; unset( $propattr['FBTYPE'] ); $values = explode( ',', $line ); foreach( $values as $vix => $value ) { $value2 = explode( '/', $value ); if( 1 < count( $value2 )) $values[$vix] = $value2; } $this->setProperty( $propname, $fbtype, $values, $propattr ); break; case 'GEO': $value= explode( ';', $line, 2 ); $this->setProperty( $propname, $value[0], $value[1], $propattr ); break; case 'EXDATE': $values= explode( ',', $line ); $this->setProperty( $propname, $values, $propattr ); break; case 'RDATE': $values = explode( ',', $line ); foreach( $values as $vix => $value ) { $value2 = explode( '/', $value ); if( 1 < count( $value2 )) $values[$vix] = $value2; } $this->setProperty( $propname, $values, $propattr ); break; case 'EXRULE': case 'RRULE': $values = explode( ';', $line ); $recur = array(); foreach( $values as $value2 ) { if( empty( $value2 )) continue; // ;-char in ending position ??? $value3 = explode( '=', $value2, 2 ); $rulelabel = strtoupper( $value3[0] ); switch( $rulelabel ) { case 'BYDAY': { $value4 = explode( ',', $value3[1] ); if( 1 < count( $value4 )) { foreach( $value4 as $v5ix => $value5 ) { $value6 = array(); $dayno = $dayname = null; $value5 = (string) $value5; if(( ctype_alpha( substr( $value5, -1 ))) && ( ctype_alpha( substr( $value5, -2, 1 )))) { $dayname = substr( $value5, -2, 2 ); if( 2 < strlen( $value5 )) $dayno = substr( $value5, 0, strlen( $value5 ) - 2 ); } if( $dayno ) $value6[] = $dayno; if( $dayname ) $value6['DAY'] = $dayname; $value4[$v5ix] = $value6; } } else { $value4 = array(); $dayno = $dayname = null; $value3[1] = (string) $value3[1]; if(( ctype_alpha( substr( $value3[1], -1 ))) && ( ctype_alpha( substr( $value3[1], -2, 1 )))) { $dayname = array( 'DAY' => substr( $value3[1], -2, 2 )); if( 2 < strlen( $value3[1] )) $dayno = substr( $value3[1], 0, strlen( $value3[1] ) - 2); } if( $dayno ) $value4[] = $dayno; if( $dayname ) $value4[] = $dayname; } $recur[$rulelabel] = $value4; break; } default: { $value4 = explode( ',', $value3[1] ); if( 1 < count( $value4 )) $value3[1] = $value4; $recur[$rulelabel] = $value3[1]; break; } } // end - switch $rulelabel } // end - foreach( $values.. . $this->setProperty( $propname, $recur, $propattr ); break; default: $this->setProperty( $propname, $line, $propattr ); break; } // end switch( $propname.. . } // end - foreach( $proprows.. . unset( $this->unparsed, $proprows ); if( is_array( $this->components ) && ( 0 < count( $this->components ))) { for( $six = 0; $six < count( $this->components ); $six++ ) $this->components[$six]->parse(); } } /*********************************************************************************/ /*********************************************************************************/ /** * delete calendar subcomponent from component container * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-20 * @param mixed $arg1 ordno / component type / component uid * @param mixed $arg2 optional, ordno if arg1 = component type * @return void */ function deleteComponent( $arg1, $arg2=FALSE ) { $argType = $index = null; if ( ctype_digit( (string) $arg1 )) { $argType = 'INDEX'; $index = (int) $arg1 - 1; } elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { $argType = strtolower( $arg1 ); $index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 1; } $cix2dC = 0; foreach ( $this->components as $cix => $component) { unset( $component->propix ); if(( 'INDEX' == $argType ) && ( $index == $cix )) { unset( $this->components[$cix] ); return TRUE; } elseif( $argType == $component->objName ) { if( $index == $cix2dC ) { unset( $this->components[$cix] ); return TRUE; } $cix2dC++; } elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { unset( $this->components[$cix] ); return TRUE; } } return FALSE; } /** * get calendar component subcomponent from component container * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-20 * @param mixed $arg1 optional, ordno/component type/ component uid * @param mixed $arg2 optional, ordno if arg1 = component type * @return object */ function getComponent ( $arg1=FALSE, $arg2=FALSE ) { $index = $argType = null; if ( !$arg1 ) { $argType = 'INDEX'; $index = $this->compix['INDEX'] = ( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1; } elseif ( ctype_digit( (string) $arg1 )) { $argType = 'INDEX'; $index = (int) $arg1; unset( $this->compix ); } elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { unset( $this->compix['INDEX'] ); $argType = strtolower( $arg1 ); if( !$arg2 ) $index = $this->compix[$argType] = ( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1; else $index = (int) $arg2; } $index -= 1; if( !empty( $index) && ( $index > end( array_keys( $this->components )))) return FALSE; $cix2gC = 0; foreach ( $this->components as $cix => $component ) { unset( $component->propix ); if(( 'INDEX' == $argType ) && ( $index == $cix )) return $component; elseif( $argType == $component->objName ) { if( $index == $cix2gC ) return $component; $cix2gC++; } elseif( !$argType && ( $arg1 == $component->getProperty( 'uid' ))) { unset( $component->propix ); return $component; } } /* not found.. . */ unset( $this->compix ); return false; } /** * add calendar component as subcomponent to container for subcomponents * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-04-24 * @param object $component calendar component * @return void */ function addSubComponent ( $component ) { $this->setComponent( $component ); } /** * add calendar component as subcomponent to container for subcomponents * * @author Kjell-Inge Gustafsson * @since 2.0.4 - 2007-06-20 * @param object $component calendar component * @param mixed $arg1 optional, ordno/component type/ component uid * @param mixed $arg2 optional, ordno if arg1 = component type * @return void */ function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) { if( '' >= $component->getConfig( 'language')) $component->setConfig( 'language' , $this->getConfig( 'language' )); $component->setConfig( 'nl' , $this->getConfig( 'nl' )); $component->setConfig( 'unique_id' , $this->getConfig( 'unique_id' )); $component->setConfig( 'format' , $this->getConfig( 'format' )); if( !in_array( $component->objName, array( 'valarm', 'vtimezone' ))) { unset( $component->propix ); /* make sure dtstamp and uid is set */ $dummy = $component->getProperty( 'dtstamp' ); $dummy = $component->getProperty( 'uid' ); } if( !$arg1 ) { $this->components[] = $component; return TRUE; } $argType = $index = null; if ( ctype_digit( (string) $arg1 )) { $argType = 'INDEX'; $index = (int) $arg1 - 1; } elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { $argType = strtolower( $arg1 ); $index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0; } $cix2sC = 0; foreach ( $this->components as $cix => $component2 ) { unset( $component2->propix ); if(( 'INDEX' == $argType ) && ( $index == $cix )) { $this->components[$cix] = $component; return TRUE; } elseif( $argType == $component2->objName ) { if( $index == $cix2sC ) { $this->components[$cix] = $component; return TRUE; } $cix2sC++; } elseif( !$argType && ($arg1 == $component2->getProperty( 'uid' ))) { $this->components[$cix] = $component; return TRUE; } } /* not found.. . insert anyway.. .*/ $this->components[] = $component; } /** * creates formatted output for subcomponents * * @author Kjell-Inge Gustafsson * @since 0.9.22 - 2007-04-07 * @return string */ function createSubComponent() { $output = null; foreach( $this->components as $component ) { if( '' >= $component->getConfig( 'language')) $component->setConfig( 'language', $this->getConfig( 'language' )); $component->setConfig( 'nl', $this->getConfig( 'nl' )); $component->setConfig( 'unique_id', $this->getConfig( 'unique_id' )); $component->setConfig( 'format', $this->getConfig( 'format' )); $output .= $component->createComponent( $this->xcaldecl ); } return $output; } /********************************************************************************/ /** * break lines at pos 75 * * Lines of text SHOULD NOT be longer than 75 octets, excluding the line * break. Long content lines SHOULD be split into a multiple line * representations using a line "folding" technique. That is, a long * line can be split between any two characters by inserting a CRLF * immediately followed by a single linear white space character (i.e., * SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence * of CRLF followed immediately by a single linear white space character * is ignored (i.e., removed) when processing the content type. * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @param string $value * @return string */ function _size75( $string ) { $strlen = strlen( $string ); $tmp = $string; $string = null; while( $strlen > 75 ) { $string .= substr( $tmp, 0, 75 ); $string .= $this->nl; $tmp = ' '.substr( $tmp, 75 ); $strlen = strlen( $tmp ); } $string .= rtrim( $tmp ); // the rest if( $this->nl != substr( $string, ( 0 - strlen( $this->nl )))) $string .= $this->nl; return $string; } /** * special characters management output * * @author Kjell-Inge Gustafsson * @since 2.2.5 - 2007-08-01 * @param string $string * @return string */ function _strrep( $string ) { switch( $this->format ) { case 'xcal': $string = htmlspecialchars( strip_tags( stripslashes( urldecode ( $string )))); break; default: if( FALSE !== strpos( $string, '"' )) $string = str_replace('"', "'", $string); if( FALSE !== strpos( $string, '\\' )) $string = str_replace('\\', '\\\\', $string); if( FALSE !== strpos( $string, ',' )) $string = str_replace(',', '\,', $string); if( FALSE !== strpos( $string, ';' )) $string = str_replace(';', '\;', $string); if( FALSE !== strpos( $string, $this->nl )) $string = str_replace( $this->nl, '\n', $string); if( FALSE !== strpos( $string, "\r" )) $string = str_replace( "\r", '', $string); break; } return $string; } /** * special characters management input (from iCal file) * * @author Kjell-Inge Gustafsson * @since 1.x.x - 2007-04-27 * @param string $string * @return string */ function _strunrep( $string ) { $string = str_replace( '\\\\', '\\', $string); $string = str_replace( '\,', ',', $string); $string = str_replace( '\;', ';', $string); $string = str_replace( '\n', $this->nl, $string); // ?? return $string; } } /*********************************************************************************/ /*********************************************************************************/ /** * class for calendar component VEVENT * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 */ class vevent extends calendarComponent { /** * constructor for calendar component VEVENT object * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function vevent() { $this->calendarComponent(); } /** * create formatted output for calendar component VEVENT object instance * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-20 * @param array $xcaldecl * @return string */ function createComponent( &$xcaldecl ) { $objectname = $this->_createFormat(); $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; $component .= $this->createAttach(); $component .= $this->createAttendee(); $component .= $this->createCategories(); $component .= $this->createComment(); $component .= $this->createContact(); $component .= $this->createClass(); $component .= $this->createCreated(); $component .= $this->createDescription(); $component .= $this->createDtend(); $component .= $this->createDtstamp(); $component .= $this->createDtstart(); $component .= $this->createDuration(); $component .= $this->createExdate(); $component .= $this->createExrule(); $component .= $this->createGeo(); $component .= $this->createLastModified(); $component .= $this->createLocation(); $component .= $this->createOrganizer(); $component .= $this->createPriority(); $component .= $this->createRdate(); $component .= $this->createRelatedTo(); $component .= $this->createRequestStatus(); $component .= $this->createRecurrenceid(); $component .= $this->createResources(); $component .= $this->createRrule(); $component .= $this->createSequence(); $component .= $this->createStatus(); $component .= $this->createSummary(); $component .= $this->createTransp(); $component .= $this->createUid(); $component .= $this->createUrl(); $component .= $this->createXprop(); if( $this->nl != substr( $component, ( 0 - strlen( $this->nl )))) $component .= $this->nl; $component .= $this->createSubComponent(); $component .= $this->componentEnd1.$objectname.$this->componentEnd2; if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { foreach( $this->xcaldecl as $localxcaldecl ) $xcaldecl[] = $localxcaldecl; } return $component; } } /*********************************************************************************/ /*********************************************************************************/ /** * class for calendar component VTODO * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 */ class vtodo extends calendarComponent { /** * constructor for calendar component VTODO object * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function vtodo() { $this->calendarComponent(); } /** * create formatted output for calendar component VTODO object instance * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-20 * @param array $xcaldecl * @return string */ function createComponent( &$xcaldecl ) { $objectname = $this->_createFormat(); $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; $component .= $this->createAttach(); $component .= $this->createAttendee(); $component .= $this->createCategories(); $component .= $this->createClass(); $component .= $this->createComment(); $component .= $this->createCompleted(); $component .= $this->createContact(); $component .= $this->createCreated(); $component .= $this->createDescription(); $component .= $this->createDtstamp(); $component .= $this->createDtstart(); $component .= $this->createDue(); $component .= $this->createDuration(); $component .= $this->createExdate(); $component .= $this->createExrule(); $component .= $this->createGeo(); $component .= $this->createLastModified(); $component .= $this->createLocation(); $component .= $this->createOrganizer(); $component .= $this->createPercentComplete(); $component .= $this->createPriority(); $component .= $this->createRdate(); $component .= $this->createRelatedTo(); $component .= $this->createRequestStatus(); $component .= $this->createRecurrenceid(); $component .= $this->createResources(); $component .= $this->createRrule(); $component .= $this->createSequence(); $component .= $this->createStatus(); $component .= $this->createSummary(); $component .= $this->createUid(); $component .= $this->createUrl(); $component .= $this->createXprop(); if( $this->nl != substr( $component, ( 0 - strlen( $this->nl )))) $component .= $this->nl; $component .= $this->createSubComponent(); $component .= $this->componentEnd1.$objectname.$this->componentEnd2; if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { foreach( $this->xcaldecl as $localxcaldecl ) $xcaldecl[] = $localxcaldecl; } return $component; } } /*********************************************************************************/ /*********************************************************************************/ /** * class for calendar component VJOURNAL * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 */ class vjournal extends calendarComponent { /** * constructor for calendar component VJOURNAL object * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function vjournal() { $this->calendarComponent(); } /** * create formatted output for calendar component VJOURNAL object instance * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-20 * @param array $xcaldecl * @return string */ function createComponent( &$xcaldecl ) { $objectname = $this->_createFormat(); $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; $component .= $this->createAttach(); $component .= $this->createAttendee(); $component .= $this->createCategories(); $component .= $this->createClass(); $component .= $this->createComment(); $component .= $this->createContact(); $component .= $this->createCreated(); $component .= $this->createDescription(); $component .= $this->createDtstamp(); $component .= $this->createDtstart(); $component .= $this->createExdate(); $component .= $this->createExrule(); $component .= $this->createLastModified(); $component .= $this->createOrganizer(); $component .= $this->createRdate(); $component .= $this->createRequestStatus(); $component .= $this->createRecurrenceid(); $component .= $this->createRelatedTo(); $component .= $this->createRrule(); $component .= $this->createSequence(); $component .= $this->createStatus(); $component .= $this->createSummary(); $component .= $this->createUid(); $component .= $this->createUrl(); $component .= $this->createXprop(); $component .= $this->componentEnd1.$objectname.$this->componentEnd2; if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { foreach( $this->xcaldecl as $localxcaldecl ) $xcaldecl[] = $localxcaldecl; } return $component; } } /*********************************************************************************/ /*********************************************************************************/ /** * class for calendar component VFREEBUSY * * @author Kjell-Inge Gustafsson * @since 0.7.3 - 2006-09-09 */ class vfreebusy extends calendarComponent { /** * constructor for calendar component VFREEBUSY object * * @author Kjell-Inge Gustafsson * @since 0.7.3 - 2006-09-09 * @return void */ function vfreebusy() { $this->calendarComponent(); } /** * create formatted output for calendar component VFREEBUSY object instance * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-20 * @param array $xcaldecl * @return string */ function createComponent( &$xcaldecl ) { $objectname = $this->_createFormat(); $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; $component .= $this->createAttendee(); $component .= $this->createComment(); $component .= $this->createContact(); $component .= $this->createDtend(); $component .= $this->createDtstart(); $component .= $this->createDtstamp(); $component .= $this->createDuration(); $component .= $this->createFreebusy(); $component .= $this->createOrganizer(); $component .= $this->createRequestStatus(); $component .= $this->createUid(); $component .= $this->createUrl(); $component .= $this->createXprop(); $component .= $this->componentEnd1.$objectname.$this->componentEnd2; if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { foreach( $this->xcaldecl as $localxcaldecl ) $xcaldecl[] = $localxcaldecl; } return $component; } } /*********************************************************************************/ /*********************************************************************************/ /** * class for calendar component VALARM * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 */ class valarm extends calendarComponent { /** * constructor for calendar component VALARM object * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-10 * @return void */ function valarm() { $this->calendarComponent(); } /** * create formatted output for calendar component VALARM object instance * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-20 * @param array $xcaldecl * @return string */ function createComponent( &$xcaldecl ) { $objectname = $this->_createFormat(); $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; $component .= $this->createAction(); $component .= $this->createAttach(); $component .= $this->createAttendee(); $component .= $this->createDescription(); $component .= $this->createDuration(); $component .= $this->createRepeat(); $component .= $this->createSummary(); $component .= $this->createTrigger(); $component .= $this->createXprop(); $component .= $this->componentEnd1.$objectname.$this->componentEnd2; if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { foreach( $this->xcaldecl as $localxcaldecl ) $xcaldecl[] = $localxcaldecl; } return $component; } } /********************************************************************************** /*********************************************************************************/ /** * class for calendar component VTIMEZONE * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-13 */ class vtimezone extends calendarComponent { var $timezonetype; /** * constructor for calendar component VTIMEZONE object * * @author Kjell-Inge Gustafsson * @since 0.3.0 - 2006-08-13 * @param string $timezonetype optional, default FALSE ( STANDARD / DAYLIGHT ) * @return void */ function vtimezone( $timezonetype=FALSE ) { if( !$timezonetype ) $this->timezonetype = 'VTIMEZONE'; else $this->timezonetype = strtoupper( $timezonetype ); $this->calendarComponent(); } /** * create formatted output for calendar component VTIMEZONE object instance * * @author Kjell-Inge Gustafsson * @since 2.0.6 - 2007-06-20 * @param array $xcaldecl * @return string */ function createComponent( &$xcaldecl ) { $objectname = $this->_createFormat(); $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; $component .= $this->createTzid(); $component .= $this->createLastModified(); $component .= $this->createTzurl(); $component .= $this->createDtstart( TRUE ); $component .= $this->createTzoffsetfrom(); $component .= $this->createTzoffsetto(); $component .= $this->createComment(); $component .= $this->createRdate( TRUE ); $component .= $this->createRrule(); $component .= $this->createTzname(); $component .= $this->createXprop(); if( $this->nl != substr( $component, ( 0 - strlen( $this->nl )))) $component .= $this->nl; $component .= $this->createSubComponent(); $component .= $this->componentEnd1.$objectname.$this->componentEnd2; if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { foreach( $this->xcaldecl as $localxcaldecl ) $xcaldecl[] = $localxcaldecl; } return $component; } } ?>Collabtive-2.0/include/class.image.php000066400000000000000000000257751237252063700200100ustar00rootroot00000000000000clear(); // clear all. if(file_exists($file_original)) { $this->file_original = $file_original; $this->image_original = $this->imagecreatefromfile($file_original); if(!$this->image_original){ $this->error($ERR["IMAGE_NOT_CREATED_FROM_FILE"]." file=$file_original"); return false; } } else { $this->error($ERR["FILE_DOESNOT_EXSIT"]." file=$file_original"); } } function clear() { // clear all the class member varaibles $this->image_original = 0; $this->file_original = ""; $this->image_original_width = 0; $this->image_original_height = 0; $this->image_original_type_code = 0; $this->image_original_type_abbr = ""; $this->image_original_html_sizes= ""; $this->image_resized = 0; $this->file_resized = ""; $this->image_resized_width = 0; $this->image_resized_height = 0; $this->image_resized_type_code = -1; $this->image_resized_type_abbr = ""; $this->image_resized_html_sizes = ""; $this->set_parameters(); } function set_parameters($jpeg_quality="55", $use_gd2=true) { $this->jpeg_quality=$jpeg_quality; $this->use_gd2=$use_gd2; } function error($msg){ //error messages and debug info: // here you can implement your own error handling echo("
      $msg
      file=".__FILE__."
      "); } function imagecreatefromfile($img_file){ global $ERR; $img=0; $img_sz = getimagesize( $img_file ); ## returns array with some properties like dimensions and type; ####### Now create original image from uploaded file. Be carefull! GIF is often not supported, as far as I remember from GD 1.6 switch( $img_sz[2] ){ case 1: $img = $this->_imagecheckandcreate("ImageCreateFromGif", $img_file); $img_type = "GIF"; break; case 2: $img = $this->_imagecheckandcreate("ImageCreateFromJpeg", $img_file); $img_type = "JPG"; break; case 3: $img = $this->_imagecheckandcreate("ImageCreateFromPng", $img_file); $img_type = "PNG"; break; // would be nice if this function will be finally supported case 4: $img = $this->_imagecheckandcreate("ImageCreateFromSwf", $img_file); $img_type = "SWF"; break; default: $img = 0; $img_type = "UNKNOWN"; $this->error($ERR["IMG_NOT_SUPPORTED"]." $img_file"); break; }//case if($img){ $this->image_original_width=$img_sz[0]; $this->image_original_height=$img_sz[1]; $this->image_original_type_code=$img_sz[2]; $this->image_original_type_abbr=$img_type; $this->image_original_html_sizes=$img_sz[3]; }else { $this->clear(); } return $img; } function _imagecheckandcreate($function, $img_file) { //inner function used from imagecreatefromfile(). //Checks if the function exists and returns //created image or false global $ERR; if(function_exists($function)) { $img = $function($img_file); }else{ $img = false; $this->error($ERR["FUNCTION_DOESNOT_EXIST"]." ".$function); } return $img; } function resize($desired_width, $desired_height, $mode="-"){ //this is core function--it resizes created image //if any of parameters == "*" then no resizing on this parameter //>> mode = "+" then image is resized to cover the region specified by desired_width, _height //>> mode = "-" then image is resized to fit into the region specified by desired_width, _height // width-to-height ratio is all the time the same //>>mode=0 then image will be exactly resized to $desired_width _height. //geometrical distortion can occur in this case. // say u have picture 400x300 and there is circle on the picture //now u resized in mode=0 to 800x300 -- circle shape will be distorted and will look like ellipse. //GD2 provides much better quality but is not everywhere installed global $ERR; if($desired_width == "*" && $desired_height == "*"){ $this->image_resized = $this->image_original; Return true; } switch($mode) { case "-": case '+': //multipliers if($desired_width != "*") $mult_x = $desired_width / $this->image_original_width; if($desired_height != "*") $mult_y = $desired_height / $this->image_original_height; $ratio = $this->image_original_width / $this->image_original_height; if($desired_width == "*"){ $new_height = $desired_height; $new_width = $ratio * $desired_height; }elseif($desired_height == "*"){ $new_height = $desired_width / $ratio; $new_width = $desired_width; }else{ if($mode=="-"){ if( $this->image_original_height * $mult_x < $desired_height ){ //image must be smaller than given $desired_ region //test which multiplier gives us best result //$mult_x does the job $new_width = $desired_width; $new_height = $this->image_original_height * $mult_x; }else{ //$mult_y does the job $new_width = $this->image_original_width * $mult_y; $new_height = $desired_height; } }else{ //mode == "+" // cover the region //image must be bigger than given $desired_ region //test which multiplier gives us best result if( $this->image_original_height * $mult_x > $desired_height ){ //$mult_x does the job $new_width = $desired_width; $new_height = $this->image_original_height * $mult_x; }else{ //$mult_y does the job $new_width = $this->image_original_width * $mult_y; $new_height = $desired_height; } } } break; case '0': //fit the region exactly. if($desired_width == "*") $desired_width = $this->image_original_width; if($desired_height == "*") $desired_height = $this->image_original_height; $new_width = $desired_width; $new_height = $desired_height; break; default: $this->error($ERR["UNKNOWN_RESIZE_MODE"]." $mode"); break; } // OK here we have $new_width _height //create destination image checking for GD2 functions: if( $this->use_gd2 ){ if( function_exists("imagecreatetruecolor")){ $this->image_resized = imagecreatetruecolor($new_width, $new_height) or $this->error($ERR["GD2_NOT_CREATED"]); }else { $this->error($ERR["GD2_UNAVALABLE"]." ImageCreateTruecolor()"); } } else { $this->image_resized = imagecreate($new_width, $new_height) or $this->error($ERR["IMG_NOT_CREATED"]); } //Resize if( $this->use_gd2 ){ if( function_exists("imagecopyresampled")){ $res = imagecopyresampled($this->image_resized, $this->image_original, 0, 0, //dest coord 0, 0, //source coord $new_width, $new_height, //dest sizes $this->image_original_width, $this->image_original_height // src sizes ) or $this->error($ERR["GD2_NOT_RESIZED"]); }else { $this->error($ERR["GD2_UNAVALABLE"]." ImageCopyResampled()"); } } else { $res = imagecopyresized($this->image_resized, $this->image_original, 0, 0, //dest coord 0, 0, //source coord $new_width, $new_height, //dest sizes $this->image_original_width, $this->image_original_height // src sizes ) or $this->error($ERR["IMG_NOT_RESIZED"]); } } function output_original($destination_file, $image_type="JPG") { //outputs original image //if destination file is empty image will be output to browser // right now $image_type can be JPG or PNG return _output_image($destination_file, $image_type, $this->image_original); } function output_resized($destination_file, $image_type="JPG") { //if destination file is empty image will be output to browser // right now $image_type can be JPG or PNG $res = $this->_output_image($destination_file, $image_type, $this->image_resized); if(trim($destination_file)){ $sz=getimagesize($destination_file); $this->file_resized = $destination_file; $this->image_resized_width = $sz[0]; $this->image_resized_height = $sz[1]; $this->image_resized_type_code=$sz[2]; $this->image_resized_html_sizes=$sz[3]; //only jpeg and png are really supported, but I'd like to think of future switch($this->image_resized_html_sizes){ case 0: $this->image_resized_type_abbr = "GIF"; break; case 1: $this->image_resized_type_abbr = "JPG"; break; case 2: $this->image_resized_type_abbr = "PNG"; break; case 3: $this->image_resized_type_abbr = "SWF"; break; default: $this->image_resized_type_abbr = "UNKNOWN"; break; } } return $res; } function _output_image($destination_file, $image_type, $image){ //if destination file is empty image will be output to browser // right now $image_type can be JPEG or PNG global $ERR; $destination_file = trim($destination_file); $res = false; if($image){ switch($image_type) { case 'JPEG': case 'JPG': $res = ImageJpeg($image, $destination_file, $this->jpeg_quality); break; case 'PNG': $res = Imagepng($image, $destination_file); break; default: $this->error($ERR["UNKNOWN_OUTPUT_FORMAT"]." $image_type"); break; } }else{ $this->error($ERR["NO_IMAGE_FOR_OUTPUT"]); } if(!$res) $this->error($ERR["UNABLE_TO_OUTPUT"]." $destination_file"); return $res; } } ?>Collabtive-2.0/include/class.message.php000066400000000000000000000247151237252063700203430ustar00rootroot00000000000000 * @name message * @version 1.0 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class message { public $mylog; /** * Konstruktor * Initialisiert den Eventlog */ function __construct() { $this->mylog = new mylog; } /** * Creates a new message or a reply to a message * * @param int $project Project ID the message belongs to * @param string $title Title/Subject of the message * @param string $text Textbody of the message * @param string $tags Tags for the message * @param int $user User ID of the user adding the message * @param string $username Name of the user adding the message * @param int $replyto ID of the message this message is replying to. Standardmessage: 0 * @return bool */ function add($project, $title, $text, $user, $username, $replyto, $milestone) { global $conn; $insStmt = $conn->prepare("INSERT INTO messages (`project`,`title`,`text`,`posted`,`user`,`username`,`replyto`,`milestone`) VALUES (?, ?, ?, ?, ?, ?, ?, ? )"); $ins = $insStmt->execute(array((int) $project, $title, $text, time(), (int) $user, $username, (int) $replyto, (int) $milestone)); $insid = $conn->lastInsertId(); if ($ins) { $this->mylog->add($title, 'message', 1, $project); return $insid; } else { return false; } } /** * Edits a message * * @param int $id Eindeutige Nummer der Nachricht * @param string $title Titel der Nachricht * @param string $text Text der Nachricht * @param string $tags Tags for the message * @return bool */ function edit($id, $title, $text) { global $conn; $updStmt = $conn->prepare("UPDATE `messages` SET `title`=?, `text`=? WHERE ID = ?"); $upd = $updStmt->execute(array($title, $text, (int) $id)); if ($upd) { $proj = $conn->query("SELECT project FROM messages WHERE ID = $id")->fetch(); $proj = $proj[0]; $this->mylog->add($title, 'message', 2, $proj); return true; } else { return false; } } /** * Deletes a message and all dependent messages * * @param int $id Eindeutige Nummer der Nachricht * @return bool */ function del($id) { global $conn; $id = (int) $id; $msg = $conn->query("SELECT title,project FROM messages WHERE ID = $id")->fetch(); $del = $conn->query("DELETE FROM messages WHERE ID = $id LIMIT 1"); $del2 = $conn->query("DELETE FROM messages WHERE replyto = $id"); $del3 = $conn->query("DELETE FROM files_attached WHERE message = $id"); if ($del) { $this->mylog->add($msg[0], 'message', 3, $msg[1]); return true; } else { return false; } } /** * Return a message including its answers * * @param int $id Eindeutige Nummer der Nachricht * @return array $message Eigenschaften der Nachricht */ function getMessage($id) { global $conn; $id = (int) $id; $message = $conn->query("SELECT * FROM messages WHERE ID = $id LIMIT 1")->fetch(); $milesobj = new milestone(); if (!empty($message)) { $replies = $conn->query("SELECT COUNT(*) FROM messages WHERE replyto = $id")->fetch(); $replies = $replies[0]; $user = new user(); $avatar = $user->getAvatar($message["user"]); $ds = $conn->query("SELECT gender FROM user WHERE ID = $message[user]")->fetch(); $gender = $ds[0]; $message["gender"] = $gender; $project = $conn->query("SELECT name FROM projekte WHERE ID = $message[project]")->fetch(); $message["pname"] = $project[0]; $posted = date(CL_DATEFORMAT . " - H:i", $message["posted"]); $message["postdate"] = $posted; $message["endstring"] = $posted; $message["replies"] = $replies; $message["avatar"] = $avatar; $message["title"] = stripslashes($message["title"]); $message["text"] = stripslashes($message["text"]); $message["username"] = stripslashes($message["username"]); $attached = $this->getAttachedFiles($message["ID"]); $message["files"] = $attached; if ($message["milestone"] > 0) { $miles = $milesobj->getMilestone($message["milestone"]); } else { $miles = array(); } $message["milestones"] = $miles; return $message; } else { return false; } } /** * Return all answers to a given message * * @param int $id Eindeutige Nummer der Nachricht * @return array $replies Antworten zur Nachricht */ function getReplies($id) { global $conn; $id = (int) $id; $sel = $conn->query("SELECT ID FROM messages WHERE replyto = $id ORDER BY posted DESC"); $replies = array(); $milesobj = new milestone(); $user = new user(); while ($reply = $sel->fetch()) { if (!empty($reply)) { $thereply = $this->getMessage($reply["ID"]); array_push($replies, $thereply); } } if (!empty($replies)) { return $replies; } else { return false; } } /** * Returns the most recent messages of a user, from the projects he is assigned to * * @param int $limit Limits the number of messages to return. * @return array $message Eigenschaften der Nachricht */ function getLatestMessages($limit = 25) { global $conn; $limit = (int) $limit; // Get the id of the logged in user and get his projects $userid = $_SESSION["userid"]; $sel3 = $conn->query("SELECT projekt FROM projekte_assigned WHERE user = $userid"); // Assemble a string of project IDs the user belongs to for IN() query. $prstring = ""; while ($upro = $sel3->fetch()) { $projekt = $upro[0]; $prstring .= $projekt . ","; } $prstring = substr($prstring, 0, strlen($prstring)-1); if ($prstring) { $sel1 = $conn->query("SELECT ID FROM messages WHERE project IN($prstring) ORDER BY posted DESC LIMIT $limit "); $messages = array(); $milesobj = new milestone(); while ($message = $sel1->fetch()) { $themessage = $this->getMessage($message["ID"]); array_push($messages, $themessage); } } if (!empty($messages)) { return $messages; } else { return false; } } /** * Returns all messages belonging to a project (without answers) * * @param int $project Eindeutige Nummer des Projekts * @return array $messages Nachrichten zum Projekt */ function getProjectMessages($project) { global $conn; $project = (int) $project; $messages = array(); $sel1 = $conn->query("SELECT ID FROM messages WHERE project = $project AND replyto = 0 ORDER BY posted DESC"); $milesobj = new milestone(); while ($message = $sel1->fetch()) { $themessage = $this->getMessage($message["ID"]); array_push($messages, $themessage); } if (!empty($messages)) { return $messages; } else { return false; } } /** * Attach a file to a message * * @param int $fid ID of the file to be attached * @param int $mid ID of the message where the file will be attached * @param int $id optional param denoting the project ID where the file will be uploaded to (if so) * @return bool */ function attachFile($fid, $mid, $id = 0) { global $conn; $fid = (int) $fid; $mid = (int) $mid; $id = (int) $id; $myfile = new datei(); // If a file ID is given, the given file will be attached // If no file ID is given, the file will be uploaded to the project defined by $id and then attached if ($fid > 0) { $ins = $conn->query("INSERT INTO files_attached (ID,file,message) VALUES ('',$fid,$mid)"); } else { $num = $_POST["numfiles"]; $chk = 0; $insStmt = $conn->prepare("INSERT INTO files_attached (ID,file,message) VALUES ('',?,?)"); for($i = 1;$i <= $num;$i++) { $fid = $myfile->upload("userfile$i", "files/" . CL_CONFIG . "/$id", $id); $ins = $insStmt->execute(array($fid, $mid)); } } if ($ins) { return true; } else { return false; } } /** * Get files attached to a message * * @param int $msg ID of the message * @return array $files Attached files */ private function getAttachedFiles($msg) { global $conn; $msg = (int) $msg; $files = array(); $sel = $conn->query("SELECT file FROM files_attached WHERE message = $msg"); while ($file = $sel->fetch()) { $sel2 = $conn->query("SELECT * FROM files WHERE ID = $file[0]"); $thisfile = $sel2->fetch(); $thisfile["type"] = str_replace("/", "-", $thisfile["type"]); $set = new settings(); $settings = $set->getSettings(); // Construct the path to the MIME-type icon $myfile = "./templates/" . $settings["template"] . "/theme/" . $settings["theme"] . "/images/files/" . $thisfile['type'] . ".png"; if (!file_exists($myfile)) { $thisfile['type'] = "none"; } // Determine if it is an image or text file or some other kind of file (required for lightbox) if (stristr($thisfile['type'], "image")) { $thisfile['imgfile'] = 1; } elseif (stristr($thisfile['type'], "text")) { $thisfile['imgfile'] = 2; } else { $thisfile['imgfile'] = 0; } array_push($files, $thisfile); } if (!empty($files)) { return $files; } else { return false; } } } ?>Collabtive-2.0/include/class.milestone.php000066400000000000000000000444521237252063700207160ustar00rootroot00000000000000 * @name milestone * @package Collabtive * @version 1.0 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later * @global $mylog */ class milestone { private $mylog; /** * Constructor * Initialize the event log */ function __construct() { $this->mylog = new mylog; } /** * Add a milestone * * @param int $project ID of the associated project * @param string $name Name of the milestone * @param string $desc Description * @param string $end Day the milestone is due * @param int $status Status (0 = finished, 1 = open) * @return bool */ function add($project, $name, $desc, $start, $end, $status = 1) { global $conn; // Convert end date to timestamp $end = strtotime($end); $start = strtotime($start); $name = htmlspecialchars($name); $insStmt = $conn->prepare("INSERT INTO milestones (`project`,`name`,`desc`,`start`,`end`,`status`) VALUES (?, ?, ?, ?, ?, ?)"); $ins = $insStmt->execute(array((int) $project, $name, $desc, $start, $end, (int) $status)); if ($ins) { $insid = $conn->lastInsertId(); $this->mylog->add($name, 'milestone' , 1, $project); return $insid; } else { return false; } } /** * Edit a milestone * * @param int $id Milestone ID * @param string $name Name * @param string $desc Description * @param string $end Day it is due * @return bool */ function edit($id, $name, $desc, $start, $end) { global $conn; $id = (int) $id; $start = strtotime($start); $end = strtotime($end); $name = htmlspecialchars($name); $updStmt = $conn->prepare("UPDATE milestones SET `name`=?, `desc`=?, `start`=?, `end`=? WHERE ID=?"); $upd = $updStmt->execute(array($name, $desc, $start, $end, $id)); if ($upd) { $nam = $conn->query("SELECT project,name FROM milestones WHERE ID = $id")->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'milestone' , 2, $project); return true; } else { return false; } } /** * Delete a milestone * * @param int $id Milestone ID * @return bool */ function del($id) { global $conn; $id = (int) $id; $nam = $conn->query("SELECT project,name FROM milestones WHERE ID = $id"); $del = $conn->query("DELETE FROM milestones WHERE ID = $id"); $del1 = $conn->query("DELETE FROM milestones_assigned WHERE milestone = $id"); if ($del) { $nam = $nam->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'milestone', 3, $project); return true; } else { return false; } } /** * Mark a milestone as open / active * * @param int $id Milestone ID * @return bool */ function open($id) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE milestones SET status = 1 WHERE ID = $id"); if ($upd) { $nam = $conn->query("SELECT project,name FROM milestones WHERE ID = $id"); $nam = $nam->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'milestone', 4, $project); return true; } else { return false; } } /** * Marka milestone as finished * Also closes all tasklist assigned to this milestone * * @param int $id Milestone ID * @return bool */ function close($id) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE milestones SET status = 0 WHERE ID = $id"); // Get attached tasklists $tasklists = $this->getMilestoneTasklists($id); // Loop through tasklists , close all tasks in them, then close tasklist itself if (!empty($tasklists)) { $tl = new tasklist(); foreach ($tasklists as $tasklist) { $tl->close_liste($tasklist["ID"],false); } } if ($upd) { $nam = $conn->query("SELECT project,name FROM milestones WHERE ID = $id"); $nam = $nam->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'milestone', 5, $project); return true; } else { return false; } } /** * Assign a milestone to a user * * @param int $milestone Milestone ID * @param int $user User ID * @return bool */ function assign($milestone, $user) { global $conn; $milestone = (int) $milestone; $user = (int) $user; $upd = $conn->query("INSERT INTO milestones_assigned (NULL,$user,$milestone)"); if ($upd) { $nam = $conn->query("SELECT project,name FROM milestones WHERE ID = $id"); $nam = $nam->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'milestone', 6, $project); return true; } else { return false; } } /** * Delete the assignment of a milestone to a given user * * @param int $milestone Milestone ID * @param int $user User ID * @return bool */ function deassign($milestone, $user) { global $conn; $milestone = (int) $milestone; $user = (int) $user; $upd = $conn->query("DELETE FROM milestones_assigned WHERE user = $user AND milestone = $milestone"); if ($upd) { $nam = $conn->query("SELECT project,name FROM milestones WHERE ID = $id"); $nam = $nam->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'milestone', 7, $project); return true; } else { return false; } } /** * Return a milestone with its tasklists * * @param int $id Milestone ID * @return array $milestone Milestone details */ function getMilestone($id) { global $conn; $id = (int) $id; $sel = $conn->query("SELECT * FROM milestones WHERE ID = $id"); $milestone = $sel->fetch(); if (!empty($milestone)) { // Format start and end date for display $endstring = date(CL_DATEFORMAT, $milestone["end"]); $milestone["endstring"] = $endstring; $milestone["fend"] = $endstring; $startstring = date(CL_DATEFORMAT, $milestone["start"]); $milestone["startstring"] = $startstring; $milestone["name"] = stripslashes($milestone["name"]); $milestone["desc"] = stripslashes($milestone["desc"]); // Get the name of the project where the message was posted for display $psel = $conn->query("SELECT name FROM projekte WHERE ID = $milestone[project]"); $pname = $psel->fetch(); $pname = $pname[0]; $milestone["pname"] = $pname; $milestone["pname"] = stripslashes($milestone["pname"]); // Daysleft contains a signed number, dayslate an unsigned one that only applies if the milestone is late $dayslate = $this->getDaysLeft($milestone["end"]); $milestone["daysleft"] = $dayslate; $dayslate = str_replace("-", "" , $dayslate); $milestone["dayslate"] = $dayslate; // Get attached tasklists and messages $tasks = $this->getMilestoneTasklists($milestone["ID"]); $milestone["tasklists"] = $tasks; $messages = $this->getMilestoneMessages($milestone["ID"]); $milestone["messages"] = $messages; return $milestone; } else { return false; } } /** * Return the latest milestones * * @param int $status Status (0 = finished, 1 = open) * @param int $lim Number of milestones to return * @return array $milestones Details of the milestones */ function getMilestones($status = 1, $lim = 100) { global $conn; $status = (int) $status; $lim = (int) $lim; $milestones = array(); $sel = $conn->query("SELECT ID FROM milestones WHERE `status`=$status ORDER BY `end` ASC LIMIT $lim"); while ($milestone = $sel->fetch()) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($milestones, $themilestone); } if (!empty($milestones)) { return $milestones; } else { return false; } } /** * Return all finished milestones of a given project * * @param int $project Project ID * @return array $stones Details of the milestones */ function getDoneProjectMilestones($project) { global $conn; $project = (int) $project; $sel = $conn->query("SELECT ID FROM milestones WHERE project = $project AND status = 0 ORDER BY `end` ASC"); $stones = array(); while ($milestone = $sel->fetch()) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($stones, $themilestone); } if (!empty($stones)) { return $stones; } else { return false; } } /** * Return all late milestones of a given project * * @param int $project Project ID * @param int $lim Number of milestones to return * @return array $milestones Dateils of the late milestones */ function getLateProjectMilestones($project, $lim = 100) { global $conn; $project = (int) $project; $lim = (int) $lim; $tod = date("d.m.Y"); $now = strtotime($tod); $milestones = array(); $sql = "SELECT ID FROM milestones WHERE project = $project AND end < $now AND status = 1 ORDER BY end ASC LIMIT $lim"; $sel1 = $conn->query($sql); while ($milestone = $sel1->fetch()) { if (!empty($milestone)) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($milestones, $themilestone); } } if (!empty($milestones)) { return $milestones; } else { return false; } } /** * Return all upcoming milestones of a given project * Upcoming milestones are milestones where the start date is in the future * * @param int $project Project ID * @param int $lim Number of milestones to return * @return array $milestones Dateils of the late milestones */ function getUpcomingProjectMilestones($project, $lim = 100) { global $conn; $project = (int) $project; $lim = (int) $lim; $tod = date("d.m.Y"); $now = strtotime($tod); $milestones = array(); $sql = "SELECT ID FROM milestones WHERE project = $project AND start > $now AND status = 1 ORDER BY end ASC LIMIT $lim"; $sel1 = $conn->query($sql); while ($milestone = $sel1->fetch()) { if (!empty($milestone)) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($milestones, $themilestone); } } if (!empty($milestones)) { return $milestones; } else { return false; } } /** * Return all open milestones of a given project * * @param int $project Project ID * @param int $lim Number of milestones to return * @return array $milestones Details of the open milestones */ function getAllProjectMilestones($project, $lim = 100) { global $conn; $project = (int) $project; $lim = (int) $lim; $tod = date(CL_DATEFORMAT); $now = strtotime($tod); $milestones = array(); $sql = "SELECT ID FROM milestones WHERE project = $project AND status = 1 ORDER BY end ASC LIMIT $lim"; $sel1 = $conn->query($sql); while ($milestone = $sel1->fetch()) { if (!empty($milestone)) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($milestones, $themilestone); } } if (!empty($milestones)) { return $milestones; } else { return false; } } /** * Return all milestone of a given project, that are not late * * @param int $project Project ID * @param int $lim Number of milestones to return * @return array $milestones Details of the milestones */ function getProjectMilestones($project, $lim = 100) { global $conn; $project = (int) $project; $lim = (int) $lim; $now = time(); $milestones = array(); $sql = "SELECT * FROM milestones WHERE project = $project AND start <= $now AND end > $now AND status = 1 ORDER BY end ASC"; if ($lim > 0) { $sql .= " LIMIT $lim"; } $sel1 = $conn->query($sql); while ($milestone = $sel1->fetch()) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($milestones, $themilestone); } if (!empty($milestones)) { return $milestones; } else { return false; } } /** * Return all milestones of a projects, that are due today * * @param int $project Project ID * @param int $lim Number of milestones to return * @return array $milestones Details of the milestones */ function getTodayProjectMilestones($project, $lim = 100) { global $conn; $project = (int) $project; $lim = (int) $lim; $tod = date("d.m.Y"); $now = strtotime($tod); $milestones = array(); $sel1 = $conn->query("SELECT * FROM milestones WHERE project = $project AND end = '$now' AND status = 1 ORDER BY end ASC LIMIT $lim"); while ($milestone = $sel1->fetch()) { $themilestone = $this->getMilestone($milestone["ID"]); array_push($milestones, $themilestone); } if (!empty($milestones)) { return $milestones; } else { return false; } } /** * Return all milestones of that belong to the loggedin user, due on a given day. * This method is needed for populating the calendar widget with data. * * @param int $m Month Month, without leading zero (e.g. 5 for march) * @param int $y Year Year in format yyyy * @param int $d Day Without leading zero (e.g. 1 for the 1st of the month $m in year $y) * @return array $milestones Details of the milestones */ function getTodayMilestones($m, $y, $d, $project = 0) { global $conn; $m = (int) $m; $y = (int) $y; if ($m > 9) { $startdate = date($d . "." . $m . "." . $y); } else { $startdate = date($d . ".0" . $m . "." . $y); } $starttime = strtotime($startdate); $user = (int) $_SESSION["userid"]; $timeline = array(); if ($project > 0) { $sel1 = $conn->query("SELECT * FROM milestones WHERE project = $project AND status=1 AND end = '$starttime' ORDER BY `end` ASC"); } else { $sel1 = $conn->query("SELECT milestones.*,projekte_assigned.user,projekte.name AS pname,projekte.status AS pstatus FROM milestones,projekte_assigned,projekte WHERE milestones.project = projekte_assigned.projekt AND milestones.project = projekte.ID HAVING projekte_assigned.user = $user AND status=1 AND pstatus != 2 AND end = '$starttime'"); } while ($stone = $sel1->fetch()) { $stone["daysleft"] = $this->getDaysLeft($stone["end"]); array_push($timeline, $stone); } if (!empty($timeline)) { return $timeline; } else { return array(); } } /** * Return all open tasklists associated to a given milestones * * @param int $milestone Milestone ID * @return array $lists Details of the tasklists */ private function getMilestoneTasklists($milestone) { global $conn; $milestone = (int) $milestone; $objtasklist = new tasklist(); $sel = $conn->query("SELECT ID FROM tasklist WHERE milestone = $milestone AND status = 1 ORDER BY ID ASC"); $lists = array(); if ($milestone) { while ($listId = $sel->fetch()) { array_push($lists, $objtasklist->getTasklist($listId["ID"])); } } if (!empty($lists)) { return $lists; } else { return false; } } private function getMilestoneMessages($milestone) { global $conn; $milestone = (int) $milestone; $objmessage = new message(); $sel = $conn->query("SELECT title,ID,milestone FROM messages WHERE milestone = $milestone"); $msgs = array(); while ($msg = $sel->fetch()) { array_push($msgs, $msg); } if (!empty($msgs)) { return $msgs; } } /** * Return the days left from today until a given point in time * * @param int $end Point in time * @return int $days Days left */ private function getDaysLeft($end) { $tod = date("d.m.Y"); $now = strtotime($tod); $diff = $end - $now; $days = floor($diff / 86400); return $days; } /** * Format a milestone's timestamp * * @param int $milestones Milestone ID * @param int $format Wanted time format * @return array $milestones Milestone with the formatted timestamp */ function formatdate(array $milestones) { $cou = 0; if ($milestones) { foreach($milestones as $stone) { $datetime = date(CL_DATEFORMAT, $stone[5]); $milestones[$cou]["due"] = $datetime; $cou = $cou + 1; } } if (!empty($milestones)) { return $milestones; } else { return false; } } } ?>Collabtive-2.0/include/class.mylog.php000066400000000000000000000143161237252063700200420ustar00rootroot00000000000000 * @name mylog * @version 1.0 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class mylog { /* * Constructor */ function __construct() { $this->userid = getArrayVal($_SESSION, "userid"); $this->uname = getArrayVal($_SESSION, "username"); } /* * Add an event log entry * * @param string $name Name of the affected object * @param string $type Type of the affected object * @param int $action Action (1 = added, 2 = edited, 3 = deleted, 4 = opened, 5 = finished, 6 = assigned, 7 = deleted assignment) * @param int $project Project ID * @return bool */ function add($name, $type, $action, $project) { global $conn; $user = $this->userid; $uname = $this->uname; $action = (int) $action; $project = (int) $project; $now = time(); $insStmt = $conn->prepare("INSERT INTO log (user,username,name,type,action,project,datum) VALUES (?, ?, ?, ?, ?, ?, ?)"); $ins = $insStmt->execute(array($user, $uname, $name, $type, $action, $project, $now)); if ($ins) { $insid = $conn->lastInsertId(); return $insid; } else { return false; } } /* * Delete an event log entry * * @param int $id Log entry ID * @return bool */ function del($id) { global $conn; $id = (int) $id; $del = $conn->query("DELETE FROM log WHERE ID = $id LIMIT 1"); if ($del) { return true; } else { return false; } } /* * Return all log entries associated with a given project * * @param int $project Project ID * @param int $limit Number of entries to return * @return array $mylog Log entries */ function getProjectLog($project, $lim = 25) { global $conn; $project = (int) $project; $lim = (int) $lim; $sel = $conn->query("SELECT COUNT(*) FROM log WHERE project = $project "); $num = $sel->fetch(); $num = $num[0]; if ($num > 200) { $num = 200; } SmartyPaginate::connect(); // set items per page SmartyPaginate::setLimit($lim); SmartyPaginate::setTotal($num); $start = SmartyPaginate::getCurrentIndex(); $lim = SmartyPaginate::getLimit(); $sql = "SELECT * FROM log WHERE project = $project ORDER BY ID DESC LIMIT $start,$lim"; $sel2 = $conn->query($sql); $mylog = array(); while ($log = $sel2->fetch()) { if (!empty($log)) { $sel3 = $conn->query("SELECT name FROM projekte WHERE ID = $log[project]"); $proname = $sel3->fetch(); $proname = $proname[0]; $log["proname"] = $proname; $log["proname"] = stripslashes($log["proname"]); $log["username"] = stripslashes($log["username"]); $log["name"] = stripslashes($log["name"]); array_push($mylog, $log); } } if (!empty($mylog)) { return $mylog; } else { return false; } } /* * Return the log of the latest activities of a given user * * @param int $user User ID * @param int $limit Number of entries to return * @return array $mylog Latest entries */ function getUserLog($user, $limit = 25) { global $conn; $user = (int) $user; $limit = (int) $limit; $sel = $conn->query("SELECT * FROM log WHERE user = $user ORDER BY ID DESC LIMIT $limit"); $mylog = array(); while ($log = $sel->fetch()) { $log["username"] = stripslashes($log["username"]); $log["name"] = stripslashes($log["name"]); array_push($mylog, $log); } if (!empty($mylog)) { return $mylog; } else { return false; } } /* * Return the latest log entries * * @param int $limit Number of entries to return * @return array $mylog Latest entries */ function getLog($limit = 5) { global $conn; $userid = $_SESSION["userid"]; $limit = (int) $limit; $mylog = array(); $sel3 = $conn->query("SELECT projekt FROM projekte_assigned WHERE user = $userid"); $prstring = ""; while ($upro = $sel3->fetch()) { $projekt = $upro[0]; $prstring .= $projekt . ","; } $prstring = substr($prstring, 0, strlen($prstring)-1); if ($prstring) { $sel = $conn->query("SELECT * FROM log WHERE project IN($prstring) OR project = 0 ORDER BY ID DESC LIMIT $limit"); while ($log = $sel->fetch()) { $sel2 = $conn->query("SELECT name FROM projekte WHERE ID = $log[project]"); $proname = $sel2->fetch(); $proname = $proname[0]; $log["proname"] = $proname; $log["proname"] = stripslashes($log["proname"]); $log["username"] = stripslashes($log["username"]); $log["name"] = stripslashes($log["name"]); array_push($mylog, $log); } } if (!empty($mylog)) { return $mylog; } else { return false; } } /* * Format the date of an entry * * @param int $log Log entry ID * @param string $format Wanted format * @return array $log Entry with the formatted time */ function formatdate($log, $format = "") { if (!$format) { $format = CL_DATEFORMAT . " (H:i:s)"; } $cou = 0; if ($log) { foreach($log as $thelog) { $datetime = date($format, $thelog[7]); $log[$cou]["datum"] = $datetime; $cou = $cou + 1; } } if (!empty($log)) { return $log; } else { return false; } } } ?>Collabtive-2.0/include/class.project.php000066400000000000000000000411401237252063700203540ustar00rootroot00000000000000 * @name project * @package Collabtive * @version 1.2 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class project { private $mylog; /** * Konstruktor * Initialisiert den Eventlog */ function __construct() { $this->mylog = new mylog; } /** * Add a project * * @param string $name Name des Projekts * @param string $desc Projektbeschreibung * @param string $end Date on which the project is due * @param int $customerID * @param int $assignme Assign yourself to the project * @return int $insid ID des neu angelegten Projekts */ function add($name, $desc, $end, $budget, $assignme = 0) { global $conn; if ($end > 0) { $end = strtotime($end); } $now = time(); $name = htmlspecialchars($name); $ins1Stmt = $conn->prepare("INSERT INTO projekte (`name`, `desc`, `end`, `start`, `status`, `budget`) VALUES (?,?,?,?,1,?)"); $ins1 = $ins1Stmt->execute(array($name, $desc, $end, $now, (float) $budget)); $insid = $conn->lastInsertId(); if ((int) $assignme == 1) { $uid = $_SESSION['userid']; $this->assign($uid, $insid); } if ($ins1) { mkdir(CL_ROOT . "/files/" . CL_CONFIG . "/$insid/", 0777); $this->mylog->add($name, 'projekt', 1, $insid); return $insid; } else { return false; } } /** * Bearbeitet ein Projekt * * @param int $id Project ID * @param string $name Name of the project * @param string $desc Description of the project * @param string $end Date on which the project is due * @param int $customerID id of a customer * @return bool */ function edit($id, $name, $desc, $end, $budget) { global $conn; $end = strtotime($end); $id = (int) $id; $budget = (float) $budget; $name = htmlspecialchars($name); $updStmt = $conn->prepare("UPDATE projekte SET name=?,`desc`=?,`end`=?,budget=? WHERE ID = ?"); $upd = $updStmt->execute(array($name, $desc, $end, $budget, $id)); if ($upd) { $this->mylog->add($name, 'projekt' , 2, $id); return true; } else return false; } /** * Deletes a project including everything else that was assigned to it (e.g. Milestones, tasks, timetracker entries) * * @param int $id Project ID * @return bool */ function del($id) { global $conn; $userid = $_SESSION["userid"]; $id = (int) $id; // Delete assignments of tasks of this project to users $task = new task(); $tasks = $task->getProjectTasks($id); if (!empty($tasks)) { foreach ($tasks as $tas) { $del_taskassign = $conn->query("DELETE FROM tasks_assigned WHERE task = $tas[ID]"); } } // Delete files and the assignments of these files to the messages they were attached to $fil = new datei(); $files = $fil->getProjectFiles($id, 1000000); if (!empty($files)) { foreach ($files as $file) { $del_files = $fil->loeschen($file[ID]); } } $del_messages = $conn->query("DELETE FROM messages WHERE project = $id"); $del_milestones = $conn->query("DELETE FROM milestones WHERE project = $id"); $del_projectassignments = $conn->query("DELETE FROM projekte_assigned WHERE projekt = $id"); $del_tasklists = $conn->query("DELETE FROM tasklist WHERE project = $id"); $del_tasks = $conn->query("DELETE FROM tasks WHERE project = $id"); $del_timetracker = $conn->query("DELETE FROM timetracker WHERE project = $id"); $del_customer = $conn->query("DELETE FROM customers_assigned WHERE project = $id"); $del_logentries = $conn->query("DELETE FROM log WHERE project = $id"); $del = $conn->query("DELETE FROM projekte WHERE ID = $id"); delete_directory(CL_ROOT . "/files/" . CL_CONFIG . "/$id"); if ($del) { $this->mylog->add($userid, 'projekt', 3, $id); return true; } else { return false; } } /** * Mark a project as "active / open" * * @param int $id Eindeutige Projektnummer * @return bool */ function open($id) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE projekte SET status=1 WHERE ID = $id"); if ($upd) { $nam = $conn->query("SELECT name FROM projekte WHERE ID = $id")->fetch(); $nam = $nam[0]; $this->mylog->add($nam, 'projekt', 4, $id); return true; } else { return false; } } /** * Marks a project, its tasks, tasklists and milestones as "finished / closed" * * @param int $id Eindeutige Projektnummer * @return bool */ function close($id) { global $conn; $id = (int) $id; $mile = new milestone(); $milestones = $mile->getAllProjectMilestones($id, 100000); if (!empty($milestones)) { foreach ($milestones as $miles) { $close_milestones = $conn->query("UPDATE milestones SET status = 0 WHERE ID = $miles[ID]"); } } $task = new task(); $tasks = $task->getProjectTasks($id); if (!empty($tasks)) { foreach ($tasks as $tas) { $close_tasks = $conn->query("UPDATE tasks SET status = 0 WHERE ID = $tas[ID]"); } } $tasklist = new tasklist(); $tasklists = $tasklist->getProjectTasklists($id); if (!empty($tasklists)) { foreach ($tasklists as $tl) { $close_tasklists = $conn->query("UPDATE tasklist SET status = 0 WHERE ID = $tl[ID]"); } } $upd = $conn->query("UPDATE projekte SET status=0 WHERE ID = $id"); if ($upd) { $nam = $conn->query("SELECT name FROM projekte WHERE ID = $id")->fetch(); $nam = $nam[0]; $this->mylog->add($nam, 'projekt', 5, $id); return true; } else { return false; } } /** * Asssigns a user to a project * * @param int $user ID of user to be assigned * @param int $id ID of project to assign to * @return bool */ function assign($user, $id) { global $conn; $insStmt = $conn->prepare("INSERT INTO projekte_assigned (user,projekt) VALUES (?,?)"); $ins = $insStmt->execute(array((int) $user, (int) $id)); if ($ins) { $userObj = new user(); $user = $userObj->getProfile($user); $this->mylog->add($user["name"], 'user', 6, $id); return true; } else { return false; } } /** * Removes a user from a project * * @param int $user User ID of user to remove * @param int $id Project ID of project to remove from * @return bool */ function deassign($user, $id) { global $conn; $sqlStmt = $conn->prepare("DELETE FROM projekte_assigned WHERE user = ? AND projekt = ?"); $milestone = new milestone(); // Delete the users assignments to closed milestones $donemiles = $milestone->getDoneProjectMilestones($id); if (!empty($donemiles)) { $sql1Stmt = $conn->prepare("DELETE FROM milestones_assigned WHERE user = ? AND milestone = ?"); foreach ($donemiles as $dm) { $sql1 = $sql1Stmt->execute(array((int) $user, $dm['ID'])); } } // Delete the users assignments to open milestones $openmiles = $milestone->getAllProjectMilestones($id, 100000); if (!empty($openmiles)) { $sql2Stmt = $conn->prepare("DELETE FROM milestones_assigned WHERE user = ? AND milestone = ?"); foreach ($openmiles as $om) { $sql2 = $sql2Stmt->execute(array((int) $user, $om['ID'])); } } $task = new task(); $tasks = $task->getProjectTasks($id); // Delete tasks assignments of the user if (!empty($tasks)) { $sql3Stmt = $conn->prepare("DELETE FROM tasks_assigned WHERE user = ? AND task = ?"); foreach ($tasks as $t) { $sql3 = $sql3Stmt->execute(array((int) $user, $t['ID'])); } } // Finally remove the user from the project $del = $sqlStmt->execute(array((int) $user, (int) $id)); if ($del) { $userObj = new user(); $user = $userObj->getProfile($user); $this->mylog->add($user["name"], 'user', 7, $id); return true; } else { return false; } } /** * Gibt alle Daten eines Projekts aus * * @param int $id Eindeutige Projektnummer * @param int $status * @return array $project Projektdaten */ function getProject($id) { global $conn; $id = (int) $id; $sel = $conn->prepare("SELECT * FROM projekte WHERE ID = ?"); $selStmt = $sel->execute(array($id)); $project = $sel->fetch(); if (!empty($project)) { if ($project["end"]) { $daysleft = $this->getDaysLeft($project["end"]); $project["daysleft"] = $daysleft; $endstring = date(CL_DATEFORMAT, $project["end"]); $project["endstring"] = $endstring; } else { $project["daysleft"] = ""; } $startstring = date(CL_DATEFORMAT, $project["start"]); $project["startstring"] = $startstring; $project["name"] = stripslashes($project["name"]); $project["desc"] = stripslashes($project["desc"]); $project["done"] = $this->getProgress($project["ID"]); $companyObj = new company(); $project["customer"] = $companyObj->getProjectCompany($id); return $project; } else { return false; } } /** * Listet die aktuellsten Projekte auf * * @param int $status Bearbeitungsstatus der Projekte (1 = offenes Projekt) * @param int $lim Anzahl der anzuzeigenden Projekte * @return array $projekte Active projects */ function getProjects($status = 1, $lim = 10) { global $conn; $status = (int) $status; $lim = (int) $lim; $projekte = array(); $sel = $conn->prepare("SELECT `ID` FROM projekte WHERE `status`= ? ORDER BY `end` ASC LIMIT $lim"); $selStmt = $sel->execute(array($status)); while ($projekt = $sel->fetch()) { $project = $this->getProject($projekt["ID"]); array_push($projekte, $project); } if (!empty($projekte)) { return $projekte; } else { return false; } } /** * Lists all projects assigned to a given member ordered by due date ascending * * @param int $user Eindeutige Mitgliedsnummer * @param int $status Bearbeitungsstatus von Projekten (1 = offenes Projekt) * @return array $myprojekte Projekte des Mitglieds */ function getMyProjects($user, $status = 1) { global $conn; $myprojekte = array(); $user = (int) $user; $sel = $conn->prepare("SELECT projekt FROM projekte_assigned WHERE user = ? ORDER BY ID ASC"); $selStmt = $sel->execute(array($user)); while ($projs = $sel->fetch()) { $projekt = $conn->query("SELECT ID FROM projekte WHERE ID = " . $projs[0] . " AND status={$conn->quote((int) $status)}")->fetch(); if ($projekt) { $project = $this->getProject($projekt["ID"]); array_push($myprojekte, $project); } } if (!empty($myprojekte)) { // Sort projects by due date ascending $date = array(); foreach ($myprojekte as $key => $row) { $date[$key] = $row['end']; } array_multisort($date, SORT_ASC, $myprojekte); return $myprojekte; } else { return false; } } /** * Lists all project IDs assigned to a user * * @param int $user ID of the user * @return array $myprojekte Project IDs for user */ function getMyProjectIds($user) { global $conn; $myprojekte = array(); $sel = $conn->prepare("SELECT projekt FROM projekte_assigned WHERE user = ? ORDER BY end ASC"); $selStmt = $sel->execute(array($user)); if ($sel) { while ($projs = $sel->fetch()) { $sel2 = $conn->query("SELECT ID FROM projekte WHERE ID = " . $projs[0]); $projekt = $sel2->fetch(); if ($projekt) { array_push($myprojekte, $projekt); } } } if (!empty($myprojekte)) { return $myprojekte; } else { return false; } } /** * Lists all the users in a project * * @param int $project Eindeutige Projektnummer * @param int $lim Maximum auszugebender Mitglieder * @return array $members Projektmitglieder */ function getProjectMembers($project, $lim = 10, $paginate = true) { global $conn; $project = (int) $project; $lim = (int) $lim; $project = (int) $project; $lim = (int) $lim; $members = array(); if ($paginate) { $num = $conn->query("SELECT COUNT(*) FROM projekte_assigned WHERE projekt = $project")->fetch(); $num = $num[0]; $lim = (int)$lim; SmartyPaginate::connect(); // set items per page SmartyPaginate::setLimit($lim); SmartyPaginate::setTotal($num); $start = SmartyPaginate::getCurrentIndex(); $lim = SmartyPaginate::getLimit(); } else { $start = 0; } $sel1 = $conn->query("SELECT user FROM projekte_assigned WHERE projekt = $project LIMIT $start,$lim"); $usr = new user(); while ($user = $sel1->fetch()) { $theuser = $usr->getProfile($user[0]); array_push($members, $theuser); } if (!empty($members)) { return $members; } else { return false; } } /** * Count members in a project * * @param int $project Project ID * @return int $num Number of members */ function countMembers($project) { global $conn; $project = (int) $project; $num = $conn->query("SELECT COUNT(*) FROM projekte_assigned WHERE projekt = $project")->fetch(); return $num[0]; } /** * Progressmeter * * @param int $project Project ID * @return array $done Percent of finished tasks */ function getProgress($project) { global $conn; $project = (int) $project; $otasks = $conn->query("SELECT COUNT(*) FROM tasks WHERE project = $project AND status = 1")->fetch(); $otasks = $otasks[0]; $clotasks = $conn->query("SELECT COUNT(*) FROM tasks WHERE project = $project AND status = 0")->fetch(); $clotasks = $clotasks[0]; $totaltasks = $otasks + $clotasks; if ($totaltasks > 0 and $clotasks > 0) { $done = $clotasks / $totaltasks * 100; $done = round($done); } else { $done = 0; } return $done; } /** * Liste the folders in a project * * @param int $project Project ID * @return array $folders Folders in the project */ function getProjectFolders($project) { global $conn; $project = (int) $project; $sel = $conn->prepare("SELECT * FROM projectfolders WHERE project = ?"); $selStmt = $sel->execute(array($project)); $folders = array(); while ($folder = $sel->fetch()) { array_push($folders, $folder); } if (!empty($folders)) { return $folders; } else { return false; } } /** * Get days until a specified date * * @param int $end End date to compare with * @return int Remaining days */ private function getDaysLeft($end) { $tod = date("d.m.Y"); $start = strtotime($tod); $diff = $end - $start; return floor($diff / 86400); } } ?>Collabtive-2.0/include/class.roles.php000066400000000000000000000232471237252063700200420ustar00rootroot00000000000000 * @name roles * @package Collabtive * @version 0.5 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class roles { function __construct() { } /** * Add a role * This method takes an array with permissions, serializes it to string, and saves it to the Database * * @param string $name Name of the role (for display) * @param array $projects Role permissions for projects * @param array $tasks Role permissions for tasks * @param array $milestones Role permissions for milestones * @param array $customers Role permissions for customers * @param array $messages Role permissions for messages * @param array $files Role permissions for files * @param array $timetracker Role permissions for timetracker * @param array $admin * @param array $chat * @return bool */ function add($name, array $projects, array $tasks, array $milestones, array $messages, array $files, array $timetracker, array $chat, array $admin) { global $conn; $projects = serialize($projects); $tasks = serialize($tasks); $milestones = serialize($milestones); $messages = serialize($messages); $files = serialize($files); $timetracker = serialize($timetracker); $chat = serialize($chat); $admin = serialize($admin); $insStmt = $conn->prepare("INSERT INTO roles (name,projects,tasks,milestones,messages,files,timetracker,chat,admin) VALUES (?,?,?,?,?,?,?,?,?)"); $ins = $insStmt->execute(array($name, $projects, $tasks, $milestones, $messages, $files, $timetracker, $chat, $admin)); if ($ins) { $insid = $conn->lastInsertId(); return $insid; } else { return false; } } /** * Edit a role * This method takes an array with permissions, serializes it to string, and saves it to the Database * Additionally it takes the ID of the role to edit * * @param int $id ID of the role to edit * @param string $name Name of the role (for display) * @param array $projects Role permissions for projects * @param array $tasks Role permissions for tasks * @param array $milestones Role permissions for milestones * @param array $customers Role permissions for customers * @param array $messages Role permissions for messages * @param array $files Role permissions for files * @param array $timetracker Role permissions for timetracker * @param array $chat * @param array $admin * @return bool */ function edit($id, $name, array $projects, array $tasks, array $milestones, array $messages, array $files, array $timetracker, array $chat, array $admin) { global $conn; $id = (int) $id; $projects = serialize($projects); $tasks = serialize($tasks); $milestones = serialize($milestones); $messages = serialize($messages); $files = serialize($files); $timetracker = serialize($timetracker); $chat = serialize($chat); $admin = serialize($admin); $updStmt = $conn->prepare("UPDATE roles SET name=?,projects=?,tasks=?,milestones=?,messages=?,files=?,timetracker=?,chat=?,admin=? WHERE ID = ?"); $upd = $updStmt->execute(array($name, $projects, $tasks, $milestones, $messages, $files, $timetracker, $chat, $admin, $id)); if ($upd) { return true; } else { return false; } } /** * Delete a role * This method takes the ID of the role to be deleted. * It returns true if the deletion was sucessful, otherwise false * * @param int $id ID of the role to be deleted * @return bool */ function del($id) { global $conn; $id = (int) $id; $del = $conn->query("DELETE FROM roles WHERE ID = $id"); $del2 = $conn->query("DELETE FROM roles_assigned WHERE role = $id"); if ($del) { return true; } else { return false; } } /** * Assign a role to a user * Assigns role $role to user $user * * @param int $role ID of the role * @param int $user ID of the user * @return bool */ function assign($role, $user) { global $conn; $role = (int) $role; $user = (int) $user; // get the number of roles already assigned to $user $chk = $conn->query("SELECT COUNT(*) FROM roles_assigned WHERE user = $user")->fetch(); $chk = $chk[0]; // If there already is a role assigned to the user, just update this entry // Otherwise create a new entry if ($chk > 0) { $ins = $conn->query("UPDATE roles_assigned SET role = $role WHERE user = $user"); } else { $ins = $conn->query("INSERT INTO roles_assigned (user,role) VALUES ($user,$role)"); } if ($ins) { return true; } else { return false; } } /** * Deassign a role from a user * Remove role $role from user $user * * @param int $role ID of the role * @param int $user ID of the user * @return bool */ function deassign($role, $user) { global $conn; $role = (int) $role; $user = (int) $user; $del = $conn->query("DELETE FROM roles_assigned WHERE user = $user AND role = $role LIMIT 1"); if ($del) { return true; } else { return false; } } /** * Get all available roles * * @param bool $limit Limit the query or show all ? * @return array $roles Array with roles */ function getAllRoles($limit = false) { global $conn; $roles = array(); if (!$limit) { $sel = $conn->query("SELECT ID FROM roles ORDER BY ID DESC"); } else { $sel = $conn->query("SELECT ID FROM roles ORDER BY ID DESC LIMIT $limit"); } while ($role = $sel->fetch()) { /** * $role["projects"] = unserialize($role["projects"]); * $role["tasks"] = unserialize($role["tasks"]); * $role["milestones"] = unserialize($role["milestones"]); * $role["messages"] = unserialize($role["messages"]); * $role["files"] = unserialize($role["files"]); * $role["timetracker"] = unserialize($role["timetracker"]); * $role["admin"] = unserialize($role["admin"]); */ // array_push($roles, $role); $therole = $this->getRole($role["ID"]); array_push($roles, $therole); } if (!empty($roles)) { return $roles; } else { return array(); } } /** * Translate name of default roles * * Intended for viewing translated list of AllRoles. * Be sure that rolenames in output * are not used for other things than viewing. * * Default Roles are Admin, User, Client * * @param array $roles Array with names to translate * @return array $roles Array with translated role names */ /** * Get the role of a user * This is mainly called by class user * * @param int $user ID of the user * @return bool */ function getUserRole($user) { global $conn; $user = (int) $user; $usr = $conn->query("SELECT role FROM roles_assigned WHERE user = $user")->fetch(); $usr = $usr[0]; if ($usr) { $role = $this->getRole($usr); } else { return false; } if (!empty($role)) { return $role; } else { return array(); } } /** * make sure all the fields are either 1 or 0 , fill empty ones with 0 * This is mainly called when adding a role * * @param array $inarr Array to sanitize * @return array $inarr Sanitized array */ function sanitizeArray($inarr) { if (!is_array($inarr)) { $inarr = array(); } if (empty($inarr["add"])) { $inarr["add"] = 0; } if (empty($inarr["edit"])) { $inarr["edit"] = 0; } if (empty($inarr["del"])) { $inarr["del"] = 0; } if (empty($inarr["close"])) { $inarr["close"] = 0; } if (empty($inarr["read"])) { $inarr["read"] = 0; } if (empty($inarr["view"])) { $inarr["view"] = 0; } return (array) $inarr; } /** * Get an array for a role * * @param int $role Role ID * @return array $therole Role as array */ private function getRole($role) { global $conn; $role = (int) $role; // Get the serialized strings from the db $sel2 = $conn->query("SELECT * FROM roles WHERE ID = $role"); $therole = $sel2->fetch(); // Unserialize to an array $therole["projects"] = unserialize($therole["projects"]); $therole["tasks"] = unserialize($therole["tasks"]); $therole["milestones"] = unserialize($therole["milestones"]); $therole["messages"] = unserialize($therole["messages"]); $therole["files"] = unserialize($therole["files"]); $therole["timetracker"] = unserialize($therole["timetracker"]); $therole["chat"] = unserialize($therole["chat"]); $therole["admin"] = unserialize($therole["admin"]); if (!empty($therole)) { return $therole; } else { return array(); } } } ?> Collabtive-2.0/include/class.rss.php000066400000000000000000001441601237252063700175230ustar00rootroot00000000000000useCached(); // use cached version if age<1 hour * $rss->title = "PHP news"; * $rss->description = "daily news from the PHP scripting world"; * * //optional * $rss->descriptionTruncSize = 500; * $rss->descriptionHtmlSyndicated = true; * * $rss->link = "http://www.dailyphp.net/news"; * $rss->syndicationURL = "http://www.dailyphp.net/".$_SERVER["PHP_SELF"]; * * $image = new FeedImage(); * $image->title = "dailyphp.net logo"; * $image->url = "http://www.dailyphp.net/images/logo.gif"; * $image->link = "http://www.dailyphp.net"; * $image->description = "Feed provided by dailyphp.net. Click to visit."; * * //optional * $image->descriptionTruncSize = 500; * $image->descriptionHtmlSyndicated = true; * * $rss->image = $image; * * // get your news items from somewhere, e.g. your database: * mysql_select_db($dbHost, $dbUser, $dbPass); * $res = mysql_query("SELECT * FROM news ORDER BY newsdate DESC"); * while ($data = mysql_fetch_object($res)) { * $item = new FeedItem(); * $item->title = $data->title; * $item->link = $data->url; * $item->description = $data->short; * * //optional * item->descriptionTruncSize = 500; * item->descriptionHtmlSyndicated = true; * * $item->date = $data->newsdate; * $item->source = "http://www.dailyphp.net"; * $item->author = "John Doe"; * * $rss->addItem($item); * } * * // valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1 (deprecated), * // MBOX, OPML, ATOM, ATOM0.3, HTML, JS * echo $rss->saveFeed("RSS1.0", "news/feed.xml"); * * // your local timezone, set to "" to disable or for GMT * * /* * Version string. */ define("FEEDCREATOR_VERSION", "Collabtive"); define("TIME_ZONE", "+01:00"); /* * A FeedItem is a part of a FeedCreator feed. * * @author Kai Blankenhorn * @since 1.3 */ class FeedItem extends HtmlDescribable { /* * Mandatory attributes of an item. */ var $title, $description, $link; /* * Optional attributes of an item. */ var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator; /* * Publishing date of an item. May be in one of the following formats: * * RFC 822: * "Mon, 20 Jan 03 18:05:41 +0400" * "20 Jan 03 18:05:41 +0000" * * ISO 8601: * "2003-01-20T18:05:41+04:00" * * Unix: * 1043082341 */ var $date; /* * Any additional elements to include as an assiciated array. All $key => $value pairs * will be included unencoded in the feed item in the form * <$key>$value * Again: No encoding will be used! This means you can invalidate or enhance the feed * if $value contains markup. This may be abused to embed tags not implemented by * the FeedCreator class used. */ var $additionalElements = Array(); // on hold // var $source; } /* * An FeedImage may be added to a FeedCreator feed. * @author Kai Blankenhorn * @since 1.3 */ class FeedImage extends HtmlDescribable { /* * Mandatory attributes of an image. */ var $title, $url, $link; /* * Optional attributes of an image. */ var $width, $height, $description; } /* * An HtmlDescribable is an item within a feed that can have a description that may * include HTML markup. */ class HtmlDescribable { /* * Indicates whether the description field should be rendered in HTML. */ var $descriptionHtmlSyndicated; /* * Indicates whether and to how many characters a description should be truncated. */ var $descriptionTruncSize; /* * Returns a formatted description field, depending on descriptionHtmlSyndicated and * $descriptionTruncSize properties * @return string the formatted description */ function getDescription() { $descriptionField = new FeedHtmlField($this->description); $descriptionField->syndicateHtml = $this->descriptionHtmlSyndicated; $descriptionField->truncSize = $this->descriptionTruncSize; return $descriptionField->output(); } } /* * An FeedHtmlField describes and generates * a feed, item or image html field (probably a description). Output is * generated based on $truncSize, $syndicateHtml properties. * @author Pascal Van Hecke * @version 1.6 */ class FeedHtmlField { /* * Mandatory attributes of a FeedHtmlField. */ var $rawFieldContent; /* * Optional attributes of a FeedHtmlField. * */ var $truncSize, $syndicateHtml; /* * Creates a new instance of FeedHtmlField. * @param $string: if given, sets the rawFieldContent property */ function FeedHtmlField($parFieldContent) { if ($parFieldContent) { $this->rawFieldContent = $parFieldContent; } } /* * Creates the right output, depending on $truncSize, $syndicateHtml properties. * @return string the formatted field */ function output() { // when field available and syndicated in html we assume // - valid html in $rawFieldContent and we enclose in CDATA tags // - no truncation (truncating risks producing invalid html) if (!$this->rawFieldContent) { $result = ""; } elseif ($this->syndicateHtml) { $result = "rawFieldContent . "]]>"; } else { if ($this->truncSize and is_int($this->truncSize)) { $result = FeedCreator::iTrunc(htmlspecialchars($this->rawFieldContent), $this->truncSize); } else { $result = htmlspecialchars($this->rawFieldContent); } } return $result; } } /* * UniversalFeedCreator lets you choose during runtime which * format to build. * For general usage of a feed class, see the FeedCreator class * below or the example above. * * @since 1.3 * @author Kai Blankenhorn */ class UniversalFeedCreator extends FeedCreator { var $_feed; function _setFormat($format) { switch (strtoupper($format)) { case "2.0": // fall through case "RSS2.0": $this->_feed = new RSSCreator20(); break; case "1.0": // fall through case "RSS1.0": $this->_feed = new RSSCreator10(); break; case "0.91": // fall through case "RSS0.91": $this->_feed = new RSSCreator091(); break; case "PIE0.1": $this->_feed = new PIECreator01(); break; case "MBOX": $this->_feed = new MBOXCreator(); break; case "OPML": $this->_feed = new OPMLCreator(); break; case "ATOM": // fall through: always the latest ATOM version case "ATOM0.3": $this->_feed = new AtomCreator03(); break; case "HTML": $this->_feed = new HTMLCreator(); break; case "JS": // fall through case "JAVASCRIPT": $this->_feed = new JSCreator(); break; default: $this->_feed = new RSSCreator091(); break; } $vars = get_object_vars($this); foreach ($vars as $key => $value) { // prevent overwriting of properties "contentType", "encoding"; do not copy "_feed" itself if (!in_array($key, array("_feed", "contentType", "encoding"))) { $this->_feed-> { $key} = $this-> { $key} ; } } } /* * Creates a syndication feed based on the items previously added. * * @see FeedCreator::addItem() * @param string format format the feed should comply to. Valid values are: * "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3", "HTML", "JS" * @return string the contents of the feed. */ function createFeed($format = "RSS0.91") { $this->_setFormat($format); return $this->_feed->createFeed(); } /* * Saves this feed as a file on the local disk. After the file is saved, an HTTP redirect * header may be sent to redirect the use to the newly created file. * @since 1.4 * * @param string format format the feed should comply to. Valid values are: * "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM", "ATOM0.3", "HTML", "JS" * @param string filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()). * @param boolean displayContents optional send the content of the file or not. If true, the file will be sent in the body of the response. */ function saveFeed($format = "RSS0.91", $filename = "", $displayContents = true) { $this->_setFormat($format); $this->_feed->saveFeed($filename, $displayContents); } /* * Turns on caching and checks if there is a recent version of this feed in the cache. * If there is, an HTTP redirect header is sent. * To effectively use caching, you should create the FeedCreator object and call this method * before anything else, especially before you do the time consuming task to build the feed * (web fetching, for example). * * @param string format format the feed should comply to. Valid values are: * "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3". * @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()). * @param timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour) */ function useCached($format = "RSS0.91", $filename = "", $timeout = 3600) { $this->_setFormat($format); $this->_feed->useCached($filename, $timeout); } } /* * FeedCreator is the abstract base implementation for concrete * implementations that implement a specific format of syndication. * * @abstract * @author Kai Blankenhorn * @since 1.4 */ class FeedCreator extends HtmlDescribable { /* * Mandatory attributes of a feed. */ var $title, $description, $link; /* * Optional attributes of a feed. */ var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays; /* * The url of the external xsl stylesheet used to format the naked rss feed. * Ignored in the output when empty. */ var $xslStyleSheet = ""; /* * @access private */ var $items = Array(); /* * This feed's MIME content type. * @since 1.4 * @access private */ var $contentType = "application/xml"; /* * This feed's character encoding. * @since 1.6.1 **/ // var $encoding = "ISO-8859-1"; var $encoding = "UTF-8"; /* * Any additional elements to include as an assiciated array. All $key => $value pairs * will be included unencoded in the feed in the form * <$key>$value * Again: No encoding will be used! This means you can invalidate or enhance the feed * if $value contains markup. This may be abused to embed tags not implemented by * the FeedCreator class used. */ var $additionalElements = Array(); /* * Adds an FeedItem to the feed. * * @param object FeedItem $item The FeedItem to add to the feed. * @access public */ function addItem($item) { $this->items[] = $item; } /* * Truncates a string to a certain length at the most sensible point. * First, if there's a '.' character near the end of the string, the string is truncated after this character. * If there is no '.', the string is truncated after the last ' ' character. * If the string is truncated, " ..." is appended. * If the string is already shorter than $length, it is returned unchanged. * * @static * @param string string A string to be truncated. * @param int length the maximum length the string should be truncated to * @return string the truncated string */ function iTrunc($string, $length) { if (strlen($string) <= $length) { return $string; } $pos = strrpos($string, "."); if ($pos >= $length-4) { $string = substr($string, 0, $length-4); $pos = strrpos($string, "."); } if ($pos >= $length * 0.4) { return substr($string, 0, $pos + 1) . " ..."; } $pos = strrpos($string, " "); if ($pos >= $length-4) { $string = substr($string, 0, $length-4); $pos = strrpos($string, " "); } if ($pos >= $length * 0.4) { return substr($string, 0, $pos) . " ..."; } return substr($string, 0, $length-4) . " ..."; } /* * Creates a comment indicating the generator of this feed. * The format of this comment seems to be recognized by * Syndic8.com. */ function _createGeneratorComment() { return "\n"; } /* * Creates a string containing all additional elements specified in * $additionalElements. * @param elements array an associative array containing key => value pairs * @param indentString string a string that will be inserted before every generated line * @return string the XML tags corresponding to $additionalElements */ function _createAdditionalElements($elements, $indentString = "") { $ae = ""; if (is_array($elements)) { foreach($elements AS $key => $value) { $ae .= $indentString . "<$key>$value\n"; } } return $ae; } function _createStylesheetReferences() { $xml = ""; if (isset($this->cssStyleSheet)) $xml .= "cssStyleSheet . "\" type=\"text/css\"?>\n"; if (isset($this->xslStyleSheet)) $xml .= "xslStyleSheet . "\" type=\"text/xsl\"?>\n"; return $xml; } /* * Builds the feed's text. * @abstract * @return string the feed's complete text */ function createFeed() { } /* * Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed to .xml. * For example: * * echo $_SERVER["PHP_SELF"]."\n"; * echo FeedCreator::_generateFilename(); * * would produce: * * /rss/latestnews.php * latestnews.xml * * @return string the feed cache filename * @since 1.4 * @access private */ function _generateFilename() { $fileInfo = pathinfo($_SERVER["PHP_SELF"]); return substr($fileInfo["basename"], 0, - (strlen($fileInfo["extension"]) + 1)) . ".xml"; } /* * @since 1.4 * @access private */ function _redirect($filename) { // attention, heavily-commented-out-area // maybe use this in addition to file time checking // Header("Expires: ".date("r",time()+$this->_timeout)); /* no caching at all, doesn't seem to work as good: Header("Cache-Control: no-cache"); Header("Pragma: no-cache"); */ // HTTP redirect, some feed readers' simple HTTP implementations don't follow it // Header("Location: ".$filename); Header("Content-Type: " . $this->contentType . "; charset=" . $this->encoding . "; filename=" . basename($filename)); Header("Content-Disposition: inline; filename=" . basename($filename)); readfile($filename, "r"); die(); } /* * Turns on caching and checks if there is a recent version of this feed in the cache. * If there is, an HTTP redirect header is sent. * To effectively use caching, you should create the FeedCreator object and call this method * before anything else, especially before you do the time consuming task to build the feed * (web fetching, for example). * @since 1.4 * @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()). * @param timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour) */ function useCached($filename = "", $timeout = 3600) { $this->_timeout = $timeout; if ($filename == "") { $filename = $this->_generateFilename(); } if (file_exists($filename) AND (time() - filemtime($filename) < $timeout)) { $this->_redirect($filename); } } /* * Saves this feed as a file on the local disk. After the file is saved, a redirect * header may be sent to redirect the user to the newly created file. * @since 1.4 * * @param filename string optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()). * @param redirect boolean optional send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file. */ function saveFeed($filename = "", $displayContents = true) { if ($filename == "") { $filename = $this->_generateFilename(); } $feedFile = fopen($filename, "w+"); if ($feedFile) { fputs($feedFile, $this->createFeed()); fclose($feedFile); if ($displayContents) { $this->_redirect($filename); } } else { echo "
      Error creating feed file, please check write permissions.
      "; } } } /* * FeedDate is an internal class that stores a date for a feed or feed item. * Usually, you won't need to use this. */ class FeedDate { var $unix; /* * Creates a new instance of FeedDate representing a given date. * Accepts RFC 822, ISO 8601 date formats as well as unix time stamps. * @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and time is used. */ function FeedDate($dateString = "") { if ($dateString == "") $dateString = date("r"); if (is_integer($dateString)) { $this->unix = $dateString; return; } if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~", $dateString, $matches)) { $months = Array("Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12); $this->unix = mktime($matches[4], $matches[5], $matches[6], $months[$matches[2]], $matches[1], $matches[3]); if (substr($matches[7], 0, 1) == '+' OR substr($matches[7], 0, 1) == '-') { $tzOffset = (substr($matches[7], 0, 3) * 60 + substr($matches[7], -2)) * 60; } else { if (strlen($matches[7]) == 1) { $oneHour = 3600; $ord = ord($matches[7]); if ($ord < ord("M")) { $tzOffset = (ord("A") - $ord - 1) * $oneHour; } elseif ($ord >= ord("M") AND $matches[7] != "Z") { $tzOffset = ($ord - ord("M")) * $oneHour; } elseif ($matches[7] == "Z") { $tzOffset = 0; } } switch ($matches[7]) { case "UT": case "GMT": $tzOffset = 0; } } $this->unix += $tzOffset; return; } if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~", $dateString, $matches)) { $this->unix = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); if (substr($matches[7], 0, 1) == '+' OR substr($matches[7], 0, 1) == '-') { $tzOffset = (substr($matches[7], 0, 3) * 60 + substr($matches[7], -2)) * 60; } else { if ($matches[7] == "Z") { $tzOffset = 0; } } $this->unix += $tzOffset; return; } $this->unix = 0; } /* * Gets the date stored in this FeedDate as an RFC 822 date. * * @return a date in RFC 822 format */ function rfc822() { // return gmdate("r",$this->unix); $date = gmdate("D, d M Y H:i:s", $this->unix); if (TIME_ZONE != "") $date .= " " . str_replace(":", "", TIME_ZONE); return $date; } /* * Gets the date stored in this FeedDate as an ISO 8601 date. * * @return a date in ISO 8601 format */ function iso8601() { $date = gmdate("Y-m-d\TH:i:sO", $this->unix); $date = substr($date, 0, 22) . ':' . substr($date, -2); if (TIME_ZONE != "") $date = str_replace("+00:00", TIME_ZONE, $date); return $date; } /* * Gets the date stored in this FeedDate as unix time stamp. * * @return a date as a unix time stamp */ function unix() { return $this->unix; } } /* * RSSCreator10 is a FeedCreator that implements RDF Site Summary (RSS) 1.0. * * @see http://www.purl.org/rss/1.0/ * @since 1.3 * @author Kai Blankenhorn */ class RSSCreator10 extends FeedCreator { /* * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0. * The feed will contain all items previously added in the same order. * @return string the feed's complete text */ function createFeed() { $feed = "encoding . "\"?>\n"; $feed .= $this->_createGeneratorComment(); if ($this->cssStyleSheet == "") { $cssStyleSheet = "http://www.w3.org/2000/08/w3c-synd/style.css"; } $feed .= $this->_createStylesheetReferences(); $feed .= "\n"; $feed .= " syndicationURL . "\">\n"; $feed .= " " . htmlspecialchars($this->title) . "\n"; $feed .= " " . htmlspecialchars($this->description) . "\n"; $feed .= " " . $this->link . "\n"; if ($this->image != null) { $feed .= " image->url . "\" />\n"; } $now = new FeedDate(); $feed .= " " . htmlspecialchars($now->iso8601()) . "\n"; $feed .= " \n"; $feed .= " \n"; for ($i = 0;$i < count($this->items);$i++) { $feed .= " items[$i]->link) . "\"/>\n"; } $feed .= " \n"; $feed .= " \n"; $feed .= " \n"; if ($this->image != null) { $feed .= " image->url . "\">\n"; $feed .= " " . $this->image->title . "\n"; $feed .= " " . $this->image->link . "\n"; $feed .= " " . $this->image->url . "\n"; $feed .= " \n"; } $feed .= $this->_createAdditionalElements($this->additionalElements, " "); for ($i = 0;$i < count($this->items);$i++) { $feed .= " items[$i]->link) . "\">\n"; // $feed.= " Posting\n"; $feed .= " text/html\n"; if ($this->items[$i]->date != null) { $itemDate = new FeedDate($this->items[$i]->date); $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; } if ($this->items[$i]->source != "") { $feed .= " " . htmlspecialchars($this->items[$i]->source) . "\n"; } if ($this->items[$i]->author != "") { $feed .= " " . htmlspecialchars($this->items[$i]->author) . "\n"; } $feed .= " " . htmlspecialchars(strip_tags(strtr($this->items[$i]->title, "\n\r", " "))) . "\n"; $feed .= " " . htmlspecialchars($this->items[$i]->link) . "\n"; $feed .= " " . htmlspecialchars($this->items[$i]->description) . "\n"; $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " "); $feed .= " \n"; } $feed .= "\n"; return $feed; } } /* * RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3. * * @see http://my.netscape.com/publish/formats/rss-spec-0.91.html * @since 1.3 * @author Kai Blankenhorn */ class RSSCreator091 extends FeedCreator { /* * Stores this RSS feed's version number. * @access private */ var $RSSVersion; function RSSCreator091() { $this->_setRSSVersion("0.91"); $this->contentType = "application/rss+xml"; } /* * Sets this RSS feed's version number. * @access private */ function _setRSSVersion($version) { $this->RSSVersion = $version; } /* * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0. * The feed will contain all items previously added in the same order. * @return string the feed's complete text */ function createFeed() { $feed = "encoding . "\"?>\n"; $feed .= $this->_createGeneratorComment(); $feed .= $this->_createStylesheetReferences(); $feed .= "RSSVersion . "\">\n"; $feed .= " \n"; $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->title), 100) . "\n"; $this->descriptionTruncSize = 500; $feed .= " " . $this->getDescription() . "\n"; $feed .= " " . $this->link . "\n"; $now = new FeedDate(); $feed .= " " . htmlspecialchars($now->rfc822()) . "\n"; $feed .= " " . FEEDCREATOR_VERSION . "\n"; if ($this->image != null) { $feed .= " \n"; $feed .= " " . $this->image->url . "\n"; $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100) . "\n"; $feed .= " " . $this->image->link . "\n"; if ($this->image->width != "") { $feed .= " " . $this->image->width . "\n"; } if ($this->image->height != "") { $feed .= " " . $this->image->height . "\n"; } if ($this->image->description != "") { $feed .= " " . $this->image->getDescription() . "\n"; } $feed .= " \n"; } if ($this->language != "") { $feed .= " " . $this->language . "\n"; } if ($this->copyright != "") { $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->copyright), 100) . "\n"; } if ($this->editor != "") { $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->editor), 100) . "\n"; } if ($this->webmaster != "") { $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->webmaster), 100) . "\n"; } if ($this->pubDate != "") { $pubDate = new FeedDate($this->pubDate); $feed .= " " . htmlspecialchars($pubDate->rfc822()) . "\n"; } if ($this->category != "") { $feed .= " " . htmlspecialchars($this->category) . "\n"; } if ($this->docs != "") { $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->docs), 500) . "\n"; } if ($this->ttl != "") { $feed .= " " . htmlspecialchars($this->ttl) . "\n"; } if ($this->rating != "") { $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->rating), 500) . "\n"; } if ($this->skipHours != "") { $feed .= " " . htmlspecialchars($this->skipHours) . "\n"; } if ($this->skipDays != "") { $feed .= " " . htmlspecialchars($this->skipDays) . "\n"; } $feed .= $this->_createAdditionalElements($this->additionalElements, " "); for ($i = 0;$i < count($this->items);$i++) { $feed .= " \n"; $feed .= " " . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100) . "\n"; $feed .= " " . htmlspecialchars($this->items[$i]->link) . "\n"; $feed .= " " . $this->items[$i]->getDescription() . "\n"; if ($this->items[$i]->author != "") { $feed .= " " . htmlspecialchars($this->items[$i]->author) . "\n"; } /* // on hold if ($this->items[$i]->source!="") { $feed.= " ".htmlspecialchars($this->items[$i]->source)."\n"; } */ if ($this->items[$i]->category != "") { $feed .= " " . htmlspecialchars($this->items[$i]->category) . "\n"; } if ($this->items[$i]->comments != "") { $feed .= " " . htmlspecialchars($this->items[$i]->comments) . "\n"; } if ($this->items[$i]->date != "") { $itemDate = new FeedDate($this->items[$i]->date); $feed .= " " . htmlspecialchars($itemDate->rfc822()) . "\n"; } if ($this->items[$i]->guid != "") { $feed .= " " . htmlspecialchars($this->items[$i]->guid) . "\n"; } $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " "); $feed .= " \n"; } $feed .= " \n"; $feed .= "\n"; return $feed; } } /* * RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0. * * @see http://backend.userland.com/rss * @since 1.3 * @author Kai Blankenhorn */ class RSSCreator20 extends RSSCreator091 { function RSSCreator20() { parent::_setRSSVersion("2.0"); } } /* * PIECreator01 is a FeedCreator that implements the emerging PIE specification, * as in http://intertwingly.net/wiki/pie/Syntax. * * @deprecated * @since 1.3 * @author Scott Reynen and Kai Blankenhorn */ class PIECreator01 extends FeedCreator { function PIECreator01() { $this->encoding = "utf-8"; } function createFeed() { $feed = "encoding . "\"?>\n"; $feed .= $this->_createStylesheetReferences(); $feed .= "\n"; $feed .= " " . FeedCreator::iTrunc(htmlspecialchars($this->title), 100) . "\n"; $this->truncSize = 500; $feed .= " " . $this->getDescription() . "\n"; $feed .= " " . $this->link . "\n"; for ($i = 0;$i < count($this->items);$i++) { $feed .= " \n"; $feed .= " " . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100) . "\n"; $feed .= " " . htmlspecialchars($this->items[$i]->link) . "\n"; $itemDate = new FeedDate($this->items[$i]->date); $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; $feed .= " " . htmlspecialchars($this->items[$i]->guid) . "\n"; if ($this->items[$i]->author != "") { $feed .= " \n"; $feed .= " " . htmlspecialchars($this->items[$i]->author) . "\n"; if ($this->items[$i]->authorEmail != "") { $feed .= " " . $this->items[$i]->authorEmail . "\n"; } $feed .= " \n"; } $feed .= " \n"; $feed .= "
      " . $this->items[$i]->getDescription() . "
      \n"; $feed .= "
      \n"; $feed .= "
      \n"; } $feed .= "
      \n"; return $feed; } } /* * AtomCreator03 is a FeedCreator that implements the atom specification, * as in http://www.intertwingly.net/wiki/pie/FrontPage. * Please note that just by using AtomCreator03 you won't automatically * produce valid atom files. For example, you have to specify either an editor * for the feed or an author for every single feed item. * * Some elements have not been implemented yet. These are (incomplete list): * author URL, item author's email and URL, item contents, alternate links, * other link content types than text/html. Some of them may be created with * AtomCreator03::additionalElements. * * @see FeedCreator#additionalElements * @since 1.6 * @author Kai Blankenhorn , Scott Reynen */ class AtomCreator03 extends FeedCreator { function AtomCreator03() { $this->contentType = "application/atom+xml"; $this->encoding = "utf-8"; } function createFeed() { $feed = "encoding . "\"?>\n"; $feed .= $this->_createGeneratorComment(); $feed .= $this->_createStylesheetReferences(); $feed .= "language != "") { $feed .= " xml:lang=\"" . $this->language . "\""; } $feed .= ">\n"; $feed .= " " . htmlspecialchars($this->title) . "\n"; $feed .= " " . htmlspecialchars($this->description) . "\n"; $feed .= " link) . "\"/>\n"; $feed .= " " . htmlspecialchars($this->link) . "\n"; $now = new FeedDate(); $feed .= " " . htmlspecialchars($now->iso8601()) . "\n"; if ($this->editor != "") { $feed .= " \n"; $feed .= " " . $this->editor . "\n"; if ($this->editorEmail != "") { $feed .= " " . $this->editorEmail . "\n"; } $feed .= " \n"; } $feed .= " " . FEEDCREATOR_VERSION . "\n"; $feed .= $this->_createAdditionalElements($this->additionalElements, " "); for ($i = 0;$i < count($this->items);$i++) { $feed .= " \n"; $feed .= " " . htmlspecialchars(strip_tags($this->items[$i]->title)) . "\n"; $feed .= " items[$i]->link) . "\"/>\n"; if ($this->items[$i]->date == "") { $this->items[$i]->date = time(); } $itemDate = new FeedDate($this->items[$i]->date); $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; $feed .= " " . htmlspecialchars($itemDate->iso8601()) . "\n"; $feed .= " " . htmlspecialchars($this->items[$i]->link) . "\n"; $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " "); if ($this->items[$i]->author != "") { $feed .= " \n"; $feed .= " " . htmlspecialchars($this->items[$i]->author) . "\n"; $feed .= " \n"; } if ($this->items[$i]->description != "") { $feed .= " " . htmlspecialchars($this->items[$i]->description) . "\n"; } $feed .= " \n"; } $feed .= "\n"; return $feed; } } /* * MBOXCreator is a FeedCreator that implements the mbox format * as described in http://www.qmail.org/man/man5/mbox.html * * @since 1.3 * @author Kai Blankenhorn */ class MBOXCreator extends FeedCreator { function MBOXCreator() { $this->contentType = "text/plain"; $this->encoding = "ISO-8859-15"; } function qp_enc($input = "", $line_max = 76) { $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); $lines = preg_split("/(?:\r\n|\r|\n)/", $input); $eol = "\r\n"; $escape = "="; $output = ""; while (list(, $line) = each($lines)) { // $line = rtrim($line); // remove trailing white space -> no =20\r\n necessary $linlen = strlen($line); $newline = ""; for($i = 0; $i < $linlen; $i++) { $c = substr($line, $i, 1); $dec = ord($c); if (($dec == 32) && ($i == ($linlen - 1))) { // convert space at eol only $c = "=20"; } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { // always encode "\t", which is *not* required $h2 = floor($dec / 16); $h1 = floor($dec % 16); $c = $escape . $hex["$h2"] . $hex["$h1"]; } if ((strlen($newline) + strlen($c)) >= $line_max) { // CRLF is not counted $output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay $newline = ""; } $newline .= $c; } // end of for $output .= $newline . $eol; } return trim($output); } /* * Builds the MBOX contents. * @return string the feed's complete text */ function createFeed() { for ($i = 0;$i < count($this->items);$i++) { if ($this->items[$i]->author != "") { $from = $this->items[$i]->author; } else { $from = $this->title; } $itemDate = new FeedDate($this->items[$i]->date); $feed .= "From " . strtr(MBOXCreator::qp_enc($from), " ", "_") . " " . date("D M d H:i:s Y", $itemDate->unix()) . "\n"; $feed .= "Content-Type: text/plain;\n"; $feed .= " charset=\"" . $this->encoding . "\"\n"; $feed .= "Content-Transfer-Encoding: quoted-printable\n"; $feed .= "Content-Type: text/plain\n"; $feed .= "From: \"" . MBOXCreator::qp_enc($from) . "\"\n"; $feed .= "Date: " . $itemDate->rfc822() . "\n"; $feed .= "Subject: " . MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title, 100)) . "\n"; $feed .= "\n"; $body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description)); $feed .= preg_replace("~\nFrom ([^\n]*)(\n?)~", "\n>From $1$2\n", $body); $feed .= "\n"; $feed .= "\n"; } return $feed; } /* * Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types. * @return string the feed cache filename * @since 1.4 * @access private */ function _generateFilename() { $fileInfo = pathinfo($_SERVER["PHP_SELF"]); return substr($fileInfo["basename"], 0, - (strlen($fileInfo["extension"]) + 1)) . ".mbox"; } } /* * OPMLCreator is a FeedCreator that implements OPML 1.0. * * @see http://opml.scripting.com/spec * @author Dirk Clemens, Kai Blankenhorn * @since 1.5 */ class OPMLCreator extends FeedCreator { function OPMLCreator() { $this->encoding = "utf-8"; } function createFeed() { $feed = "encoding . "\"?>\n"; $feed .= $this->_createGeneratorComment(); $feed .= $this->_createStylesheetReferences(); $feed .= "\n"; $feed .= " \n"; $feed .= " " . htmlspecialchars($this->title) . "\n"; if ($this->pubDate != "") { $date = new FeedDate($this->pubDate); $feed .= " " . $date->rfc822() . "\n"; } if ($this->lastBuildDate != "") { $date = new FeedDate($this->lastBuildDate); $feed .= " " . $date->rfc822() . "\n"; } if ($this->editor != "") { $feed .= " " . $this->editor . "\n"; } if ($this->editorEmail != "") { $feed .= " " . $this->editorEmail . "\n"; } $feed .= " \n"; $feed .= " \n"; for ($i = 0;$i < count($this->items);$i++) { $feed .= " items[$i]->title, "\n\r", " "))); $feed .= " title=\"" . $title . "\""; $feed .= " text=\"" . $title . "\""; // $feed.= " description=\"".htmlspecialchars($this->items[$i]->description)."\""; $feed .= " url=\"" . htmlspecialchars($this->items[$i]->link) . "\""; $feed .= "/>\n"; } $feed .= " \n"; $feed .= "\n"; return $feed; } } /* * HTMLCreator is a FeedCreator that writes an HTML feed file to a specific * location, overriding the createFeed method of the parent FeedCreator. * The HTML produced can be included over http by scripting languages, or serve * as the source for an IFrame. * All output by this class is embedded in
      tags to enable formatting * using CSS. * * @author Pascal Van Hecke * @since 1.7 */ class HTMLCreator extends FeedCreator { var $contentType = "text/html"; /* * Contains HTML to be output at the start of the feed's html representation. */ var $header; /* * Contains HTML to be output at the end of the feed's html representation. */ var $footer ; /* * Contains HTML to be output between entries. A separator is only used in * case of multiple entries. */ var $separator; /* * Used to prefix the stylenames to make sure they are unique * and do not clash with stylenames on the users' page. */ var $stylePrefix; /* * Determines whether the links open in a new window or not. */ var $openInNewWindow = true; var $imageAlign = "right"; /* * In case of very simple output you may want to get rid of the style tags, * hence this variable. There's no equivalent on item level, but of course you can * add strings to it while iterating over the items ($this->stylelessOutput .= ...) * and when it is non-empty, ONLY the styleless output is printed, the rest is ignored * in the function createFeed(). */ var $stylelessOutput = ""; /* * Writes the HTML. * @return string the scripts's complete text */ function createFeed() { // if there is styleless output, use the content of this variable and ignore the rest if ($this->stylelessOutput != "") { return $this->stylelessOutput; } // if no stylePrefix is set, generate it yourself depending on the script name if ($this->stylePrefix == "") { $this->stylePrefix = str_replace(".", "_", $this->_generateFilename()) . "_"; } // set an openInNewWindow_token_to be inserted or not if ($this->openInNewWindow) { $targetInsert = " target='_blank'"; } // use this array to put the lines in and implode later with "document.write" javascript $feedArray = array(); if ($this->image != null) { $imageStr = "
      " . "" .
            FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100) . "image->width) { $imageStr .= " width='" . $this->image->width . "' "; } if ($this->image->height) { $imageStr .= " height='" . $this->image->height . "' "; } $imageStr .= "/>"; $feedArray[] = $imageStr; } if ($this->title) { $feedArray[] = ""; } if ($this->getDescription()) { $feedArray[] = "
      " . str_replace("]]>", "", str_replace("getDescription())) . "
      "; } if ($this->header) { $feedArray[] = "
      " . $this->header . "
      "; } for ($i = 0;$i < count($this->items);$i++) { if ($this->separator and $i > 0) { $feedArray[] = "
      " . $this->separator . "
      "; } if ($this->items[$i]->title) { if ($this->items[$i]->link) { $feedArray[] = ""; } else { $feedArray[] = "
      " . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100) . "
      "; } } if ($this->items[$i]->getDescription()) { $feedArray[] = "
      " . str_replace("]]>", "", str_replace("items[$i]->getDescription())) . "
      "; } } if ($this->footer) { $feedArray[] = "
      " . $this->footer . "
      "; } $feed = "" . join($feedArray, "\r\n"); return $feed; } /* * Overrrides parent to produce .html extensions * * @return string the feed cache filename * @since 1.4 * @access private */ function _generateFilename() { $fileInfo = pathinfo($_SERVER["PHP_SELF"]); return substr($fileInfo["basename"], 0, - (strlen($fileInfo["extension"]) + 1)) . ".html"; } } /* * JSCreator is a class that writes a js file to a specific * location, overriding the createFeed method of the parent HTMLCreator. * * @author Pascal Van Hecke */ class JSCreator extends HTMLCreator { var $contentType = "text/javascript"; /* * writes the javascript * @return string the scripts's complete text */ function createFeed() { $feed = parent::createFeed(); $feedArray = explode("\n", $feed); $jsFeed = ""; foreach ($feedArray as $value) { $jsFeed .= "document.write('" . trim(addslashes($value)) . "');\n"; } return $jsFeed; } /* * Overrrides parent to produce .js extensions * * @return string the feed cache filename * @since 1.4 * @access private */ function _generateFilename() { $fileInfo = pathinfo($_SERVER["PHP_SELF"]); return substr($fileInfo["basename"], 0, - (strlen($fileInfo["extension"]) + 1)) . ".js"; } } ?> Collabtive-2.0/include/class.search.php000066400000000000000000000251671237252063700201660ustar00rootroot00000000000000 * @name search * @version 0.4.6 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class search { function __construct() { } function dosearch($query, $project = 0) { if (empty($query)) { return false; } if ($project == 0) { $projects = $this->searchProjects($query); $milestones = $this->searchMilestones($query); if ($_SESSION["userpermissions"]["admin"]["add"]) { $messages = $this->searchMessage($query); } else { $messages = array(); } $tasks = $this->searchTasks($query); $files = $this->searchFiles($query); $user = $this->searchUser($query); $result = array_merge($projects, $milestones, $tasks, $messages , $files, $user); } else { $milestones = $this->searchMilestones($query, $project); if ($_SESSION["userpermissions"]["admin"]["add"]) { $messages = $this->searchMessage($query, $project); } else { $messages = array(); } $tasks = $this->searchTasks($query, $project); $files = $this->searchFiles($query, $project); $user = $this->searchUser($query, $project); $result = array_merge($milestones, $tasks, $messages , $files, $user); } if (!empty($result)) { return $result; } else { return false; } } function searchProjects($query) { global $conn; $selStmt = $conn->prepare("SELECT `ID`,`name`,`desc`,`status` FROM projekte WHERE `name` LIKE ? OR `desc` LIKE ? OR ID = ? HAVING status=1"); $selStmt->execute(array("%{$query}%", "%{$query}%", $query)); $projects = array(); while ($result = $selStmt->fetch()) { if (!empty($result)) { $result["type"] = "project"; $result["icon"] = "projects.png"; $result["name"] = stripslashes($result["name"]); $result["desc"] = stripslashes($result["desc"]); $result["url"] = "manageproject.php?action=showproject&id=$result[ID]"; array_push($projects, $result); } } if (!empty($projects)) { return $projects; } else { return array(); } } function searchMilestones($query, $project = 0) { global $conn; $project = (int) $project; if ($project > 0) { $sel = $conn->prepare("SELECT `ID`,`name`,`desc`,`status`,`project` FROM milestones WHERE `name` LIKE ? OR `desc` LIKE ? HAVING project = ? AND status=1"); $sel->execute(array("%{$query}%", "%{$query}%", $project)); } else { $sel = $conn->prepare("SELECT `ID`,`name`,`desc`,`status`,`project` FROM milestones WHERE `name` LIKE ? OR `desc` LIKE ? HAVING status=1"); $sel->execute(array("%{$query}%", "%{$query}%")); } $milestones = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $project = $conn->query("SELECT name FROM projekte WHERE ID = $result[project]")->fetch(); $project = $project[0]; $result["pname"] = $project; $result["type"] = "milestone"; $result["icon"] = "miles.png"; $result["name"] = stripslashes($result["name"]); $result["desc"] = stripslashes($result["desc"]); $result["url"] = "managemilestone.php?action=showmilestone&msid=$result[ID]&id=$result[project]"; array_push($milestones, $result); } } if (!empty($milestones)) { return $milestones; } else { return array(); } } function searchMessage($query, $project = 0) { global $conn; $project = (int) $project; if ($project > 0) { $sel = $conn->prepare("SELECT `ID`,`title`,`text`,`posted`,`user`,`username`,`project` FROM messages WHERE `title` LIKE ? OR `text` LIKE ? HAVING project = ? "); $sel->execute(array("%{$query}%", "%{$query}%", $project)); } else { $sel = $conn->prepare("SELECT `ID`,`title`,`text`,`posted`,`user`,`username`,`project` FROM messages WHERE `title` LIKE ? OR `text` LIKE ?"); $sel->execute(array("%{$query}%", "%{$query}%")); } $messages = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $project = $conn->query("SELECT name FROM projekte WHERE ID = $result[project]")->fetch(); $project = $project[0]; $result["pname"] = $project; $result["type"] = "message"; $result["icon"] = "msgs.png"; $result["title"] = stripslashes($result["title"]); $result["text"] = stripslashes($result["text"]); $result["username"] = stripslashes($result["username"]); $posted = date("d.m.y - H:i", $result["posted"]); $result["endstring"] = $posted; $result["url"] = "managemessage.php?action=showmessage&mid=$result[ID]&id=$result[project]"; array_push($messages, $result); } } if (!empty($messages)) { return $messages; } else { return array(); } } function searchTasks($query, $project = 0) { global $conn; $project = (int) $project; if ($project > 0) { $sel = $conn->prepare("SELECT `ID`,`title`,`text`,`status`,`project` FROM tasks WHERE `title` LIKE ? OR `text` LIKE ? HAVING project = ? AND status=1"); $sel->execute(array("%{$query}%", "%{$query}%", $project)); } else { $sel = $conn->prepare("SELECT `ID`,`title`,`text`,`status`,`project` FROM tasks WHERE `title` LIKE ? OR `text` LIKE ? HAVING status=1"); $sel->execute(array("%{$query}%", "%{$query}%")); } $tasks = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $project = $conn->query("SELECT name FROM projekte WHERE ID = $result[project]")->fetch(); $project = $project[0]; $result["pname"] = $project; $result["type"] = "task"; $result["icon"] = "task.png"; $result["title"] = stripslashes($result["title"]); $result["text"] = stripslashes($result["text"]); $result["url"] = "managetask.php?action=showtask&tid=$result[ID]&id=$result[project]"; array_push($tasks, $result); } } if (!empty($tasks)) { return $tasks; } else { return array(); } } function searchFiles($query, $project = 0) { global $conn; $project = (int) $project; if ($project > 0) { $sel = $conn->prepare("SELECT `ID`,`name`,`desc`,`type`,`datei`,`title`,`project` FROM `files` WHERE `name` LIKE ? OR `desc` LIKE ? OR `title` LIKE ? HAVING project = ?"); $sel->execute(array("%{$query}%", "%{$query}%", "%{$query}%", $project)); } else { $sel = $conn->prepare("SELECT `ID`,`name`,`desc`,`type`,`datei`,`title`,`project` FROM `files` WHERE `name` LIKE ? OR `desc` LIKE ? OR `title` LIKE ?"); $sel->execute(array("%{$query}%", "%{$query}%", "%{$query}%")); } $files = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $project = $conn->query("SELECT name FROM projekte WHERE ID = $result[project]")->fetch(); $project = $project[0]; $result["pname"] = $project; $result["ftype"] = str_replace("/", "-", $result["type"]); $set = new settings(); $settings = $set->getSettings(); $myfile = CL_ROOT . "/templates/" . $settings["template"] . "/images/symbols/files/" . $result["ftype"] . ".png"; if (stristr($result["type"], "image")) { $result["imgfile"] = 1; } elseif (stristr($result['type'], "text")) { $result["imgfile"] = 2; } else { $result["imgfile"] = 0; } if (!file_exists($myfile)) { $result["ftype"] = "none"; } $result["title"] = stripslashes($result["title"]); $result["desc"] = stripslashes($result["desc"]); // $result["tags"] = stripslashes($result["tags"]); $result["type"] = "file"; $result[3] = "file"; $result["icon"] = "files.png"; array_push($files, $result); } } if (!empty($files)) { return $files; } else { return array(); } } function searchUser($query) { global $conn; $sel = $conn->query("SELECT `ID`,`email`,`name`,`avatar`,`lastlogin`, `gender` FROM user WHERE name LIKE " . $conn->quote("%{$query}%")); $user = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $result["type"] = "user"; $result["name"] = stripslashes($result["name"]); $result["url"] = "manageuser.php?action=profile&id=$result[ID]"; $result["type"] = "user"; $result[3] = "user"; $result["icon"] = ($result['gender'] == "m" ? "user-marker-male.png" : "user-marker-female.png"); array_push($user, $result); } } if (!empty($user)) { return $user; } else { return array(); } } //Limit search results to objects which the user belongs to function limitResult(array $result, $userid) { $finresult = array(); $userid = (int) $userid; foreach($result as $res) { if ($res["type"] != "project" and $res["type"] != "user") { if (chkproject($userid, $res["project"])) { array_push($finresult, $res); } } else { if (chkproject($userid, $res["ID"])) { array_push($finresult, $res); } } } return $finresult; } } ?>Collabtive-2.0/include/class.settings.php000066400000000000000000000125071237252063700205530ustar00rootroot00000000000000 * @name settings * @package Collabtive * @version 0.7.5 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class settings { public $mylog; /* * Constructor */ function __construct() { } /* * Returns all global settings * * @return array $settings Global system settings */ function getSettings() { global $conn; $selStmt = $conn->prepare("SELECT settingsKey,settingsValue FROM settings"); $sel = $selStmt->execute(array()); $settings = array(); while ($selSettings = $selStmt->fetch()) { // Create a key/value array $settings[$selSettings["settingsKey"]] = $selSettings["settingsValue"]; } if (!empty($settings)) { return $settings; } else { return false; } } /* * Edits the global system settings * * @param string $name System name * @param string $subtitle Subtitle is displayed under the system name * @param string $locale Standard locale * @param string $timezone Standard timezone * @param string $templ Template * @param string $rssuser Username for RSS Feed access * @param string $rsspass Password for RSS Feed access * @return bool */ function editSettings($name, $subtitle, $locale, $timezone, $dateformat, $templ, $theme, $rssuser, $rsspass) { global $conn; // This is an artifact of refactoring to a key/value table for the settings // Create an arrray containing the settings fields as keys and new values from the user as values $theSettings = array("name" => $name, "subtitle" => $subtitle, "locale" => $locale, "timezone" => $timezone, "dateformat" => $dateformat, "template" => $templ, "theme" => $theme, "rssuser" => $rssuser, "rsspass" => $rsspass); // Now prepare a statement to edit one settings row $updStmt = $conn->prepare("UPDATE settings SET `settingsValue` = ? WHERE `settingsKey` = ?"); // Loop through the array containing the key/value pairs, writing the database field to $setKey and the value to $setVal foreach($theSettings as $setKey => $setVal) { // Execute the prepared statement by binding the current settings field and values $upd = $updStmt->execute(array($setVal, $setKey)); } if ($upd) { return true; } else { return false; } } /* * Edits the global mail notification settings * * @param int $onoff 1 = nofitications on, 0 = notifications off * @param string $mailfrom Sender * @param string $mailfromname Name of the sender * @param string $method Method (e.g. SMTP) * @param string $mailhost Host * @param string $mailuser User * @param string $mailpass Password * @return bool */ function editMailsettings($onoff, $mailfrom, $mailfromname, $method, $mailhost, $mailuser, $mailpass) { global $conn; // This is an artifact of refactoring to a key/value table for the settings $theSettings = array("mailnotify" => $onoff, "mailfrom" => $mailfrom, "mailfromname" => $mailfromname, "mailmethod" => $method, "mailhost" => $mailhost, "mailuser" => $mailuser, "mailpass" => $mailpass); $updStmt = $conn->prepare("UPDATE settings SET `settingsValue` = ? WHERE `settingsKey` = ?"); foreach($theSettings as $setKey => $setVal) { $upd = $updStmt->execute(array($setVal, $setKey)); } if ($upd) { return true; } else { return false; } } /* * Returns all available templates * * @return array $templates */ function getTemplates() { $handle = opendir(CL_ROOT . "/templates"); $templates = array(); // Iterate through the templates directory and count each subdirectory within it as a template while (false !== ($file = readdir($handle))) { $type = filetype(CL_ROOT . "/templates/" . $file); if ($type == "dir" and $file != "." and $file != "..") { $template = $file; array_push($templates, $template); } } if (!empty($templates)) { return $templates; } else { return false; } } /* * Returns all available themes for a given template * * @param string $template The template whose themes get fetched * * @return array $templates */ function getThemes($template) { $handle = opendir(CL_ROOT . "/templates/$template/theme"); $themes = array(); // Iterate through the templates directory and count each subdirectory within it as a template while (false !== ($file = readdir($handle))) { $type = filetype(CL_ROOT . "/templates/$template/theme/" . $file); if ($type == "dir" and $file != "." and $file != "..") { $theme = $file; array_push($themes, $theme); } } if (!empty($themes)) { return $themes; } else { return false; } } }Collabtive-2.0/include/class.smtp.php000066400000000000000000001004071237252063700176730ustar00rootroot00000000000000smtp_conn = 0; $this->error = null; $this->helo_rply = null; $this->do_debug = 0; } /************************************************************* * CONNECTION FUNCTIONS * ***********************************************************/ /** * Connect to the server specified on the port specified. * If the port is not specified use the default SMTP_PORT. * If tval is specified then a connection will try and be * established with the server for that number of seconds. * If tval is not specified the default is 30 seconds to * try on the connection. * * SMTP CODE SUCCESS: 220 * SMTP CODE FAILURE: 421 * @access public * @return bool */ public function Connect($host,$port=0,$tval=30) { /* set the error val to null so there is no confusion */ $this->error = null; /* make sure we are __not__ connected */ if($this->connected()) { /* ok we are connected! what should we do? * for now we will just give an error saying we * are already connected */ $this->error = array("error" => "Already connected to a server"); return false; } if(empty($port)) { $port = $this->SMTP_PORT; } /* connect to the smtp server */ $this->smtp_conn = fsockopen($host, // the host of the server $port, // the port to use $errno, // error number if any $errstr, // error message if any $tval); // give up after ? secs /* verify we connected properly */ if(empty($this->smtp_conn)) { $this->error = array("error" => "Failed to connect to server", "errno" => $errno, "errstr" => $errstr); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF; } return false; } /* sometimes the SMTP server takes a little longer to respond * so we will give it a longer timeout for the first read * - Windows still does not have support for this timeout function */ if(substr(PHP_OS, 0, 3) != "WIN") socket_set_timeout($this->smtp_conn, $tval, 0); /* get any announcement stuff */ $announce = $this->get_lines(); /* set the timeout of any socket functions at 1/10 of a second */ //if(function_exists("socket_set_timeout")) // socket_set_timeout($this->smtp_conn, 0, 100000); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce; } return true; } /** * Initiate a TSL communication with the server. * * SMTP CODE 220 Ready to start TLS * SMTP CODE 501 Syntax error (no parameters allowed) * SMTP CODE 454 TLS not available due to temporary reason * @access public * @return bool success */ public function StartTLS() { $this->error = null; # to avoid confusion if(!$this->connected()) { $this->error = array("error" => "Called StartTLS() without being connected"); return false; } fputs($this->smtp_conn,"STARTTLS" . $extra . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 220) { $this->error = array("error" => "STARTTLS not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } //Begin encrypted connection if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { return false; } return true; } /** * Performs SMTP authentication. Must be run after running the * Hello() method. Returns true if successfully authenticated. * @access public * @return bool */ public function Authenticate($username, $password) { // Start authentication fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($code != 334) { $this->error = array("error" => "AUTH not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } // Send encoded username fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($code != 334) { $this->error = array("error" => "Username not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } // Send encoded password fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($code != 235) { $this->error = array("error" => "Password not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Returns true if connected to a server otherwise false * @access public * @return bool */ public function Connected() { if(!empty($this->smtp_conn)) { $sock_status = socket_get_status($this->smtp_conn); if($sock_status["eof"]) { // hmm this is an odd situation... the socket is // valid but we are not connected anymore if($this->do_debug >= 1) { echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"; } $this->Close(); return false; } return true; // everything looks good } return false; } /** * Closes the socket and cleans up the state of the class. * It is not considered good to use this function without * first trying to use QUIT. * @access public * @return void */ public function Close() { $this->error = null; // so there is no confusion $this->helo_rply = null; if(!empty($this->smtp_conn)) { // close the connection and cleanup fclose($this->smtp_conn); $this->smtp_conn = 0; } } /*************************************************************** * SMTP COMMANDS * *************************************************************/ /** * Issues a data command and sends the msg_data to the server * finializing the mail transaction. $msg_data is the message * that is to be send with the headers. Each header needs to be * on a single line followed by a with the message headers * and the message body being seperated by and additional . * * Implements rfc 821: DATA * * SMTP CODE INTERMEDIATE: 354 * [data] * . * SMTP CODE SUCCESS: 250 * SMTP CODE FAILURE: 552,554,451,452 * SMTP CODE FAILURE: 451,554 * SMTP CODE ERROR : 500,501,503,421 * @access public * @return bool */ public function Data($msg_data) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Data() without being connected"); return false; } fputs($this->smtp_conn,"DATA" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 354) { $this->error = array("error" => "DATA command not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } /* the server is ready to accept data! * according to rfc 821 we should not send more than 1000 * including the CRLF * characters on a single line so we will break the data up * into lines by \r and/or \n then if needed we will break * each of those into smaller lines to fit within the limit. * in addition we will be looking for lines that start with * a period '.' and append and additional period '.' to that * line. NOTE: this does not count towards are limit. */ // normalize the line breaks so we know the explode works $msg_data = str_replace("\r\n","\n",$msg_data); $msg_data = str_replace("\r","\n",$msg_data); $lines = explode("\n",$msg_data); /* we need to find a good way to determine is headers are * in the msg_data or if it is a straight msg body * currently I am assuming rfc 822 definitions of msg headers * and if the first field of the first line (':' sperated) * does not contain a space then it _should_ be a header * and we can process all lines before a blank "" line as * headers. */ $field = substr($lines[0],0,strpos($lines[0],":")); $in_headers = false; if(!empty($field) && !strstr($field," ")) { $in_headers = true; } $max_line_length = 998; // used below; set here for ease in change while(list(,$line) = @each($lines)) { $lines_out = null; if($line == "" && $in_headers) { $in_headers = false; } // ok we need to break this line up into several smaller lines while(strlen($line) > $max_line_length) { $pos = strrpos(substr($line,0,$max_line_length)," "); // Patch to fix DOS attack if(!$pos) { $pos = $max_line_length - 1; $lines_out[] = substr($line,0,$pos); $line = substr($line,$pos); } else { $lines_out[] = substr($line,0,$pos); $line = substr($line,$pos + 1); } /* if we are processing headers we need to * add a LWSP-char to the front of the new line * rfc 822 on long msg headers */ if($in_headers) { $line = "\t" . $line; } } $lines_out[] = $line; // now send the lines to the server while(list(,$line_out) = @each($lines_out)) { if(strlen($line_out) > 0) { if(substr($line_out, 0, 1) == ".") { $line_out = "." . $line_out; } } fputs($this->smtp_conn,$line_out . $this->CRLF); } } // ok all the message data has been sent so lets get this // over with aleady fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "DATA not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Expand takes the name and asks the server to list all the * people who are members of the _list_. Expand will return * back and array of the result or false if an error occurs. * Each value in the array returned has the format of: * [ ] * The definition of is defined in rfc 821 * * Implements rfc 821: EXPN * * SMTP CODE SUCCESS: 250 * SMTP CODE FAILURE: 550 * SMTP CODE ERROR : 500,501,502,504,421 * @access public * @return string array */ public function Expand($name) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Expand() without being connected"); return false; } fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "EXPN not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } // parse the reply and place in our array to return to user $entries = explode($this->CRLF,$rply); while(list(,$l) = @each($entries)) { $list[] = substr($l,4); } return $list; } /** * Sends the HELO command to the smtp server. * This makes sure that we and the server are in * the same known state. * * Implements from rfc 821: HELO * * SMTP CODE SUCCESS: 250 * SMTP CODE ERROR : 500, 501, 504, 421 * @access public * @return bool */ public function Hello($host="") { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Hello() without being connected"); return false; } // if a hostname for the HELO was not specified determine //a suitable one to send if(empty($host)) { // we need to determine some sort of appopiate default // to send to the server $host = "localhost"; } // Send extended hello first (RFC 2821) if(!$this->SendHello("EHLO", $host)) { if(!$this->SendHello("HELO", $host)) return false; } return true; } /** * Sends a HELO/EHLO command. * @access private * @return bool */ private function SendHello($hello, $host) { fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => $hello . " not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } $this->helo_rply = $rply; return true; } /** * Gets help information on the keyword specified. If the keyword * is not specified then returns generic help, ussually contianing * A list of keywords that help is available on. This function * returns the results back to the user. It is up to the user to * handle the returned data. If an error occurs then false is * returned with $this->error set appropiately. * * Implements rfc 821: HELP [ ] * * SMTP CODE SUCCESS: 211,214 * SMTP CODE ERROR : 500,501,502,504,421 * @access public * @return string */ public function Help($keyword="") { $this->error = null; // to avoid confusion if(!$this->connected()) { $this->error = array( "error" => "Called Help() without being connected"); return false; } $extra = ""; if(!empty($keyword)) { $extra = " " . $keyword; } fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 211 && $code != 214) { $this->error = array("error" => "HELP not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return $rply; } /** * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more Recipient * commands may be called followed by a Data command. * * Implements rfc 821: MAIL FROM: * * SMTP CODE SUCCESS: 250 * SMTP CODE SUCCESS: 552,451,452 * SMTP CODE SUCCESS: 500,501,421 * @access public * @return bool */ public function Mail($from) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Mail() without being connected"); return false; } $useVerp = ($this->do_verp ? "XVERP" : ""); fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "MAIL not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Sends the command NOOP to the SMTP server. * * Implements from rfc 821: NOOP * * SMTP CODE SUCCESS: 250 * SMTP CODE ERROR : 500, 421 * @access public * @return bool */ public function Noop() { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Noop() without being connected"); return false; } fputs($this->smtp_conn,"NOOP" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "NOOP not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Sends the quit command to the server and then closes the socket * if there is no error or the $close_on_error argument is true. * * Implements from rfc 821: QUIT * * SMTP CODE SUCCESS: 221 * SMTP CODE ERROR : 500 * @access public * @return bool */ public function Quit($close_on_error=true) { $this->error = null; // so there is no confusion if(!$this->connected()) { $this->error = array( "error" => "Called Quit() without being connected"); return false; } // send the quit command to the server fputs($this->smtp_conn,"quit" . $this->CRLF); // get any good-bye messages $byemsg = $this->get_lines(); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; } $rval = true; $e = null; $code = substr($byemsg,0,3); if($code != 221) { // use e as a tmp var cause Close will overwrite $this->error $e = array("error" => "SMTP server rejected quit command", "smtp_code" => $code, "smtp_rply" => substr($byemsg,4)); $rval = false; if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF; } } if(empty($e) || $close_on_error) { $this->Close(); } return $rval; } /** * Sends the command RCPT to the SMTP server with the TO: argument of $to. * Returns true if the recipient was accepted false if it was rejected. * * Implements from rfc 821: RCPT TO: * * SMTP CODE SUCCESS: 250,251 * SMTP CODE FAILURE: 550,551,552,553,450,451,452 * SMTP CODE ERROR : 500,501,503,421 * @access public * @return bool */ public function Recipient($to) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Recipient() without being connected"); return false; } fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250 && $code != 251) { $this->error = array("error" => "RCPT not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Sends the RSET command to abort and transaction that is * currently in progress. Returns true if successful false * otherwise. * * Implements rfc 821: RSET * * SMTP CODE SUCCESS: 250 * SMTP CODE ERROR : 500,501,504,421 * @access public * @return bool */ public function Reset() { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Reset() without being connected"); return false; } fputs($this->smtp_conn,"RSET" . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "RSET failed", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more Recipient * commands may be called followed by a Data command. This command * will send the message to the users terminal if they are logged * in. * * Implements rfc 821: SEND FROM: * * SMTP CODE SUCCESS: 250 * SMTP CODE SUCCESS: 552,451,452 * SMTP CODE SUCCESS: 500,501,502,421 * @access public * @return bool */ public function Send($from) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Send() without being connected"); return false; } fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "SEND not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more Recipient * commands may be called followed by a Data command. This command * will send the message to the users terminal if they are logged * in and send them an email. * * Implements rfc 821: SAML FROM: * * SMTP CODE SUCCESS: 250 * SMTP CODE SUCCESS: 552,451,452 * SMTP CODE SUCCESS: 500,501,502,421 * @access public * @return bool */ public function SendAndMail($from) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called SendAndMail() without being connected"); return false; } fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "SAML not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more Recipient * commands may be called followed by a Data command. This command * will send the message to the users terminal if they are logged * in or mail it to them if they are not. * * Implements rfc 821: SOML FROM: * * SMTP CODE SUCCESS: 250 * SMTP CODE SUCCESS: 552,451,452 * SMTP CODE SUCCESS: 500,501,502,421 * @access public * @return bool */ public function SendOrMail($from) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called SendOrMail() without being connected"); return false; } fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250) { $this->error = array("error" => "SOML not accepted from server", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return true; } /** * This is an optional command for SMTP that this class does not * support. This method is here to make the RFC821 Definition * complete for this class and __may__ be implimented in the future * * Implements from rfc 821: TURN * * SMTP CODE SUCCESS: 250 * SMTP CODE FAILURE: 502 * SMTP CODE ERROR : 500, 503 * @access public * @return bool */ public function Turn() { $this->error = array("error" => "This method, TURN, of the SMTP ". "is not implemented"); if($this->do_debug >= 1) { echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF; } return false; } /** * Verifies that the name is recognized by the server. * Returns false if the name could not be verified otherwise * the response from the server is returned. * * Implements rfc 821: VRFY * * SMTP CODE SUCCESS: 250,251 * SMTP CODE FAILURE: 550,551,553 * SMTP CODE ERROR : 500,501,502,421 * @access public * @return int */ public function Verify($name) { $this->error = null; // so no confusion is caused if(!$this->connected()) { $this->error = array( "error" => "Called Verify() without being connected"); return false; } fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply; } if($code != 250 && $code != 251) { $this->error = array("error" => "VRFY failed on name '$name'", "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF; } return false; } return $rply; } /******************************************************************* * INTERNAL FUNCTIONS * ******************************************************************/ /** * Read in as many lines as possible * either before eof or socket timeout occurs on the operation. * With SMTP we can tell if we have more lines to read if the * 4th character is '-' symbol. If it is a space then we don't * need to read anything else. * @access private * @return string */ private function get_lines() { $data = ""; while($str = @fgets($this->smtp_conn,515)) { if($this->do_debug >= 4) { echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF; echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF; } $data .= $str; if($this->do_debug >= 4) { echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF; } // if the 4th character is a space then we are done reading // so just break the loop if(substr($str,3,1) == " ") { break; } } return $data; } } ?> Collabtive-2.0/include/class.tags.php000066400000000000000000000273341237252063700176550ustar00rootroot00000000000000cloudlimit = 0; } /** * Formats the an input string to be stored as tags. * Possible format: word1,word2,word / word1, word2, word3 / word1 word2 word3 * OR a mix of the preceding * * Extracts the words from the string, makes the first character uppercase, and reassembles the tagstring * * @param string $ tags Tagstring to be formatted * @return string worktags Formatted tags */ public function formatInputTags($tags) { // Trim string $tags = trim($tags); // Compress string internal spaces: $count = 1; while ($count) { $tags = str_replace(" ", " ", $tags, $count); } // String liegt jetzt als "txt1, txt2, txt3" / "txt1,txt2,txt3" / "txt1 txt2 txt3" vor, // bei entsprechender Usereingabe auch als "txt1 txt2,txt3, txt4" $tags = str_replace(" ", "," , $tags); // String liegt jetzt als "txt1,,txt2,,txt3" /txt1,txt2,txt3" / "txt1,txt2,txt3" vor, // bei entsprechender Usereingabe auch als "txt1,txt2,txt3,,txt4 $tags = str_replace(",,", "," , $tags); // String liegt jetzt als "txt1,txt2,txt3" /txt1,txt2,txt3" / "txt1,txt2,txt3" vor, // bei entsprechender Usereingabe auch als "txt1,txt2,txt3,txt4" $tags = strtolower($tags); if (!empty($tags)) { $tags = explode(",", $tags); $worktags = ""; foreach($tags as $tag) { if ($tag != "" and $tag != ",") { $tag = trim($tag); $tag = ucfirst($tag); $worktags .= $tag . ","; } } $worktags = substr($worktags, 0, strlen($worktags)-1); } else { $worktags = ""; } if (!empty($worktags)) { return $worktags; } else { return false; } } /** * Splits a tag string into an array * * @param tagstr $ Tagstring to be split * @return array tags Array with the t ags */ public function splitTagStr($tagstr) { $tags = explode(",", $tagstr); if (!empty($tags)) { return $tags; } else { return false; } } /** * Gets all the content for a given tag in a given project * * @param string $ tag The wanted tag * @param int $ project The project * @return array content The content for the tag */ public function getTagContent($tag, $project) { $files = $this->getFiles($tag, $project); $messages = $this->getMessages($tag, $project); $user = $this->getUser($tag); $content = array_merge($files, $messages, $user); if (!empty($content)) { return $content; } else { return false; } } /** * Builds a tagcloud * * @param string $ tag The wanted tag * @param int $ project The project * @return array content The content for the tag */ public function getTagcloud($project) { global $conn; $project = (int) $project; $sel1 = $conn->query("SELECT tags FROM files WHERE tags != '' AND project = $project"); $sel2 = $conn->query("SELECT tags FROM messages WHERE tags != '' AND project = $project"); $tags1 = array(); $worktags = ""; while ($dat = $sel1->fetch()) { $tag = $dat[0]; $tag = ucfirst($tag); if ($tag != "" and $tag != ",") { $worktags .= $tag . ","; } } while ($dat = $sel2->fetch()) { $tag = $dat[0]; $tag = ucfirst($tag); if ($tag != "" and $tag != ",") { $worktags .= $tag . ","; } } $worktags = substr($worktags, 0, strlen($worktags)-1); $tags1 = explode(",", $worktags); $tagsnum = array_count_values($tags1); $tagsnum = array_filter($tagsnum, array($this, "limitcloud")); $thecloud = new tagcloud($tagsnum); $thecloud->itemsPerRow = 3; $thecloud->rows = ceil(count($tagsnum) / 3); $thecloud->padding = 3; $thecloud->maxFontSize = 16; $thecloud->minFontSize = 10; $thecloud->linkUrlPrefix = "managetags.php?action=gettag&id=$project&tag="; return $thecloud->getCloud(); } // SELECT * FROM `files` WHERE tags REGEXP ',{0,1}Wort1,{0,1}' private function limitcloud($arr) { if ($arr > $this->cloudlimit) { return true; } else { return false; } } private function getFiles($query, $project = 0) { global $conn; $project = (int) $project; if ($project > 0) { $sel = $conn->query("SELECT `ID`,`name`,`desc`,`type`,`datei`,`title`,`project`,`tags` FROM `files` WHERE `tags` LIKE " . $conn->quote("%{$query}%") . " HAVING project = $project"); } else { $sel = $conn->query("SELECT `ID`,`name`,`desc`,`type`,`datei`,`title`,`project`,`tags` FROM `files` WHERE `tags` LIKE " . $conn->quote("%{$query}%")); } $files = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $project = $conn->query("SELECT name FROM projekte WHERE ID = $result[project]")->fetch(); $project = $project[0]; $result["pname"] = $project; $result["ftype"] = str_replace("/", "-", $result["type"]); $set = new settings(); $settings = $set->getSettings(); $myfile = CL_ROOT . "/templates/" . $settings["template"] . "/images/symbols/files/" . $result["ftype"] . ".png"; if (stristr($result["type"], "image")) { $result["imgfile"] = 1; } elseif (stristr($result['type'], "text")) { $result["imgfile"] = 2; } else { $result["imgfile"] = 0; } if (!file_exists($myfile)) { $result["ftype"] = "none"; } $result["title"] = stripslashes($result["title"]); $result["desc"] = stripslashes($result["desc"]); $result["tags"] = stripslashes($result["tags"]); $thetags = $this->splitTagStr($result["tags"]); $result["tagsarr"] = $thetags; $result["tagnum"] = count($result["tagsarr"]); $result["type"] = "file"; $result[3] = "file"; $result["icon"] = "files.png"; array_push($files, $result); } } if (!empty($files)) { return $files; } else { return array(); } } private function getMessages($query, $project = 0) { global $conn; $project = (int) $project; if ($project > 0) { $sel = $conn->query("SELECT `ID`,`title`,`text`,`posted`,`user`,`username`,`project`,`tags` FROM messages WHERE `tags` LIKE " . $conn->quote("%{$query}%") . " HAVING project = $project "); } else { $sel = $conn->query("SELECT `ID`,`title`,`text`,`posted`,`user`,`username`,`project`,`tags` FROM messages WHERE `tags` LIKE " . $conn->quote("%{$query}%")); } $messages = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $project = $conn->query("SELECT name FROM projekte WHERE ID = $result[project]")->fetch(); $project = $project[0]; $result["pname"] = $project; $result["type"] = "message"; $result["icon"] = "msgs.png"; $result["tagsarr"] = $this->splitTagStr($result["tags"]); $result["tagnum"] = count($result["tagsarr"]); $result["title"] = stripslashes($result["title"]); $result["text"] = stripslashes($result["text"]); $result["username"] = stripslashes($result["username"]); $posted = date("d.m.y - H:i", $result["posted"]); $result["endstring"] = $posted; $result["url"] = "managemessage.php?action=showmessage&mid=$result[ID]&id=$result[project]"; array_push($messages, $result); } } if (!empty($messages)) { return $messages; } else { return array(); } } private function getUser($query) { global $conn; $sel = $conn->query("SELECT `ID`,`email`,`name`,`avatar`,`lastlogin`,`tags`, `gender` FROM user WHERE tags LIKE " . $conn->quote("%{$query}%")); $user = array(); while ($result = $sel->fetch()) { if (!empty($result)) { $result["type"] = "user"; $result["name"] = stripslashes($result["name"]); $result["url"] = "manageuser.php?action=profile&id=$result[ID]"; $result["type"] = "user"; $result["tagsarr"] = $this->splitTagStr($result["tags"]); $result["tagnum"] = count($result["tagsarr"]); $result[3] = "user"; $result["icon"] = ($result['gender'] == "m" ? "user-marker-male.png" : "user-marker-female.png"); array_push($user, $result); } } if (!empty($user)) { return $user; } else { return array(); } } } // end class tags class tagcloud extends tags { public $rows; public $itemsPerRow; public $minFontSize; public $maxFontSize; public $padding; public $linkUrlPrefix; private $keywordsArray; private $minTagValue; private $maxTagValue; private $fontRatio; private $fontOffset; function __construct ($keys, $rows = 3, $rowitems = 3, $minfont = 10, $maxfont = 20) { // init default values $this->keywordsArray = $keys; $this->Rows = $rows; $this->itemsPerRow = $rowitems; $this->minFontSize = $minfont; $this->maxFontSize = $maxfont; if (!empty($this->keywordsArray)) { $this->minTagValue = min($this->keywordsArray); $this->maxTagValue = max($this->keywordsArray); } } function getCloud() { if (isset($this->maxTagValue) and isset($this->minTagValue) and $this->minTagValue > 0 and $this) { $fsize = $this->maxFontSize - $this->minFontSize; $tval = $this->maxTagValue - $this->minTagValue; if ($fsize > 0 and $tval > 0) { $this->fontRatio = $fsize / $tval; } else { $this->fontRatio = 1; } $this->fontOffset = $this->maxFontSize - ($this->fontRatio * $this->maxTagValue); } $htmlCode = ""; $AbsoluteIndex = 0; reset($this->keywordsArray); for ($NumofRows = 1;$NumofRows <= $this->rows;$NumofRows++) { for ($itemsPerRow = 1;$itemsPerRow <= $this->itemsPerRow;$itemsPerRow++) { $AbsoluteIndex++; $currentKey = key($this->keywordsArray); if (!empty($currentKey)) { $currentValue = $this->keywordsArray[$currentKey]; } $TagSize = floor(($this->fontRatio * $currentValue) + $this->fontOffset); $htmlCode .= "linkUrlPrefix . $currentKey . "\"style=\"font-size:" . $TagSize . "pt;padding:" . $this->padding . "px;\">" . $currentKey . ""; next($this->keywordsArray); } $htmlCode .= "
      "; } return $htmlCode; } } ?>Collabtive-2.0/include/class.task.php000066400000000000000000000536671237252063700176710ustar00rootroot00000000000000 * @author Eva Kiszka * @name task * @package Collabtive * @version 1.2 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class task { private $mylog; /** * Constructor * Initializes the event log */ function __construct() { $this->mylog = new mylog; } /** * Add a task * * @param string $start Start date of the task * @param string $end Date the task is due * @param string $title Title of the task (optional) * @param string $text Description of the task * @param int $liste Tasklist the task is associated with * @param int $assigned ID of the user who has to complete the task * @param int $project ID of the project the task is associated with * @return int $insid New task's ID */ function add($start, $end, $title, $text, $liste, $project) { global $conn; $title = htmlspecialchars($title); $liste = (int) $liste; $project = (int) $project; $start_fin = strtotime($start); $end_fin = strtotime($end); if (empty($start_fin)) { $start_fin = $start; } if (empty($end_fin)) { $end_fin = $end; } // write to db $insStmt = $conn->prepare("INSERT INTO tasks (start, end, title, text, liste, status, project) VALUES (?, ?, ?, ?, ?, 1, ?)"); $ins = $insStmt->execute(array($start_fin, $end_fin, $title, $text, $liste, $project)); if ($ins) { $insid = $conn->lastInsertId(); // logentry $nameproject = $this->getNameProject($insid); $this->mylog->add($nameproject[0], 'task', 1, $nameproject[1]); return $insid; } else { return false; } } /** * Edit a task * * @param int $id Task ID * @param string $start Start date * @param string $end Due date * @param string $title Title of the task * @param string $text Task description * @param int $liste Tasklist * @param int $assigned ID of the user who has to complete the task * @return bool */ function edit($id, $start, $end, $title, $text, $liste) { global $conn; $id = (int) $id; $liste = (int) $liste; $title = htmlspecialchars($title); //convert time string to timestamp $start = strtotime($start); $end = strtotime($end); $updStmt = $conn->prepare("UPDATE tasks SET `start`=?, `end`=?, `title`=?, `text`=?, `liste`=? WHERE ID = ?"); $upd = $updStmt->execute(array($start, $end, $title, $text, $liste, $id)); if ($upd) { // Remove all the users from the task. Done to ensure no double assigns occur since the handler scripts call this::assign() on their own. $conn->query("DELETE FROM tasks_assigned WHERE `task` = $id"); $nameproject = $this->getNameProject($id); $this->mylog->add($nameproject[0], 'task', 2, $nameproject[1]); return true; } else { return false; } } /** * Delete a task * * @param int $id Task ID * @return bool */ function del($id) { global $conn; $id = (int) $id; $nameproject = $this->getNameProject($id); $del = $conn->query("DELETE FROM tasks WHERE ID = $id LIMIT 1"); if ($del) { $del2 = $conn->query("DELETE FROM tasks_assigned WHERE task=$id"); $this->mylog->add($nameproject[0], 'task', 3, $nameproject[1]); return true; } else { return false; } } /** * Reactivate / open a task * * @param int $id Task ID * @return bool */ function open($id) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE tasks SET status = 1 WHERE ID = $id"); if ($upd) { $nameproject = $this->getNameProject($id); $this->mylog->add($nameproject[0], 'task', 4, $nameproject[1]); return true; } else { return false; } } /** * Close a task. If it's the last task of its tasklist, the list gets closed, too. * * @param int $id Task ID * @return bool */ function close($id) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE tasks SET status = 0 WHERE ID = $id"); if ($upd) { $nameproject = $this->getNameProject($id); $this->mylog->add($nameproject[0], 'task', 5, $nameproject[1]); return true; } else { return false; } } /** * Assign a task to a user * * @param int $task Task ID * @param int $id User ID * @return bool */ function assign($task, $id) { global $conn; $task = (int) $task; $id = (int) $id; $upd = $conn->query("INSERT INTO tasks_assigned (user,task) VALUES ($id,$task)"); if ($upd) { return true; } else { return false; } } /** * Delete the assignment of a task to a user * * @param int $task Task ID * @param int $id User ID * @return bool */ function deassign($task, $id) { global $conn; $task = (int) $task; $id = (int) $id; $upd = $conn->query("DELETE FROM tasks_assigned WHERE user = $id AND task = $task"); if ($upd) { return true; } else { return false; } } /** * Return a task * * @param int $id Task ID * @return array $task Task details */ function getTask($id) { global $conn; $id = (int) $id; $task = $conn->query("SELECT * FROM tasks WHERE ID = $id")->fetch(); if (!empty($task)) { // format datestring according to dateformat option if (is_numeric($task['start'])) { $startstring = date(CL_DATEFORMAT, $task["start"]); } else { $startstring = date(CL_DATEFORMAT, strtotime($task["start"])); } if (is_numeric($task['end'])) { $endstring = date(CL_DATEFORMAT, $task["end"]); } else { $endstring = date(CL_DATEFORMAT, strtotime($task["end"])); } // get list and projectname of the task $details = $this->getTaskDetails($task); $list = $details["list"]; $pname = $details["pname"]; // get remainig days until due date $tage = $this->getDaysLeft($task['end']); // Get the user(s) assigned to the task from the db $usel = $conn->query("SELECT user FROM tasks_assigned WHERE task = $task[ID]"); $users = array(); while ($usr = $usel->fetch()) { // push the assigned users to an array array_push($users, $usr[0]); $task["user"] = "All"; $task["user_id"] = $users; } // If only one user is assigned , get his profile and add him to users, user_id fields if (count($users) == 1) { $usrobj = new user(); $usr = $users[0]; $user = $usrobj->getProfile($usr); $task["user"] = stripslashes($user["name"]); $task["users"] = array($user); $task["user_id"] = $user["ID"]; } elseif (count($users) > 1) { // if there is more than one user push them to the users field. no user or user_id field is present. $usrobj = new user(); $task["users"] = array(); $task["user"] = ""; $task["user_id"] = 0; foreach($users as $user) { $usr = $usrobj->getProfile($user); $task["user"] .= $usr["name"] . " "; array_push($task["users"], $usr); } } $task["startstring"] = $startstring; $task["endstring"] = $endstring; $task["title"] = stripslashes($task["title"]); $task["text"] = stripslashes($task["text"]); $task["pname"] = stripslashes($pname); $task["list"] = $list; $task["daysleft"] = $tage; return $task; } else { return false; } } /** * Return all open tasks of a project * * @param int $project Project ID * @return array $lists Tasks */ function getProjectTasks($project, $status = 1) { global $conn; $project = (int) $project; $status = (int) $status; $lists = array(); if ($status !== false) { $sel2 = $conn->query("SELECT ID FROM tasks WHERE project = $project AND status=$status"); } else { $sel2 = $conn->query("SELECT ID FROM tasks WHERE project = $project"); } while ($tasks = $sel2->fetch()) { $task = $this->getTask($tasks["ID"]); array_push($lists, $task); } if (!empty($lists)) { return $lists; } else { return false; } } /** * Return all active / open tasks of a given project and user * * @param int $project Project ID * @param int $limit Number of tasks to return * @return array $lists Tasks */ function getMyProjectTasks($project, $limit = 10) { global $conn; $project = (int) $project; $limit = (int) $limit; // Get the id of the currently logged in user. $user = $_SESSION['userid']; $lists = array(); $now = time(); $sel2 = $conn->query("SELECT ID FROM tasks WHERE project = $project AND status=1 AND end > $now ORDER BY `end` ASC LIMIT $limit"); while ($tasks = $sel2->fetch()) { $chk = $conn->query("SELECT ID FROM tasks_assigned WHERE user = $user AND task = $tasks[ID]")->fetch(); $chk = $chk[0]; if ($chk) { $task = $this->getTask($tasks["ID"]); array_push($lists, $task); } } if (!empty($lists)) { return $lists; } else { return false; } } /** * Return open tasks from a given project a user * * @param int $project Project ID * @param int $limit Number of tasks to return * @param int $user User ID (0 means the user, to whom the session belongs) * @return array $lists Tasks */ function getAllMyProjectTasks($project, $limit = 10, $user = 0) { global $conn; $project = (int) $project; $limit = (int) $limit; $user = (int) $user; // If no user is given, use the currently logged in one. if ($user < 1) { $user = $_SESSION['userid']; } $lists = array(); $now = time(); $sel2 = $conn->query("SELECT tasks.*,tasks_assigned.user FROM tasks,tasks_assigned WHERE tasks.ID = tasks_assigned.task HAVING tasks_assigned.user = $user AND tasks.project = $project AND status=1 ORDER BY `end` ASC "); while ($tasks = $sel2->fetch()) { $task = $this->getTask($tasks["ID"]); array_push($lists, $task); } if (!empty($lists)) { return $lists; } else { return false; } } /** * Returns all late tasks of a user from a given project * * @param int $project Project ID * @param int $limit Number of tasks to return * @return array $lists Tasks */ function getMyLateProjectTasks($project, $limit = 10) { global $conn; $project = (int) $project; $limit = (int) $limit; $user = $_SESSION["userid"]; $lists = array(); $tod = date("d.m.Y"); $now = strtotime($tod); $sel2 = $conn->query("SELECT tasks.*,tasks_assigned.user FROM tasks,tasks_assigned WHERE tasks.ID = tasks_assigned.task HAVING tasks_assigned.user = $user AND tasks.project = $project AND status=1 AND end < $now ORDER BY `end` ASC LIMIT $limit"); while ($tasks = $sel2->fetch()) { $task = $this->getTask($tasks["ID"]); array_push($lists, $task); } if (!empty($lists)) { return $lists; } else { return false; } } /** * Returns all tasks of today of a user from a given project * * @param int $project Project ID * @param int $limit Number of tasks to return * @return array $lists Tasks */ function getMyTodayProjectTasks($project, $limit = 10) { global $conn; $project = (int) $project; $limit = (int) $limit; $user = $_SESSION["userid"]; $tod = date("d.m.Y"); $lists = array(); $now = strtotime($tod); $sel2 = $conn->query("SELECT tasks.*,tasks_assigned.user FROM tasks,tasks_assigned WHERE tasks.ID = tasks_assigned.task HAVING tasks_assigned.user = $user AND tasks.project = $project AND status=1 AND end = '$now' ORDER BY `end` ASC LIMIT $limit"); while ($tasks = $sel2->fetch()) { $task = $this->getTask($tasks["ID"]); array_push($lists, $task); } if (!empty($lists)) { return $lists; } else { return false; } } /** * Return all done tasks of a user from a given project * * @param int $project Project ID * @param int $limit Number of tasks to return * @return array $lists Tasks */ function getMyDoneProjectTasks($project, $limit = 5) { global $conn; $project = (int) $project; $limit = (int) $limit; $user = $_SESSION["userid"]; $lists = array(); $now = time(); $sel2 = $conn->query("SELECT tasks.*,tasks_assigned.user FROM tasks,tasks_assigned WHERE tasks.ID = tasks_assigned.task HAVING tasks_assigned.user = $user AND tasks.project = $project AND status=0 ORDER BY `end` ASC LIMIT $limit"); while ($tasks = $sel2->fetch()) { $task = $this->getTask($tasks["ID"]); array_push($lists, $task); } if (!empty($lists)) { return $lists; } else { return false; } } /** * Return all tasks (from a project) due on the specified date * * @param int $m Month * @param int $y Year * @param int $d Day * @param int $project Project ID (Default: 0 = all projects) * @return array $timeline Tasks */ function getTodayTasks($m, $y, $d, $project = 0) { global $conn; $m = (int) $m; $y = (int) $y; if ($m > 9) { $startdate = date($d . "." . $m . "." . $y); } else { $startdate = date($d . ".0" . $m . "." . $y); } $starttime = strtotime($startdate); $user = (int) $_SESSION["userid"]; $timeline = array(); if ($project > 0) { $sql = "SELECT * FROM tasks WHERE status=1 AND project = $project AND end = '$starttime'"; } else { $sql = "SELECT tasks.*,tasks_assigned.user,projekte.name AS pname FROM tasks,tasks_assigned,projekte WHERE tasks.ID = tasks_assigned.task AND tasks.project = projekte.ID HAVING tasks_assigned.user = $user AND status=1 AND end = '$starttime'"; } $sel1 = $conn->query($sql); while ($stone = $sel1->fetch()) { $stone["daysleft"] = $this->getDaysLeft($stone["end"]); array_push($timeline, $stone); } if (!empty($timeline)) { return $timeline; } else { return array(); } } /** * Return the owner of a given task * * @param int $id Task ID * @return array $user ID of the user who has to complete the task */ function getUser($id) { global $conn; $id = (int) $id; $user = $conn->query("SELECT user FROM tasks_assigned WHERE task = $id")->fetch(); if (!empty($user)) { $uname = $conn->query("SELECT name FROM user WHERE ID = $user[0]")->fetch(); $uname = $uname[0]; $user[1] = stripslashes($uname); return $user; } else { return false; } } /** * Return the owner of a given task * * @param int $id Task ID * @return array $user ID of the users who has to complete the task */ function getUsers($id) { global $conn; $id = (int) $id; $sql = $conn->query("SELECT user FROM tasks_assigned WHERE task = $id"); $result = array(); while ($user = $sql->fetch()) { $sel2 = $conn->query("SELECT name FROM user WHERE ID = $user[0]"); $uname = $sel2->fetch(); $uname = $uname[0]; $user[1] = stripslashes($uname); $result[] = $user; } return $result; } /** * Export all tasks of a user via iCal * * @param int $user User ID * @param bool $show_long * @return bool */ function getIcal($user,$show_long = true) { $user = (int) $user; $show_long = (bool) $show_long; $username = $_SESSION["username"]; $project = new project(); $myprojects = $project->getMyProjects($user); $tasks = array(); if (!empty($myprojects)) { foreach($myprojects as $proj) { $task = $this->getAllMyProjectTasks($proj["ID"], 10000); if (!empty($task)) { array_push($tasks, $task); } } } $etasks = reduceArray($tasks); require("class.ical.php"); $heute = date("d-m-y"); $cal = new vcalendar(); $fname = "tasks_" . $username . ".ics"; $cal->setConfig('directory', CL_ROOT . '/files/' . CL_CONFIG . '/ics'); $cal->setConfig('filename', $fname); $cal->setConfig('unique_id' , ''); $cal->setProperty('X-WR-CALNAME' , "Collabtive Aufgaben für " . $username); $cal->setProperty('X-WR-CALDESC' , ''); $cal->setProperty('CALSCALE' , 'GREGORIAN'); $cal->setProperty('METHOD' , 'PUBLISH'); foreach($etasks as $etask) { // split date in Y / M / D / h / min / sek variables $jahr = date("Y", $etask["start"]); $monat = date("m", $etask["start"]); $tag = date("d", $etask["start"]); $std = date("h", $etask["start"]); $min = date("i", $etask["start"]); $sek = date("s", $etask["start"]); // split date in Y / M / D / h / min / sek variables $ejahr = date("Y", $etask['end']); $emonat = date("m", $etask['end']); $etag = date("d", $etask['end']); $estd = date("h", $etask['end']); $emin = date("i", $etask['end']); $esek = date("s", $etask['end']); $e = new vevent(); $e->setProperty('categories' , $etask['list']); if ($show_long){ // if we have a task lasting 10 month, normally it will be displayed every day within this time span. $e->setProperty('dtstart' , $jahr, $monat, $tag, $std, $min); // 24 dec 2007 19.30 } else { // if the show_long flag is set, it will only be shown at the due date $e->setProperty('dtstart' , $ejahr, $emonat, $etag, $estd, $emin); } $e->setProperty('due' , $ejahr, $emonat, $etag, $estd, $emin); // 24 dec 2007 19.30 $e->setProperty('dtend' , $ejahr, $emonat, $etag, $estd, $emin); $e->setProperty('description' , $etask["text"]); $e->setProperty('status' , "NEEDS-ACTION"); // $e->setProperty('comment' , $etask[text]); $e->setProperty('summary' , $etask["title"]); $e->setProperty('location' , 'Work'); $cal->setComponent($e); } $cal->returnCalendar(); return true; } /** * Return a tasks project name and tasklist name * * @param array $task Task ID * @return array $details Name of associated project and tasklist */ private function getTaskDetails(array $task) { global $conn; $psel = $conn->query("SELECT name FROM projekte WHERE ID = $task[project]"); $pname = $psel->fetch(); $pname = stripslashes($pname[0]); $list = $conn->query("SELECT name FROM tasklist WHERE ID = $task[liste]")->fetch(); $list = stripslashes($list[0]); if (isset($list) or isset($pname)) { $details = array("list" => $list, "pname" => $pname); } if (!empty($details)) { return $details; } else { return false; } } /** * Return the number of left days until a task is due * * @param string $end Timestamp of the date the task is due * @return int $days Days left */ private function getDaysLeft($end) { $tod = date("d.m.Y"); $now = strtotime($tod); $diff = $end - $now; $days = floor($diff / 86400); return $days; } /** * Return the name of the associated project and text of a given task * * @param int $id Task ID * @return array $nameproject Name and project */ private function getNameProject($id) { global $conn; $id = (int) $id; $nam = $conn->query("SELECT text,liste,title FROM tasks WHERE ID = $id")->fetch(); $text = stripslashes($nam[2]); $list = $nam[1]; $project = $conn->query("SELECT project FROM tasklist WHERE ID = $list")->fetch(); $project = $project[0]; $nameproject = array($text, $project); if (!empty($nameproject)) { return $nameproject; } else { return false; } } } ?> Collabtive-2.0/include/class.tasklist.php000066400000000000000000000206771237252063700205600ustar00rootroot00000000000000 * @package Collabtive * @name tasklist * @version 1.0 * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class tasklist { public $mylog; /** * Constructor * Initialize the event log */ function __construct() { $this->mylog = new mylog; } /** * Add a tasklist * * @param int $project ID of the associated project * @param string $name Name of the tasklist * @param string $desc Description of the tasklist * @param int $access Access level (0 = public) * @param int $milestone ID of the associated milestone (0 = no association) * @return bool */ function add_liste($project, $name, $desc, $access = 0, $milestone = 0) { global $conn; $name = htmlspecialchars($name); $insStmt = $conn->prepare("INSERT INTO tasklist (`project`, `name`, `desc`, `start`, `status`, `access`, `milestone`) VALUES (?, ?, ?, ?, 1, ?, ?)"); $ins = $insStmt->execute(array((int) $project, $name, $desc, time(), (int) $access, (int) $milestone)); if ($ins) { $insid = $conn->lastInsertId(); $this->mylog->add($name, 'tasklist', 1, $project); return $insid; } else { return false; } } /** * Edit a tasklist * * @param int $id Tasklist ID * @param string $name Tasklist name * @param string $desc Tasklist description * @param int $milestone ID of the associated milestone * @return bool */ function edit_liste($id, $name, $desc, $milestone) { global $conn; $name = htmlspecialchars($name); $updStmt = $conn->prepare("UPDATE tasklist SET `name` = ?, `desc` = ?, `milestone` = ? WHERE ID = ?"); $upd = $updStmt->execute(array($name, $desc, $milestone, $id)); if ($upd) { $proj = $conn->query("SELECT project FROM tasklist WHERE ID = $id")->fetch(); $proj = $proj[0]; $this->mylog->add($name, 'tasklist', 2, $proj); return true; } else { return false; } } /** * Delete a tasklist * * @param int $id Tasklist ID * @return bool */ function del_liste($id) { global $conn; $id = (int) $id; $sel = $conn->query("SELECT project, name FROM tasklist WHERE ID = $id"); $del = $conn->query("DELETE FROM tasklist WHERE ID = $id LIMIT 1"); if ($del) { $tasks1 = $this->getTasksFromList($id); $taskobj = new task(); if (!empty($tasks1)) { foreach($tasks1 as $task) { $taskobj->del($task["ID"]); } } $tasks2 = $this->getTasksFromList($id, 0); if (!empty($tasks2)) { foreach($tasks2 as $task) { $taskobj->del($task["ID"]); } } $sel1 = $sel->fetch(); $proj = $sel1[0]; $name = $sel1[1]; $this->mylog->add($name, 'tasklist', 3, $proj); return true; } else { return false; } } /** * Reactivate / open a tasklist * * @param int $id Tasklist ID * @return bool */ function open_liste($id) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE tasklist SET status = 1 WHERE ID = $id"); if ($upd) { $nam = $conn->query("SELECT project, name FROM tasklist WHERE ID = $id")->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'tasklist', 4, $project); return true; } else { return false; } } /** * Finish / close a tasklist * * * @param int $id Tasklist ID * @param bool $closeMilestones Determines if the parent milestone is closed too if $id is the last assigned tasklist to that ms * @return bool */ function close_liste($id, $closeMilestones = true) { global $conn; $id = (int) $id; $upd = $conn->query("UPDATE tasklist SET status = 0 WHERE ID = $id"); if ($closeMilestones) { // Close assigned milestone too, if no other open tasklists are assigned to it $milestone = $conn->query("SELECT milestone FROM tasklist WHERE ID = $id")->fetch(); if ($milestone[0] > 0) { $cou = $conn->query("SELECT count(*) FROM tasklist WHERE milestone = $milestone[0] AND status = 1")->fetch(); if ($cou[0] == 0) { $miles = new milestone(); $miles->close($milestone[0]); } } } // Close tasks in this list $tasks = $this->getTasksFromList($id); if (!empty($tasks)) { $taskobj = new task(); foreach($tasks as $task) { $taskobj->close($task["ID"]); } } // Log entry if ($upd) { $nam = $conn->query("SELECT project, name FROM tasklist WHERE ID = $id")->fetch(); $project = $nam[0]; $name = $nam[1]; $this->mylog->add($name, 'tasklist', 5, $project); return true; } else { return false; } } /** * Return all tasklists (including its open tasks) associated with a given project * * @param int $project Project ID * @param int $status Tasklist status (0 = Finished, 1 = Active) * @return array $tasklists Details of the tasklists */ function getProjectTasklists($project, $status = 1) { global $conn; $project = (int) $project; $status = (int) $status; $sel = $conn->query("SELECT * FROM tasklist WHERE project = $project AND status=$status"); $tasklists = array(); $taskobj = new task(); while ($list = $sel->fetch()) { $sel2 = $conn->query("SELECT ID FROM tasks WHERE liste = $list[ID] AND status=1 ORDER BY `end`,`title` ASC"); $list['tasks'] = array(); while ($tasks = $sel2->fetch()) { array_push($list['tasks'], $taskobj->getTask($tasks["ID"])); } $sel3 = $conn->query("SELECT ID FROM tasks WHERE liste = $list[ID] AND status=0 ORDER BY `end` ASC"); $list['oldtasks'] = array(); while ($oldtasks = $sel3->fetch()) { array_push($list['oldtasks'], $taskobj->getTask($oldtasks["ID"])); } array_push($tasklists, $list); } if (!empty($tasklists)) { return $tasklists; } else { return false; } } /** * Return a tasklist * * @param int $id Taskist ID * @return array $tasklist Tasklist details */ function getTasklist($id) { global $conn; $selStmt = $conn->prepare("SELECT * FROM `tasklist` WHERE ID = ?"); $sel = $selStmt->execute(array($id)); // $sel = $conn->query("SELECT * FROM tasklist WHERE ID = $id"); $tasklist = $selStmt->fetch(); if (!empty($tasklist)) { $startstring = date(CL_DATEFORMAT, $tasklist["start"]); $tasklist["startstring"] = $startstring; $tasklist["name"] = stripslashes($tasklist["name"]); $tasklist["desc"] = stripslashes($tasklist["desc"]); $tasklist["tasks"] = $this->getTasksFromList($tasklist["ID"]); return $tasklist; } else { return false; } } /** * Return all open or all finished tasks of a given tasklist * * @param int $id Tasklist ID * @param int $status Status of the tasks (0 = finished, 1 = open) * @return array $tasks Details of the tasks */ function getTasksFromList($id, $status = 1) { global $conn; $id = (int) $id; $status = (int) $status; $taskobj = new task(); $sel = $conn->query("SELECT ID FROM tasks WHERE `liste` = $id AND `status` = $status ORDER BY `end`,`title` ASC"); $tasks = array(); while ($task = $sel->fetch()) { array_push($tasks, $taskobj->getTask($task["ID"])); } if (!empty($tasks)) { return $tasks; } else { return false; } } } ?>Collabtive-2.0/include/class.timetracker.php000066400000000000000000000273441237252063700212320ustar00rootroot00000000000000 * @name timetracker * @version 1.0 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class timetracker { private $mylog; /** * Constructor * Initialize the event log */ function __construct() { $this->mylog = new mylog; } /** * Add timetracker entry * * @param int $user User ID the timetrack belongs to * @param int $project Project ID the timetrack belongs to * @param int $task Task ID the timetrack belongs to * @param string $comment Comment on the timetrack * @param string $started Startdate of the tracked time period * @param string $ended Enddate of the tracked time period * @return int $insid Mysql ID of the inserted timetrack */ function add($user, $project, $task, $comment, $started, $ended, $startday = "", $endday = "") { global $conn; $username = $_SESSION['username']; if (!$startday) { $startday = date(CL_DATEFORMAT); } if (!$endday) { $endday = $startday; } $started = $startday . " " . $started; $started = strtotime($started); $ended = $endday . " " . $ended; $ended = strtotime($ended); $hours = $ended - $started; $hours = $hours / 3600; $hours = round($hours, 2); if ($started >= $ended) { return false; } $insStmt = $conn->prepare("INSERT INTO timetracker (user,project,task,comment,started,ended,hours,pstatus) VALUES (?,?,?,?,?,?,?,0)"); $ins = $insStmt->execute(array((int) $user, (int) $project, (int) $task, $comment, $started, $ended, $hours)); if ($ins) { $insid = $conn->lastInsertId(); $title = $username . " " . $hours . "h"; return $insid; } else { return false; } } /** * Edit timetracker entry * * @param int $id Timetrack ID to edit * @param int $task Task ID the timetrack belongs to * @param string $comment Comment on the timetrack * @param string $started Startdate of the tracked time period * @param string $ended Enddate of the tracked time period * @return bool */ function edit($id, $task, $comment, $started, $ended) { global $conn; if ($started >= $ended) { return false; } $hours = $ended - $started; $hours = $hours / 3600; $hours = round($hours, 2); $updStmt = $conn->prepare("UPDATE timetracker SET task=?, comment=?, started=?, ended=?, hours=? WHERE ID = ?"); $upd = $updStmt->execute(array((int) $task, $comment, (int) $started, (int) $ended, $hours, (int) $id)); if ($upd) { return true; } else { return false; } } /** * Delete timetracker entry * * @return bool */ function del($id) { global $conn; $id = (int) $id; $del = $conn->query("DELETE FROM timetracker WHERE ID = $id"); if ($del) { return true; } else { return false; } } function setPaystatus($pstatus, $id) { global $conn; $pstatus = (int) $pstatus; $id = (int) $id; $upd = $conn->query("UPDATE timetracker SET pstatus = $pstatus WHERE ID = $id"); if ($upd) { return true; } else { return false; } } /** * Return a timetrack * * @param int $id Timetrack ID * @return array $track */ function getTrack($id) { global $conn; $id = (int) $id; $sel = $conn->query("SELECT * FROM timetracker WHERE ID = $id"); $track = array(); $track = $sel->fetch(); if (!empty($track)) { if (isset($track["started"]) and isset($track["ended"])) { $hours = $track["ended"] - $track["started"]; $hours = $hours / 3600; $hours = round($hours, 2); $track["hours"] = $hours; $day = date(CL_DATEFORMAT, $track["started"]); $endday = date(CL_DATEFORMAT, $track["ended"]); $track["started"] = date("H:i", $track["started"]); $track["ended"] = date("H:i", $track["ended"]); $track["day"] = $day; $track["endday"] = $endday; } if (isset($track["comment"])) { $track["comment"] = stripslashes($track["comment"]); } return $track; } else { return false; } } function getUserTrack($user, $project = 0, $task = 0, $start = 0, $end = 0 , $lim = 50) { global $conn; $user = (int) $user; $project = (int) $project; $lim = (int) $lim; $task = (int) $task; // $start = (int) $start; // those are strings, not numbers // $end = (int) $end; if ($project > 0) { $sql = "SELECT * FROM timetracker WHERE user = $user AND project = $project"; $num = "SELECT COUNT(*) FROM timetracker WHERE user = $user AND project = $project"; $order = " ORDER BY ended ASC"; } else { $sql = "SELECT * FROM timetracker WHERE user = $user"; $num = "SELECT COUNT(*) FROM timetracker WHERE user = $user"; $order = " ORDER BY ended ASC"; } if ($task > 0) { $sql .= " AND task = $task"; $num .= " AND task = $task"; } if ($start > 0 and $end > 0) { $start = strtotime($start); $end = strtotime($end . " +1 day"); $end = $end - 1; $sql .= " AND ended >=$start AND ended<=$end "; $num .= " AND ended >=$start AND ended<=$end "; } if ($num) { $num = $conn->query($num)->fetch(); $num = $num[0]; } else { $num = 0; } //needs to be refactroed if ($lim > 0) { $sql = $sql . $order; SmartyPaginate::connect(); SmartyPaginate::setLimit($lim); SmartyPaginate::setTotal($num); $start = SmartyPaginate::getCurrentIndex(); $lim = SmartyPaginate::getLimit(); $limi = " LIMIT $start,$lim"; $sql = $sql . $limi; } $sel = $conn->query($sql); $track = array(); $ttask = new task(); if (isset($sel)) { while ($data = @$sel->fetch()) { $endstring = date("H:i", $data["ended"]); $startstring = date("H:i", $data["started"]); $daystring = date("d.m.y", $data["ended"]); $tasks = $ttask->getTask($data["task"]); if (!empty($tasks)) { $tasks = $tasks["title"]; $data["tname"] = $tasks; } $pname = $conn->query("SELECT name FROM projekte WHERE ID = $data[project]")->fetch(); $pname = stripslashes($pname[0]); $uname = $conn->query("SELECT name FROM user WHERE ID = $data[user]")->fetch(); $uname = stripslashes($uname[0]); $data["endstring"] = $endstring; $data["startstring"] = $startstring; $data["daystring"] = $daystring; $data["uname"] = $uname; $data["pname"] = $pname; $data["comment"] = stripslashes($data["comment"]); $data["comment"] = nl2br($data["comment"]); array_push($track, $data); } } if (!empty($track)) { return $track; } else { return false; } } function getProjectTrack($project, $user = 0, $task = 0, $start = 0, $end = 0, $lim = 50) { global $conn; $project = (int) $project; $user = (int) $user; $lim = (int) $lim; // make sure task is an array - this needs to be refactored if (!is_array($task)) { $task = array($task); } // make sure all the fields are ints for ($index = 0; $index < count($task);$index++) { $task[$index] = (int) $task[$index]; } $task = join(',', $task); // $start = (int) $start; // those are strings, not numbers // $end = (int) $end; // those are strings, not numbers if ($user > 0) { $sql = "SELECT * FROM timetracker WHERE project = $project AND user = $user"; $num = "SELECT COUNT(*) FROM timetracker WHERE project = $project AND user = $user"; $order = " ORDER BY ended ASC"; } else { $sql = "SELECT * FROM timetracker WHERE project = $project"; $num = "SELECT COUNT(*) FROM timetracker WHERE project = $project"; $order = " ORDER BY ended ASC"; } if ($task > 0) { $sql .= " AND task in ($task)"; $num .= " AND task in ($task)"; } if ($start > 0 and $end > 0) { $start = strtotime($start); $end = strtotime($end . " +1 day"); $end = $end - 1; $sql .= " AND ended >=$start AND ended<=$end "; $num .= " AND ended >=$start AND ended<=$end "; } if ($num) { $num = $conn->query($num)->fetch(); $num = $num[0]; } else { $num = 0; } $sql = $sql . $order; // needs to be refactored if ($lim > 0) { SmartyPaginate::connect(); SmartyPaginate::setLimit($lim); SmartyPaginate::setTotal($num); $start = SmartyPaginate::getCurrentIndex(); $lim = SmartyPaginate::getLimit(); $limi = " LIMIT $start,$lim "; $sql = $sql . $limi; } $sel = $conn->query($sql); $track = array(); $ttask = new task(); if (isset($sel)) { while ($data = @$sel->fetch()) { $endstring = date("H:i", $data["ended"]); $startstring = date("H:i", $data["started"]); $daystring = date(CL_DATEFORMAT, $data["ended"]); $tasks = $ttask->getTask($data["task"]); if (!empty($tasks)) { $tasks = $tasks["title"]; $data["tname"] = $tasks; } $pname = $conn->query("SELECT name FROM projekte WHERE ID = $data[project]")->fetch(); $pname = stripslashes($pname[0]); $uname = $conn->query("SELECT name FROM user WHERE ID = $data[user]")->fetch(); $uname = stripslashes($uname[0]); $data["endstring"] = $endstring; $data["startstring"] = $startstring; $data["daystring"] = $daystring; $data["uname"] = $uname; $data["pname"] = $pname; $data["comment"] = stripslashes($data["comment"]); $data["comment"] = nl2br($data["comment"]); array_push($track, $data); } } if (!empty($track)) { return $track; } else { return false; } } /** * Get total time spent on a given timetrack * * @param array $track Timetrack to evaluate * @return float $totaltime Total time spent on the timetrack */ function getTotalTrackTime(array $track) { $totaltime = 0; foreach($track as $data) { $totaltime = $totaltime + $data["hours"]; } if (!($totaltime > 0)) { $totaltime = 0; } return $totaltime; } } ?> Collabtive-2.0/include/class.toXml.php000066400000000000000000000055401237252063700200150ustar00rootroot00000000000000 * @name toXml * @private $writer PHP XML Writer object * @version 0.4.8 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or later */ class toXml { private $writer; function __construct() { //create XMLWriter Object $this->writer = (object) new XMLWriter(); } /** * Convert array to complete XML document. * Accepts an associative array. * Also accepts a numeric and associative indexed array (as for example returned by mysql_fetch_array()), * but strips the numeric index from those. * * @param array $inarr Array to convert * @param string $rootname Name of the root XML element * @return string Array as XML */ public function arrToXml(array $inarr, $rootname) { $writer = $this->writer; //$writer->openURI('php://output'); $writer->openMemory(); //start a new document $writer->startDocument("1.0","utf-8","yes"); $writer->setIndent(true); //create the root element $writer->startElement($rootname); // $writer->writeAttribute("count",count($inarr)); //convert the array recursively $this->convertit($inarr); //end the root element $writer->endElement(); //close the document $writer->endDocument(); //return the XML as string return $writer->outputMemory(); } /** * Convert array to JSON. * Accepts an associative array. * Also accepts a numeric and associative indexed array (as for example returned by mysql_fetch_array()) * This is a wrapper around PHPs json_encode() * * @param array $inarr Array to convert * @return string Array as JSON */ public function arrToJSON(array $inarr) { return json_encode($inarr); } /** * Private function that recursively converts an Array to XML. * Used by arrToXml() * Accepts an associative array. * Also accepts a numeric and associative indexed array (as for example returned by mysql_fetch_array()), * but strips the numeric index from those. * * @param array $inarr Array to convert * * @return void */ private function convertit(array $inarr) { $writer = $this->writer; foreach($inarr as $key => $val) { //if value is an array again, recursively call this function if(is_array($val)) { //if key is numeric, convert it to a string if(is_numeric($key)) { $numkey = $key; $key = "node"; $writer->startElement($key); //$writer->writeAttribute("num",$numkey); } else { $writer->startElement($key); } //convert $val recursively $this->convertit($val); $writer->endElement(); } else { if(!is_numeric($key)) { $writer->writeElement($key,strip_tags($val)); } } } } } ?>Collabtive-2.0/include/class.user.php000066400000000000000000000364761237252063700177040ustar00rootroot00000000000000 * @name user * @version 0.7 * @package Collabtive * @link http://www.o-dyn.de * @license http://opensource.org/licenses/gpl-license.php GNU General Public License v3 or laterg */ class user { public $mylog; /** * Constructor * Initializes event log */ function __construct() { $this->mylog = new mylog; } /** * Creates a user * * @param string $name Name of the member * @param string $email E-mail address of the member * @param string $company Company of the member * @param string $pass Password * @param string $locale Localisation * @param float $rate Hourly rate * @return int $insid ID of the newly created member */ function add($name, $email, $company, $pass, $locale = "", $tags = "", $rate = 0.0) { global $conn; $pass = sha1($pass); $ins1Stmt = $conn->prepare("INSERT INTO user (name,email,company,pass,locale,tags,rate) VALUES (?, ?, ?, ?, ?, ?, ?)"); $ins1 = $ins1Stmt->execute(array($name, $email, $company, $pass, $locale, $tags, $rate)); if ($ins1) { $insid = $conn->lastInsertId(); $this->mylog->add($name, 'user', 1, 0); return $insid; } else { return false; } } /** * Edits a member * * @param int $id Member ID * @param string $name Member name * @param string $realname realname * @param string $role role * @param string $email Email * @param string $company Company of the member * @param string $zip ZIP-Code * @param string $gender Gender * @param string $url URL * @param string $address1 Adressline1 * @param string $address2 Addressline2 * @param string $state State * @param string $country Country * @param string $locale Localisation * @param string $avatar Avatar * @return bool */ function edit($id, $name, $realname, $email, $tel1, $tel2, $company, $zip, $gender, $url, $address1, $address2, $state, $country, $tags, $locale, $avatar = "", $rate = 0.0) { global $conn; $rate = (float) $rate; $id = (int) $id; if ($avatar != "") { $updStmt = $conn->prepare("UPDATE user SET name=?, email=?, tel1=?, tel2=?, company=?, zip=?, gender=?, url=?, adress=?, adress2=?, state=?, country=?, tags=?, locale=?, avatar=?, rate=? WHERE ID = ?"); $upd = $updStmt->execute(array($name, $email, $tel1, $tel2, $company, $zip, $gender, $url, $address1, $address2, $state, $country, $tags, $locale, $avatar, $rate, $id)); } else { $updStmt = $conn->prepare("UPDATE user SET name=?, email=?, tel1=?, tel2=?, company=?, zip=?, gender=?, url=?, adress=?, adress2=?, state=?, country=?, tags=?, locale=?, rate=? WHERE ID = ?"); $upd = $updStmt->execute(array($name, $email, $tel1, $tel2, $company, $zip, $gender, $url, $address1, $address2, $state, $country, $tags, $locale, $rate, $id)); } if ($upd) { $this->mylog->add($name, 'user', 2, 0); return true; } else { return false; } } /** * Generate a new password and send it to the user's e-mail address * * @param string $email E-mail address entered by the user * @return string */ function resetPassword($email) { global $conn; $user = $conn->query("SELECT ID, email, locale FROM user WHERE email={$conn->quote($email)} LIMIT 1")->fetch(); if ($user["email"] == $email) { $id = $user["ID"]; $locale = $user['locale']; } if (isset($id)) { $dummy = array_merge(range('0', '9'), range('a', 'z'), range('A', 'Z'), range('0', '9')); shuffle($dummy); mt_srand((double)microtime() * 1000000); $newpass = ""; for ($i = 1; $i <= 10; $i++) { $swap = mt_rand(0, count($dummy)-1); $tmp = $dummy[$swap]; $newpass .= $tmp; } $sha1pass = sha1($newpass); $upd = $conn->query("UPDATE user SET `pass` = '$sha1pass' WHERE ID = $id"); if ($upd) { return array('newpass'=>$newpass, 'locale'=>$locale); } else { return false; } } else { return false; } } /** * Change password * * @param int $id Member ID * @param string $oldpass Old password * @param string $newpass New password * @param string $repeatpass Repetition of the new password * @return bool */ function editpass($id, $oldpass, $newpass, $repeatpass) { global $conn; $id = (int) $id; if ($newpass != $repeatpass) { return false; } $newpass = sha1($newpass); $oldpass = sha1($oldpass); $chk = $conn->query("SELECT ID, name FROM user WHERE ID = $id AND pass = {$conn->quote($oldpass)}")->fetch(); $chk = $chk[0]; $name = $chk[1]; if (!$chk) { return false; } $upd = $conn->query("UPDATE user SET pass={$conn->quote($newpass)} WHERE ID = $id"); if ($upd) { return true; } else { return false; } } /** * Change password as admin * * @param int $id User ID * @param string $newpass New password * @param string $repeatpass Repetition of the new password * @return bool */ function admin_editpass($id, $newpass, $repeatpass) { global $conn; $id = (int) $id; if ($newpass != $repeatpass) { return false; } $newpass = sha1($newpass); $upd = $conn->query("UPDATE user SET pass={$conn->quote($newpass)} WHERE ID = $id"); if ($upd) { return true; } else { return false; } } /** * Delete a user * * @param int $id User ID * @return bool */ function del($id) { global $conn; $id = (int) $id; $chk = $conn->query("SELECT name FROM user WHERE ID = $id")->fetch(); $name = $chk[0]; $del = $conn->query("DELETE FROM user WHERE ID = $id"); $del2 = $conn->query("DELETE FROM projekte_assigned WHERE user = $id"); $del3 = $conn->query("DELETE FROM milestones_assigned WHERE user = $id"); $del4 = $conn->query("DELETE FROM tasks_assigned WHERE user = $id"); $del5 = $conn->query("DELETE FROM log WHERE user = $id"); $del6 = $conn->query("DELETE FROM timetracker WHERE user = $id"); $del7 = $conn->query("DELETE FROM roles_assigned WHERE user = $id"); if ($del) { $this->mylog->add($name, 'user', 3, 0); return true; } else { return false; } } /** * Get a user profile * * @param int $id User ID * @return array $profile Profile */ function getProfile($id) { global $conn; $id = (int) $id; $sel = $conn->query("SELECT * FROM user WHERE ID = $id"); $profile = $sel->fetch(); if (!empty($profile)) { $profile["name"] = stripslashes($profile["name"]); if (isset($profile["company"])) { $profile["company"] = stripslashes($profile["company"]); } if (isset($profile["adress"])) { $profile["adress"] = stripslashes($profile["adress"]); } if (isset($profile["adress2"])) { $profile["adress2"] = stripslashes($profile["adress2"]); } if (isset($profile["state"])) { $profile["state"] = stripslashes($profile["state"]); } if (isset($profile["country"])) { $profile["country"] = stripslashes($profile["country"]); } $tagsobj = new tags(); $profile["tagsarr"] = $tagsobj->splitTagStr($profile["tags"]); $rolesobj = (object) new roles(); $profile["role"] = $rolesobj->getUserRole($profile["ID"]); return $profile; } else { return false; } } /** * Get the avatar of a user * * @param int $id User ID * @return array $profile Avatar */ function getAvatar($id) { $id = (int) $id; global $conn; $sel = $conn->query("SELECT avatar FROM user WHERE ID = $id"); $profile = $sel->fetch(); $profile = $profile[0]; if (!empty($profile)) { return $profile; } else { return false; } } /** * Log a user in * * @param string $user User name * @param string $pass Password * @return bool */ function login($user, $pass) { global $conn; if (!$user) { return false; } $user = $conn->quote($user); $pass = sha1($pass); $sel1 = $conn->query("SELECT ID,name,locale,lastlogin,gender FROM user WHERE (name = $user OR email = $user) AND pass = '$pass'"); $chk = $sel1->fetch(); if ($chk["ID"] != "") { $rolesobj = new roles(); $now = time(); $_SESSION['userid'] = $chk['ID']; $_SESSION['username'] = stripslashes($chk['name']); $_SESSION['lastlogin'] = $now; $_SESSION['userlocale'] = $chk['locale']; $_SESSION['usergender'] = $chk['gender']; $_SESSION["userpermissions"] = $rolesobj->getUserRole($chk["ID"]); $userid = $_SESSION['userid']; $seid = session_id(); $staylogged = getArrayVal($_POST, 'staylogged'); if ($staylogged == 1) { setcookie("PHPSESSID", "$seid", time() + 14 * 24 * 3600); } $upd1 = $conn->query("UPDATE user SET lastlogin = '$now' WHERE ID = $userid"); return true; } else { return false; } } /** * Log a user in * * @param string $user User name * @param string $pass Password * @return bool */ function openIdLogin($url) { /* here the openid auth should take place */ try { $openid = new LightOpenID($_SERVER['HTTP_HOST']); if (!$openid->mode) { $openid->identity = $url; header('Location: ' . $openid->authUrl()); } elseif ($openid->mode == 'cancel') { return false; } else { $identity = $openid->data['openid_identity']; $sel1 = $conn->query("SELECT ID from openids WHERE identity='$identity'"); if ($row = $sel1->fetch()) { $id = $row['ID']; } else return false; // die("SELECT ID,name,locale,lastlogin,gender FROM user WHERE ID=$id"); $sel1 = $conn->query("SELECT ID,name,locale,lastlogin,gender FROM user WHERE ID=$id"); $chk = $sel1->fetch(); if ($chk["ID"] != "") { $rolesobj = new roles(); $now = time(); $_SESSION['userid'] = $chk['ID']; $_SESSION['username'] = stripslashes($chk['name']); $_SESSION['lastlogin'] = $now; $_SESSION['userlocale'] = $chk['locale']; $_SESSION['usergender'] = $chk['gender']; $_SESSION["userpermissions"] = $rolesobj->getUserRole($chk["ID"]); $userid = $_SESSION['userid']; $seid = session_id(); $staylogged = getArrayVal($_POST, 'staylogged'); if ($staylogged == 1) { setcookie("PHPSESSID", "$seid", time() + 14 * 24 * 3600); } $upd1 = $conn->prepare("UPDATE user SET lastlogin = ? WHERE ID = ?"); $upd1Stmt = $upd1->execute(array($now,$userid)); return true; } else { return false; } } } catch(ErrorException $e) { return false; } } /** * Logout * * @return bool */ function logout() { session_start(); session_destroy(); session_unset(); setcookie("PHPSESSID", ""); return true; } /** * Returns all users * * @param int $lim Limit * @return array $users Registrierte Mitglieder */ function getAllUsers($lim = 10) { global $conn; $lim = (int) $lim; $num = $conn->query("SELECT COUNT(*) FROM `user`")->fetch(); $num = $num[0]; SmartyPaginate::connect(); // set items per page SmartyPaginate::setLimit($lim); SmartyPaginate::setTotal($num); $start = SmartyPaginate::getCurrentIndex(); $lim = SmartyPaginate::getLimit(); $sel2 = $conn->query("SELECT ID FROM `user` ORDER BY ID DESC LIMIT $start,$lim"); $users = array(); while ($user = $sel2->fetch()) { array_push($users, $this->getProfile($user["ID"])); } if (!empty($users)) { return $users; } else { return false; } } /** * Get all users who are logged in * * @param int $offset Allowed time from last login * @return array $users */ function getOnlinelist($offset = 200) { global $conn; $offset = (int) $offset; $time = time(); $now = $time - $offset; $sel = $conn->query("SELECT * FROM user WHERE lastlogin >= $now"); $users = array(); while ($user = $sel->fetch()) { $user["name"] = stripslashes($user["name"]); $user["company"] = stripslashes($user["company"]); $user["adress"] = stripslashes($user["adress"]); $user["adress2"] = stripslashes($user["adress2"]); $user["state"] = stripslashes($user["state"]); $user["country"] = stripslashes($user["country"]); array_push($users, $user); } if (!empty($users)) { return $users; } else { return false; } } /** * Is the given user logged in? * * @param int $user Member ID * @param int $offset Allowed time from last login * @return bool */ function isOnline($user, $offset = 30) { global $conn; $user = (int) $user; $offset = (int) $offset; $time = time(); $now = $time - $offset; $sel = $conn->query("SELECT ID FROM user WHERE lastlogin >= $now AND ID = $user"); $user = $sel->fetch(); if (!empty($user)) { return true; } else { return false; } } /** * Get a user's ID * * @param string $user Username * @return int $theid */ function getId($user) { global $conn; $sel = $conn->query("SELECT ID FROM user WHERE name = {$conn->quote($user)}"); $id = $sel->fetch(); $id = $id[0]; $theid = array(); $theid["ID"] = $id; if ($id > 0) { return $theid; } else { return array(); } } } ?> Collabtive-2.0/include/class.vCard.php000066400000000000000000000371561237252063700177610ustar00rootroot00000000000000card_filename = (string) time() . '.vcf'; $this->rev = (string) date('Ymd\THi00\Z', time()); $this->setLanguage($lang); } // end function private function setString($var, $value = '') { if (strlen(trim($value)) > 0) { $this->$var = (string) $value; } // end if } // end function public function setFirstName($string = '') { $this->setString('first_name', $string); } // end function public function setMiddleName($string = '') { $this->setString('middle_name', $string); } // end function public function setLastName($string = '') { $this->setString('last_name', $string); } // end function public function setEducationTitle($string = '') { $this->setString('edu_title', $string); } // end function public function setAddon($string = '') { $this->setString('addon', $string); } // end function public function setNickname($string = '') { $this->setString('nickname', $string); } // end function public function setCompany($string = '') { $this->setString('company', $string); } // end function public function setOrganisation($string = '') { $this->setString('organisation', $string); } // end function public function setDepartment($string = '') { $this->setString('department', $string); } // end function public function setJobTitle($string = '') { $this->setString('job_title', $string); } // end function public function setNote($string = '') { $this->setString('note', $string); } // end function public function setTelephoneWork1($string = '') { $this->setString('tel_work1_voice', $string); } // end function public function setTelephoneWork2($string = '') { $this->setString('tel_work2_voice', $string); } // end function public function setTelephoneHome1($string = '') { $this->setString('tel_home1_voice', $string); } // end function public function setTelephoneHome2($string = '') { $this->setString('tel_home2_voice', $string); } // end function public function setCellphone($string = '') { $this->setString('tel_cell_voice', $string); } // end function public function setCarphone($string = '') { $this->setString('tel_car_voice', $string); } // end function public function setPager($string = '') { $this->setString('tel_pager_voice', $string); } // end function public function setAdditionalTelephone($string = '') { $this->setString('tel_additional', $string); } // end function public function setFaxWork($string = '') { $this->setString('tel_work_fax', $string); } // end function public function setFaxHome($string = '') { $this->setString('tel_home_fax', $string); } // end function public function setISDN($string = '') { $this->setString('tel_isdn', $string); } // end function public function setPreferredTelephone($string = '') { $this->setString('tel_preferred', $string); } // end function public function setTelex($string = '') { $this->setString('tel_telex', $string); } // end function public function setWorkStreet($string = '') { $this->setString('work_street', $string); } // end function public function setWorkZIP($string = '') { $this->setString('work_zip', $string); } // end function public function setWorkCity($string = '') { $this->setString('work_city', $string); } // end function public function setWorkRegion($string = '') { $this->setString('work_region', $string); } // end function public function setWorkCountry($string = '') { $this->setString('work_country', $string); } // end function public function setHomeStreet($string = '') { $this->setString('home_street', $string); } // end function public function setHomeZIP($string = '') { $this->setString('home_zip', $string); } // end function public function setHomeCity($string = '') { $this->setString('home_city', $string); } // end function public function setHomeRegion($string = '') { $this->setString('home_region', $string); } // end function public function setHomeCountry($string = '') { $this->setString('home_country', $string); } // end function public function setPostalStreet($string = '') { $this->setString('postal_street', $string); } // end function public function setPostalZIP($string = '') { $this->setString('postal_zip', $string); } // end function public function setPostalCity($string = '') { $this->setString('postal_city', $string); } // end function public function setPostalRegion($string = '') { $this->setString('postal_region', $string); } // end function public function setPostalCountry($string = '') { $this->setString('postal_country', $string); } // end function public function setURLWork($string = '') { $this->setString('url_work', $string); } // end function public function setRole($string = '') { $this->setString('role', $string); } // end function public function setEMail($string = '') { $this->setString('email', $string); } // end function private function setLanguage($isocode = '') { $this->lang = (string) (($this->isValidLanguageCode($isocode) == true) ? ';LANGUAGE=' . $isocode : ''); } // end function public function setBirthday($timestamp) { $this->birthday = (int) date('Ymd', $timestamp); } // end function public function setPhoto($type, $photo) { $this->photo = "PHOTO;TYPE=$type;ENCODING=BASE64:" . base64_encode($photo); } private function quotedPrintableEncode($quotprint) { /** * //beim Mac Umlaute nicht kodieren !!!! sonst Fehler beim Import * if ($progid == 3) * { * $quotprintenc = preg_replace("~([\x01-\x1F\x3D\x7F-\xBF])~e", "sprintf('=%02X', ord('\\1'))", $quotprint); * return($quotprintenc); * } * //bei Windows und Linux alle Sonderzeichen kodieren * else * { */ $quotprint = (string) str_replace('\r\n', chr(13) . chr(10), $quotprint); $quotprint = (string) str_replace('\n', chr(13) . chr(10), $quotprint); $quotprint = (string) preg_replace("~([\x01-\x1F\x3D\x7F-\xFF])~e", "sprintf('=%02X', ord('\\1'))", $quotprint); $quotprint = (string) str_replace('\=0D=0A', '=0D=0A', $quotprint); return (string) $quotprint; } // end function public static function isValidLanguageCode($code) // PHP5: protected { return (boolean) ((preg_match('(^([a-zA-Z]{2})((_|-)[a-zA-Z]{2})?$)', trim($code)) > 0) ? true : false); } // end function private function generateCardOutput($format) { $this->output_format = (string) $format; if ($this->output_format == 'vcf') { $this->output = (string) "BEGIN:VCARD\r\n"; $this->output .= (string) "VERSION:2.1\r\n"; $this->output .= (string) "N;ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->last_name . ";" . $this->first_name . ";" . $this->middle_name . ";" . $this->addon) . "\r\n"; $this->output .= (string) "FN;ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->first_name . " " . $this->middle_name . " " . $this->last_name . " " . $this->addon) . "\r\n"; if (strlen(trim($this->nickname)) > 0) { $this->output .= (string) "NICKNAME;ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->nickname) . "\r\n"; } // end if $this->output .= (string) "ORG" . $this->lang . ";ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->organisation) . ";" . $this->quotedPrintableEncode($this->department) . "\r\n"; if (strlen(trim($this->job_title)) > 0) { $this->output .= (string) "TITLE" . $this->lang . ";ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->job_title) . "\r\n"; } // end if if (isset($this->note)) { $this->output .= (string) "NOTE" . $this->lang . ";ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->note) . "\r\n"; } // end if if (isset($this->tel_work1_voice)) { $this->output .= (string) "TEL;WORK;VOICE:" . $this->tel_work1_voice . "\r\n"; } // end if if (isset($this->tel_work2_voice)) { $this->output .= (string) "TEL;WORK;VOICE:" . $this->tel_work1_voice . "\r\n"; } // end if if (isset($this->tel_home1_voice)) { $this->output .= (string) "TEL;HOME;VOICE:" . $this->tel_home1_voice . "\r\n"; } // end if if (isset($this->tel_cell_voice)) { $this->output .= (string) "TEL;CELL;VOICE:" . $this->tel_cell_voice . "\r\n"; } // end if if (isset($this->tel_car_voice)) { $this->output .= (string) "TEL;CAR;VOICE:" . $this->tel_car_voice . "\r\n"; } // end if if (isset($this->tel_additional)) { $this->output .= (string) "TEL;VOICE:" . $this->tel_additional . "\r\n"; } // end if if (isset($this->tel_pager_voice)) { $this->output .= (string) "TEL;PAGER;VOICE:" . $this->tel_pager_voice . "\r\n"; } // end if if (isset($this->tel_work_fax)) { $this->output .= (string) "TEL;WORK;FAX:" . $this->tel_work_fax . "\r\n"; } // end if if (isset($this->tel_home_fax)) { $this->output .= (string) "TEL;HOME;FAX:" . $this->tel_home_fax . "\r\n"; } // end if if (isset($this->tel_home2_voice)) { $this->output .= (string) "TEL;HOME:" . $this->tel_home2_voice . "\r\n"; } // end if if (isset($this->tel_isdn)) { $this->output .= (string) "TEL;ISDN:" . $this->tel_isdn . "\r\n"; } // end if if(isset($this->photo)) { $this->output .= (string) $this->photo . "\r\n"; } if (isset($this->tel_preferred)) { $this->output .= (string) "TEL;PREF:" . $this->tel_preferred . "\r\n"; } // end if $this->output .= (string) "ADR;WORK:;" . $this->company . ";" . $this->work_street . ";" . $this->work_city . ";" . $this->work_region . ";" . $this->work_zip . ";" . $this->work_country . "\r\n"; $this->output .= (string) "LABEL;WORK;ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->company) . "=0D=0A" . $this->quotedPrintableEncode($this->work_street) . "=0D=0A" . $this->quotedPrintableEncode($this->work_city) . ", " . $this->quotedPrintableEncode($this->work_region) . " " . $this->quotedPrintableEncode($this->work_zip) . "=0D=0A" . $this->quotedPrintableEncode($this->work_country) . "\r\n"; $this->output .= (string) "ADR;HOME:;" . $this->home_street . ";" . $this->home_city . ";" . $this->home_region . ";" . $this->home_zip . ";" . $this->home_country . "\r\n"; $this->output .= (string) "LABEL;HOME;ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->home_street) . "=0D=0A" . $this->quotedPrintableEncode($this->home_city) . ", " . $this->quotedPrintableEncode($this->home_region) . " " . $this->quotedPrintableEncode($this->home_zip) . "=0D=0A" . $this->quotedPrintableEncode($this->home_country) . "\r\n"; $this->output .= (string) "ADR;POSTAL:;" . $this->postal_street . ";" . $this->postal_city . ";" . $this->postal_region . ";" . $this->postal_zip . ";" . $this->postal_country . "\r\n"; $this->output .= (string) "LABEL;POSTAL;ENCODING=QUOTED-PRINTABLE:" . $this->quotedPrintableEncode($this->postal_street) . "=0D=0A" . $this->quotedPrintableEncode($this->postal_city) . ", " . $this->quotedPrintableEncode($this->postal_region) . " " . $this->quotedPrintableEncode($this->postal_zip) . "=0D=0A" . $this->quotedPrintableEncode($this->postal_country) . "\r\n"; if (isset($this->url_work)) { $this->output .= (string) "URL;WORK:" . $this->url_work . "\r\n"; } // end if if (isset($this->role)) { $this->output .= (string) "ROLE" . $this->lang . ":" . $this->role . "\r\n"; } // end if if (isset($this->birthday)) { $this->output .= (string) "BDAY:" . $this->birthday . "\r\n"; } // end if if (isset($this->email)) { $this->output .= (string) "EMAIL;PREF;INTERNET:" . $this->email . "\r\n"; } // end if if (isset($this->tel_telex)) { $this->output .= (string) "EMAIL;TLX:" . $this->tel_telex . "\r\n"; } // end if $this->output .= (string) "REV:" . $this->rev . "\r\n"; $this->output .= (string) "END:VCARD\r\n"; } // end if output_format == 'vcf' } // end function public function getCardOutput($format = "vcf") { if (!isset($this->output) || $this->output_format != $format) { $this->generateCardOutput($format); } // end if return (string) $this->output; } // end function public function outputFile($format = 'vcf') { if ($format == 'vcf') { header('Content-Type: text/x-vcard'); header('Content-Disposition: attachment; filename=vCard_' . date('Y-m-d_H-m-s') . '.vcf'); echo $this->getCardOutput('vcf'); } // end if } // end function private function getCardFilePath() { $path_parts = pathinfo($_SERVER['SCRIPT_NAME']); $port = (string) (($_SERVER['SERVER_PORT'] != 80) ? ':' . $_SERVER['SERVER_PORT'] : ''); return (string) 'http://' . $_SERVER['SERVER_NAME'] . $port . $path_parts["dirname"] . '/' . $this->download_dir . '/' . $this->card_filename; } // end function } // end class vCard ?>Collabtive-2.0/include/class.xls.php000066400000000000000000000151741237252063700175240ustar00rootroot00000000000000open($file); } function open($file) { if ($this->state != "CLOSED") { return false; } if (!empty($file)) { $this->fp = @fopen($file, "w+"); } else { return false; } if ($this->fp == false) { return false; } $this->state = "OPENED"; fwrite($this->fp, $this->GetHeader()); return $this->fp; } function close() { if ($this->state != "OPENED") { return false; } if ($this->newRow) { fwrite($this->fp, ""); $this->newRow = false; } fwrite($this->fp, $this->GetFooter()); fclose($this->fp); $this->state = "CLOSED"; return ; } function GetHeader() { $lastsav = date("e"); $header = << EOH; return $header; } function GetFooter() { return "
      "; } function writeLine(array $line_arr, $width = 64) { if ($this->state != "OPENED") { return false; } fwrite($this->fp, ""); foreach($line_arr as $col) { fwrite($this->fp, "$col"); } fwrite($this->fp, ""); } function writeBoldLine(array $line_arr, $width = 64) { if ($this->state != "OPENED") { return false; } fwrite($this->fp, ""); foreach($line_arr as $col) { fwrite($this->fp, "$col"); } fwrite($this->fp, ""); } function writeHeadLine(array $line_arr, $width = 64) { if ($this->state != "OPENED") { return false; } fwrite($this->fp, ""); foreach($line_arr as $col) { fwrite($this->fp, "

      $col

      "); } fwrite($this->fp, ""); } function writeRow() { if ($this->state != "OPENED") { return false; } if ($this->newRow == false) { fwrite($this->fp, ""); } else { fwrite($this->fp, ""); $this->newRow = true; } } function writeColspan($value, $colspan = 0) { if ($this->state != "OPENED") { return false; } fwrite($this->fp, "$value"); } function writeCol($value) { if ($this->state != "OPENED") { return false; } fwrite($this->fp, "$value"); } } ?>Collabtive-2.0/include/font/000077500000000000000000000000001237252063700160375ustar00rootroot00000000000000Collabtive-2.0/include/font/freeserif.ctg.z000066400000000000000000000251751237252063700207720ustar00rootroot00000000000000x䨾(| Āuݾ:3sv{"` & ,` < ""( * &b8 . !H$ )H %HR4 -H҃ #2, + 'r< / ( "(($(J2,(ʃ "***&n>6z>hF1hf9hZV5hڂv=:N3n;z^7~?A`0a`8FQ`4Ƃq`<&I`2i`:fY`6y`>XE`1Xe`9XVU`5Xւu`=6M`3m`;v]`7}`?8C08c88NS48΂s<.K2k:n[6{>xG1xg9x^W5xނw=>O3o;AbB Ѐ&$B-hC( =0"#(0* 0&c80.0!L$0)L0%LS40-L 0#3,0+0's<0/ , "(,$,K2,, "+**&k:.!l&)l%l[6-l#;.+'{>/p !p(p$G1p, p"')p*p&g9p.p!\%p)\p%\W5p-\ p#7-p+p'w=p/ <#(<$<O3,< "/+*&o;.!|')|%|_7-|#?/+ RF*Ґ d"(bB6AC>"H(20h(:bX(6x(>JD(1Jd(9JRT(5JҢt(=ʀ2L(3ʂl(;ʁr\(7ʃ|(?* B0*b8*JR4*ʢr<*J2j:jZ6z>jF1jf9jZV5jڢv=:N3ꂺn;z^7~?Ah0ah8FQh4Ƣqh<&Ih2ih:fYh6yh>ZEh1Zeh9ZVUh5Z֢uh=ڀ6Mh3ڂmh;ځv]h7ڃ}h?:C0:c8:NS4:΢s<.K2k:n[6{>zG1zg9z^W5zޢw=>O3o;*HQ芡 QK8P\S|%QDV(Q0%P)ѕJL%[U)JB%XI$U)ɕJJ%ZIU) <2,3c,EɪdS+9zPʭQ*JRH)Q*ŔJ RJ)Q*B=+J%RETS+5J-RGS+ J#Di4S+-J+FiS+J'EtS+=JPJO P*e2LPF*e2NLP&*e2MPf*e2O,P*eLYPV*eNYlP6*eMٮPv*eOٯP*rL9PN*rN9\P.*rMPn*rO*MC1Vul`L11qG‘qGq ±qq'‰q'q ©qqg™qgq¹qq\…q\q \¥q\q\W•q\Wq \µq\q7q7q ­qqwqwq½q<ƒ<<£<<O“<O <³</‹/ «o›o»|‡| |§|H~G1~g9~_W5~w=?O3+*PPjJT2Rm*TWT_FT#(jT5L hjt5SVqxj|5PMXMWj 5JMQӪj5IͬfQj5KͭQjZH-Qj ZJ-Q˪jZIVQj ZK۫QjHm6Qj JmQ۪jIvQl|wS>֪}پ?~_T!Pu:\TG1Xu:^NT')Tu:]X3Ylu:WW EPuL]PWꚿ:uAݨnR7[ԭPo_7]m?}FM}?IkzH=Q zJ=QϪzI^Q zKQH}>Q J}Qߪ%ԏ'E~S?4A i5U4]34S#՘fi5GyE"jZ-Z4-CbkqZ<-@K%kIZ2-BKyTZj-VK2hLZf-U˦erh9\Zn-O_^-_+ +ъjŴZ VJ+jZVIUѪjմZ VKzZ}Pk5֚MfZPBkZkmZ;}xZYuպiݵZO[i@m6X ՆiCGh#Qhm6V9m6I~jϿE^~Ӿk?OkC銎CGohLt[纣 =#Ο8=)G֣Q0=УlcXzl=gk<=~(OJ D??3Idz)z*=FOz&=/fѳzz.=ẉ j> "zQ^\/K2zY^^W+*zUڿt^KzPKC8T6ћz JozIwѻz+ԿG }>DӇ#cqx}>QjOѧit}>/tiOM}@_/K2}B_Wk#&}E޲M}_w;]n}WߧCa~T?O'F8gsy~Q_֯Wku~Sw{}04X?՟KUux7[^?PտFfPBb`C54C7 {A j=k kxoD0"F#fF4#Èi2bqF<#Hh$2IF2#Hi2RiF:#hd22YF6#i2ryF>#/s0 FQ(n0JFQ(oT0*FQͨn0jFgߒ$IF=hh42MF3hi2ZmF;ht2:]F7i2z}F?1h C0c1i2Fc8c1hL2&S4c1Øi2fs4'S|a4_7 6ߚl~1$(hD'1 !0bq .O"$L$$Nb$M␸$O$IL$INR$IMҐ$IO2$L$Nr$M$O )L)NJ)Mʐ)O*LNjMꐺ{/$I"H}Ҁ4$Hc҄4%Hs҂$Hk҆%H{ҁt$Hg^$INzMOdLdNFdMƐdO&dRd JN3d&Ef9d.Gd!YD%d)YFd%YEV5d-YG֓ d#D6B$I9dNvdMdO9L9NN9Mΐ9O.LNnMOyLyN^yMސyO>LN~P@!ETT:5I QڔS R4H#4 Jh@4Ic4K4MH4 MJ4MIS4 MK4H34 J4Is4K-H ´-J-IKҴ -KH+ʴ JIkڴKmHƴ mJmI[ִ mKH;δ Gڍv=hOڋ}h_ڏ@:CP:#H:cX:D:NST:N3L:Φs\:Χ B.KR.+JkZFn[Vn;N{^AzGQz'IzgYzEz^WUz^7Mzަw]zާC>OS>/Ko[G~_W~?`!0T1dQƘlƙs|EdXdEea,`XtdXleX|%dXb%eXrdXjeXzedXfeeXvdXneX~VdXaVeXqVdXiVeXyVUdXeVUeXuVdXmVeX}ր5dXcք5eXsւdXkֆeX{ցudXgօueXwփdXoևeX6 d`6 ep6d?^6c61>MfST6Mg3L6fs\6g B-fKR-g+JfkZgFmf[Vf`;.a῀`~vdav  t"NS4;βs<.K2®k:n[6{>{G1{žgyx%{^7-{޳#>/+ƾ,–jiniZ̲,c ˵<˷"XHVd+ +݊aŴbY8XqxV|+Jd%XIdVr+JeOcY VF+beY٭V?eXy|VPU*dXEbVqU*eXerVyUѪ>UŪ*YխVMU۪cյ[ V#jj5[-V+jk[V'ju[=V/k[ k5j [#(k5k[$k5ŚjM[3,k5ǚkͳ[ "kZj-[+*kZk[&kjm[;.kk[!_~XGcqu:eXgsyuѺd]XWkuuӺeݶXw{}AhCzb=Ϭ zmZl}Z߬Fg[5[ ۴Mmf[ms۱ڞv$;Ŏjف͎nǰcڱv;oďo'ډv;NnSکv;Nog3ڙv;nsڹv;o څv].nKڥv].oW+ڕv]ͮnװkڵڡuCy=ngkjd7M즡na[٭6v[`w;ٝ.vWa{ٽ>v_`ك!P{=aG٣1X{=ޞ`O'ٓ)T{=ݞaϴgٳ9\{=Wg^d/Ker{^ekuz{do[mv{e{}~}>dGcq}>egsy}Ѿd_Wku}Ӿe߶w{}~d?Ogs~eow{d_owr5sp9w.#<̣<<c<<<O̓<OS<O<O3<̳<s<< /̋/K//+̫kơo[oo;̻{|̇|G||'|̧|g|||_̗|_W|_|_7|̷|w||?̏?O??/̯o̟_?̿8r;9c8C0rl;#߉Dt"9(݉9zt'Ӊv8qxN|'I$v8IdNr'Iv8itNz'd'7-~UZfrr;y:N`8FNaS):*pJ:NS)Tp*:NSͩpj:NSϩ4p~9N,titZ96smmv{tr:;]NPKw?N/s; g3 s;#(g3s;$g3řLs;3άPΜ|g3ϙ,p:gYNrgY_W;k:glr6;[6grv;{>gs9r;G1s9rN;g9s\r.;W5sùrn;w=y9/W! E` M &,a .!+<"$"("&"%b8"'"H$$"H&"H%R4"H'ҋ "$2,"&"%r<"'($ "(&(%J2('ʋ $**&%j:'h$&h&h%Z6h'ڋ$:.&%z>'b$!b&b%F1b'Ƌ b$&)b&b%f9b'bX$%bX&bX%V5bX'֋ b$6-b&b%v=b'8$#8&8%N38'΋ ⢸$.+⪸&⦸%n;⮸'x$'x&x%^7x'ދ$>/&.p\Ůj̵\ u=w#Hnd7 s7ݍtc8n\7M&t$nR7MtS4nZ7ft3,nV7 9\nn7w Bna[-wK%Rni[-w+Jne[jnu[/pk:n蓸[ϭ6pßZn#m6s-ܖn+msۻ܎n'vs=ܞn/pw;pGw;Np'w;͝pgw;ϝ.YJwϕ w]q׆s׻܍&wns;ܝ.ws܃!{=s'ܓ){=sϻ܋%{Ž^s7ܛ-{ǽs܇?}>q }qߺ~q/4ƒ{ygxG<1xs=iE"y(^T/ h^t/Ӌxq+$/K%y0{IΑ 'cH /Kxit^z/ex|yٽ^N/y^AW+yŽ^IW+y ^EW_^_WͫW#IWӫxuz^}k5xMf^skxmv^{ux]n^wy@/ټ4 {#(o7{$o7śM{3,o7Ǜ{ "o }y˽Jo[](6xMfomvx;]no;y#Qw;Nyczwɻ]z׼ w˻z{=zϼ {z}z߼GU_U] ?z}3m/''#H~d??ݏc8~\?O'$~R?OS4~pt=$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IOg3~?s~? ~_/K~_.?G1?Og_z޿_/W_MۿC?_oJ$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IYaބ {>C)sؗa{؏}(@ ̀4`u1#QBy ,hA F3*r ^?H9H$ I~| ٯɃA տ: u&H!I _h??Bg)2RPJ~gr9\A O7 BAHP4(J%RALP6(*JAJP5Tj5ZANP7 FAI4h4Z-VAM6h:NAK5tz=^AO7A`H04 F#Q`L06&I`J05Lf3Y`N07 E`I4X,V+U`M6X6MoG )ӥCollabtive-2.0/include/font/freeserif.php000066400000000000000000001543511237252063700205330ustar00rootroot0000000000000032,'FontBBox'=>'[-879 -545 1767 934]','ItalicAngle'=>0,'Ascent'=>900,'Descent'=>-300,'Leading'=>90,'CapHeight'=>662,'XHeight'=>450,'StemV'=>70,'StemH'=>30,'AvgWidth'=>401,'MaxWidth'=>1752,'MissingWidth'=>700); $cw=array(0=>700,32=>250,33=>333,34=>408,35=>500,36=>500,37=>833,38=>778,39=>180,40=>333,41=>333,42=>500,43=>564,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>278,59=>278,60=>564,61=>564,62=>564,63=>444,64=>921,65=>722,66=>667,67=>667,68=>722,69=>611,70=>556,71=>722,72=>722,73=>333,74=>389,75=>722,76=>611,77=>889,78=>722,79=>722,80=>556,81=>722,82=>667,83=>556,84=>611,85=>722,86=>722,87=>944,88=>722,89=>722,90=>611,91=>333,92=>296,93=>333,94=>469,95=>500,96=>333,97=>444,98=>500,99=>444,100=>500,101=>444,102=>333,103=>500,104=>500,105=>278,106=>278,107=>500,108=>278,109=>778,110=>500,111=>500,112=>500,113=>500,114=>333,115=>389,116=>278,117=>500,118=>500,119=>722,120=>500,121=>500,122=>444,123=>480,124=>200,125=>480,126=>541,160=>250,161=>333,162=>500,163=>500,164=>500,165=>500,166=>200,167=>500,168=>333,169=>793,170=>276,171=>444,172=>564,173=>333,174=>792,175=>333,176=>400,177=>564,178=>320,179=>320,180=>333,181=>500,182=>483,183=>250,184=>333,185=>320,186=>310,187=>441,188=>750,189=>750,190=>750,191=>444,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>889,199=>667,200=>611,201=>611,202=>611,203=>611,204=>333,205=>333,206=>333,207=>333,208=>722,209=>722,210=>722,211=>722,212=>722,213=>722,214=>722,215=>564,216=>722,217=>722,218=>722,219=>722,220=>722,221=>722,222=>576,223=>500,224=>444,225=>444,226=>444,227=>444,228=>444,229=>444,230=>651,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>501,241=>500,242=>500,243=>500,244=>500,245=>500,246=>500,247=>564,248=>500,249=>500,250=>500,251=>500,252=>500,253=>500,254=>496,255=>500,256=>722,257=>444,258=>722,259=>444,260=>722,261=>444,262=>667,263=>444,264=>667,265=>444,266=>667,267=>444,268=>667,269=>444,270=>722,271=>630,272=>722,273=>500,274=>611,275=>444,276=>611,277=>444,278=>611,279=>444,280=>611,281=>444,282=>611,283=>444,284=>722,285=>500,286=>722,287=>500,288=>722,289=>500,290=>722,291=>500,292=>722,293=>500,294=>722,295=>500,296=>333,297=>278,298=>333,299=>278,300=>333,301=>278,302=>333,303=>278,304=>333,305=>278,306=>703,307=>529,308=>389,309=>278,310=>722,311=>500,312=>500,313=>611,314=>278,315=>611,316=>278,317=>611,318=>396,319=>611,320=>444,321=>611,322=>278,323=>722,324=>500,325=>722,326=>500,327=>722,328=>500,329=>556,330=>721,331=>500,332=>722,333=>500,334=>722,335=>500,336=>722,337=>500,338=>889,339=>709,340=>667,341=>333,342=>667,343=>333,344=>667,345=>333,346=>556,347=>389,348=>556,349=>389,350=>556,351=>389,352=>556,353=>389,354=>611,355=>278,356=>611,357=>415,358=>611,359=>278,360=>722,361=>500,362=>722,363=>500,364=>722,365=>500,366=>722,367=>500,368=>722,369=>500,370=>722,371=>500,372=>944,373=>722,374=>722,375=>500,376=>722,377=>611,378=>444,379=>611,380=>444,381=>611,382=>444,383=>333,384=>500,385=>777,386=>576,387=>520,388=>646,389=>520,390=>667,391=>811,392=>558,393=>722,394=>830,395=>646,396=>500,397=>534,398=>611,399=>710,400=>518,401=>629,402=>358,403=>824,404=>665,405=>729,406=>333,407=>336,408=>810,409=>500,410=>286,411=>480,412=>944,413=>798,414=>500,415=>726,416=>722,417=>540,418=>1043,419=>778,420=>667,421=>500,422=>667,423=>556,424=>389,425=>627,426=>592,427=>285,428=>626,429=>376,430=>611,431=>782,432=>544,433=>743,434=>722,435=>813,436=>657,437=>611,438=>444,439=>530,440=>556,441=>389,442=>394,443=>500,444=>615,445=>439,446=>421,447=>500,448=>190,449=>350,450=>600,451=>333,452=>1333,453=>1166,454=>944,455=>1000,456=>889,457=>556,458=>1111,459=>1000,460=>778,461=>722,462=>444,463=>333,464=>278,465=>722,466=>500,467=>722,468=>500,469=>722,470=>500,471=>722,472=>500,473=>722,474=>500,475=>722,476=>500,477=>444,478=>722,479=>444,480=>722,481=>444,482=>889,483=>651,484=>722,485=>500,486=>722,487=>500,488=>722,489=>500,490=>722,491=>500,492=>722,493=>500,494=>530,495=>389,496=>278,497=>1333,498=>1166,499=>944,500=>722,501=>500,502=>944,503=>522,504=>722,505=>500,506=>722,507=>444,508=>889,509=>651,510=>722,511=>500,512=>722,513=>444,514=>722,515=>444,516=>611,517=>444,518=>611,519=>444,520=>333,521=>278,522=>333,523=>278,524=>722,525=>500,526=>722,527=>500,528=>667,529=>333,530=>667,531=>333,532=>722,533=>500,534=>722,535=>500,536=>556,537=>389,538=>611,539=>279,540=>424,541=>455,542=>722,543=>500,544=>715,545=>588,546=>565,547=>468,548=>611,549=>444,550=>722,551=>444,552=>611,553=>444,554=>722,555=>500,556=>722,557=>500,558=>722,559=>500,560=>722,561=>500,562=>722,563=>500,564=>407,565=>597,566=>379,567=>278,568=>771,569=>760,570=>722,571=>667,572=>444,573=>611,574=>611,575=>389,576=>444,577=>444,578=>444,579=>667,580=>722,581=>722,582=>611,583=>444,584=>389,585=>278,586=>810,587=>601,588=>667,589=>333,590=>722,591=>500,592=>444,593=>500,594=>507,595=>500,596=>444,597=>444,598=>606,599=>624,600=>444,601=>444,602=>703,603=>426,604=>426,605=>662,606=>454,607=>353,608=>624,609=>500,610=>484,611=>500,612=>582,613=>500,614=>500,615=>500,616=>278,617=>306,618=>278,619=>340,620=>294,621=>364,622=>556,623=>778,624=>778,625=>778,626=>596,627=>599,628=>500,629=>491,630=>668,631=>693,632=>640,633=>336,634=>339,635=>444,636=>338,637=>339,638=>372,639=>372,640=>457,641=>456,642=>389,643=>466,644=>483,645=>466,646=>506,647=>278,648=>336,649=>512,650=>517,651=>514,652=>500,653=>722,654=>500,655=>510,656=>600,657=>444,658=>389,659=>456,660=>444,661=>444,662=>444,663=>444,664=>722,665=>468,666=>454,667=>623,668=>524,669=>354,670=>505,671=>443,672=>625,673=>444,674=>444,675=>798,676=>795,677=>805,678=>539,679=>549,680=>678,681=>722,682=>533,683=>554,684=>500,685=>500,686=>611,687=>716,688=>332,689=>333,690=>240,691=>228,692=>228,693=>299,694=>300,695=>477,696=>328,697=>250,698=>408,699=>333,700=>333,701=>333,702=>333,703=>333,704=>258,705=>258,706=>374,707=>374,708=>383,709=>383,710=>333,711=>333,712=>250,713=>333,714=>333,715=>333,716=>250,717=>333,718=>333,719=>333,720=>278,721=>278,722=>333,723=>333,724=>333,725=>333,726=>333,727=>333,728=>333,729=>333,730=>333,731=>333,732=>333,733=>382,734=>336,735=>352,736=>331,737=>187,738=>263,739=>332,740=>300,741=>460,742=>460,743=>460,744=>460,745=>460,746=>477,747=>475,748=>339,749=>333,750=>444,751=>383,752=>383,753=>294,754=>294,755=>327,756=>261,757=>437,758=>437,759=>333,760=>278,761=>175,762=>175,763=>175,764=>175,765=>337,766=>337,767=>326,768=>0,769=>0,770=>0,771=>0,772=>0,773=>0,774=>0,775=>0,776=>0,777=>0,778=>0,779=>0,780=>0,781=>0,782=>0,783=>0,784=>0,785=>0,786=>0,787=>0,788=>0,789=>0,790=>0,791=>0,792=>0,793=>0,794=>0,795=>0,796=>0,797=>0,798=>0,799=>0,800=>0,801=>0,802=>0,803=>0,804=>0,805=>0,806=>0,807=>0,808=>0,809=>0,810=>0,811=>0,812=>0,813=>0,814=>0,815=>0,816=>0,817=>0,818=>0,819=>0,820=>0,821=>0,822=>0,823=>0,824=>0,825=>0,826=>0,827=>0,828=>0,829=>0,830=>0,831=>0,832=>0,833=>0,834=>0,835=>0,836=>0,837=>0,838=>0,839=>0,840=>0,841=>0,842=>0,843=>0,844=>0,845=>0,846=>0,847=>0,848=>0,849=>0,850=>0,851=>0,852=>0,853=>0,854=>0,855=>0,856=>0,857=>0,858=>0,859=>0,860=>0,861=>0,862=>0,863=>0,864=>0,865=>0,866=>0,867=>0,868=>0,869=>0,870=>0,871=>0,872=>0,873=>0,874=>0,875=>0,876=>0,877=>0,878=>0,879=>0,880=>535,881=>433,882=>537,883=>497,884=>199,885=>199,890=>332,894=>278,900=>267,901=>333,902=>722,903=>250,904=>800,905=>902,906=>507,908=>818,910=>861,911=>871,912=>286,913=>722,914=>667,915=>586,916=>660,917=>611,918=>611,919=>722,920=>726,921=>333,922=>722,923=>722,924=>889,925=>722,926=>628,927=>722,928=>722,929=>556,931=>627,932=>611,933=>696,934=>742,935=>722,936=>808,937=>743,938=>333,939=>718,940=>583,941=>426,942=>536,943=>286,944=>514,945=>583,946=>527,947=>480,948=>534,949=>426,950=>466,951=>536,952=>534,953=>286,954=>544,955=>476,956=>536,957=>480,958=>514,959=>500,960=>587,961=>528,962=>452,963=>537,964=>420,965=>514,966=>643,967=>480,968=>693,969=>693,970=>286,971=>514,972=>500,973=>514,974=>693,976=>534,977=>587,978=>620,979=>809,980=>620,981=>640,982=>684,983=>534,984=>556,985=>500,986=>594,987=>426,988=>556,989=>445,990=>656,991=>400,992=>722,993=>570,994=>960,995=>673,996=>592,997=>522,998=>580,999=>460,1000=>500,1001=>338,1002=>842,1003=>593,1004=>564,1005=>412,1006=>634,1007=>447,1008=>534,1009=>534,1010=>485,1011=>278,1012=>726,1013=>361,1014=>361,1015=>576,1016=>542,1017=>667,1018=>889,1019=>709,1020=>534,1021=>667,1022=>1000,1023=>1000,1024=>613,1025=>613,1026=>748,1027=>570,1028=>659,1029=>487,1030=>337,1031=>337,1032=>385,1033=>943,1034=>985,1035=>827,1036=>669,1037=>723,1038=>709,1039=>723,1040=>711,1041=>576,1042=>626,1043=>570,1044=>639,1045=>613,1046=>937,1047=>580,1048=>723,1049=>723,1050=>669,1051=>684,1052=>891,1053=>723,1054=>722,1055=>723,1056=>576,1057=>659,1058=>608,1059=>709,1060=>750,1061=>714,1062=>728,1063=>682,1064=>984,1065=>988,1066=>725,1067=>863,1068=>576,1069=>659,1070=>966,1071=>648,1072=>434,1073=>495,1074=>468,1075=>388,1076=>490,1077=>436,1078=>662,1079=>406,1080=>524,1081=>524,1082=>498,1083=>490,1084=>632,1085=>524,1086=>491,1087=>524,1088=>500,1089=>424,1090=>422,1091=>471,1092=>694,1093=>482,1094=>524,1095=>506,1096=>756,1097=>756,1098=>505,1099=>626,1100=>431,1101=>432,1102=>664,1103=>492,1104=>434,1105=>434,1106=>479,1107=>388,1108=>432,1109=>347,1110=>269,1111=>278,1112=>278,1113=>677,1114=>711,1115=>514,1116=>498,1117=>524,1118=>471,1119=>524,1120=>978,1121=>664,1122=>718,1123=>506,1124=>947,1125=>647,1126=>901,1127=>635,1128=>1248,1129=>894,1130=>937,1131=>654,1132=>1278,1133=>907,1134=>516,1135=>391,1136=>870,1137=>694,1138=>726,1139=>491,1140=>780,1141=>550,1142=>780,1143=>550,1144=>1207,1145=>946,1146=>877,1147=>611,1148=>978,1149=>664,1150=>978,1151=>664,1152=>594,1153=>428,1154=>232,1155=>0,1156=>0,1157=>0,1158=>0,1159=>0,1160=>0,1161=>0,1162=>715,1163=>522,1164=>562,1165=>430,1166=>556,1167=>511,1168=>564,1169=>398,1170=>586,1171=>392,1172=>623,1173=>463,1174=>1001,1175=>688,1176=>580,1177=>401,1178=>696,1179=>517,1180=>713,1181=>532,1182=>669,1183=>498,1184=>813,1185=>572,1186=>730,1187=>524,1188=>934,1189=>652,1190=>1030,1191=>722,1192=>750,1193=>516,1194=>659,1195=>424,1196=>608,1197=>452,1198=>722,1199=>563,1200=>722,1201=>562,1202=>773,1203=>518,1204=>972,1205=>693,1206=>681,1207=>506,1208=>726,1209=>540,1210=>682,1211=>510,1212=>866,1213=>553,1214=>866,1215=>553,1216=>333,1217=>937,1218=>662,1219=>618,1220=>448,1221=>702,1222=>490,1223=>723,1224=>499,1225=>723,1226=>547,1227=>682,1228=>506,1229=>891,1230=>632,1231=>337,1232=>711,1233=>434,1234=>711,1235=>434,1236=>891,1237=>630,1238=>623,1239=>436,1240=>710,1241=>436,1242=>710,1243=>436,1244=>937,1245=>662,1246=>580,1247=>406,1248=>530,1249=>366,1250=>723,1251=>524,1252=>723,1253=>524,1254=>722,1255=>491,1256=>722,1257=>491,1258=>722,1259=>491,1260=>659,1261=>432,1262=>709,1263=>471,1264=>709,1265=>471,1266=>709,1267=>471,1268=>682,1269=>506,1270=>572,1271=>388,1272=>863,1273=>626,1274=>572,1275=>388,1276=>720,1277=>445,1278=>722,1279=>495,1280=>556,1281=>504,1282=>900,1283=>634,1284=>803,1285=>518,1286=>553,1287=>471,1288=>964,1289=>637,1290=>968,1291=>682,1292=>722,1293=>433,1294=>714,1295=>504,1296=>532,1297=>407,1298=>702,1299=>489,1300=>960,1301=>644,1302=>823,1303=>698,1304=>961,1305=>748,1306=>722,1307=>505,1308=>947,1309=>693,1310=>669,1311=>498,1312=>992,1313=>710,1314=>1029,1315=>742,1329=>794,1330=>712,1331=>782,1332=>854,1333=>711,1334=>702,1335=>707,1336=>655,1337=>777,1338=>782,1339=>710,1340=>663,1341=>830,1342=>917,1343=>672,1344=>469,1345=>666,1346=>858,1347=>685,1348=>856,1349=>618,1350=>858,1351=>709,1352=>719,1353=>714,1354=>731,1355=>702,1356=>874,1357=>719,1358=>844,1359=>519,1360=>703,1361=>608,1362=>586,1363=>750,1364=>780,1365=>714,1366=>684,1369=>120,1370=>120,1371=>269,1372=>307,1373=>241,1374=>312,1375=>300,1377=>786,1378=>506,1379=>542,1380=>541,1381=>506,1382=>503,1383=>478,1384=>499,1385=>541,1386=>539,1387=>508,1388=>289,1389=>750,1390=>540,1391=>513,1392=>508,1393=>503,1394=>531,1395=>518,1396=>500,1397=>243,1398=>473,1399=>406,1400=>499,1401=>407,1402=>793,1403=>414,1404=>463,1405=>500,1406=>516,1407=>758,1408=>504,1409=>466,1410=>288,1411=>758,1412=>510,1413=>501,1414=>562,1415=>543,1417=>278,1418=>280,1425=>0,1426=>0,1427=>0,1428=>0,1429=>0,1430=>0,1431=>418,1432=>0,1433=>0,1434=>0,1435=>0,1436=>0,1437=>0,1438=>0,1439=>0,1440=>0,1441=>0,1442=>0,1443=>0,1444=>0,1445=>0,1446=>0,1447=>0,1448=>0,1449=>0,1450=>0,1451=>0,1452=>0,1453=>0,1454=>0,1455=>0,1456=>0,1457=>0,1458=>0,1459=>0,1460=>0,1461=>0,1462=>0,1463=>0,1464=>0,1465=>0,1466=>0,1467=>0,1468=>0,1469=>0,1470=>440,1471=>0,1472=>126,1473=>0,1474=>0,1475=>418,1476=>0,1477=>0,1478=>350,1479=>0,1488=>537,1489=>537,1490=>350,1491=>537,1492=>537,1493=>350,1494=>350,1495=>537,1496=>537,1497=>350,1498=>537,1499=>537,1500=>537,1501=>537,1502=>537,1503=>350,1504=>350,1505=>537,1506=>537,1507=>537,1508=>537,1509=>537,1510=>537,1511=>537,1512=>537,1513=>537,1514=>537,1520=>537,1521=>537,1522=>537,1523=>396,1524=>396,1548=>226,1563=>250,1567=>473,1569=>350,1570=>321,1571=>249,1572=>399,1573=>249,1574=>776,1575=>249,1576=>950,1577=>424,1578=>925,1579=>924,1580=>738,1581=>748,1582=>701,1583=>397,1584=>399,1585=>328,1586=>331,1587=>951,1588=>949,1589=>949,1590=>949,1591=>557,1592=>550,1593=>625,1594=>602,1601=>801,1602=>696,1603=>757,1604=>655,1605=>549,1606=>651,1607=>424,1608=>399,1609=>776,1610=>776,1611=>0,1613=>0,1614=>0,1615=>0,1616=>0,1617=>0,1618=>0,1619=>0,1620=>0,1621=>0,1632=>297,1633=>254,1634=>427,1635=>497,1636=>440,1637=>465,1638=>466,1639=>421,1640=>459,1641=>424,1643=>212,1652=>300,1662=>926,1670=>750,1688=>338,1711=>874,1740=>776,1748=>176,1920=>450,1921=>501,1922=>582,1923=>544,1924=>482,1925=>433,1926=>448,1927=>462,1928=>474,1929=>471,1930=>469,1931=>537,1932=>499,1933=>514,1934=>471,1935=>572,1936=>880,1937=>440,1938=>476,1939=>594,1940=>469,1941=>448,1942=>441,1943=>519,1944=>573,1945=>459,1946=>447,1947=>496,1948=>541,1949=>887,1950=>883,1951=>964,1952=>558,1953=>505,1954=>471,1955=>554,1956=>459,1957=>486,1958=>36,1959=>36,1960=>43,1961=>45,1962=>43,1963=>45,1964=>45,1965=>45,1966=>45,1967=>45,1968=>0,2304=>0,2305=>0,2306=>398,2307=>398,2308=>862,2309=>862,2310=>1042,2311=>553,2312=>553,2313=>597,2314=>848,2315=>967,2316=>828,2317=>654,2318=>654,2319=>654,2320=>654,2321=>1042,2322=>1042,2323=>1042,2324=>1042,2325=>743,2326=>798,2327=>694,2328=>694,2329=>730,2330=>734,2331=>888,2332=>814,2333=>834,2334=>734,2335=>629,2336=>629,2337=>653,2338=>609,2339=>694,2340=>654,2341=>694,2342=>588,2343=>694,2344=>654,2345=>654,2346=>615,2347=>788,2348=>621,2349=>694,2350=>694,2351=>694,2352=>575,2353=>575,2354=>787,2355=>848,2356=>848,2357=>621,2358=>654,2359=>615,2360=>734,2361=>609,2364=>398,2365=>569,2366=>341,2367=>341,2368=>341,2369=>0,2370=>0,2371=>0,2372=>0,2373=>0,2374=>0,2375=>615,2376=>615,2377=>341,2378=>341,2379=>341,2380=>341,2381=>0,2382=>0,2384=>1047,2385=>0,2386=>0,2387=>0,2388=>0,2389=>0,2392=>743,2393=>798,2394=>694,2395=>814,2396=>653,2397=>609,2398=>788,2399=>694,2400=>967,2401=>828,2402=>0,2403=>0,2404=>398,2405=>478,2406=>455,2407=>420,2408=>569,2409=>509,2410=>702,2411=>629,2412=>569,2413=>702,2414=>609,2415=>609,2416=>626,2417=>398,2418=>862,2425=>814,2426=>694,2427=>654,2428=>814,2429=>569,2430=>730,2431=>621,2433=>0,2434=>300,2435=>312,2437=>594,2438=>776,2439=>469,2440=>513,2441=>535,2442=>561,2443=>604,2444=>481,2447=>580,2448=>604,2451=>540,2452=>620,2453=>570,2454=>485,2455=>484,2456=>471,2457=>457,2458=>408,2459=>452,2460=>591,2461=>551,2462=>771,2463=>414,2464=>404,2465=>522,2466=>415,2467=>450,2468=>551,2469=>477,2470=>478,2471=>449,2472=>448,2474=>535,2475=>611,2476=>443,2477=>534,2478=>492,2479=>474,2480=>442,2482=>542,2486=>507,2487=>467,2488=>523,2489=>419,2492=>0,2493=>419,2494=>202,2495=>189,2496=>202,2497=>0,2498=>0,2499=>0,2500=>0,2503=>294,2504=>289,2507=>774,2508=>825,2509=>0,2510=>356,2519=>219,2524=>523,2525=>420,2527=>469,2528=>604,2529=>481,2530=>0,2531=>0,2534=>500,2535=>437,2536=>479,2537=>507,2538=>497,2539=>500,2540=>482,2541=>503,2542=>517,2543=>481,2544=>443,2545=>443,2546=>429,2547=>383,2548=>432,2549=>478,2550=>539,2551=>158,2552=>365,2553=>280,2554=>357,2561=>0,2562=>0,2563=>385,2565=>728,2566=>884,2567=>656,2568=>656,2569=>580,2570=>580,2575=>482,2576=>728,2579=>580,2580=>728,2581=>534,2582=>518,2583=>602,2584=>674,2585=>530,2586=>502,2587=>576,2588=>476,2589=>558,2590=>501,2591=>510,2592=>540,2593=>508,2594=>512,2595=>558,2596=>468,2597=>518,2598=>488,2599=>518,2600=>522,2602=>518,2603=>490,2604=>546,2605=>500,2606=>530,2607=>654,2608=>522,2610=>710,2611=>710,2613=>498,2614=>530,2616=>530,2617=>501,2620=>286,2622=>156,2623=>174,2624=>174,2625=>0,2626=>0,2631=>0,2632=>0,2635=>0,2636=>0,2637=>0,2641=>0,2649=>534,2650=>618,2651=>492,2652=>484,2654=>506,2662=>616,2663=>480,2664=>560,2665=>480,2666=>468,2667=>492,2668=>514,2669=>538,2670=>572,2671=>560,2672=>0,2673=>0,2674=>498,2675=>596,2676=>900,2677=>0,2946=>0,2947=>616,2949=>910,2950=>1072,2951=>848,2952=>591,2953=>492,2954=>1123,2958=>602,2959=>602,2960=>691,2962=>753,2963=>753,2964=>1597,2965=>677,2969=>697,2970=>607,2972=>691,2974=>871,2975=>589,2979=>1230,2980=>688,2984=>560,2985=>911,2986=>477,2990=>625,2991=>672,2992=>452,2993=>553,2994=>651,2995=>804,2996=>645,2997=>740,2998=>767,2999=>865,3000=>870,3001=>1067,3006=>452,3007=>176,3008=>0,3009=>404,3010=>601,3014=>690,3015=>500,3016=>840,3018=>1150,3019=>1000,3020=>1488,3021=>0,3024=>753,3031=>844,3046=>500,3047=>677,3048=>829,3049=>673,3050=>793,3051=>845,3052=>861,3053=>602,3054=>910,3055=>807,3056=>553,3057=>697,3058=>906,3059=>609,3060=>853,3061=>1585,3062=>664,3063=>978,3064=>1325,3065=>845,3066=>731,3330=>417,3331=>221,3333=>1055,3334=>1195,3335=>792,3336=>1469,3337=>570,3338=>1244,3339=>676,3340=>897,3342=>1008,3343=>1008,3344=>1538,3346=>586,3347=>981,3348=>1254,3349=>776,3350=>798,3351=>691,3352=>1095,3353=>811,3354=>728,3355=>963,3356=>704,3357=>1245,3358=>1106,3359=>466,3360=>531,3361=>984,3362=>1028,3363=>1102,3364=>780,3365=>732,3366=>485,3367=>737,3368=>747,3370=>780,3371=>962,3372=>1023,3373=>500,3374=>511,3375=>792,3376=>530,3377=>512,3378=>712,3379=>556,3380=>519,3381=>716,3382=>786,3383=>921,3384=>977,3385=>978,3389=>375,3390=>403,3391=>283,3392=>323,3393=>275,3394=>258,3395=>378,3396=>378,3398=>542,3399=>478,3400=>1070,3402=>0,3403=>0,3404=>0,3405=>89,3415=>677,3424=>676,3425=>1006,3426=>0,3427=>0,3430=>559,3431=>660,3432=>674,3433=>933,3434=>671,3435=>699,3436=>704,3437=>694,3438=>678,3439=>684,3440=>981,3441=>742,3442=>1056,3443=>660,3444=>664,3445=>870,3449=>864,3450=>1137,3451=>776,3452=>534,3453=>860,3454=>780,3455=>866,3458=>254,3459=>254,3461=>616,3462=>922,3463=>908,3464=>907,3465=>626,3466=>615,3467=>763,3468=>1109,3469=>1019,3470=>1311,3471=>1050,3472=>1477,3473=>677,3474=>746,3475=>1314,3476=>741,3477=>741,3478=>1170,3482=>894,3483=>715,3484=>715,3485=>719,3486=>741,3487=>834,3488=>719,3489=>677,3490=>677,3491=>1302,3492=>1005,3493=>919,3494=>677,3495=>719,3496=>677,3497=>741,3498=>677,3499=>1123,3500=>743,3501=>779,3502=>677,3503=>444,3504=>741,3505=>921,3507=>444,3508=>677,3509=>677,3510=>715,3511=>787,3512=>719,3513=>741,3514=>719,3515=>604,3517=>763,3520=>719,3521=>715,3522=>677,3523=>719,3524=>787,3525=>763,3526=>677,3530=>0,3535=>329,3536=>319,3537=>319,3538=>0,3539=>0,3540=>0,3542=>0,3544=>329,3545=>691,3546=>1062,3547=>1333,3548=>1278,3549=>1235,3550=>1292,3551=>461,3570=>680,3571=>481,3572=>948,3585=>532,3586=>472,3587=>534,3588=>532,3589=>544,3590=>583,3591=>417,3592=>488,3593=>604,3594=>472,3595=>534,3596=>716,3597=>717,3598=>568,3599=>568,3600=>457,3601=>637,3602=>731,3603=>790,3604=>531,3605=>542,3606=>522,3607=>577,3608=>468,3609=>603,3610=>554,3611=>554,3612=>556,3613=>556,3614=>604,3615=>604,3616=>568,3617=>542,3618=>496,3619=>442,3620=>530,3621=>512,3622=>568,3623=>478,3624=>543,3625=>614,3626=>525,3627=>578,3628=>659,3629=>514,3630=>514,3631=>450,3632=>402,3633=>0,3634=>378,3635=>415,3636=>0,3637=>0,3638=>0,3639=>0,3640=>0,3641=>0,3642=>0,3647=>620,3648=>286,3649=>521,3650=>447,3651=>426,3652=>424,3653=>333,3654=>453,3655=>0,3656=>0,3657=>0,3658=>0,3659=>0,3660=>0,3661=>0,3662=>0,3663=>657,3664=>528,3665=>528,3666=>571,3667=>594,3668=>631,3669=>632,3670=>478,3671=>713,3672=>597,3673=>565,3674=>615,3675=>1381,4256=>453,4257=>448,4258=>546,4259=>619,4260=>478,4261=>481,4262=>459,4263=>707,4264=>467,4265=>471,4266=>842,4267=>464,4268=>443,4269=>707,4270=>460,4271=>465,4272=>686,4273=>440,4274=>550,4275=>561,4276=>580,4277=>467,4278=>630,4279=>466,4280=>517,4281=>456,4282=>502,4283=>464,4284=>534,4285=>440,4286=>443,4287=>522,4288=>460,4289=>463,4290=>536,4291=>455,4292=>468,4293=>449,4304=>454,4305=>452,4306=>544,4307=>629,4308=>451,4309=>452,4310=>452,4311=>702,4312=>451,4313=>452,4314=>820,4315=>451,4316=>453,4317=>695,4318=>449,4319=>448,4320=>694,4321=>501,4322=>544,4323=>518,4324=>560,4325=>450,4326=>627,4327=>452,4328=>490,4329=>452,4330=>485,4331=>452,4332=>485,4333=>443,4334=>500,4335=>582,4336=>455,4337=>451,4338=>482,4339=>414,4340=>453,4341=>418,4342=>741,4343=>452,4344=>452,4345=>544,4346=>454,4347=>410,4348=>339,4608=>583,4609=>770,4610=>560,4611=>525,4612=>525,4613=>583,4614=>758,4616=>598,4617=>787,4618=>817,4619=>583,4620=>758,4621=>612,4622=>875,4623=>817,4624=>817,4625=>1050,4626=>1050,4627=>817,4628=>1050,4629=>817,4630=>787,4631=>1021,4632=>933,4633=>1137,4634=>1067,4635=>980,4636=>1065,4637=>962,4638=>962,4639=>1097,4640=>831,4641=>1021,4642=>851,4643=>735,4644=>875,4645=>968,4646=>817,4647=>881,4648=>583,4649=>642,4650=>583,4651=>758,4652=>700,4653=>583,4654=>700,4655=>758,4656=>583,4657=>787,4658=>787,4659=>583,4660=>729,4661=>583,4662=>583,4663=>817,4664=>642,4665=>817,4666=>846,4667=>642,4668=>758,4669=>744,4670=>642,4671=>817,4672=>700,4673=>700,4674=>700,4675=>758,4676=>700,4677=>700,4678=>729,4680=>846,4682=>1079,4683=>700,4684=>700,4685=>1021,4688=>700,4689=>700,4690=>700,4691=>758,4692=>700,4693=>758,4694=>729,4696=>846,4698=>1079,4699=>700,4700=>700,4701=>1021,4704=>525,4705=>758,4706=>758,4707=>525,4708=>700,4709=>773,4710=>525,4711=>787,4712=>525,4713=>758,4714=>758,4715=>525,4716=>700,4717=>773,4718=>525,4719=>525,4720=>729,4721=>729,4722=>729,4723=>802,4724=>729,4725=>729,4726=>758,4727=>729,4728=>758,4729=>758,4730=>758,4731=>817,4732=>758,4733=>817,4734=>758,4735=>758,4736=>612,4737=>817,4738=>817,4739=>612,4740=>787,4741=>583,4742=>875,4744=>962,4746=>992,4747=>700,4748=>758,4749=>904,4752=>408,4753=>583,4754=>525,4755=>554,4756=>481,4757=>554,4758=>642,4759=>671,4760=>700,4761=>758,4762=>729,4763=>700,4764=>671,4765=>700,4766=>758,4767=>700,4768=>583,4769=>735,4770=>822,4771=>583,4772=>793,4773=>583,4774=>583,4775=>694,4776=>554,4777=>729,4778=>773,4779=>554,4780=>700,4781=>554,4782=>554,4784=>992,4786=>1021,4787=>671,4788=>787,4789=>904,4792=>729,4793=>904,4794=>948,4795=>729,4796=>875,4797=>729,4798=>729,4800=>1137,4802=>1167,4803=>758,4804=>875,4805=>1108,4808=>758,4809=>875,4810=>700,4811=>700,4812=>700,4813=>992,4814=>758,4816=>554,4817=>787,4818=>758,4819=>583,4820=>758,4821=>496,4822=>612,4824=>525,4825=>700,4826=>700,4827=>525,4828=>685,4829=>729,4830=>510,4831=>729,4832=>962,4833=>962,4834=>962,4835=>962,4836=>962,4837=>1021,4838=>962,4839=>962,4840=>467,4841=>525,4842=>671,4843=>612,4844=>612,4845=>671,4846=>671,4848=>612,4849=>875,4850=>817,4851=>642,4852=>729,4853=>729,4854=>758,4855=>817,4856=>700,4857=>758,4858=>715,4859=>700,4860=>700,4861=>787,4862=>758,4863=>700,4864=>700,4865=>758,4866=>715,4867=>700,4868=>700,4869=>787,4870=>758,4871=>700,4872=>467,4873=>671,4874=>671,4875=>612,4876=>612,4877=>583,4878=>525,4880=>846,4882=>904,4883=>554,4884=>700,4885=>817,4888=>525,4889=>729,4890=>729,4891=>612,4892=>671,4893=>583,4894=>525,4896=>817,4897=>1021,4898=>1021,4899=>817,4900=>992,4901=>758,4902=>817,4903=>1021,4904=>1079,4905=>1137,4906=>1137,4907=>1050,4908=>1312,4909=>1050,4910=>1050,4911=>1123,4912=>647,4913=>793,4914=>822,4915=>647,4916=>793,4917=>764,4918=>583,4919=>647,4920=>583,4921=>793,4922=>822,4923=>583,4924=>793,4925=>764,4926=>583,4927=>793,4928=>540,4929=>758,4930=>583,4931=>467,4932=>583,4933=>481,4934=>612,4936=>758,4937=>700,4938=>758,4939=>700,4940=>831,4941=>671,4942=>758,4943=>700,4944=>758,4945=>758,4946=>758,4947=>817,4948=>758,4949=>758,4950=>817,4951=>758,4952=>642,4953=>980,4954=>758,4961=>233,4962=>583,4963=>408,4964=>408,4965=>525,4966=>525,4967=>233,4968=>700,4969=>671,4970=>612,4971=>642,4972=>642,4973=>642,4974=>583,4975=>700,4976=>758,4977=>642,4978=>583,4979=>700,4980=>729,4981=>720,4982=>583,4983=>758,4984=>700,4985=>904,4986=>612,4987=>583,4988=>875,5024=>711,5025=>678,5026=>604,5027=>667,5028=>796,5029=>301,5030=>516,5031=>544,5032=>457,5033=>716,5034=>703,5035=>383,5036=>628,5037=>709,5038=>455,5039=>601,5040=>472,5041=>574,5042=>730,5043=>939,5044=>498,5045=>528,5046=>667,5047=>891,5048=>505,5049=>792,5050=>957,5051=>725,5052=>595,5053=>733,5054=>698,5055=>638,5056=>720,5057=>732,5058=>624,5059=>638,5060=>565,5061=>903,5062=>655,5063=>681,5064=>675,5065=>949,5066=>683,5067=>547,5068=>693,5069=>732,5070=>529,5071=>569,5072=>536,5073=>677,5074=>631,5075=>542,5076=>973,5077=>543,5078=>607,5079=>652,5080=>652,5081=>693,5082=>514,5083=>803,5084=>658,5085=>597,5086=>627,5087=>659,5088=>679,5089=>706,5090=>563,5091=>618,5092=>767,5093=>776,5094=>731,5095=>492,5096=>808,5097=>823,5098=>796,5099=>689,5100=>716,5101=>518,5102=>521,5103=>719,5104=>563,5105=>776,5106=>634,5107=>822,5108=>621,5920=>502,5921=>502,5922=>500,5923=>498,5924=>500,5925=>502,5926=>502,5927=>502,5928=>500,5929=>503,5930=>502,5931=>502,5932=>500,5933=>500,5934=>500,5935=>796,5936=>500,5937=>502,5938=>0,5939=>0,5940=>0,5941=>230,5942=>397,6480=>537,6481=>537,6482=>531,6483=>678,6484=>682,6485=>628,6486=>732,6487=>721,6488=>598,6489=>583,6490=>702,6491=>554,6492=>683,6493=>554,6494=>710,6495=>695,6496=>523,6497=>678,6498=>589,6499=>272,6500=>506,6501=>515,6502=>515,6503=>210,6504=>210,6505=>515,6506=>515,6507=>515,6508=>229,6509=>705,6512=>649,6513=>538,6514=>568,6515=>520,6516=>544,6656=>820,6657=>958,6658=>758,6659=>859,6660=>958,6661=>727,6662=>904,6663=>940,6664=>850,6665=>905,6666=>838,6667=>961,6668=>1000,6669=>880,6670=>1189,6671=>1246,6672=>1177,6673=>757,6674=>1246,6675=>1192,6676=>709,6677=>1192,6678=>1075,6679=>0,6680=>0,6681=>534,6682=>690,6683=>0,6686=>697,6687=>500,7424=>484,7425=>595,7426=>651,7427=>446,7428=>446,7429=>483,7430=>483,7431=>409,7432=>426,7433=>278,7434=>260,7435=>483,7436=>409,7437=>595,7438=>483,7439=>483,7440=>435,7441=>507,7442=>507,7443=>673,7444=>709,7445=>378,7446=>483,7447=>483,7448=>372,7449=>456,7450=>446,7451=>409,7452=>483,7453=>488,7454=>660,7455=>500,7456=>483,7457=>632,7458=>409,7459=>355,7460=>444,7461=>681,7462=>392,7463=>483,7464=>483,7465=>372,7466=>541,7467=>470,7468=>484,7469=>595,7470=>446,7471=>446,7472=>483,7473=>409,7474=>409,7475=>483,7476=>483,7477=>223,7478=>260,7479=>483,7480=>409,7481=>595,7482=>483,7483=>483,7484=>483,7485=>378,7486=>372,7487=>446,7488=>409,7489=>483,7490=>632,7491=>297,7492=>297,7493=>335,7494=>440,7495=>335,7496=>335,7497=>297,7498=>297,7499=>285,7500=>285,7501=>335,7502=>186,7503=>335,7504=>521,7505=>335,7506=>335,7507=>297,7508=>483,7509=>483,7510=>335,7511=>186,7512=>335,7513=>326,7514=>521,7515=>335,7516=>442,7517=>353,7518=>321,7519=>357,7520=>430,7521=>321,7522=>186,7523=>223,7524=>335,7525=>335,7526=>353,7527=>321,7528=>353,7529=>430,7530=>321,7531=>754,7532=>500,7533=>500,7534=>333,7535=>778,7536=>500,7537=>500,7538=>333,7539=>333,7540=>389,7541=>278,7542=>444,7543=>500,7544=>483,7545=>447,7546=>774,7547=>280,7548=>278,7549=>500,7550=>483,7551=>514,7552=>500,7553=>500,7554=>333,7555=>676,7556=>525,7557=>278,7558=>802,7559=>507,7560=>500,7561=>333,7562=>389,7563=>384,7564=>500,7565=>500,7566=>444,7567=>602,7568=>637,7569=>648,7570=>590,7571=>559,7572=>426,7573=>590,7574=>413,7575=>444,7576=>360,7577=>638,7578=>389,7579=>335,7580=>293,7581=>283,7582=>337,7583=>299,7584=>229,7585=>251,7586=>335,7587=>322,7588=>188,7589=>212,7590=>278,7591=>182,7592=>240,7593=>233,7594=>208,7595=>287,7596=>499,7597=>533,7598=>401,7599=>374,7600=>330,7601=>329,7602=>426,7603=>262,7604=>312,7605=>197,7606=>344,7607=>336,7608=>323,7609=>334,7610=>325,7611=>293,7612=>403,7613=>288,7614=>257,7615=>354,7680=>722,7681=>444,7682=>667,7683=>500,7684=>667,7685=>500,7686=>667,7687=>500,7688=>667,7689=>444,7690=>722,7691=>500,7692=>722,7693=>500,7694=>722,7695=>500,7696=>720,7697=>500,7698=>722,7699=>500,7700=>611,7701=>444,7702=>611,7703=>444,7704=>611,7705=>444,7706=>611,7707=>444,7708=>611,7709=>444,7710=>556,7711=>333,7712=>722,7713=>500,7714=>722,7715=>500,7716=>722,7717=>500,7718=>722,7719=>500,7720=>722,7721=>500,7722=>722,7723=>500,7724=>333,7725=>278,7726=>333,7727=>278,7728=>722,7729=>500,7730=>722,7731=>500,7732=>722,7733=>500,7734=>611,7735=>278,7736=>611,7737=>278,7738=>611,7739=>278,7740=>611,7741=>278,7742=>889,7743=>778,7744=>889,7745=>778,7746=>889,7747=>778,7748=>722,7749=>500,7750=>722,7751=>500,7752=>722,7753=>500,7754=>722,7755=>500,7756=>722,7757=>500,7758=>722,7759=>500,7760=>722,7761=>500,7762=>722,7763=>500,7764=>556,7765=>500,7766=>556,7767=>500,7768=>667,7769=>333,7770=>667,7771=>333,7772=>667,7773=>333,7774=>667,7775=>333,7776=>556,7777=>389,7778=>556,7779=>389,7780=>556,7781=>389,7782=>556,7783=>389,7784=>556,7785=>389,7786=>611,7787=>278,7788=>611,7789=>278,7790=>611,7791=>278,7792=>611,7793=>278,7794=>722,7795=>500,7796=>722,7797=>500,7798=>722,7799=>500,7800=>722,7801=>500,7802=>722,7803=>500,7804=>722,7805=>500,7806=>722,7807=>500,7808=>944,7809=>722,7810=>944,7811=>722,7812=>944,7813=>722,7814=>944,7815=>722,7816=>944,7817=>722,7818=>722,7819=>500,7820=>722,7821=>500,7822=>722,7823=>500,7824=>611,7825=>444,7826=>611,7827=>444,7828=>611,7829=>444,7830=>500,7831=>278,7832=>722,7833=>500,7834=>444,7835=>333,7836=>333,7837=>333,7838=>659,7839=>534,7840=>722,7841=>444,7842=>722,7843=>444,7844=>722,7845=>444,7846=>722,7847=>444,7848=>722,7849=>454,7850=>722,7851=>444,7852=>722,7853=>444,7854=>722,7855=>444,7856=>722,7857=>444,7858=>722,7859=>454,7860=>722,7861=>444,7862=>722,7863=>444,7864=>611,7865=>444,7866=>611,7867=>444,7868=>611,7869=>444,7870=>611,7871=>444,7872=>611,7873=>444,7874=>613,7875=>444,7876=>611,7877=>444,7878=>611,7879=>444,7880=>333,7881=>278,7882=>333,7883=>278,7884=>722,7885=>500,7886=>722,7887=>500,7888=>722,7889=>500,7890=>722,7891=>500,7892=>722,7893=>500,7894=>722,7895=>500,7896=>722,7897=>500,7898=>722,7899=>540,7900=>722,7901=>540,7902=>720,7903=>540,7904=>722,7905=>540,7906=>722,7907=>540,7908=>722,7909=>500,7910=>717,7911=>500,7912=>782,7913=>544,7914=>782,7915=>544,7916=>782,7917=>544,7918=>782,7919=>544,7920=>782,7921=>544,7922=>722,7923=>500,7924=>722,7925=>500,7926=>722,7927=>501,7928=>722,7929=>500,7930=>914,7931=>514,7932=>500,7933=>342,7934=>722,7935=>530,7936=>583,7937=>583,7938=>583,7939=>583,7940=>583,7941=>583,7942=>583,7943=>583,7944=>722,7945=>722,7946=>813,7947=>817,7948=>763,7949=>765,7950=>720,7951=>722,7952=>426,7953=>426,7954=>426,7955=>426,7956=>426,7957=>426,7960=>770,7961=>770,7962=>902,7963=>919,7964=>940,7965=>936,7968=>536,7969=>536,7970=>536,7971=>536,7972=>536,7973=>536,7974=>536,7975=>536,7976=>847,7977=>859,7978=>986,7979=>1010,7980=>1026,7981=>1029,7982=>918,7983=>921,7984=>286,7985=>286,7986=>302,7987=>320,7988=>300,7989=>306,7990=>312,7991=>303,7992=>475,7993=>507,7994=>617,7995=>654,7996=>655,7997=>660,7998=>551,7999=>566,8000=>500,8001=>500,8002=>500,8003=>500,8004=>500,8005=>500,8008=>816,8009=>825,8010=>969,8011=>995,8012=>938,8013=>955,8016=>514,8017=>514,8018=>514,8019=>514,8020=>514,8021=>514,8022=>514,8023=>514,8025=>818,8027=>988,8029=>989,8031=>893,8032=>693,8033=>693,8034=>693,8035=>693,8036=>693,8037=>693,8038=>693,8039=>693,8040=>836,8041=>843,8042=>1006,8043=>1024,8044=>974,8045=>986,8046=>905,8047=>896,8048=>583,8049=>583,8050=>426,8051=>426,8052=>536,8053=>536,8054=>286,8055=>286,8056=>500,8057=>500,8058=>514,8059=>514,8060=>693,8061=>693,8064=>583,8065=>583,8066=>583,8067=>583,8068=>583,8069=>583,8070=>583,8071=>583,8072=>888,8073=>889,8074=>984,8075=>991,8076=>943,8077=>948,8078=>884,8079=>886,8080=>536,8081=>536,8082=>536,8083=>536,8084=>536,8085=>536,8086=>536,8087=>536,8088=>1017,8089=>1026,8090=>1153,8091=>1179,8092=>1195,8093=>1199,8094=>1088,8095=>1088,8096=>693,8097=>693,8098=>693,8099=>693,8100=>693,8101=>693,8102=>693,8103=>693,8104=>1034,8105=>1040,8106=>1210,8107=>1229,8108=>1176,8109=>1186,8110=>1098,8111=>1090,8112=>583,8113=>583,8114=>583,8115=>583,8116=>583,8118=>583,8119=>583,8120=>722,8121=>722,8122=>722,8123=>722,8124=>889,8125=>250,8126=>332,8127=>500,8128=>500,8129=>534,8130=>536,8131=>536,8132=>536,8134=>536,8135=>536,8136=>761,8137=>800,8138=>829,8139=>893,8140=>883,8141=>500,8142=>500,8143=>500,8144=>286,8145=>286,8146=>286,8147=>286,8150=>286,8151=>286,8152=>333,8153=>333,8154=>447,8155=>537,8157=>500,8158=>500,8159=>500,8160=>514,8161=>514,8162=>514,8163=>514,8164=>528,8165=>528,8166=>514,8167=>514,8168=>696,8169=>696,8170=>816,8171=>828,8172=>721,8173=>333,8174=>333,8175=>500,8178=>693,8179=>693,8180=>693,8182=>693,8183=>693,8184=>832,8185=>899,8186=>847,8187=>852,8188=>928,8189=>500,8190=>500,8192=>500,8193=>1000,8194=>500,8195=>1000,8196=>333,8197=>250,8198=>167,8199=>500,8200=>250,8201=>200,8202=>100,8203=>0,8204=>0,8205=>0,8206=>0,8207=>0,8208=>333,8209=>333,8210=>500,8211=>500,8212=>1000,8213=>1000,8214=>293,8215=>478,8216=>250,8217=>250,8218=>250,8219=>250,8220=>444,8221=>444,8222=>444,8223=>444,8224=>500,8225=>500,8226=>350,8227=>350,8228=>620,8229=>620,8230=>1000,8231=>250,8232=>0,8233=>0,8234=>0,8235=>0,8236=>0,8237=>0,8238=>0,8239=>250,8240=>1000,8241=>1363,8242=>247,8243=>411,8244=>611,8245=>247,8246=>411,8247=>611,8248=>469,8249=>250,8250=>250,8251=>629,8252=>666,8253=>444,8254=>500,8255=>953,8256=>953,8257=>314,8258=>931,8259=>333,8260=>167,8261=>383,8262=>383,8263=>888,8264=>777,8265=>777,8266=>500,8267=>453,8268=>453,8269=>450,8270=>500,8271=>278,8272=>882,8273=>500,8274=>497,8275=>500,8276=>953,8277=>512,8278=>410,8279=>855,8280=>620,8281=>620,8282=>179,8283=>621,8284=>564,8285=>179,8286=>179,8287=>111,8288=>0,8289=>0,8290=>0,8291=>0,8292=>0,8304=>320,8305=>180,8308=>320,8309=>320,8310=>320,8311=>320,8312=>320,8313=>320,8314=>300,8315=>300,8316=>300,8317=>216,8318=>216,8319=>335,8320=>320,8321=>320,8322=>320,8323=>320,8324=>320,8325=>320,8326=>320,8327=>320,8328=>320,8329=>320,8330=>300,8331=>300,8332=>300,8333=>216,8334=>216,8336=>320,8337=>304,8338=>340,8339=>337,8340=>298,8352=>698,8353=>667,8354=>667,8355=>556,8356=>500,8357=>778,8358=>722,8359=>940,8360=>1026,8361=>813,8362=>869,8363=>512,8364=>741,8365=>722,8366=>611,8367=>1340,8368=>489,8369=>601,8370=>619,8371=>722,8372=>556,8373=>611,8374=>498,8376=>524,8400=>0,8401=>0,8402=>0,8403=>0,8404=>0,8405=>0,8406=>0,8407=>0,8408=>0,8409=>0,8410=>0,8411=>0,8412=>0,8413=>0,8414=>0,8415=>0,8416=>0,8417=>0,8418=>0,8419=>0,8420=>0,8421=>0,8422=>0,8423=>0,8424=>0,8425=>0,8426=>0,8427=>0,8428=>0,8429=>0,8430=>0,8431=>0,8432=>0,8448=>751,8449=>723,8450=>674,8451=>954,8452=>556,8453=>781,8454=>806,8455=>518,8456=>667,8457=>822,8458=>490,8459=>824,8460=>663,8461=>818,8462=>500,8463=>500,8464=>578,8465=>613,8466=>715,8467=>417,8468=>778,8469=>751,8470=>880,8471=>792,8472=>832,8473=>589,8474=>729,8475=>892,8476=>711,8477=>755,8478=>667,8479=>667,8480=>939,8481=>1156,8482=>1008,8483=>722,8484=>659,8485=>389,8486=>743,8487=>757,8488=>663,8489=>286,8490=>722,8491=>722,8492=>846,8493=>613,8494=>533,8495=>363,8496=>587,8497=>690,8498=>556,8499=>1021,8500=>387,8501=>537,8502=>537,8503=>350,8504=>537,8505=>417,8506=>906,8507=>1155,8508=>655,8510=>586,8511=>722,8513=>663,8514=>485,8515=>485,8516=>637,8522=>516,8523=>778,8525=>899,8526=>386,8528=>780,8529=>770,8530=>980,8531=>750,8532=>750,8533=>750,8534=>750,8535=>750,8536=>750,8537=>750,8538=>750,8539=>750,8540=>750,8541=>750,8542=>750,8543=>750,8544=>333,8545=>658,8546=>977,8547=>1041,8548=>722,8549=>1040,8550=>1363,8551=>1679,8552=>1051,8553=>722,8554=>1046,8555=>1366,8556=>611,8557=>667,8558=>722,8559=>889,8560=>278,8561=>536,8562=>794,8563=>734,8564=>500,8565=>758,8566=>1016,8567=>1274,8568=>754,8569=>500,8570=>764,8571=>1022,8572=>278,8573=>444,8574=>500,8575=>778,8576=>1082,8577=>722,8578=>1090,8579=>667,8580=>444,8581=>667,8582=>528,8583=>722,8584=>1093,8585=>771,8592=>964,8593=>472,8594=>964,8595=>500,8596=>964,8597=>499,8598=>964,8599=>964,8600=>964,8601=>964,8602=>964,8603=>964,8604=>1009,8605=>1009,8606=>964,8607=>500,8608=>964,8609=>499,8610=>1093,8611=>1093,8612=>1093,8613=>500,8614=>1093,8615=>500,8616=>500,8617=>964,8618=>964,8619=>964,8620=>964,8621=>1151,8622=>964,8623=>592,8624=>482,8625=>482,8626=>482,8627=>482,8628=>658,8629=>658,8630=>1069,8631=>1069,8632=>836,8633=>964,8634=>939,8635=>939,8636=>964,8637=>964,8638=>499,8639=>499,8640=>964,8641=>964,8642=>499,8643=>499,8644=>964,8645=>840,8646=>964,8647=>964,8648=>840,8649=>964,8650=>840,8651=>964,8652=>964,8653=>964,8654=>964,8655=>964,8656=>964,8657=>550,8658=>964,8659=>550,8660=>964,8661=>550,8662=>1047,8663=>1047,8664=>1047,8665=>1047,8666=>964,8667=>964,8668=>1092,8669=>1092,8670=>500,8671=>500,8672=>964,8673=>500,8674=>964,8675=>500,8676=>964,8677=>964,8678=>964,8679=>596,8680=>964,8681=>596,8682=>594,8683=>594,8684=>594,8685=>595,8686=>596,8687=>596,8688=>966,8689=>926,8690=>926,8691=>596,8692=>964,8693=>842,8694=>964,8695=>964,8696=>964,8697=>964,8698=>964,8699=>964,8700=>964,8701=>964,8702=>964,8703=>964,8704=>587,8705=>716,8706=>494,8707=>587,8708=>587,8709=>746,8710=>612,8711=>612,8712=>536,8713=>536,8714=>439,8715=>536,8716=>536,8717=>439,8718=>506,8719=>823,8720=>823,8721=>713,8722=>564,8723=>564,8724=>564,8725=>636,8726=>636,8727=>471,8728=>497,8729=>497,8730=>549,8731=>549,8732=>549,8733=>636,8734=>853,8735=>509,8736=>575,8737=>559,8738=>509,8739=>200,8740=>250,8741=>320,8742=>320,8743=>564,8744=>564,8745=>654,8746=>654,8747=>416,8748=>750,8749=>1083,8750=>722,8751=>750,8752=>1083,8753=>697,8754=>722,8755=>722,8756=>565,8757=>568,8758=>250,8759=>629,8760=>564,8761=>758,8762=>564,8763=>636,8764=>636,8765=>636,8766=>503,8767=>614,8768=>636,8769=>636,8770=>636,8771=>636,8772=>636,8773=>636,8774=>636,8775=>636,8776=>636,8777=>636,8778=>636,8779=>636,8780=>636,8781=>636,8782=>636,8783=>636,8784=>564,8785=>564,8786=>564,8787=>564,8788=>735,8789=>755,8790=>564,8791=>564,8792=>564,8793=>564,8794=>564,8795=>564,8796=>600,8797=>564,8798=>564,8799=>564,8800=>564,8801=>636,8802=>636,8803=>636,8804=>636,8805=>636,8806=>636,8807=>636,8808=>636,8809=>636,8810=>900,8811=>899,8812=>410,8813=>636,8814=>636,8815=>636,8816=>636,8817=>636,8818=>636,8819=>636,8820=>636,8821=>636,8822=>636,8823=>636,8824=>636,8825=>636,8826=>636,8827=>636,8828=>636,8829=>636,8830=>636,8831=>636,8832=>636,8833=>636,8834=>636,8835=>636,8836=>636,8837=>636,8838=>636,8839=>636,8840=>636,8841=>636,8842=>636,8843=>636,8844=>654,8845=>654,8846=>654,8847=>636,8848=>636,8849=>636,8850=>636,8851=>636,8852=>636,8853=>636,8854=>636,8855=>636,8856=>636,8857=>636,8858=>636,8859=>636,8860=>636,8861=>636,8862=>636,8863=>636,8864=>636,8865=>636,8866=>600,8867=>600,8868=>712,8869=>712,8870=>466,8871=>466,8872=>595,8873=>588,8874=>710,8875=>706,8876=>595,8877=>596,8878=>588,8879=>706,8880=>636,8881=>636,8882=>636,8883=>636,8884=>636,8885=>636,8886=>1296,8887=>1296,8888=>966,8889=>564,8890=>626,8891=>564,8892=>564,8893=>566,8894=>570,8895=>582,8896=>744,8897=>744,8898=>764,8899=>764,8900=>512,8901=>250,8902=>471,8903=>629,8904=>636,8905=>636,8906=>636,8907=>816,8908=>816,8909=>636,8910=>636,8911=>636,8912=>636,8913=>636,8914=>654,8915=>654,8916=>654,8917=>564,8918=>564,8919=>564,8920=>1215,8921=>1215,8922=>636,8923=>636,8924=>636,8925=>636,8926=>636,8927=>636,8928=>636,8929=>636,8930=>636,8931=>636,8932=>636,8933=>636,8934=>636,8935=>636,8936=>636,8937=>636,8938=>636,8939=>636,8940=>636,8941=>636,8942=>250,8943=>1000,8944=>1000,8945=>1000,8946=>601,8947=>536,8948=>464,8949=>536,8950=>536,8951=>464,8952=>536,8953=>536,8954=>601,8955=>536,8956=>464,8957=>536,8958=>464,8959=>600,8960=>780,8961=>442,8962=>794,8968=>474,8969=>474,8970=>474,8971=>474,8976=>564,8977=>503,8978=>791,8979=>791,8980=>593,8981=>560,8982=>563,8983=>563,8984=>800,8985=>564,8986=>800,8987=>632,8988=>474,8989=>474,8990=>474,8991=>474,8992=>686,8993=>686,8994=>658,8995=>658,8996=>800,8997=>800,8998=>800,8999=>800,9000=>800,9001=>329,9002=>329,9003=>800,9004=>800,9031=>777,9032=>777,9040=>777,9047=>777,9054=>777,9088=>800,9089=>800,9090=>800,9091=>800,9094=>800,9095=>800,9096=>800,9097=>800,9098=>800,9100=>800,9103=>788,9104=>788,9105=>788,9106=>788,9108=>800,9109=>800,9110=>800,9111=>800,9112=>800,9113=>800,9114=>800,9115=>384,9116=>384,9117=>384,9118=>384,9119=>384,9120=>384,9121=>388,9122=>388,9123=>388,9124=>388,9125=>388,9126=>388,9127=>494,9128=>494,9129=>494,9130=>494,9131=>494,9132=>494,9133=>494,9134=>686,9138=>1287,9139=>1287,9140=>860,9141=>861,9142=>861,9144=>889,9145=>889,9146=>889,9147=>889,9148=>889,9149=>889,9166=>800,9167=>800,9180=>896,9181=>896,9182=>903,9183=>904,9184=>910,9185=>910,9186=>761,9187=>910,9189=>942,9190=>817,9216=>800,9217=>800,9218=>800,9219=>800,9220=>800,9221=>800,9222=>800,9223=>800,9224=>800,9225=>800,9226=>800,9227=>800,9228=>800,9229=>800,9230=>800,9231=>800,9232=>800,9233=>800,9234=>800,9235=>800,9236=>800,9237=>800,9238=>800,9239=>800,9240=>800,9241=>800,9242=>800,9243=>800,9244=>800,9245=>800,9246=>800,9247=>800,9248=>800,9249=>800,9251=>500,9252=>800,9312=>788,9313=>788,9314=>788,9315=>788,9316=>788,9317=>788,9318=>788,9319=>788,9320=>788,9321=>788,9472=>889,9473=>889,9474=>889,9475=>889,9484=>889,9485=>889,9486=>889,9487=>889,9488=>889,9489=>889,9490=>889,9491=>889,9492=>889,9493=>889,9494=>889,9495=>889,9496=>889,9497=>889,9498=>889,9499=>889,9500=>889,9501=>889,9502=>889,9503=>889,9504=>889,9505=>889,9506=>889,9507=>889,9508=>889,9509=>889,9510=>889,9511=>889,9512=>889,9513=>889,9514=>889,9515=>889,9516=>889,9517=>889,9518=>889,9519=>889,9520=>889,9521=>889,9522=>889,9523=>889,9524=>889,9525=>889,9526=>889,9527=>889,9528=>889,9529=>889,9530=>889,9531=>889,9532=>889,9533=>889,9534=>889,9535=>889,9536=>889,9537=>889,9538=>889,9539=>889,9540=>889,9541=>889,9542=>889,9543=>889,9544=>889,9545=>889,9546=>889,9547=>889,9552=>889,9553=>889,9554=>889,9555=>889,9556=>889,9557=>889,9558=>889,9559=>889,9560=>889,9561=>889,9562=>889,9563=>889,9564=>889,9565=>889,9566=>889,9567=>889,9568=>889,9569=>889,9570=>889,9571=>889,9572=>889,9573=>889,9574=>889,9575=>889,9576=>889,9577=>889,9578=>889,9579=>889,9580=>889,9581=>889,9582=>889,9583=>889,9584=>889,9585=>889,9586=>889,9587=>889,9588=>889,9589=>889,9590=>889,9591=>889,9592=>889,9593=>889,9594=>889,9595=>889,9596=>600,9597=>889,9598=>600,9599=>889,9600=>761,9601=>761,9602=>761,9603=>761,9604=>761,9605=>761,9606=>761,9607=>761,9608=>761,9609=>761,9610=>761,9611=>761,9612=>761,9613=>761,9614=>761,9615=>761,9616=>761,9617=>1000,9618=>1000,9619=>1000,9620=>761,9621=>761,9622=>761,9623=>761,9624=>761,9625=>761,9626=>761,9627=>761,9628=>761,9629=>761,9630=>761,9631=>761,9632=>761,9633=>761,9634=>761,9635=>761,9636=>761,9637=>761,9638=>761,9639=>761,9640=>761,9641=>761,9642=>532,9643=>532,9644=>761,9645=>761,9646=>761,9647=>761,9648=>761,9649=>761,9650=>892,9651=>892,9652=>446,9653=>446,9654=>892,9655=>892,9656=>446,9657=>446,9658=>892,9659=>892,9660=>892,9661=>892,9662=>446,9663=>446,9664=>892,9665=>892,9666=>446,9667=>446,9668=>892,9669=>892,9670=>788,9671=>788,9672=>788,9673=>791,9674=>494,9675=>791,9676=>791,9677=>785,9678=>791,9679=>791,9680=>791,9681=>791,9682=>791,9683=>791,9684=>791,9685=>791,9686=>791,9687=>791,9688=>350,9689=>761,9690=>761,9691=>761,9692=>791,9693=>791,9694=>791,9695=>791,9696=>791,9697=>791,9698=>761,9699=>761,9700=>761,9701=>761,9702=>350,9703=>761,9704=>761,9705=>761,9706=>761,9707=>761,9708=>892,9709=>892,9710=>892,9711=>885,9712=>761,9713=>761,9714=>761,9715=>761,9716=>791,9717=>791,9718=>791,9719=>791,9720=>761,9721=>761,9722=>761,9723=>761,9724=>761,9725=>570,9726=>570,9727=>761,9728=>800,9729=>800,9730=>748,9731=>800,9732=>800,9733=>811,9734=>816,9735=>468,9736=>677,9737=>724,9738=>944,9739=>944,9740=>686,9741=>944,9742=>715,9743=>715,9744=>757,9745=>755,9746=>755,9747=>756,9748=>800,9749=>837,9750=>719,9751=>719,9752=>782,9753=>822,9754=>954,9755=>954,9756=>933,9757=>489,9758=>933,9759=>489,9760=>517,9761=>660,9762=>724,9763=>732,9764=>886,9765=>577,9766=>489,9767=>563,9768=>490,9769=>770,9770=>725,9771=>860,9772=>668,9773=>753,9774=>724,9775=>730,9776=>600,9777=>600,9778=>600,9779=>600,9780=>600,9781=>600,9782=>600,9783=>600,9784=>730,9785=>724,9786=>724,9787=>724,9788=>799,9789=>659,9790=>659,9791=>495,9792=>495,9793=>495,9794=>686,9795=>661,9796=>544,9797=>608,9798=>605,9799=>545,9800=>804,9801=>583,9802=>796,9803=>1006,9804=>825,9805=>1189,9806=>1144,9807=>1189,9808=>683,9809=>808,9810=>1146,9811=>797,9812=>758,9813=>757,9814=>758,9815=>758,9816=>758,9817=>758,9818=>758,9819=>758,9820=>758,9821=>758,9822=>758,9823=>758,9824=>770,9825=>770,9826=>770,9827=>770,9828=>770,9829=>770,9830=>770,9831=>770,9832=>895,9833=>333,9834=>513,9835=>722,9836=>722,9837=>371,9838=>377,9839=>402,9840=>642,9841=>655,9842=>869,9843=>905,9844=>905,9845=>905,9846=>905,9847=>905,9848=>905,9849=>905,9850=>905,9851=>1016,9852=>1064,9853=>1064,9854=>954,9855=>606,9856=>522,9857=>522,9858=>522,9859=>522,9860=>522,9861=>522,9862=>845,9863=>844,9864=>844,9865=>844,9866=>748,9867=>748,9868=>748,9869=>748,9870=>748,9871=>748,9872=>726,9873=>726,9874=>963,9875=>770,9876=>1038,9877=>388,9878=>997,9879=>787,9880=>508,9881=>809,9882=>1014,9883=>859,9884=>818,9885=>972,9888=>1000,9889=>546,9890=>784,9891=>786,9892=>738,9893=>542,9894=>601,9895=>700,9896=>511,9897=>861,9898=>611,9899=>611,9900=>544,9901=>782,9902=>1025,9903=>1141,9904=>1000,9905=>513,9906=>510,9907=>642,9908=>722,9909=>719,9910=>777,9911=>495,9912=>602,9913=>836,9914=>666,9915=>666,9916=>691,9920=>689,9921=>689,9922=>689,9923=>689,9985=>974,9986=>961,9987=>974,9988=>980,9990=>789,9991=>790,9992=>791,9993=>690,9996=>549,9997=>855,9998=>911,9999=>933,10000=>911,10001=>945,10002=>974,10003=>755,10004=>846,10005=>762,10006=>761,10007=>571,10008=>677,10009=>763,10010=>760,10011=>759,10012=>754,10013=>494,10014=>552,10015=>537,10016=>577,10017=>692,10018=>786,10019=>788,10020=>788,10021=>790,10022=>793,10023=>794,10025=>823,10026=>789,10027=>841,10028=>823,10029=>833,10030=>816,10031=>831,10032=>923,10033=>744,10034=>723,10035=>749,10036=>790,10037=>792,10038=>695,10039=>776,10040=>768,10041=>792,10042=>759,10043=>707,10044=>708,10045=>682,10046=>701,10047=>826,10048=>815,10049=>789,10050=>789,10051=>707,10052=>687,10053=>696,10054=>689,10055=>786,10056=>787,10057=>713,10058=>791,10059=>785,10061=>873,10063=>762,10064=>762,10065=>759,10066=>759,10070=>784,10072=>138,10073=>277,10074=>415,10075=>392,10076=>392,10077=>668,10078=>668,10081=>732,10082=>544,10083=>544,10084=>910,10085=>667,10086=>760,10087=>760,10088=>390,10089=>390,10090=>317,10091=>317,10092=>276,10093=>276,10094=>509,10095=>509,10096=>410,10097=>410,10098=>234,10099=>234,10100=>334,10101=>334,10102=>788,10103=>788,10104=>788,10105=>788,10106=>788,10107=>788,10108=>788,10109=>788,10110=>788,10111=>788,10112=>788,10113=>788,10114=>788,10115=>788,10116=>788,10117=>788,10118=>788,10119=>788,10120=>788,10121=>788,10122=>788,10123=>788,10124=>788,10125=>788,10126=>788,10127=>788,10128=>788,10129=>788,10130=>788,10131=>788,10132=>894,10136=>748,10137=>924,10138=>748,10139=>918,10140=>927,10141=>928,10142=>928,10143=>834,10144=>873,10145=>828,10146=>924,10147=>924,10148=>917,10149=>930,10150=>931,10151=>463,10152=>883,10153=>836,10154=>836,10155=>867,10156=>867,10157=>696,10158=>696,10159=>874,10161=>874,10162=>760,10163=>946,10164=>771,10165=>865,10166=>771,10167=>888,10168=>967,10169=>888,10170=>831,10171=>873,10172=>927,10173=>970,10174=>918,10214=>545,10215=>545,10216=>329,10217=>329,10218=>496,10219=>496,10224=>1000,10225=>1000,10226=>1104,10227=>1102,10228=>964,10229=>1000,10230=>1000,10231=>1000,10232=>1000,10233=>1000,10234=>1000,10235=>1000,10236=>1000,10237=>1000,10238=>1000,10239=>1392,10752=>860,10753=>860,10754=>860,10755=>766,10756=>766,10757=>756,10758=>756,10761=>745,10781=>702,10815=>722,11008=>1000,11009=>1000,11010=>1000,11011=>1000,11012=>1222,11013=>1000,11014=>1000,11015=>1000,11016=>1000,11017=>1000,11018=>1000,11019=>1000,11020=>1244,11021=>1000,11026=>770,11027=>770,11028=>770,11029=>770,11030=>770,11031=>770,11032=>770,11033=>770,11034=>770,11035=>1000,11036=>1000,11037=>283,11038=>283,11039=>846,11040=>846,11041=>799,11042=>799,11043=>807,11044=>1000,11045=>461,11046=>461,11047=>461,11048=>461,11049=>360,11050=>360,11051=>283,11052=>854,11053=>854,11054=>628,11055=>628,11088=>589,11089=>443,11090=>443,11091=>802,11092=>803,11264=>645,11265=>793,11266=>851,11267=>700,11268=>851,11269=>640,11270=>774,11271=>665,11272=>733,11273=>834,11274=>834,11275=>734,11276=>790,11277=>580,11278=>834,11279=>979,11280=>738,11281=>410,11282=>775,11283=>471,11284=>734,11285=>851,11286=>895,11287=>722,11288=>638,11289=>620,11290=>721,11291=>793,11292=>821,11293=>699,11294=>793,11295=>682,11296=>569,11297=>791,11299=>751,11300=>705,11301=>874,11302=>665,11303=>1139,11304=>1023,11305=>1238,11306=>762,11310=>759,11312=>484,11313=>595,11314=>638,11315=>525,11316=>638,11317=>480,11318=>580,11319=>499,11320=>550,11321=>625,11322=>626,11323=>550,11324=>592,11325=>435,11326=>626,11327=>734,11328=>553,11329=>308,11330=>581,11331=>353,11332=>550,11333=>638,11334=>671,11335=>542,11336=>478,11337=>465,11338=>540,11339=>594,11340=>616,11341=>524,11342=>594,11343=>512,11344=>427,11345=>589,11347=>564,11348=>529,11349=>655,11350=>499,11351=>854,11352=>767,11353=>929,11354=>571,11358=>569,11360=>611,11361=>289,11362=>627,11363=>556,11364=>667,11365=>447,11366=>303,11367=>728,11368=>500,11369=>734,11370=>511,11371=>611,11372=>444,11373=>680,11374=>889,11375=>722,11377=>651,11378=>1075,11379=>881,11380=>500,11381=>557,11382=>383,11383=>643,11384=>559,11385=>339,11386=>722,11387=>397,11388=>180,11389=>469,11392=>719,11393=>499,11394=>532,11395=>381,11396=>615,11397=>433,11398=>969,11399=>680,11400=>647,11401=>443,11402=>593,11403=>402,11404=>573,11405=>405,11406=>698,11407=>509,11408=>726,11409=>493,11410=>283,11411=>238,11412=>628,11413=>455,11414=>653,11415=>471,11416=>819,11417=>589,11418=>698,11419=>507,11420=>546,11421=>378,11422=>722,11423=>489,11424=>724,11425=>524,11426=>526,11427=>375,11428=>647,11429=>438,11430=>615,11431=>433,11432=>719,11433=>519,11434=>762,11435=>538,11436=>649,11437=>461,11438=>721,11439=>519,11440=>964,11441=>681,11456=>689,11457=>464,11464=>579,11465=>391,11466=>493,11467=>355,11492=>408,11493=>499,11494=>496,11495=>986,11496=>466,11497=>461,11498=>934,11517=>256,11518=>617,11519=>266,11744=>0,11745=>0,11746=>0,11747=>0,11748=>0,11749=>0,11750=>0,11751=>0,11752=>0,11753=>0,11754=>0,11755=>0,11756=>0,11757=>0,11758=>0,11759=>0,11760=>0,11761=>0,11762=>0,11763=>0,11764=>0,11765=>0,11766=>0,11767=>0,11768=>0,11769=>0,11770=>0,11771=>0,11772=>0,11773=>0,11774=>0,11775=>0,11799=>333,42560=>607,42561=>411,42562=>611,42563=>410,42564=>487,42565=>347,42566=>368,42567=>286,42568=>722,42569=>519,42570=>550,42571=>468,42572=>1145,42573=>775,42574=>665,42575=>548,42576=>1014,42577=>736,42578=>910,42579=>675,42580=>966,42581=>677,42582=>1042,42583=>648,42584=>722,42585=>513,42586=>932,42587=>700,42588=>1042,42589=>749,42590=>780,42591=>550,42594=>896,42595=>635,42596=>933,42597=>635,42598=>1139,42599=>777,42600=>722,42601=>500,42602=>790,42603=>560,42604=>1262,42605=>850,42606=>734,42607=>0,42608=>0,42609=>0,42610=>0,42611=>519,42620=>0,42621=>0,42622=>510,42623=>201,42624=>639,42625=>488,42626=>475,42627=>347,42628=>1160,42629=>842,42630=>1000,42631=>768,42632=>737,42633=>531,42634=>827,42635=>530,42636=>608,42637=>438,42638=>742,42639=>545,42640=>608,42641=>480,42642=>926,42643=>654,42644=>671,42645=>518,42646=>992,42647=>780,42752=>318,42753=>318,42754=>318,42755=>318,42756=>318,42757=>318,42758=>318,42759=>318,42760=>307,42761=>307,42762=>307,42763=>307,42764=>307,42765=>307,42766=>307,42767=>307,42768=>307,42769=>307,42770=>460,42771=>460,42772=>460,42773=>460,42774=>460,42775=>374,42776=>445,42777=>564,42778=>564,42779=>354,42780=>354,42781=>243,42782=>243,42783=>243,42784=>564,42785=>564,42786=>276,42787=>242,42788=>386,42789=>276,42790=>722,42791=>500,42792=>895,42793=>703,42794=>532,42795=>409,42796=>437,42797=>389,42798=>592,42799=>600,42800=>378,42801=>378,42802=>1183,42803=>708,42804=>1154,42805=>758,42806=>1089,42807=>716,42808=>902,42809=>586,42810=>902,42811=>586,42812=>912,42813=>572,42814=>667,42815=>444,42816=>722,42817=>500,42818=>722,42819=>500,42820=>722,42821=>500,42822=>713,42823=>361,42824=>611,42825=>289,42826=>750,42827=>544,42828=>918,42829=>658,42830=>1262,42831=>848,42832=>556,42833=>500,42838=>722,42839=>500,42852=>576,42853=>496,42854=>576,42855=>496,42873=>722,42874=>500,42875=>483,42876=>341,42877=>611,42878=>611,42879=>447,42880=>611,42881=>278,42882=>689,42883=>500,42884=>483,42885=>341,42886=>667,42887=>444,42888=>333,42889=>278,42890=>282,42891=>286,42892=>278,43003=>556,43004=>556,43005=>889,43006=>333,43007=>1298,64256=>589,64257=>534,64258=>530,64259=>805,64260=>799,64261=>586,64262=>677,64275=>971,64276=>969,64277=>978,64278=>971,64279=>1219,64285=>350,64286=>0,64287=>537,64288=>537,64297=>564,64298=>537,64299=>537,64300=>537,64301=>537,64302=>537,64303=>537,64304=>537,64305=>537,64306=>350,64307=>537,64308=>537,64309=>350,64310=>350,64312=>537,64313=>350,64314=>537,64315=>537,64316=>537,64318=>537,64320=>350,64321=>537,64323=>537,64324=>537,64326=>537,64327=>537,64328=>537,64329=>537,64330=>537,64331=>350,64332=>537,64333=>537,64334=>537,64335=>537,64342=>926,64343=>926,64344=>308,64345=>308,64378=>750,64379=>750,64380=>580,64381=>580,64394=>338,64395=>338,64402=>874,64403=>874,64404=>329,64405=>329,64508=>776,64509=>700,64510=>304,64511=>304,65010=>640,65020=>837,65136=>300,65140=>300,65142=>300,65144=>300,65146=>300,65148=>300,65152=>724,65153=>321,65154=>275,65155=>249,65156=>275,65157=>399,65158=>399,65159=>249,65160=>275,65161=>776,65162=>776,65163=>301,65164=>264,65165=>249,65166=>275,65167=>950,65168=>950,65169=>293,65170=>293,65171=>424,65172=>622,65173=>925,65174=>925,65175=>308,65176=>308,65177=>924,65178=>924,65179=>298,65180=>298,65181=>738,65182=>738,65183=>574,65184=>574,65185=>748,65186=>750,65187=>600,65188=>600,65189=>701,65190=>775,65191=>596,65192=>596,65193=>397,65194=>397,65195=>399,65196=>399,65197=>328,65198=>328,65199=>331,65200=>331,65201=>951,65202=>951,65203=>600,65204=>600,65205=>949,65206=>949,65207=>649,65208=>649,65209=>949,65210=>949,65211=>823,65212=>823,65213=>949,65214=>949,65215=>805,65216=>805,65217=>557,65218=>557,65219=>460,65220=>460,65221=>550,65222=>550,65223=>455,65224=>550,65225=>625,65226=>575,65227=>674,65228=>550,65229=>602,65230=>577,65231=>578,65232=>577,65233=>801,65234=>801,65235=>300,65236=>300,65237=>696,65238=>696,65239=>650,65240=>650,65241=>757,65242=>757,65243=>318,65244=>318,65245=>655,65246=>655,65247=>206,65248=>206,65249=>549,65250=>549,65251=>403,65252=>403,65253=>651,65254=>651,65255=>323,65256=>323,65257=>424,65258=>622,65259=>525,65260=>476,65261=>399,65262=>399,65263=>776,65264=>776,65265=>776,65266=>776,65267=>296,65268=>264,65269=>676,65270=>724,65271=>676,65272=>724,65273=>676,65274=>724,65275=>676,65276=>724,65279=>0,65533=>900,65535=>700); // --- EOF --- Collabtive-2.0/include/font/freeserif.z000066400000000000000000032522271237252063700202210ustar00rootroot00000000000000xxUEY{ {/"RDcW {;bC"vEBIg!}=9p<33mY IG<~m\?`m~/YD'9bTg aY1hԘ;=G~.2u܈Qv0p*N1ef϶HSϙBi⓶'Mf晒^3B@'ۋ{ 9@4Z>˔#a$qxT:{2OjB}if"X-yAzU>sϷR*5|4yMPH {"s6tVshEf#YYl^we}s< & Y#6n ȚJr~&Gu?z6GnrRש%!§jiݻYK2źPI+p~Ed(s:JJ#ȅėc0PbBۡ|UڶƁ9 2Mo[w)Cоvd:`7'D楆M`y쿔ZsJ[7j/<$uPl}gz%3 _v [EMSw`Fgsjo35u{D_KltP+ ї> {mձ}~ضߌ>2 WtGKݞB֙x['z:[nHqfA;4`lYK %m˯~R_rBҐ1EOi(HʓC} G7XIu[~+nrc.^"v,k`N\<;΅e cñҏyɎqH2BGcV{G:YMQ6fǛ]Ar`KʅWs, t.N,>ܽ3~6_bF8;w~8離i_s[FoEUcm\yI:˥ #pƍjs78piu%?$+_cQ͏U\WX ͪ z5rfskr;^Ǧq, Qm﷘P܅\Sg<1W}Τڢ:֍f~mL_N98M=چIp6\z~茲sEcrhUb5_Ae]FXfř0}6N%u:Ζ"V~}A)9q)O1G3>5u<4 E>H{E4ҩ*y "0ur@1Sp*Y_K2}D%ʗ=Qeȥxd)y}3!R1BCuKJ;* q ӮmpI-\ĕp_] ͫIx,A=^3 a*/²Ϫ 7Mp# =y5<7|ރw᭠N. ?MSz~r\ZK^IkhC5ݾnsՌȶ0 Nj29k1za>Ga!gy$ 6DY ;65Ym +fjH/X1?Yy,v؜Fxy%p/ ib{񄱐2 ư\G"|M3ݫt2 u4ϒL2YGQG:v'sdt EZ:*uݷGH$dQHb xvM#]&rN G0 ȧŴJ7ܪ>f6e ~"o'ƾ#+r ÷R톟9, *#uw&hKWpJ{a`6WOL&ns+sopx_2OW忖 y-䋌-#MK]<23_9c}6vRl$v3.~E!}}V>71y\E+?/<"vӶ<]N<χ[B)\]._r]ԽZ˚Z7a~:B7lDtoa)m_Ƈ^.sg}v,tU/l٨T G0~qjc[oR-z!cgHZ 1Gr>\'Ua kzD]蚻N~|֣qVGЇ5%zB?%uy a'ex|=B-iK7R;&Z9?ow s ®z NY,[q)1Y}ꧮE=~J[X:XyNk>>s~Y7m%ov}g gMǯѣqiFE6}4p5h"ٶ~۬ѮDv";[ϝCw=2 s=ĹގeibC,mkga${;g!!O$꧁I8SCƓ[<d%Y2/mQvDv` EV7]kL7j8{~D"GW`Ϸ:]6 7dg5d-]~x7F>hV CaJ1sN^`gM!m!~f%zh26X~|=u&G)"dήY ِ5tœ1@] : ] Yが@Fv`x>C3G e+5#)'kn\]$0]> ˥qySvn33󜡞羂-430-_.cLm+\ξ|T4m"(a`*n) 2?uj̓VGs w3 rMkw~rxޕ&󂷃qu/&[*Vt'/^eq("mo3Ӄy9ofxJ{O<Ӧ!|w֣W ^-6--; x8؛RR9 F1 \zJ'Φ޷1޷HXݱt :flQw#nAK7”ƹ8YWIQ-^qd'c!nv邾Q9>u}~ wR`Cu^f=̬'YZXl?U78㔕QGٗ_?+%0Sm˚ ky_1z,Q7Koqô~5˟#ss3Ev.-MWo;oFv9>qv-.kO;'yC1ȏߑBty7{f*7w8[;x 瘓1?Ƽ^C>7hP_{+8ovy9l<×UCHM5{!_n}Ld] v91^u11?HZJc$w;c/,ᖀ> Ϭ]e&03y3N)7r Yye~E7Hđ)i̇n~"]xWRGS=%'@'^y>իd 09+sLg-qop[Mn&?EʉPkG|Ɓ}jP?ʿaO\g0 sYk"(!zIXG3s-@Ur;%go!?YXyy[~77x}̋~s%«la#͗ۃ8Afyr'e2AȻ o41 湘W[Xs9+B07Kߔa=`p/Qgx62< CRL9Ͽ=¾-CB?QR̼75Y1P7kx?fJ!чv#L@aeYca*6=LS!ι2عpWa6*r uw.`@φZ0cϨa[YgHdH0s  wC-G2 7ʑ~N])1fD없>hM\]gρ 'A4 \y sC:mGn<'[ Ş%} Md,⹇hnt8\?WÜ#u谏hEKMBk$s ygOg|j$0<T+1Ǟ @g4<}3.x*;x'x_lN ދYw,v>kg7;1|WY7 ?9v,(f,vIńF_i@h<ٛ 5YrbڣYFggc~Ϸ[%n{l9+wm̋{qvϧ=YA<r]`_'yg,71/@ͺj n{YBJE|.muH:֜ -po#] ~oU& KW敖2T3~v"͟$x+>qts`6ݞ-G!ېvkc&-sao{tzFvLfMw7">d=!|9 ߿ʂkutH⪙<}gJԼؿF1܆-emTxF!;[${s4sNsk ]}o{-{ܹ~O#Wzѧ&!R_[&vVbor;"1Pĺ/~"fErՅy$'' I!iNF(eeõJͷ! o/yދr=[7SWl{kd m>3恦vUsgIo?mTjpDL2vԢ̪lJ710ȚgS /۱c>UiYŶzگGhamoD0~:FQ5\Ye07'X֗N o 17I#G?'-uߝ1}'|'q3wJIZ&n}{x/a 3yv ~:H{ nf|<&5ݗW<_LXk$bjz{Wg09kgt?!\k`GRF%&dG!5uhs;q@"w}iC]n{VHǹ};ʭx>΍`!V[K?bZC 26 Bߗ7Пgl>ySLGK_'MZWj\YCwYGx5uu&t#k.CEϞ"()p<eoVǝ)yR'Ğ=t鎹~IKeP;LpߩòEb+fofq(_,VJI7LvB㯒nOгo꿜0~Pz}"nYatX)5)A~E{-gS|cV~_?Ϛ?W<<4e.hJ٫o5)Nu7yBw+r? 8gq:uHs<ٙ&9k?[~]ȷk)?f۳n=*?lj{FjZ+gYLc {6'~?Ǿ>=f^潤g}]=5qb7bNn|yzdo%cQ= Ԉggp3FT)G?uu)evwqdmK]Cmq+:pq!oG4ecLK)8>pMvz=:j9,WY=y-k׿ןy̪3ηz[-&='vߟF_}=؃eg31&ش༚IVw31韥ss\6~;ui<jy/;CG}~%ʹ??L_?釞魒~;}]'im{ۘ c15j30?{txrtmrc~Sɬfn^q avw3V? ON. >]w2&]fo@ Ӓ{C^|tY474@zC P]273n.&M=?77nvJ~w/~{cbϊ7`{!X7^=q_Bvx%]vBhgym-ܡ$"Z>:?!\xx/`.ouv˓p"cɉr$>^L{e瑁0&; |kK}d۹pLIA`%fs~N9nwƌϼ?sEoKWHwwr4ėNbcFn}?KO5ne8l<^r0)+*l{efkפӕ>n\9rzM̶&g)e{Wߙb)#3X:ahl8J{4stTYau[saoK-sm F ٮg߽_ h.F̞GdRjþ))d`:MSzf]~ pw8irkf >zYw3L39)]|ho@O VWHH<| A6?gI|\(|݈ vl_l6o`azߓGƏ$ܶL,doꦘ=/"-=׸ aMWJݾڥϱY9ᄛFjK9 *cwvqy9WvU˽t`m c]6eicnLH&cEg$)vm~8ՒKCF g@mhv{j$w3z-))IK?cٮ4c,eC2BewZzk׌v-[]?͖?-4]{fC?rr/aI@*vH7w ' V1iǚ!t_W @P S6L2A?T˧Tw2Ww;XvLjT?oV- iF*Q1Fami.#wVP{lY"2Nw]H)הivȫ"Ɓ1ģB[1(sH}?v$kĕa <̘UZٵX̝0w2a^Ёq3q11g)W^DE{|AKr+?ܪ30nI_л{vC5? {"PY탮4=7}nQp[g*}](f#ϔ Paft7Ӆf^Iz ޗWBoI;8X:/`ko( ~LwWU{6Nz0Ou^g+:Qհde̬HZM;,~X X}'\ 00q'F C69G05cXkOģ橚>tpkIqvp_Vws.c\sg啬_ ZU>@*-bR6;Dy&!g:=—t2)ZM9%FQ(wtv@<9F@jh%0O !iwRx V"V)ORDU071C`"AN9|Ûz߈kW=}6?%Z}^Bq*[)1_x?_1{MH;n֤os)Q,pUuS[ftp󹖮r̴XO3ޘ-asqkz KX}]#XȸlRmj y~iHìdY;&<vq."o!ٶ;i;3aS ՇЅ>yK nM0_^*ègfF0bS@y}ƱwXXs4yaipi^maF[aA?WLq߳y ̭u30W ew'@[6h:#9<=1{Ot^7plY92ԩlJFNamQD{65Ygsox}JjCfo^F݌#pց5๒hߡl^}wҤ[u22l'KpWQoݩwxCD8b2ګy}jt0 wA+Ÿ=vzm!xn#AGpkzkU^FV17Vt,ƧSFu22a~iJq8+eeyK ԏuj!tbWmWq;y,Moȑq-eprOc~_3|g " B_7sCj{U$N@h#c{D ~f#=e Tپ6/!{ stb|Buo B7¹X[>:F~X[ab;}!1ЃU GZoKA y?KRZͼ쟱])p4Cb~H]$*MWʐiҨ_sKc hʸ90/\}qvQGes='㮬ucH0!tz?9=#<(zCǭ_n5k}}1wzFLe3Օb?/n.jOy#TP1L_7dz>υ;SvT;2}fiK-lŝE~luRWQ8_xxrNv;N+w&zNyQ {xk7bo sND9F okc>d]ocWNFx[N?zoɁ1^Ͻf{=go1y rJ}aҼg/hy!G*M^ ?FJ@&n)Vcy;=Ԁ2}2}gC8;R+c{go㥖n5eH#?RNo{'*5Tȫt]{9{ݾ7[< g*JijhC>{zS7bw { w^L{{"ȕu<xԬ۠wbT# Gҍy;UwzW9n)qR>E3|<{k>yw> oDCۺJL{[iҿ !{w}/WcC{ [nwʨRb1]K ~ɗb{w;]Fn>Yt~ss]kM.vYUػ?ۧr֢~ʂ4$gY@:6]~cɃMY\ꌢ<@?<"ʏUܷ1A7é>Oy>{zߏ;G >̞YB5IqpY}z4-@P${Ҫꝺ{{y_V6cdqչj׼>8o2+78?T3gx<:W~~pWyӟ6M+77{=Z.-+LǦs޻mJ/B>iWu@]C.rx7ЃbCGBWþ^tq?C0 ?y|?>D^{w{wsZ-%u{Q5УB(H8tfLܷ7azHZ}0cWƾΟ P3i] }ۏ~w8/.y\N!u35>?u;| ߼ji5ZP17e;N 󿮊€w˲\ blm:рqÐ|(a{60?iMoy;T YojÆBA.}`v)c*9|~9w8_Can]TC\p'ݼwй2?Vg!Ů^cZ2/tfn˓@XgYV곩"LK>\nqf:cd[O܍r!̇;&x NgX o^wdw39.q0%#aD g{7KWjzgE\y)hj ;B++JhNz2vӂ8?kF^I !w}U{E;8ʛ2}f4fwiӎݩܫ]u6L پ\:kwn%fo]>S,'^u/M}ًa/)NbVǬd~o. Ew'Ru6ok}bR>MX>F x:y\u^+2c;I#N]s[h%Ifn뷑>7яFb9~#Ձ ?}Cg>̋7R?0x?71ѷOݻd/ހ pԗ8Lr0޾c8_##tZ7_ƍ|^j5:e /ּyO-W"k l2^Bb8ɇ vY;O~#?H~]9"*&gl!y~IH-#Au{0r~To~[ nNenA cF(Ů{^@37;ᙀ1i=}7 8BނL|e~ R|A7̇<+ ?N3GthGowPToECvI8i8mӘԩ ؃8Ȁj1&=m[(|UMcd%&X磟Aov0+$|)  c+QH ՘1K<Ȝsxsy+dh ~ ]sO:;v>\le=ouˏp]NRIK[Mz@;=!Ɗ~]i̼8̾pBy/Bۇ1q Qrq{EW4{vN[߅7,Է s+i+?УZPash.=Nǚ.@3 t\t?h9kMҭJ=X\aLc5O|d+Nv"clfS@6r,k*p֯>=9}G ׬o2m.aKwy?{Ws>6A8=8=[CߒZ[16SOkV#'W>?LjnLޗ sw^6pe;[zgVp7332+7L{<^2Uof6iuQ q3-%:6sqmt/#'Z"1A#>;UL{c3$rk^wyGc"I{_{z7 %CzZV4(Ͼt'"|5m:z(2%h{O.f^=9uƥ S0= ar{IsUz';_0{wv3׊~E_SW%Q.>n3[ZPqęKJdV6a})Od"{cx3[2i(Mbw]Nr:dlN3k6̅tq<6\N<[d&eaa[&]&^M#\¥ZN]-g_y'}|/}}*z×BquWMw ?1^(͕M]S?82Yeep/!98[q߅]ydv&ku}@1ގݜht0C}7[mX쭰w_?dܛ[g&M }Ü對}];s7:p˙Sh9eHeG#A-ێ'HCs*y=<=~ 3iqзO?zH5<QS30ϜJx{}TK BhK\9,hD5+}!xxs/4 swo.bN$8dظ dh|w{/Ꝼӂ+1 |} ڧe>ݨg}sI/h΄;Q#ӃihIv0${U0[B-&hęA\C..OY-ܐ  pMlmSnd7{>;5 uh׌U1/gp_^\'Kۜ:~3{Vh켊mܓH1u2km3mD(Y#:'4'LdCd2P,Q{'3>os ߜgNDsW%s,Ìź˽=nœ<ߖf][J_>ΘoZm'{MwKRu6zm Vmrʼ%S㉮GǨ:wH9Yc=ⰹ:d,5/߼1o u$뷵fYuzs>~_כ6fEd]::];um)W]כQ{֖[v~~h9_y;"Yf+|v+}1m #3w}Fged ѳӧ諾ncؑZIǸ9t":Ɩ=1=qYigf0F=ʦgJmoos15^ʤi1 m5؆|ջǜ}|vsJ iEp nq3@]^tW"/!G>rUzFﶋxU:gq$>~'6J¿ /_o9KlXwW{(a2=P!&H-=۽Ľޝ> GcDž _^W/.7kи1qĝ7+=q $Oxf⥉W$I%ą/&~ĕ_'kbY$uRI]'MTtdĤcN"[L7䇒O~:wW$*䲈IEDDGG#GGFΎ\"rW7#"F|);kꄴiqM>)koL_0%o/M_U֌Ԍ 2fϸ(cw3gխW77ڹ9rs=&wB܋s_}?sέ;![j]DEёѣF^- (f4r m@ō+ &-,._ps,YbfGj>(YQˢ#[tzE/SQѦ"ײ5'|'Nzb^y\y{)_>o(۷s_EYTWyAE[}]n>&<%|]@+M>D+.K#%xyU7'ޞ4Z(qqďЊ5?%OrI52%M4(i(Zq Zqb䫒oJ-ǒL^$yYV+GL$IGEzDF#'FΏ̎\7omST'Wi%=>>>WъwWJ&};Z18cJuGfϬ+uH;2Њr/],rwI̼Yy=Vʗ}̿%M h;/F_+hF(7~)+L)lV@+N)[B$ i|dEъEЊEg]VvъߊXV'>q?Q^.9M;,[~A巕WZ-y/{/y^yyzxy{7yzx'zӼc(o5jUQr`ފ=+vVl\bcuU\SW|^iʊ+U,x⭊%oV,xⵊW+^x'+xo)|:|}5W_>_P~~gO-X6l|1eƔ.U6oYeʺu*X֡]Y벢eʲRWJ\R鋥/.,]P\鳥O>Udy>ZHå>X@}Sz{]vhYrqɅ%痜[rvɬJ,9(9ԒKN*9dB1%JKt(i\Ҩ$AINI-lٰ-ooY-oly}+[m-ll˥[o^yG7?͓7y扛'lc7|摛nn{ߣmܶ7Lp܆&l c70jÀ 6n3Jg잱eƕ3.1k{v9ۼo*˼/V-{4 7薳"gi9弛NΒg_cǾi$7>yq6$'/ bOiӼnWG__ ٛ XDm;1p $5@$̺I7 S\O =Er}W!F׸)k\1 ? `~ yOx rO-%>᷑WA |'c/|KE/%R݉kx/; 8q$G31Abӑ3cx3;y;N$M3s2D瓩xvČ%b%_|L9#k%T H}$WI:uP3%n8D:{xxw#ft=JG'kBDt6~2fU /o>N:eIѝtoHʕN$~ҷb>ɸi>A3jcf\@3D'#zH|Idğa3ό~?:)eS?30/{&0&u續IS1< ==IBp\|10q.s`咟\"0~Pr'P/|RУ\\NrsRr\H3cS.u=f\\FХ\-G\ƣ\"2)8|t?({a|ͣS"-vϻ3c`uOjIhT4Î36F2NS>7:G?S|T{>ϼJ{nM}G4J2>QQ~#}'G~X44Ʈ(EStOcT2Ƥ(厢wi/G){yR(/$mҨ(sPy':`KcI# 81. /W@z.kĸ؈I#F1c[mؘo̼NӷBƐB!}/dl(M=O!}:i6Lg+,Ig/Ga~ 9'yqXjwE!/1S͘K хB Ҍ_;r\5E+EiРy|aft恷)}ݰ<>Ks;sۮ|jVR݃Wa+_l~n*S5{T*׵z߰TR+!{7,Z5RΝ?,n놥 3뿍˽)D-?ϰf>O"asx燎͙gюS g\óE׿"/a 4s\sB60v_h5D1w:;288_x+KuNF8hPc5N8־nWYw׎MCοw"U2ǘE\tzϑn}Zrd֐GdV CL8 IBHRBΐ+'wn Bp|!5\6_eCPGmP,}QQ2Jp(ʆBP>TÃRP-T5áfj:nahGBhh yx"-Ó*<ZgB32o0% 3¬0'vc Â(,%!#, Š< 6 uɯC$;tK]s#„~9_9$t rޞxbQrÐVa^Xg"|&g#<;+~D[%N~%<{`?&OKoAC{FWv oq&ab%rD'rBIap6#g 2i"-3Bf(ѢJk/L;޼%3">H*Q2#2A ,X2#*K޴jMZֲ̨dFtzvh"ߞ+ߏ-.SEF[^hRVOȑPFj/#Hj~MiK̈OO{1i2+]~FhbdǑmӲO*+Xeׯ޸.p]| ʘv:R%ZHKSvۮi-:"/9i#ꌬݶȴ+<O2u̾rRy ̗vt$Ճ3pNk|3"ZP# 7p!هp37e> 02Pm6w&١ӑFl;֤E|I_ETQ#Af.#yoM[n}" נ|->r?ܾGii3njݒa.CȌ経qMZ,xe4u2e~j2jeDVN%_ħZ^'{g3ٛq{3B^ĸǿ9+{"/]$޸HC)"K,.˛^ߕ8|\ryS̙+%{%["o+Irku2#OXZ9g;yY/<{}O}=Өg?+,&oF_ggE{;ڳVgϲ13QLΑgi}c=z,ם!F;_܉7|#·Cl \wl t֐Ѩ ^&_FrkEa/XL?wwy*CqŭWR܃Nq9s7Nw{=0o 1%TSɬWRV6ϕ2~U kUW&U`U\Uҹ^Cj?C>5RVMS5}OqF 5jw sRpP5xX{X{XjWki-=l֒|e6կ~m똓:xձ^/椮9kNꚓr֓'g=9Y_@߆6ķ7߈#Ԉ_#ݘ^՘^D#zG}D&6 MmB&p>*yj*WS} cΛfG=049nN?f-k Ó|I3>.`yZ֮[gz춁mjS;<ٞ|y;[GZu4,;҉cg]t UO~N! =a,=Ŀ'= sO WOY/p%_/~[{y>}{~rG=39ϔ|V=s?~}^8, @@}Hˁ k̃h:HA Az0HAnn`=} u~ o6`_^k\C`~Qz/y꽬P P5T00ӟat0yWxUW 5u^~}t| HXcN:Ly Ʒ֛4-f:Ž91Qo,q|}<އ{8~i:,Oq3 33nY,zwx5Wz9.`s{p|\@]Bmɹ"[dV{1-s9\0[KƏ蹌rVȷBޕt8`X|&L*_%*5Vɹ&^^[j3g^mm55zF5>s]Rr5kՇ|'~b=u0:]'zzYr=ֻWd=~{,` n plPgب7xoxni\o俑.ڤ&6&Zoc6nM flf6÷Y6> [ڢ[ۢO[|l-"ʵ|µ0moY&696mFk;ݶvboWwYg{LYЇps<;l@0g?k'v±>;i}p%v]zhVn1ٍn3ۜq{k=Qw=ȱGt/~{c/߽pYO>w?s<~fy84 sG?bzG=jQxqLcf<&1sqzp}:| ˧|>駸}*g8}gb>s9\'\ x㤽r4#'I>[J;gZ~Q""XVfCDP6Mc,+Dxg)2SL#gCD\s_m 5YMM'8;J$_$>%ÐR] 93؍iDY!⦺ ·սG-o!& [Xz^^ʙw8pʫj߱(DM!"T>2lSy[BDfS+ 悴+(Bݙ&t*E/ʷ< eh=KMDZ$-O)\K|y?eh^Zٵ!P_D9uʥ3yY/[y: rWhhFET[* ֫YUyȹqg!axk1jmmV[:KzL< hPކ毑S"GyD&f&֛Qճ f<x5 }{6OBxzp=n x~kXZ3F6 ۈis[mk-^miomaoW;,w;x۩ӎjOp7;alOvPkz;(;p= ׳p= k'9;, |]i֕]q&>'z=Cw^%_o{C~å??{hV@}(@s< |lE jK ˎC60}EWE kkjN{nogG&o5}1RG9 Qz_oK pm4>9ZGїw콫zcuk5/vd>ug8Le:a Nq*S&4NSo:f؟L3՞iNf,3Kg;l7[9s\у9z=sv1O<9=Gxom50_5-> h |,BZ-B ^(B"9zE8/Z-q>A -R<>ۏpY&2|ùq_+t?LL:gY?b5tYZy?1c[6FOnF97Mz Mp{> ϼ[±m mn3K_܁ǝwʿK]j[O1b/}g/{>o<Fw~@xt qr<\qvG>9r1u\q8>S~ g}9 ' $S"Rkxswi~e볰}osQ$'^0/qQ%|.3OE__v~e1f{Uu kE_ |"*+!2zȒƶ70Dƻ ' I/z?$>\tyT̝ɭ^-CCmFȼ\q,(&_3nj]6 a/w~׆;s" K% 4YP|A5 LBp<)$D:Ȼ2ry2VtZ_ %[ٿW{!)?DއmX+n< )W.q=i_sZK:<)׊kӸ5kc-}xߗn}qkϽӟ_s0RcZ+J>8rXky֩7 lЇma3}%(V9¼Mﶩ]hE4+`7 v/ {`pܧ߯wa;  \sa5;31q?.S>u|gp|>wj}OwҌsRr})K+r~szƧ}N~3Ydz~>v?x>'$%voE__q_aModvUk{ ο !*QBʨ!*:orQq!*> Q YB\3Da'BT6!*W4njnòBT!*Oev-DݲDS] Q%J']+ǽt)si+຿ʨSƱWnQ*vU! N])U*UQhj4v?9{uzWmuxZo 1 ׂ`Tm5jQuFzQtǷ>iX4k@4k伱C#⛈yϦ879xj ÓzS-V?Ʊ Qmš޼_oGuќyzNv;-t+h֝pؓ>=T/~qM>CǾU^ps0><>n5L34!0%y_{'j(|C< ajbU1\a5Z7`|CF7]H(<-[mFwckmilo&=) 4yYl>q΅e"9.i%|^}Ml9W6x^kz;#j#Vzv]wۋ>9?(aXr t9 4N߈<+^'p4E˸op]Qi{G5:r3/DG ёmBt34DǦ1!:JN CtJIe&7ѹ;p􁣏>#>+ G_8pIL?~zϽՏhݏhԏhOO3͟s<6PAw^?! g///2ߡr *Ǽjoϧp#oZ H<7ƌ2_|߲o?h.Ϝg3CO|l|{Ͻ3b9ǘ1>Ƹoce lc7}<05cXX}ƌ{>Xƪ18ӏq0q7'8wꏗk\@{:M&8^=qD=H4(D&7 z8|Lkاa Sԛ8)0Nq*S T8<7Lc*S T81 ipLc481 i4/Mw>Ct^ LXf2̄sILXf,Xf2 Ŷe,lf7}0,q=' 1;mb\̥\̥\5os/s\'nmٙo7877 s,;K9ȹ,e!, aYBX²,eub[L4ZLŴ]L\bh =Xo -?퇴3pa)]Y*##:.Sc.ezLe-e.ӛezr~r=\ +hF+hF+hF+iF+^J~+J|4cd SL3ϔ?S\L3ϔ_%*=X`ϧ1X`փհex/YjWy6f ]Zu>1O'f}Bu4YGu[Gu[Gu[GuzN|=XO[Oi>i=N^q'1pڀ6 8miNpF97ʹQN1(F97Fۨwqc6&߄&&6ɹIMrns鴙N鴙N鱙N鴙N鴙Ni>mѧ-V[i>mѧ-8yraيVi+i+i+{l6 m8miNpچ6 8mi;Nqڎv}ڮOi>mק,}'1Yg~Yg~;ߡwCP;ߡwST;ߩNwS]Rߥ.wK]R߭nw[V߭nG=Q{ߣ{գ+f~ϽW?^>hq`>}0q?a~ø_~}߯}? 9fY>`;`y, :AsvȜwC;wϘaX?Gݎ=*(;Fc1oNޟv|9N }}_d_t=|RNzRON%_/%l_uLқSҏSֿ+u2_Wf+{_׸|v}7j~#7v~Z0}ZZo[yl|%g?cg`;#sp3p5w8gnS,}7?~y."\Rgu~Q\=+M~~nw׏]B+f?Ct}>_{kp5w kfM__o9ir8F C .;.QB!G̘#А#6/r9P9LJIr$O37aWB׆3rg!G1y·`zwڷ5+Zȑw8;r aCT?%if?3.wN 9 oZf/m9;r^B04~! ] 9 _XM#ةp2G)/҆ d+¯nE(.OQ-ʷ(-]EV1-FbW b)c1%Gqwg#tKcI9KYIXKII\J^ݽجzėRtázQzóa~Ll =9mnnyr=)S<S<)OSzJZ VjmZJb~γ:d:puYL.u߅]`j0uՓn淛>wí;=A8'{K^ ^^{e{go:ևӇ}Q}׬5}7gG=ҥ\ws{Nsp>sr=x^_6@r 70 a(@5;H3HAsa0| ֆ3D̋t/b/Ke^֏i^Lߡjm(݇1La>;'aև _Q9^*.*Lpn=mkxN7h.oqϐGFiLo& o|#?RoNo~Km:ڼ9{wyqї1VX30V}6άx>13Ԛ`'؟ 5LLD\'1QIN$qNyΓOa2&b2̓d'48E/TT7U>ͼO3՚tئt?3h803ԛaog5SLygڟ~LfٛEY͂q-l=moza-n9>戛#x;s#h sKjՇbw.|9ypγ?<ϳ?|Ϸ?̧-gX_`} ,4 qX(Bs"hE`:^dN4_b\?KܟK^b},|h>Cf kK/wYj...gTݳR; ,ɳ_st8  9(Aqt_!:dCt8 aq֎>B#4?b6t;*< 1XL?N4T~A/h/ĝqV'~ۗj 791k~+;Gh{IqU?pӼij暘ko> 2 -(;FF&u9!6V\w>ƷbbFD~BlRf-YLJ3۶\j:bobo?:y{<ػux-+bobS{Cl[z "ClQ!LiT8XJ-Vi t5MW{Z- }BL*މb] ÃU2\UԭcXj!QMVo2p{爭Qь#Bl-Xk+Oݳ! # ?Q<~=fy}|Qm7;09=>aER֟I:=iIOS0Ugc+z{.}_ky;9#g.tGW|M azM>Ź~z߱=^x}~`ot@u1 c_91v/K_e/ghfއ/vW*t.p_#zLd-=|Σ+{>8w>N?з@TMoDD:{~oɮt SFiOm:lqtX7=9;Þgؙg&v\-gعjՋydϧ -4w],!v Zp_d9R:~DhVh꯰fe+J=Y J=~b>Vc3ɤrw<*sZrc ~ka-x~BOD:soශܨ؈F7QLl{na6v3}~ [VʽU&v9˹],xe˂?ˌs;hN٥a-f~s{蹇{pڣ{o=b}|^ُ~wkx<u{9Ax,`8!aq=G}2 1>Ο3}.sO'a=sKڧkog۷wF`NϚ:y\~'$O4 h-/^w.\/u/ _E.|Q͋4E}E."%^Rޗghx Kf>DKf.g~g5eח+,o~ W^Q<0ϟ|W] 翬%o7=79Bo!EbCi-Tj2B\t6>֝q9JlVMbrL3CgL٘%KHr6c|sb04YYؔ_!11<Ư\5mgOhISt|έplck[ m>՗vzҎ6iO{9:8$=ruI:څ]v7xCl>=҃.=VO=)w/5z^07qMb{>Ǿ8~|Ѽ~?f?fz:`{[?X %9_PyY/n8^ s9f#(ޢ|.=ރkYxl~'zNc=Kٴc6y0y*n1NK`6KHj&n N zln:mSg;wS]rq7=fs(> vc8w_}S{uB?pSrx/F>߻qV9~zsf BCbB|qvC|I9Ɨ_Z/;&ė|__*BCU[kY!ך  7Ncj>2-7)⽿?* f>Vs-ĴI{?~k o_6w;^ ΧC|Mz^bG⟃V@axCh2arZ9okC(u;)Ŀ-h:{ч8Kbh1IgCw3ggC8Σ|Z,eQnK؇g^ GdrOW9:~w ~̛ )~G 8ýss~z>?!9 9c;NO~n~O"?I/9%װ~!ğWG}YX9'>E.Yq}9`<E? UoO.!"- #BBTِ]Ưr%<& y!!1oNRCM-Bbnr y&[$$?${{zHZ>RCCB!!HH( <$Xpw[ƻ{f/TPZ}w"$;$i[rH(X_yB瑄JU_~UyW 0W_TH&$ԖճVCHh FBB㌐v Mh c3XwݜvObtHhy6$$LXrb? S&[M5|Yo<D-luܞ7$d6 {ܛyPZz9mI>_._F z=>G61."}w٬FWpS\̄wDcCb%$F_ 9Bblg/&;'e!1eRHy<$or~M̝\ vyBuCyCb>m吘_;SygI,(G!EؘXYH,V-$U!$oXZАXϽjˌ eGfrWBby+FadXLJʆjrWpXZBbu䉍[GfC4s%ڭhgķ۱tY;9^q鮦ĞܚgHH'ϩ|8A4}_ef:*pիؓj}y:$~׮7pV[g!y!HHJ*N>P: I'"hiVah&gQWbH*-V5aƳ &_SLݻr.51!8|2_\Wn<9~n%`(1&$s'UR{JSjyH*($݇}pO,C?R:,{0y˻.?U xUV0*Ѳ䮬7U[U·pyο_:j]6uץY=wۈ~hOk!8MlJ`iq8 9ZR'| V= kkmmKvӦa|VL'[]wQ7rHcOz[L< k޵?F4^O?{lzq4t\f7VGq\:ϷBYd˿ R=2BtLڭ6+q'a=<`&k߂Vls],|vຳlHo7l{^~mla<!VGO3}nFNX=vߗC)+s5-}w3sil+/;&wkWxv OzHCrcT,$Ǵ9v\!9HN !9WtHi`HytH9$r:$7Ő|G79;Brڕ\()$v^ZH.fx|{= տ?.$frCryF0<8+$WJ\U -$гNOXLW_oMCFO99y=nmaozmUoηØ/Y١N?OwܝЗ/`IN _eь_Z_:Mu-gdzt:4?읃9:S㜞;gVϻ7?^w?ٿ X.vӯo|ol\u_%_bRR"/!%CHRↆ!%aHHI䓔'HIiRrn )vˆuCJ!!%o5ւf#4&lTH|ř|gC皔ԼLԵ0;RG3W~տ3SN̾R Y?N4OA*,\yS!Kd _Y!>2!CJņ!CJU[&OujRCqIZkۯs]|X_4jHcB#Λ(m4-BʓmBSZ}zxHi-3QvtkRګ݁OG{tZH!|J*WF359[麗qF_9u7z4X/)/6D^4/e6Ta|^q*-Z<#SFe՗ao.<{ cBx?03/pdkSNe^Mw2L8g9)x|󅎋-6K u}z!eY*k !e=N賑pl+>ێSY'I!eN{>8 :bqIHTgN8I5N9= ]O=wp33$G5~E\R]vM+/Ή;I6[3Lzn-u{gi Kea齪 *U (TĎGA#6Pa$|~ϋ^9sß7>*CRdHR)&{,<3B1ERu[)F`Pq 3pYQ]Cq|I1.vy?b (xQ %(|Nx+lb£(&rDA7bSLVz1Ԡ8׀Fk~q( ]K1@k}fG-A2]g=bwQ̄3NS {bfnـv5fx l<_rcsbȸd,ޥx .\ˠeϡ@ ,/Cљ ȼZؕx vZ YWC1hIbZZ ڗe((fڭWz^{^ }loC -by@GA1փhbB&!n@{ l 6Ȼ 2l=vmlηہw;e;nv0{2L1< <yz<>h>:=o=oOI${= O'^v{^ {{A{/ >|sDAi3,`>Ƽ } ݼ 9^|:|Ac}/G(d; o@go&|M|2oAWo[۰۠6ڿ9ށwṗ!?>BGc1~g@OS3~ނ/+s:<t1c21ߢ[}C7?ט'O3x:> ^~.~o3j7;l;OB_hFz81 d2%`zP׳\(JJJIVJ)2 9J)((eNĺQRG>``TF:JTl,pPJaި^6PPJ,(e p(Px0( eXE)Rx4 kPޥjA{+bnGසmh/) Q/h[O)-C،%t,C)GA+٢U"ੁjK~@m۸7k-K<;~I+ tm94FVa >a6 e'R-B/< CaPhDH7 ?t@ghB]dǂDZA7tnԏq84xb8l"Mlo D@{l1 m}J)t5>72@x6fn&|n}̆gd·r.>Y|98΀/gndX o!|q!p6 |\{+<?zX zKKc.ó ^RJ] <sd^ Bq]ǥˠr^]W@Wu%lt%h] [CfUs5׀k ӵk hlnu Fs#ll&Fz#mǹ 7oM&vpbޡn7o 7D쭠q0|wf m-NwB7w..]ݐn< ? {A>!{u`m q~:yphwN  a . .#G(? A濰+7QݰnȽvn!9h==4'6ʽ?Z >Ƚ:<}S r=x|?Mpi |xz2}\G"')S 9:~_KK~8l||G<| _> x pߡ;}zî?F?@G'' /9Wo || }`뿡۞>N )=x޳b1 b)|7V|Jq(R4ʖجy(P|!n@G9e(Pl.rؼi()6xf *P^ e_قz,>YOb9P?j Co-kAWz/^n5a(m"VIQBbk)֑~ |(ku" >SL^5 `|Q2yf Ԡ 0'bKk)Z ~6R,l% #1 Ѧ"0~UQl5VG xU[G@z\5mwm|-?iD9BA1z 6ZC P`öCa}md ܣ (6 :N~4h4 ~ ~e,~1b^nc0 0`}x .=z>:; 4aa׳"|.L\vA<Ï@%c)->2f9\|<;zY  jj_Ey1x2@kARy_ׁ+`'g+a+ߥ*xkӵ}|e_tnL7@Wc7A9{fйr+{܁C[ם ݀|o}y?dxv0W`Bm(;x0twA7.~>E\<ANC  ܻa=I< q?O)A|?ُvABAӐii@8/A7/A aFaÐe2ڿ/C6@oWënU<x_@5y uAw#f^:@.QQQ| xX; ?9?<Ǡc1-} o۰;hm}tށ>C?ﻰۻ˻==z>d|!th}=~[|ևdx>Fl}< r~ O 1ͧ3 :|矃_ _߿/}<2z?!OW~~]~ޟO?> ~_a_@7| 4~O/~@gΟ_hd : z:r? M!B(3U(?P*RRAJRϤ (R*e f CIvɿT](x3xsޥT{Sl@RBG ж`R,1c@K҆R(]PC9FTU,(R>5hj iTZn ACx)3 =i)CHmR٠'dCST_(<9 .EF;7tn< ^LJ>}˯G~pχO·g@3L˙L9nb!p,}F٠mAEiڜ??9v.x<P|.F%d).Klh-堵2+C[+f%`VfUx~rcZ Bvlw1_g'.?^hw9:ϯ@+ t%Jƕo=,WU*j|tOנh{-h^ l6nt:߀:Fׁ\@::u:п>t=^{]`Mhm po7ٍAt}}dx6}q(i&JB)*:Xut(tbߩo-TFbFCZu) |/hmKﴸG=b)zz!!2ޢQ3̢r-s*(}=elq]qDB ˅zK&oηU.qT9.Ҝq._lN^0c$/ {!oR~PţaVq*רW?a+ѱ%DҨ:6x#c ʘJ.4LZ̨Fھ}fAj[__?1,{EeuەG㣋?׌p6'~N*GJ, 5QQiy~xB\SA YI8Cp:'0E# }Syn5mA6gkߗXYF&F|FytMvkgM9pp .sΚo7&{^h5px&*+\3d)*fH1:^ЫFAsSWp'IRP! ^ukG̀n׫a]Sku;؆ .gmVDO3Θ%:TlgEkˋ/\O.kR)+qT4jdc7E2u1dȅDΠACX^m؞vRXEJE$ 9rV+u7vFLqa. b>?CQr K DxPU{Y7LA6z}.BiP jZTJem8uuJ䎮W\,+7pjJhT"+Qk#V-QԜ.KT*cdJۊ֒< #r]Mn\EjQ.a}p+srMvYRAӴIoţ \EH>j?ϣ8!oEMC1Bpv4oV=Dl1p#O[>JmLSz<WµEUوL:|)?H7]}`ߦXbOiRsӝ`"D.|:ѸEߢqDlQUlg:MUt'ahK)yJꓼ,:@İd%Ca.'X=>Ro%霍 .٦ .syX+)u$V_IJҚvLEUa#2: YD6,E6*;Xt͕\McŖl mR>&x΂qS7 G) @ Dґz2e7K3ΙR诸gvQrY`fL^tfB6u)h'Oi|€WXH G *ɰTU[MJuZ8wlF \1n,5NK y|F^."g7wW 7n`_mZՖ+#cwv6WÙHmEh;kq"xTS.D;* ?Ւ:UKb6|yc&/WGl/uZzʳy݃3c% ۘߗG#/b7yCr)mR h OH?qdKMػW bkAPhm"鹦&Nr!۶7C~=u"XQm 1$[HSթƷi\Z0;UҬV>U閏<סY,ZcQOB C_!w_yt}NtkyU>>>Ucx1{ F-lnFW>QU8n.@_Ě[ˬ9tcoؼϺ{ᾒ+o|χ0#!p#saJq bk<9:]n0"<Ncw!7{ 4*s:A  85cit9ګU/+ikW辨uRpUGs$&ia'|s`l!J$Ѥ=cAKY[s\4nzFM c *9JLO6t/ͥ"UƠlҡy)^:\#"IؚSVt6$pVKPYT^2fʔdi,f>>;a-5U5sU/1+Hv񨑡N݃c,3J<_ȚűAU$eJs<;29:/'ZahN )=Ი]թ4xcƙk]>쉡%<S?oks$ih gv޺v׭~M†a;|߷beN.aĥ:2MBx,}Wbxbɂ1zkPb9aPOxeq蚑͌F"_}-f,aK͇yP%M7l-kh 5%U-S SUoYS:0lt)Fg G;yRsgӈ'G0JFUYt$KVvĜuw;8Avީ b0FD,blތ.c:w՗uvMtUlTcj̀;0(C]E+V ~zj_a ZLK%. ś әCcӿfyIp-g/Go]}e{nYݝxYfp4'*$~#"A$/I2dߢYUܺy5]5סwHE+6/g}ܵܝCZ.`UZbQc^g^k>2ت検0^OX!8K3BT⊯%ǀ(Xy}VaBwxy{+_QM[kC\Qo#qT=.`m݆F H[gFh~`0ϭ,ıwXb,}%tREU6["N#g7WX}<⦏W@Eh|pz5!3p?)T Ix#&c_^!sTuȮM,V$yss͊|61'n3cLb1&axzMIȠѝB =6̹?kw`(a-F.CՑ!ZPzRHMoX$ZvjYkCy!gS:/|ˊ@#S?wQ|{EɿtɜަOoqr*0Gh$c_,DXBiilGSuēVƊ6k̤b+`5:`H;kJ;sU6VhڑuYlicgh5v 5ϣ<`]ͱdrʣ8ޔa fjlΚ5EVkWI7B-3$n=R }8xm$ъR6\UmV; [unE.9F=z"P5'_Q#v A&X1E拦xIurKZ6l䌥ʬ&o_Җ+ih>oҜyj.-Q53:Ɲ)ڛo+=!g7S aOu2m-+7w+mg~θQyÇrJM}w1WV)޹dkCXd%rktXg 6zĤR#J]\^'f16@,1g*l4HlqRe?kꅵKET*(SM4.\>7m'zOLEBɭ1!#j MwN?8j5u̪h$[| ^?٫ u-@aNYV.]U:`r1Z:IKlYma(9#!ɜl+9eu>x,a-e2H0&Xe e7j.-IRو)a3s,0ut9~KY7'iխ11eZUXɥF$nY05HVb-Rt=^j?8MDxճ} )&YճgUeRR,D|Y6RWS7,ziawO*yB! z*TҙBآY:]xL2(3T& F{pHFHϭaG>vZ^I~HMeߔZU3輯 :2s88/>&qhx?_ oXjwZ{)` |04ǐ!Wj=:jԎ'^+N`_c[Ͷ s JI>b0O{2SA p+^5 4#^RÁn/sc]Yd3I I,?<&} Bt#]_ڽbch}Eðh#9jʬukϼs1suz|.?cJ:tgruLpJnXad&s\UVC$Uh٠уNG^2W'=1Ha Dm53a  8yžUQLvRWz#U !Վ*X 5`h0=6UVKQlub8? n?iGRc3bq3]oY JX}3@ߞ4k[I%RYVrd~W/h侨BM@E>Z-X-Z'o2)Y}&S:gH#%<]nN\&L6g=&qi~@ӜZ[U%ULoA/C);Bt6us^%SIH^)Q/gRўs>N~8O;A\r}Ϣ5֠tk,n7|^w`+w;[lob:5֘ڠ$Vd 6SeߐCb&r$O_@W\w/EFtaaJ+pHqo [6OPj͕S1T/XB !&;+1rº!29"Y^bcʨ_g5#㋵Jڠ^((=(8UEc^:A:^r_䜠@Q)IM*M&MliQK;:MnWzRT;)ķ ww׍jHϋYYpWO{b1| 21ң>(E =Kx5.~ Y) *7)̜w*e+nq,\pMM N|CnYmG\;$}i#ɥIƢ$̧}=]a6J89Fo1 o{c0NmvX[[ɭ4-W{-ͅ 8Ȳ`h )VVlzSѪQeZ* ijb*:g(SmzcWt~Ie# x#ԕKeD=("nBj3!=QLx ^a& ٲjQee_JEczY4QX䫬j}k8 l1T̩WA9ȃVj?WpK2dpy':Xr$11HS8/g2G)2.lxY\y4c|ƑG11A'2ZALzϿάr④jF-#kkF)ojl(6 #z`VfA@qи޴ˌƐj%ju91]tX.8#s}uVA. "Eh)cj;>#BUo"%5ϼKm"Kc vU8X\C_2l<ԦB*b:e%ouɹKS#JD+gjʗ ;[Us6CUR>0eIC%I{bS9n;vPxAn=3ȇ 'hQRAp[ M=ȫMUuJ͟2ߍ>@!J|:[dGYSR:eU6[sy_=M~8Kxz"R2`6T\USxM(}J[^ͱR~bIz\$.Bc^O tqIB\Ke!˄3ջ0䖆]#:n2}nѕO[B|*z0G=̟bU'mDžy9G\9M|uÉrt⺴V[NrY> .trI(| sZ:deeZRtHzg󖤣o|[NIN2&=-|Pv1)>zV/Oz.7pрhv t잪75%0B8 uBދdE_Ah~ܧ~)~i[Qi4+]="oF>L%ό+}pO2y"#uCTNN,o*ęYS;~m>+ Qלr:[6?9-ŋ(Fl pTB>e PiUwU4 2q~T͍7G{SjJ`rԧrϊِuƨvM^6]'O_wzѦ7 <^ȷH⧄`6?>MI'$}|#'WgsjIBζ検#{E 椼!QJ'o 7CǗ˓C?$KR>Q/-g֋rZ?^~AʦG!}m}L`O|[3=m+BSjZ0JD[]44րF(ZǮ^NL1ua",Uۧ]9&Vn_>w2jSEDMӝ'K6޽~ p#'կ=^ԋ~G8LDIUkބF<583rDhnX^)=#CU%#fU*V #|IOH~0/V= g]X7\QEBuSoG/DͱS*ԜԿ U٩z&!*F5SȨs38<azBq-g֖KЗ:|eOC!׻-e*_Šڻh?'kI:Om0jKꊍ\d_k Fej}u.w,hL<`#Tj+ <_1fYI nKrhu9ғ6}% Hڧ^^9ޓQO YoyJ4DegI ַ^}uxV{~2cɈ),ƽ{ 3rt+uGyEe%uݗ%nPY?!H,sk FkC0_'UBֲqr :|&(IQv~)NS/~Sy"U"~҃/cƟ9IH&?m޳'Ϟ$6GdgO5}Ҩ$q|>:~S/o xIRZmΏ}ry}I*g=*X2]r_ޡ #a ݣVۊb/o:AҜ~h-h/ .!Bs.'#gy|K7ٍ+o~ڛ咾b0Qu.#dދզjXs@X#%sI*)JU2)V:(:0_fd?KIsmZv3<>sDF9a / NRYO>soyOGKϠSz)U|ryσ)xzeuM1{`3:3mh%KI5mm|Z͵\!_N3djbgb*\I$Nf/b )Đ?cbqL'?| SE[t /آwtamquo2/'zBT=>>8sBIF`{r+qjXK@QeʍV ųK}֢Rb;xʴpArN2~5YQゥqvoA} 6>p `Qx 6΄۸D&|C飿: ;eA>FzpB Yuh3>?IKb?R-$ êƁ8Kg:2x&i1zt{4ٴ[ԧ/1T|bu1| h&VEMHjhYY#GU$8MzG9K6gW:#?XR')PjS\ϯ>%c)M}%"w}g{8K gK=)xn b EQ3W娰M܈xG3uw.ѦB&{+}E\6pSk'[o@/ 3s.2dY9͊}f"TFXԾпrd&I,IAXc*&UyDl䢆P mB=d\qU,q臔^'M@A["KG7< +5I(h|@߄71WA݅E.y) cpb*y @>hbǣZYdR DeSt|yNޫs߬>.a9y̭^Kd_}\kWr>_ЧS<#Ș$){Pދޢrp|@r;y8MO5R%߇<~j *_)ϸs7m74|?s;J̄[J7x=COSWS>PA  GGjjt!p(Hӑ_`4^*~r7na]B2֔-$&< [|F JB c~굓 cfpn r߶M_]#<$c[+yNm.qobT[;"wep@E-ܞӘƬlf_!HD LXEqcoGgm)½07)I_=Mfcf\f+q[Uy٩ TcuCd 8^ƋP:]/F}~b0^d >{ɷP_g [(:uKrT#%iÙ\AI86sݙ(@Zu9SEY2 f4ե >}0q7;F\X:y\ޜuS{QU1`k׵/\Νnʍ=B>@U{w+7Zgiw`LiVUX;Ah.nXۓY,wd 6/h*p,_%1y=Fc^"Ǽdg)m|~K4|RIlʅ *jBn%*&v.~)eo[=I4Tbtkee3 WwVH+\.[2}7rTVdrc3c΍ 䭗zoFsUyLVoٛz)kS_/z [*{ DVs! ^p{f!;L-EIKs\KWW+OiuH)WxIZr4DLI4UxY ކ"K*GT'K>V-9mҪ ēU1`Β/M8tu7ZnzTte&}/?et'_ h6b6KiNK(Oܓ@ kzqX | 6H륋*3<_{si[ǝ_$ 0ҟr=xn2BFˈ̗^XSY%&B2!xC)xQ7$J8u'R>&:5$8޸d+l< 5:[/Ueђ:Ƶy]FWxoR5^լ Gf*.g7 qX¿'3}NoOD8a vUVFE.,q=)*R%fʴ\e&J]l=vyQ'I琧eljh%D7+CEq7n*P$4ǟ7 l˕5[k3[; X50^:EqZrIKxg,Vx=3\*mT}XBeB`XORN|AXKO%&z>K]UbҰ&S]u+_5rؠ7:+7z\e°YLnOsՁ:<5OK]3̐IWY^cF=!Yh8'm2զ:SkS 'c',9:riEꯓ/L Mkh ^4.-%›54+d #S/, 9b>69{=2U#3޶3Ν۔ԗvV .$:ɽ G頱J qzo:Ի,۲ljr/lcl  S C%K(! N B DߙݻS!_^Afggf:ixq AkXuebd`M!qJonl-.wBa#9  0 Fwys@hP*Lw|5` ,,QI ${z\sJZe pީl5=k,mvf芃ksMK8B>&'֕4FACqƕ GRamzqϋp5 Z7Fq:I::f5_$I\%FEa2lorE?/T[\@"H7%L.-$m &{-PI~ Q+p c6u$gk^L6;lVSftP_Խ&x2l̍] 4@j [_͵.{Ug3иؗ #Rl"N;0"$4ATÎX`mΈXJl(t4E9F Z4>Rru8jцUb+bl*Wh;.Z ңdl\ qyQQ{F 5m-CC-szk[G[[GuEu ۵C{M\=ؿsq'%ۣ^W9b $ *O.)HJ3VtY[C(dRC`Jv>a2#]#tK'4/}Q(hw9 2ޤ+UUX;DտdWJŶj [ +)I = Oi^?q/E&2]sZbq֤pX OTa+J+S'%8BV&t"d1fV'h*dw^}w%xAM/Hq.(B<ŹY1jӋĚ.@C WVd\RҪk֠f*`ΕM xy;:gi,ZLPL ˜(}UCGFEUO>Hq$ξ30$csK rآ\Ƴo]}@>xIٹ-l#8Z>Y'߂ s3suu^!drɌrz-jwj7=55%"|I׼g]5GU9Y0<‚\dHrB;xc)Əw t5:-cҫ[=?[8̜s恦\.]mӼs{z%r%1h=®{mX,i+f6.?@gG@=0okME2ų bi,X/aLN\?:RԦZE|K#xmr1'RVw&~v9lH!P?tRB_@2ZٳHxGOJIcM^5-T;]k&'46i yBA ]Ta/2H1l&٫/H~7Y<689}2߆¾\2X~4aA0u8  {0֖`kqNqt 7/gԥv%y'N |^yf)k˽8p #1|w ˤX.A]W؟ 釔 ~ӿZRʣtTnF|9b;l#B;kdz*[csE};K  ǸU|&}Iq Ga߄O8zԢ)dA:G3|_ zEfNy&AЉ8ʭ+ zK>qcZngLѢ FӦ &^ŻiI⼈?j TEE箳s:RA|;ڲ(SNT q&9o'mǍhS707|Q~߄] 3^Cv} AVQwLwdJ{H6Υ@khCA!?WA.@=<['W\r䅻yA-:^PݶYmpIl %kVz(.ckn؝ɯZ;;$.`ҿrsi}7} ~d A9;ߢF{Lhu5H (wy8Z5Y($1"v?(I$!! hNL. r*!eXK?xj=w\kRNkU[5>DMp4Z X"1$lR,dMe;e+d)U YoQa͒+,mϟ3@U!PU^L:WI;"I$x|@/ ˩[ |-#6T'D/_h7-3)fC}tC' U_b\t621x27a,tf2IJNZ "hOfN{""9s,;j =Fߏ+7An1 \μoP>#gx|"롦LI\ b\ IU R+&O~>ZP?q؊u繛9LJC18GnO.(=6%ŏxFkQW[I"QݎR-}pÿHK? .TUNu. '؏C=?Zmu4H[=`p7nfCB֕;=[c7cݯ.x|0 B%i0w>+TG_>x/2@Kƪ3BDcs+uc1==Gmp|cPKU͋5Mh1?1׫%O5C`;`z1Ǘ&?hQo1%Gg#^#n {fGstQ,](\^,UdY[w-e ñ@4r\RT_'q$|e4S:VlZ>&1q|*xT.r%"_%oxw I_L_Ȋx)Iiyi\4ْojF!%p!Ob$.R̆1?bG%H}"#qOR2L*o*Ob[=xf1|9߈%Bl ~dGoUa}+gH@}&p "9<9={}^mhVtoDjGp^6kA5P…ɺp»#+ @)¿S+D =wU }WT"Osf‡fȔ f&!/,!Rp-0'giwto&k?D}G{}x_TtW c@`f-ڈI8&\DGU1müT Hg{'k,{JcKk[$;ŹŨםIӍD[`WM F{%TX.DZsOJғK*~"*HM"4{Պe _ג,4!9@|BRF:yy y^H<}xRd=;^臩8M;.>aNJʙd޺S8׷:j҃ |h\{ɸBg&@ƀn*E,=\Fjms]wvd-cmЖxwCY/z֜B5]szwUp !bUB@H%88MnMq,_ O]);[{9a_qvXaZ=0&D*s.^M;C^\Wq7>|/^||d(/#&1yn2$Ii=[TFfW;MoDzDßW ͙9fKR+:ӱ,Hgi1z=h A C49Sn^zn%:zz4/k]dQ2Iv)8pηZ u7]47ՔŰ~%yc9WzBbS C/Z9`/۰t)!!U6@iIt %w~CBد=&t4_EkkIl@ge*Ey:#N]>/[HJWfM¥`eDs_柒4}4AӷR$ShG%Ga AF?rJpC|`CE V<&RV*{+0\?- Y)`6vrכvAw[{B$;u1=8ؗʳ1.c8Ot)Sd*f1fG|KSbG4QHWȦ+/`]aidJD:|xpHK.Z@ t ^(za:eLs@9l6U@<F,5fOUI{ֳWzKfz+Ц[0ļP;%⣼̎Q$'E"<00I }kbPQ>^POE;wU9|f]z7^.ߑ{dpߣ$I&JZoH]q7='_xogJ^>Xη\@%UR*y!g`> u)S\7'bşVR1ǙiّH8U|>,A;NTU-?5ST9jC;:k=u|B՞uǶ`yP9ڦ}bҕɽwx{+G^."4`'8 |?6 Ad|ϩm2E%W괵%:dgjXmRZc%h,^WA6ET! ~𓂸?~ ??(n>~_r8Q2'/9qpG3-x1ҤU|3_ 5vQbjO^[6Ym ޕ 753y&cdue2rٹoEiv7wㆣp0)n:5rE/+_6xjCaibx~os9n#c,,@Yx&/MhKؖI˩?/)AjG`rK`zx׏m}W65,M%T|c7](o̘떭ܙ/D|STg}bQQP…>0IW#hњXs9KwyusOnFcɰ*uT,N%-јPT:n(쳲u+gKuoJ;TģwǢoڗN->#Miu5sW,ﯩo\t񅖆xS&MSz17)ڴpҔ\%*mzѼ5/ lu~j()'7 *.UQ,L1Ͱwxr5viJR*G^β̄0&Nfgo#CS~*I+غS-]I*`Ųj|iΚY^1hMa~J΄틷X_yKbvqe 1g-N_=1{J A*ihIn#61iX<ܠ1F+@ȑXe8n0+0O<8b8vhUsr5h+'j*G{\ޟ5zƢ^?jeIco:t*,*9iearZU<[!Z-Mjeqr_|">#<ߜ*Mhn\> xHΕ8A弼zDf4IcN`בTM|xW*Kfwp@Jd=wIg/)h3WkTrxy@Eb ?UBLWY}|S\/\׻ȏ E/MJ"b|$ր&AOm8FF1djtrbB>z!veݘ~ QsG}IDQĊ<\kf_K6hqvK1U5UwJV>?$8߶ 8VGSucPS-U"ɮm7UIKC j/ r/F.04z ˒Y4  #Ǜ?d_,[-ه,{~/'E98fhVw^5 _1_dvoxkȮZISZGW`vNF/4hW2NvǸpװᰛYq2r !C3aړ^Yw^~}c~ m"~ Rkc3S8l(]G\F84}X8/a*'F y&3B$W/+'a8Ng|cY @@%NZ,i:8] nVe0` ,Z#~Q{BP}яN\$R47$Te`w0eݼs}hUw|O$a%;ڔRM̽cXo]]DB/94;" ݵe :/ X_!"ITEncb1,e@lx'hRv&~B;SHa?J4bߞTA_DuG{ҙn?xcnDƀ6>$Y nrv}puѪ-HE6[khB>x AJ:#b?&r~W/yk_:& U ͒ږR3|;TC5/̞ڃ ʎl (%ĉ}>@cn|@HE i++Hl9X^74\ O4ZA,%O4&!'oֈEx'XB;NIk o|v:ψ zvIэh@(IdL")&aUO 6(Ac xSL!P*<{$gTpi6I%&kOeുR><{0GO|PicZElE“`$mjs"SNUźm:sU+Dx@oqrv}*\]5Ӓ] +V?)4>o Hm #0tv!q)yDz$&+yĖFC^%G*k؛͜8{K FVѻ"KCE}Ia/ Zh-#xq# U` ab䕅lm( }aS7Q.7< FطF1\.q$:+CB)n/x%- r\VURT@}8x~!Z&\?&+xwy<o,ojd*lNɹUZO <djJZ'fJDqg1ϸT!k[$1 gȣ@߷L܁8H}i7tB.Yh-@6bu<Џ貈.f&u({Z`Q`߁ Hߖ!͔[*C^T\3j)?vr:ޞ:%ԛh|F_ |h7$حE\[* ]*<^k0;y]QA}M9B 4g?y> @}ZOE23 [29.bK$ X-jK&Q֫z;/B"©LJ3-J5M|s[`40+OH~d@˾2ufom!TcgRC{ 1ŏ[vvWя(=Rw'yFU>y'w~ֱԥ#S\^˱viبR7ف{!`@V 6%j@`˃/1Դ=G?;%vjt03#*y#Ku`:0$ %b. -g>{EZ&ծ@0>If g(pKygO%m>x(hdT~⑒e?q)2v#|V#w4fjkbmSd^ Itس8uk4XwgLw|5Vd֦ -ko!3߾|U+Wx*<$R n%|jAQTf$ej: _YV~׉o+1Lȟw@ h)grP:378gWR ZIȸZ| "P`ˀ5Բ xi7^b@/GDϡV>}|EtdcFKvpƻ6 ݃2*{4y{/27*{/@!{ջZ>oXAe1]x-즨: Q.ԈHat_֬1 6F9hվ>#e2ATxg 7A!E *\Br x %E\yrr5P͝cr_2j3_l9TrSHͤCMcJ A: FzMP0qƠY՞D(|yEϧA@ëg9qto]A}4Zr9 *Q"Ls_|oc+'-jCaXb쫨ݿBCjzvpгQ\g஀qR7|͝?Ee g [F}O1D}NmC2 ˶b)5 viW xOzn6иcoyyϢqUwΞH}{i9Cg`1 ?=*yn iamZw:g=9^۩>؅y+=^eȕ^wv -22οs7=i#O?OD㸟{Ciex-4 2_L4M︛ѹS(4#D9,4˸S_5{YJ[$ x1ҪRZz(:/f};o/;[6ZUrƯKS L_Vt(fz-c1X=~ qQ^T\TqO0Ma)#\P5INP(!t٫=h܄X>_p˸[ߕ3d'f^gqAgp m^qcY>7#Cr4/sS(j])ՙu:s]] P\{1z@~^-FEuu>ϫCbmr&4v 6o7 z +]QsuAr^Ņ_Q }J팺V ٽ&bb 5ފ$T+]su's)cac53Bt0.+?3g?q٣7ROs/qDثyZTrܯ'GO;6-0F6M#ǼJKɘC ^ƾGxB'%Wfg/a͞D55ѕ[ߣ6 Ycc/ZF~rBI݄BuHRFZ) [5VkVZ a%Kښ8v@goE|Urrj>`ֶL H ^!b7ɿOSGw[Q_1{uyv9s>EӰmP-\"]K}(0s]xP0/(–ZہLɳ{ƧM.$CA$Lqam ;pwqq&l(Rsvh-mv _!X~taAm_MANn^4t3|+P ߀#dP#2~]#π/HOck>wB$ECI'3HTd ʪ(7ɕ*Iaű%ҫF5 *J*igH5PV+,@hHV:k;-:J4h|F,ob2c#0rw{6oW,Qxl>a}dq΍]wCJ ؕR%"M mRUP΀ ɀY< }FkҠqގƹS)+'aW |VS(-,tt1.@1likXj 'Ka~Am%i2_^a찻6bRh,=*Tulի\E/33bJc#DWg}Yfib^JK-NpP &ڢ"IwOFI{x\zR>qI[3@(Yal oj2=~%ty5vSm-Bk H'4 Wˆ|2/7+:oPAa\jRFdPoјuwj%` @;? ,`SJ mH3x`Y .׿:Jk܂ A3ߵ_vZE POP}kXPd=kq0$Ya{B ~I 5@^Ʀf -'w(& _( uHIP,?~ZH".S  mt$Đac=פpc40-3ԫ+H& M TXEe%f7/`0?]t@s_Qb Hn7J9 ߌۅ|vn'?Ec T_,!^yU= 7?˜ ol|9D{ 00$U{  ){g[4Q7Pf($R>) n'i02jwOEfb?x Qd>4f'F"69BqÖDQdlI[!x=޿IØPsS&jEFQXa6uYplN$t⩂W>3|<,/4Ў?C<^y+gYMOfr=`蚯uu:Z&tkX|NoctAMFsn[ ɩ 2qDB-'0A})Xͥ@h-s.i3vD(T&}C/dzXHid-{m/9D>D搏FV+!ឡL؇37qݞW 1Txz/d+Fl[gc.+c=,>pE}*!;9<,tR^/`oh>ه86tT-pg}%<Κ#hg8iqh)޿s4#i.NGK_ 80?;.8-ҳ]~=1X~)*õhڦ7pî?$ܭE>LZCAd _1~:*z/:)ZnMe87N,rP3NwbחR/3)LNL$LNAaQBU@zLU 1!FjT58RLкi閝;窠Z֫-u27&S--K:UP8as_'hm]NөɑYy= x^K5#|ŠJ@@"YMWc>4xbF#F>F k P"_dN.jԸbQgScM#;7RN##9P[h Gs]&P=dh xIcWa֨i LD R/c;.~EaYۘ SP,]!Z|?T>y'QK- |GRE^S)%VN J8'[sҞKj[ig[4%\Lp_fӑhzb{Z})v* '\qj͝;B$XK#c_d-AXuoK'z7u2bl0!g"Yj٬'\-{;Rr()[Z pް_uz>o[S]@ ""!cVV%?scn0fhTڞY6?k6ixcZ-:)[6W-uDݦ_Iv(N=ތ`.ȶ EtvGk=$ėl'8nFA/2R&uZcN՟`t-{C 6̺2Q4~I*g!*ψgZċg$abadBx$g'5i0Qj}ye|_5uMuN  f,S;'Y:Am{(c{|,A W* IIY'8/rJt|I&rϦasNm6sg4TgZkOyN0 lsr}HMc6#A -|-mvM`l{'ƾiM|`™yur'!9.>Dw4GPW-ar*t@.ڳ kw-׸'M@ڮxӹ!pZtk+V3?ppNo2ȟ$ǀ{sXNE%|U(s\OMɲ1gՑF=$x)F-nD72E6J0gWHxhfCMhde&_&!b_m- &yW5k肅-YKtsw5 ӒX`SZW1ZX9A&IbF&i?$eʢшD%OR\N J&G(xDbk ),8Z;BMMP.d7_aAܴ 2\S<+燈v[uhRw4+F*IK5NIV ~Gͬ\4kY,}Mr}=<6TEs?wilưǔ`n#i|xhv~"PG#>r $"EM +7/wr:h@0,7pV\IH!R\@Pot{.Բ`Pt@ls^4_s z֪y9OؓM, rV/P6G<'/bGμG#x5~Mbٹzԗ25tA'LVt^nDl _˦TVyWe﮽ 81&J([z7|hm %2Fo)NkjwlkOio4&Q5r;H=S;RxM2ʼ>0ԂiL4Z%;\2"LJScבܭH1uV yOK[Lׯ/{zG>'Dړf B:$UPnJQv(?qZ)V8k 4R#yVI V{gU:=hNjS [.(̶`@42nJd_rޛ0X*kumtn Ge߰xH|#lr gmc p5N(x3H161 5Fbrl8o../|M 6\"ܽ[xɆ E5ƒ*36pP]-k } ԩM"FFӳuvk:]Ioإ"6o|]uъ556n}lwSX|+j4.Om0}QڳfZG== >h siǂRp CML%v;3?Q:X T 7t62/i2j-J9SsHJIkZ (^}^SQ@=ۅݑQũs6۝iY%ThMgڡeZdX2=M($%q [nOx|da-ֆ4gvP;uR$zZJJ||ԭLrA.C{e#Lz >Qu||h@}wVo:dQ4?pq⋸F3P("n4i\ZlΣ֮uO]6 rRodV{MƧ0 4Hۻf"o gbTPl~|6u? slPBí~`q~ޯTµk!)* Eiڞ!ct^Hd WwiZw*⪘AQPo Ԃ+b;DSLǓ*x޹*qzi #\N W Dd':e\ 5A."H`SZZki紪rP|9%B9 1Q#L: rMC"<7bq'i:rho뱉` B:qZtƱ%Z $lF=aPBOp7zZc^3ղ׽BŇwYZ6kBÌx}` VpE 1S1jdp96 V49r>P oВm%V)nqL~6Hq Dn2UcP-\P;UeD:Ia$垰R;_Dn==#BEhP&-ЇP͒3Y!,D~1YC#Й$mjrX&ͽ^,\RJunJE\)ht+7 d2Jap/@T[dm 7ϑgO~7u=iOjf,E08R#i0}-o3;=7T:,pƬ;lO]yG[zӷdڂ[nJ$ Nަu%{ѩmt[5:+Jma)/ݫw{rD{B @VF *\e#וiֈUX`->5v,[*5^ HuFؔ^qp+|_R;A'^qG2M_7w5 ?Г(*r3}Œ'jZ$/ޒQ{ t{/6 F}tzynp;pA~qvT-'x1/$ח^Rw7F2KRFxflP9l ʘW=lZ_dMe!Zn#;k2A͙)Oޚm\H$2zERsζg ~v뮯t|G0@Eo_]`l6qoxVNr}-qs3QBIapddv0<Ƒ(w0 wĜv(u<-4il&v8b Ύ^OS?9t \T盾 ü=Vo(&Uf57\{=3\L\1#/5QH;$ [xm!W_< UAsȂB>,4ZU<.gcC̞}z)5v>JT&1I%vsjnJțIT67 pgXbiJn(u:6^rhu,̖߸\!n<_t'9?F8 Mr{\qWش6:4]|H-3} n`͌u1q/4Q9Z!.6xSP{)l7=ߑnJ/pɗ1g7υ|%@2{#0SǗSŬpyx,+Ck(ϵXLeo|g;p>9Z_+LDgC&H ry5*ΞF)NfטϋVwZn>ww,5-@6탷Ԯ% 7itdzl'>u|SxGQuQ>//'/b^;˼KG4o3jޯBw(?Igd=&ɂ+7Wm>B4$>M.6Q/4i&҆;v+hE5%l:>a)gFzhW .tcK;ĥYx;407>L"9-ǶIwp6{噑EO,L3Խ+{ս[+=n]TgQouU뒑c=1I~l3d}=~(0ywD=Y ޻ =$<"kCxql^ϵF穊*xl:.=DBstyɱh9BwDd U ]ҢU:nn/QI?:$i?ҫUCrhMNp羧S @bj e Ct rtUt9Lh teQ# 9myogۺ<16G,K/"\(i.??Ly(]%rO47W9ǾJƹr_k=~#H8 jzÃkpNJ.lXm X_q-vp6}|_ 7Uå'TCm~N0wz,o鿒RTdj}3+o] ~ y 3*;7@6iNs Gr!CU 9Щ2kRBwNAl=9). O.9Ve2a<gHo->+w9oPXޚPsMk!$B8C6.($*6]hNTkK%b87%KNzwڔzv"Mjij'|D[hGf&"8h*slb䒮]tK(ڼs佐Fsi=~~*yYĂlaj{OqlymZugw[D ]-f =X?K:U* dItCAr.e:fi`rx͖c:Sš&/ס D"J@:n4C9C9_/CBk /4>:??֞,޶Ld V !.~*аۮ)>ݕU  Tg" uJB:( {! JH !gEzS Ӈ> pB&;p{K!=C5".5rBoѯ387V5qt5nBƳ|.@~@o?nk׀J߃r)#"1qƻݓU6c27hć\cS-WS'Fc^\h&՞T*3UԯJڭZQV6xĔDϼM(Vr., ]9ʪ53[֍٠d.9)urBmd/78"$SցJrcGfᱺF޷%QeXh/Xx”Fjdvټ_wѕ*$i_n85J2uYܐE L1CXXʟ-7?kOſκCjZ{Mi1k@yz2 ֨QkggZh") zFd.!ТzIw}`c jS>盂f7 a&[^[bXs)=pZ+!D|©F~Jx Ng)N6Sx pzK7$vbR|BV"3楪+@WЌxUH/-Ynm{E^!olܢ3=[-Y˚qm3+L뙦-w\4Վn`bgڹx38O^1Uw<3c 4Gw*!L9R#h݀|>szOb7:7olfyD^M]&ME¦أ\SG>}mv)Q ,[xKQP< xɪFz܁8^3>S<{gl6/] 5J::e2*b-({C>CR4ӌN]8f& ,Z,:D;UjKoJQhPRҭį! R-y= F~eKa>T_!"Y_QLAB<2I@Ixz*w~ޅtI9"Ú"Psn,WM׭0-hY'h2{T= 3`Ԋ,}<ţNښقᯠ"9Rh7rF%5 fpc2$7CL8>;ϫЧmaw4*!lmE{YM1\21d-5CJ٭]w!zjZд-"Rټ%**S# ;v#RHwLT/U}|1YIX /Mmߵ|VF>8Ӱd0,>O4s/cB %Ji#r¶(xu5t'&JZci}\g0!f,j~26d_&٢ }d)l=^!jɡc7EbB)(K8Vs|lK ڡs.&86P o9^e>Ap cxf9͓!oz`1KeUĩ7pXBз'mxc?{6@W^o&}]$#_:ܬ\j6y9pЦ''Ek^.1,k 9lQ|`b|,hv>-gY\$ߤjGq-6Or6mٴCǠPyI3roALpi練ZN_=~_ i F _4@iYU4mHtݡD٤a}mȗ[EC||Y4}ɭU^kМ?F]\nڣO3lxTP޷qA8.o|7[U%ϳZt6zƽUCF+zݕ-/0&V]z+B^ee&C]g;/佮C]o, r:H*rL,s(<'*̖ E˹fV 'E ^܅¦>R P&*衒!|Ԡ6 ]zr|VUR8eXxWJJ216|OiJ'%B,d+Je1KIf y<ț&tcL.kT䟙aoU%-2%yLQ97ep?RN+q:yي0y>;2!3@_ TQgfD57Sr*B 擟G3爛':(7[LTf so(R8-7"Ē^?. 5ɳ`ا'R/pQ[r1B3&ZJ6`(=UV(re 6 /DZ*khWz.eE(kZD{4`xTO:Ǧ˒dh:UMAC능qkE}ٌv8nuŦt>R(D|& V,|k}ɎzCk]ܟToبqYl#vm(oL~3 3tYdJ蓘 ,KΈ֪v-7LDyjh*3e0evTXErY9R ƎF&Yru^qgcb{@S A٢G6ujCiog|)fk1SRb@]P9;T0SkD%hG7 2]rnPSTDbh8ǥFݔI{x,..0] J4\J*s˘<k *O`wP|Y~SDQBʠRe|ȇ4qCmYh[.F/e MG`x F@SHc`Qp9vns bw K ))K5Go xLxn7H"I㞣2_kH(9U<~n\ݣqa5͑荴;E7u @1Cuo%,:>BRaYHń@и]jxph9mg}pYx1#PdAQc*ȟzA)㄀; ~^ښ,=@H3(幷epŽ] n v}XW΢ dͲeg_fpSdtF# S S^,=f}GUVi6AIt13e[W-ݱ{bI}&Q/|:kOXˎ%֌3%!l;{#7yvfb3ܟ Z \zЂUqOqUxdc8?ÝSʁ4itPN'_xȱA׏^޳7>z\(<: 3 g\Xp{5Q&`l w,2z 2xc~,԰vuW( Ev{# 1..?+vL-Ӱ Rޝw]u+S"T-/\8;MkI%ӣ(#a5iS;dL:Yƶ]ܼԦ(bзçMRX#C_Yk1Mj`֡ߎZ)[" 7;HrM~Ut&Qդնn8ST]B "i{^ΰE;}%,oЇ5/Apc^Dta{ߓf3ժkEbF&A=-҉kBc؏ZI[ qsʪd$fv遳~`>E I̺UX5l>{Oo# WA9s]1>Q  osR0F~) 3^AYsj& ?oUYUA; .X}Tl!Pīd*UJ )(Z)5 s9 1D*UcT&-/TMo!c4c穱cHUmsxu ൥KT1DC,Jo#NqRʏ}kqڍ_wwpدң޷/b`qs3J+ *wR@&=1n(_[qJSqpvh0ː)w-@cWdЯ\S֌%zԔ"1-K ϒ;1УLjKCI=uGFRXnh7oS^A`5CS.;qmF\Ξ [{ѓ5ŕ}?juE{hE6Z+j16ksa&g:; \n"0;T'&+}8a‚;ҡ/qw nޙ*TӤ"ʤFAU$['f S)Bqףb_^ʇ?C9tV);JL ,_.(z=b3y+3}ѰP \/zcvhĕ:y6=umM}ɧ8zVk(x +we2\.F*}쀫WMϜgx5j,5gfslq" M?wPՐڳ((~:ې0RO9z'A& 'o5FҮq*z︯V7y3\J3-,}[g:F d7R21+ kE2Tf0J,_'WrOPD­TȤ}Q̓YQ36xYaF1VYL}՜ 1ǣiQ%r+.#I]_8NL|z)Χo"C5"6̧t`%&L?W}_qE>\=N$g\RʭzT;I2\pڢ5kJ?_meV1Mgwpu;aMO5|8鷜?a?-F\񝼮r25 '%8R\kTE╬Gr9//弊 3Q]za)oaf}R[AUQ 5%筅Y ΂59&f >bs~ 5rppnA )TzbYM[QsYӣRhYl^]7xM$ sLSS΀+|uL)8j|P2%=TQ]eM~KxdCE]7:w\J~"i8KusfnrYNgko}x&ʂ<~ }k)0E3#ceQYG^y2gCC~hY;B9jfL!rǫ.*H_Ys47Ng`2י>#ƲPP1?&kRE\;" %%-ǟzzax:E5E:7/x]ٓ}*άr7LߺMюEtrFEw_s N^pVk_A㟨2]t`Vks*v?:tt&v|fC1su|h6PѰkf1â3,DF9:cZm&`ov'K] {݈ݒָ;f*,J}>N1YxovK q7=/EurHJ<48J\5^m]3c-;%;(kc轛C.aV/E!q.7(ļBʦ* 7\^wc qo,R@4(]gRSw}dU0@;sQ`hHq)Mp ψgut:t˙HPr{բ]~TXYJTl C2K9ЮRz$D^O񎣴A?'Ӫ!o*I$Rt[Eg#7>J'%=`)cS:hh75mnkp"d艞f(@Z(;Z%X_s s3|{0jcw(onv .^͎a^}߄t25lg#N3'1 DržzWt宭 ';_R?q\TDUQo߽@46Q`7[#!0N'43 Sqǵd%I=T3xQ%N j|a`dϸL*tdX`4pU"b bF{jW:G#fd#L],sYa52gӌGmL`07ÝrNp"a &6F~c%:y{r'ش̍1g<PImF9K=` >aW-,6Hmol`^CL.i3AeeD̘eR(:ĕ&3,(Y&iXјoa`:#ߪ2L&߸Old !$ʄх A15`RGvݫV1k~x޶Z yD|p86|__G:kmxΘ4TZcֵ/*X2moal+DŽA^ ų"]=PlF-n6_%RAp$h+3oL 8j Ě}pgϠ[c2`-Q5|a̟(>1\?8џ~P"ÅL0EDj67YDa yF<)!0%&KᲐKN|26 ,Xn͜@ RO9b'\7ޣ#=cqYW;: A#'49Fe ;ŝM ǘd~:Y}*^y^ _{L$eOg66;s08P4 t1<%Aiҩ%gA;?F~ Zg7j g\OoֺWR΍آp<㖑&Y&46t!]?cǶ1GϏ’˜a`GYDДeS7X+`ox@XMTtEG/'7^u- Z}r?P}eLOhÁ5ǟ…+ŻۧVwW<>_m{姥#3K1v<2P+<%Gy (ܾ0,30,g|y%%vlf.%$Y@Ϲ1-x7Oϱc416 ̶9O6\EҺ-##q2qDLjb&IR p"/wu+DNȾ84&Fm$.㭈Yό+.Rj]CC`L!&à)X>}L& Hw#&#$D?u}b͊1hs׮|(2d"۷[m չ9bp%¿A7g'H3Crg `R)Fesn^N C)Uk2H^Ĕ2Jl1WTRZ?5T֩ӄ1ŸHwosb#ދ}> Rq?~],G |Yfaz,{C~6p2K%C_jkY%\ʱ\a&73YrJH)3H/dԻٌ!38ӻ 4iH{sk: u#oܢW|O8-D 䩞!Uu pzׯ)I&hKDm $5kL_N?ǒ%qS?eUVJǑl?y!wa*g2qFl d$,:aaA`SMBgm_z(=0_#Å QO{ʕ O9(R+ӵ3\+w&R*H.ظel?H%~å9Hb!&0% "zR;[@h56BY㺕+QbcHkfA+⋏qwF{pA!*CD%qY+9cs> 11o9 K7z t5r,f۴A*p,yMya!˼BY67]%sڄS#;:[ YYljr"SN9VjKZ2#i2./W~'MkbǗ 46ZBD 6+Zr%tWz#BE }]c;c?i|9%vb|.5\Sp|mE{d]b- ?4c1t[3`1c<.(%ToYx['pc"   [8} s]^.^W+ïzYh? ><[)pi"ƆhA5Sݙԫ6>O䎩0si߲ޝXgeK / ֲssTfC&i$VhÞTgsɞMטOmgok!s) bZ =rUְztkOL廂7|۾vˏ'?דP_iZ1DVDVlMFʸ p: }MA5.C.s`CE}+oq>ĘLb ӒVx`/K{&*355l# G2O8C鸥o|V1'pF3N?cpWu FDdE]Rܪi}_bO]޽wE՗9x&^}yFÚ1ЩzUOSٶmn"4+[Ҡ8[kUM M9/ *BJٷg*hWP )z7m9y`rIeZrL3`e*h ųp}_{8!0=fxJP}{qgb)lM Y཯4lEbҠcb3lmD9/.z|nM;y8&Vs#Z" yP1IQ{y;&C0_^QjbW+^$_m#ſcl߽NH>{^bp?'?XbYF/ߴ+PoڱJҞOݺ1DrmLƺЩR*hD6p|7]ZVoXua8a $vXX=g9y^|ؚ1gwrԙ-fxMU'wvss6{3%}Ye\ԬDgyurUU.2 oK87}svs[M@C͎s<+\?uϝC8/]T9|+kϜ IMXǪ'B_>GWdT3tF4#pif+oYƵ8c7>|Fgg#BQy:td3ܚ{L\n߳8wIUbM84)l,&umX{K) {Оs]{͉iUA%2(7!u拿it޴k>]U}SO^5yѡ#Y\׭ݰ0@ᾚW}j9ĪE={pj@I/ygJ2V(TL љ/ N&#=$P/ԫzrN]]ݕ;ǙI=a"3 $GE1b""f5k`MʊaE}'o^w{=;{n9|ŪhUᣜ҉Sʴz`2B]@={q. Ukڷ잁yk Hի]ڭ[^>q<3@B_"\W}"K} 0.otٺziAjcJWt,8x`9Ժt|襍*yrYe"1A{6kk_l.JkojWlJk{wNKN4oTxA{vnDžѝ3Jw$bEMn6%eI/ȻmtgKhuu7]wv[=r+!wwj=/?H~8?{9S^z3q^`||q3i!θ&ԯ])`ݥez[ܡhIl~;ׯGy"˦1[q. ~w18k/o` 2jHgO\7YC7-=u;Z>rzftQ]ڪ{Él'· cY}ѷcǷoػv| J 孻*֟{7swwzwOI3߽;sرX;vdbO !?z%2r2x2?c'ע$w4+MR5k6GW3[L?:gW Wݼ;Ź(%x׬_6a .x+O]pLgJmu8ejqL=c'ۈ5U#|7|+M#FK\'<#w.B Wg>G;crxꞭSl|[D̉6O=^-8裑]>Hmp&=3ZZF99%С^o}ۆ|c|ֽ<ObMۦˠ+dǒ+x]dnm/yK8sfÑ`)VxU$iFVH:<@8<O\dN%_ ! @+N=|~Xed8vP-wtHߚRB.ǧ_\EOx Ƴjgֻn)18Q މt|=sW/px%kFTc$'CWrq}D*0H[{# `ry6o '?e/tSRmU3u!ͅוOGu}(S|?"zp rzN'7M{O_^NGBի5ޞVb=W"te1/p0mQxx3B]]uw\ވq:wkN\KL=ܓy19/I8{?/疱Щ~={_GOE3+hRphGԏ\|2[8(Y3Z^}kpn5ߗLY[k[暣_Z82vO3O.LNCFxџIIwUU5k-kvL::[7 7oM7=#MHOݼJEJKd6V&9qJԊFVd|8_yBoOGF!fO;h!AEbk}/;8vJd:w@:WrS/qe9l] پy} 6;A#[rog=H7q&Vf6uJCI 򆾨 .n_sѪ^0}cO0z xGl-`1+LY z2=ÉToix(P/ݼCg`}Ḙ/nkm'j,4|>\No}׽63Gok״hxҳW:9a-׳u Z dzYX qwaLgBm| ߞHe-OP+e;ߐ>iC4x/_6Z{mUi#`3e t`N7.=/F5x"}~E Y{?w) =į/rN-b8o8]9OW׬GCA񁱗@m}h ā yp:LnNrԶ(|Gs—8i.i09=6PH3u\u$՜}P倕l}-~{LM nHlC^O.7. &@U_Y\)}weK{&׽ؐ3{^sv {(n2o:/6>} ncQ+:C4yX~*:;֝pMnMSIdB3ȖY׽j(ƛ_pEOXw2x ) m%4 p, >lƌ2ӆ2KύxC<0ɭ ͪ~k 5༆|ҿQI+ϯ"Ĥ$∍%ӈ)t@鼦bUAKReyw~po\.˅`r}"6x)n5ԨRydyN, DHA1l&t0,CaLcwR!e;99Ÿ_:"~r"qz+c3 ďv*b7]xrQ]?8Bbm7sʍ 4ki,|ސ.yn! :d[|( K+X_u?OZr/aʟl2cc;|W,$v*nMt·/kF}SYvrEm4*lfABctfd$`o?3i_}GĮ Cs#O@T7jgͿyZxKר${!xۮ7n>]/_8cWǕSW]`VSJWO§AT+J4eۃ7OC z4*t mط:VbVffhyN= ɯ~2~Okf: ^'m˳#gF 1b]maFv]Jߣb,41c 7pʉAn1ˤfnnU+C+qlںP 42d821w%3;(i% =.h)oMwyIlyN8{s!<2GvޫvƋAj,<~kvtIW.OpA^тtσ|&WJz}yU9w[/L.#S_Hib⍗_n|h&^,%HzgvDs}FVB߶>!*tG--XZ#^,pkmxr^ ;_[10 Nt5m6аT&`( 7d `4S+My/wt^ eɜ`FEѣ:z [#VNUsijj~ImrVg\^;>eV~o7\寕=H.Z34%zFGTcG$Oo]'4}̐u$i}(%AYN22//E(X(؋=N C#q>PWZ>> 0.yIjc|RBBS:(mS1]>2c@n4=1UD5- e5Z(FTwFsL7:n8J>!HhZ7/9AhxNjk5VDsU5J]Lxhv3 ͏uo [k W\4|\G"ѕVEi;}u{ {4ޟ"^oWS<9J)/ T:W9X9%l.ď~'}?j>\ki]>.^?'z{Rv}*kuqf Y̥;}x)F82Eq4TR%ayI?VSl"@#1Nzj+Q$޾5,74B*zE?Y'CNE!2Ck?!]0\gHxYy'!q}/ ^_/>_o/nVXkGlmu3u e% 4г,39u6FI; .j@] v"Tn:~ꁺNk<zt;-Etx/[GtGw;Xh)x`=QEԖߗLzD9_{h9'=Ϡ=u@E4 u3>0@AѳBYu=g pT=nq6ioָ8t\ FQVLljk`<;וT6?M')j?xa!v\4~~CƯ缄_7~o OߘYfOjuSjCIY?n_<.+IJixz\7^p{ҫg L' zaP u;|{vaG.vExiF2h d l(b(P,:4LPMiEr,E5|АxF3ئ2Z,0v =/'ڗ!>of~f }B(5m#1^1~FĨZ)qQtM6f!5͇f98-2~"8[M}"-@S[ZσK_3KDq.S,нf{~e#g|aMŖPo9Ƶj`Kx?9K#J0EN.5NLЊH bt.ay]reYrE7{2QX S\ q$8G @*t+"(_ 9h4(0* A2L|Ч8@Vc]n[|zIάIX{ K| Ft rn=asu ޓDkD%3 xzyK:7eָ F 2.3L]5ڭ8U/*p;h k di/^n-F/ *_q=s)C8i*[g8R[7ܗ W?XYQWJ~&K*LfBm=d.Ԯu eQRI|6D0fNW;'eHq8C `)Ҵɖ>YW1?e C@\)#'EL[;L_4 `@G -Is,ѧīA()E$@˽75&G2,C\}x(yB VO# U++և HM{>aߣ>gy+Ia4U@U#iZ>8r`okd,樳D?e  ZuWBEQ6/oL ߖ [V %25T:P 1@By3D\10\ _m K˦j˃1Cd W/K`O0q`ĔZq "{X3)Y$(^h0oiU[E4DIj=݄5.5R/L޵:ƤEs8Ƒ# F{>SFsIZoKjv5JC9j[xwP,}K' 埨˲B!s;gXdk!qO!T)&E H[c8 S8fa*G4Oyųvn[}@Rʆr. D{έ cG {'0&j-.0?դljcZukU??Z]Zɸ_yƋ )T_jz-BSJL) o= &R]&X1SbaM3k$AAe 3M97nɲw_mN `j@2h "Ȋ#r'Tɻ1pi׋HS]($|mfS&%=>B^4ⲿJ=0yJCqjґ AG?|Yg g aYu[ (.@X|-f zED}[^u,RǁgD}7Ë /i9ВJ Kv̾e( f'Ǹp"ZmUW =4ؽT9 w3kwfe̚ @vKқo7~fSyEU`..:&@`[Z,NGSCjw(lwgCbO,.QWd7L ""՜οNPP9.̷$Z7-'~Kob )QTՒחV=R('zVɹ!Ξ 4qsL5BJL # ~Ê7O9ʞa)+٫|<=N^~OeMKV f38e_PP^Y: vH2`>qeBѯM%tjK;X`z9k z1XzZIgz?qߗ#pPB= ˙uܸro9)faL6e2A[[r E47Z:3yg|9o*BCre2-?D"HGc,:B D[{0z. ^* 6%(i=m\硨0"@ɖg%9YMe,,y3>Gr "r 4Ir^e7cZ?a.<7\P7`"K\!{-!)˜i?(e J˅*7UQ7('RJP@Gpq$s˵1^ M$9NcJk5A DТF#h2ǧZ$n&tdr#lZ`K0֫+&VO D𛡢h66d=7_K!-yDi=/Ep 4#y`“NW୧z&ʙ!>ߡ1g\ J~ O#`f'}>rl1͚,rD>!iĻBfTre\y U>y6öܒ=/HRQBҡ.Nn 9|_ 3֟q,4.') !bw!噰UI5@~C+DD<գ %qa:܃ 6"o<T9Hl$$ << Oq==-Ϡ0"Dٹnf2 rrYָ:yC]yfnAf&C^73Ed5n6{8׾ECn!R =nI(HĶ4u A%7ڿuF0JmX$f4HW,pkoV/0V[єN)âPgf:ڽ%Y_ijvդ;OZ _ym8};w4gꑤ? LM7P=_V,E?WffKXXqgE)5.7Sfo$Һ) $s[Q&Bh9 eMa>&x^S<{;\|$YR.ਞ'5пShY捸?ﲵ=$@ȾjZyu{O>D@_s @on??BϿFݨgH-\M!Oldo&O8暙Z2vl-Z l=SDe9+ h4l M,2ppp^&Z׾ĐOC|.GnC\ok}1 #M3|zTl6l6M7e|llfGE16v.56.Y P: s#$" `O*/1p zMn=S_%٪V 7_> ҏDw{-+h]gߑNX@ CpIo+!EV壽E.A/qM& QڲHEu@C3TO2p/ԍ3x̆>6և>i`,GZj6oD춠/\K7Uj&j[}^v~,*@7Djn,7cճi 7k?-_9~-پ.h0O Z9Mk08X'wmۢ>\qɂB/mv6,\ԥ՗S@z}de2rh!:#+}VKK$[MrG ͮ)xfk'Wi`gx|h|IתQUsF\GNq\N4:cc=K;ѻmoj'ǀ+.ک;p}]eٰA? MIo:kFwv]|y›MgL${+Gں; `w^ݰfVztn횣+G߼fhi{,GdwWPڠLڃʚ2깠>yWy`[ eGk`q`~_]9#(N^*ɺ}ƥGN eրT.گrm}ZQݶ d+['Ս;ͫ AafV쁘u߿+9:Y" *: JN#\a)"؇1A3Ti||G*ɑ-EJasջ34EfzJjmxs;>0;k. fpS& vv|*C.p]qű d Ǟ3op‰Ǵ\=幍axl|LJ׿>jѳ/~a(3t_~aSU ʣ[kvW [qQ|^ાƴu~;dksg4ym`kN'lHL#'FN?l ̕GQӓĭSG*5 >1pG֕*zѿW~ *e:Np"Ľ#;nݽ! :n;JOQ-3W'$9n8#jq&|!x 0HDŕ'orhpQJ÷~ `g@Op7B352>YU}Zqc;θOզ> jX˥,>nWV{|suMiXR9@$ )d:4Oq4t<.GD{q^XL7g^c4:GR%̖z^a/xF]vQ+GT=fL >E\5$Snh"GB 0Cdj/I{)- ūd, |#?xpd+qp֐~]oKe}r(5@m=fĄyڠ\_]϶qtl`a/<>\-X>֣x,~lm ljwRAKL_\U Ki&;_dEt٨"Wκ[ߌ ػ wn"RO.d?מ!:[ÕͽÞT$~OQQ-~+Tv^dz<^Ce+/.U"̽Z4߀G<pI>ma #C 5ޕ2HWm[厨*%|,*'pTtoX%_˾$r JGy2Fh>); 5]7{LK-֑cV J/*3s/ M^||x:l.+<*.H }>vT'>B(n tDh߯frXw\0ja}fǦ-pZM M.vb]_[w]@Գpk$ۚ;G/OG)٥ȕSv4S6`kf3"Xy_ ͩ!J_%ݹz_ +"$\g_w=NlaƩp\( Zj4Fԋ@|02"MvGp{'Ek; %L|8 z{c=LiR9!GԲRz.cKZSH/HΉPĭDZ/u]'ix94' ~zfdu&''yxE?B_vcXqLz_wr<7+C_'$c26VRc\ hC5:zo' Bţ#7W*JeKapw(ѨX*p粄qrm_9X=։Ojj/~džJEMf&*tK(|Wu8dN^ w޲Ϲ". ?.1Eh4B}\8c\`YqY1|5Ig;6C^n2+\H*`,/хcXHJb,fL6(s1rCL 6CR(+o4fŤG $US!Y RK/+U mXR|R5cjk鹌G?s;aL\h׺[Vج79LߨEpH{4@7-Ht2- kqqKVT_|6BO*#ȼ4oHzFg+E-$ROHl86 Jt$ T>"eo(fsI.ĻmIA;wE]i HΫcTr0(5x IrUYrB gWod#ŧilxN-OoR9NfE [_0_Ĕ7,o u苤W<[(d6-4/cqGkv/&$IzDlZle ?}"F{#{d<0 |B 0CX%~REI69$AqYG\תO(>wSU RadqœU [HkOvZb2^30J@Nkrv9T\- i ٭5}Q{jH IFiI}"iEC@*P4uMЌP䚾:#\Iu!'ul?!`SϛP@\447 KSAx h> +(UX3=n~zkT={kG8w<%Mzϛ d6#lψ" 4˃T( w>WYqTUxc׺u0C x(Z˜W?`XpTʂ8=*GTQʂ1s{O8ȇc )!624ծkܹWr[46 R9(,¦ڃ[YCVMx٩=zi(Q6-!A)ho.zZeYci/U Iy1 ӍT~2DNJnMK0 h7bWA㉣+pn쎋@IBQ>Nr#PhX@ѷ@Y|2 X,f8=/ fHɲ+ K oXLλ#PbX@тsDyS Yɲ^~u X&)dW6c&{KmvuٰS}WSTQv؆m\#+h}lCBOEJV\;:%M[jY^5U fQPm榎)o8F25 H-Yޯ&dFn@ aW: +?HSVEsGFY& 9_MMX!32R <|Dfˆ?B0w pUQidIJHҒ?E3LpF1e&Rad:$+FQ:xgK(Cͮw}YNv^ L~ߎ٘Ohl8`nqF9 g'P} R a ;(ba!#[ XÏX<9gX:D`ͺn`/EƵQmYB`ڛgCON nrK&AH9J'w_7[8>Kh;'@tm&7|?J.j6>2cP&E<[6p?=i+tgBğtR2 Erl9-~;_};xv ]b҅qxgUzD1 Ly+L{|α%&kjޗo,^30OR;qj$ke*msn踞2uތ)'.DZ6ʦNccy&^EurqΏW.XA%= L* GyECtzW~qpE 9LpS'>jyMl3dȅ@աDtte3 Mb嘈r:RRz鷕Yjpz gDܯ^a{6טhg`B2  ho}܄G=:!fDp}$ɖwCcKy{p1Zh{8I^UU]U]Suwuig{A*FHH6&acg=6?l0`㈱,0h{~Vu̮?F=U{99M'A$/E|̴X-ʰV W SI/$/0 x%Di93նA? w]ǯcֹ ,3qOoA2VeU}{gNr渇)$_şn$}=+66D1.D|1]SίRN6û7gLq|17B85xN&W&&P >slb e|S"Va_m D2uQDvYVC?q'zŕM"rߢ /{F9:%^5{X >ff񝹝P,M@,>=gJ pOIR<˯Kӌ/e¥Qh cq1 兹U7;1W::8MP^ϓjih&^K@[!D>Jx:=A0m; Ăs?KI ڲVަ h;gy3{ytãC=RƝьtiԙ_'9\ӏ@1:ǒ*ǥ噒 b4/Δ^ũMR& 'GƇ^BTϋ0"Zox-2jbě%ǓI!]p4+37 oOE0Ce%%)ӵhr͔9 tn$֛D#4Xdl[C,1nER)X*­9P gZisCcX/LFJlf3 j<^ 1$iBNӛnL!bz:!!c-zYotnhGAw否|nxl瘟sxŠl`7Km}x0WhD#9lfQā1Cg;j»4z]cAj7I#e!/vCAY14Gqg8x;R6,C WZ($zkyPғ18\ǐc)E]B+$.KkGVK ;O<Pd[鰱roj)DžA4kfAc[# i__vhzh|84˒s<{oLQ4=H"H!)!)<D ޅNkh_$:)6y9 ] /F`G~ Um1WQMŌ1c+ &4jz:u9p5˪?b1+ގ;O`f;`}Z3%HZ %ȇNıo -"=7b m@ݻkId6o"gobKW)zp${!(&ɱA2_O6G|3灅1P "o\ռE_Fr@; 8U ɡ|qp h ]q&pY˸\]#bMѦ #ldQӷaw njaxbi~M]ߤ',.o6Q'{.?wm _^jǝ˗q塠0SЀ_  o-!ph+JP? &C;'q"|q4y1 lF҈;)+x?G%ͷ0vǍ"5\lœ _ (3vQ M~K q[r^tvUt1Ȳ!uz)P,A&Bv =ӥd4Nbc,K gG۔c()ۼw'wc^ZXϊ^JB$>jJ i/` f9:XTʙ_q@yGyȤ=)w|2Q.̘S! ȉЎ =y[al%ԂtWpcTQUX0 H8voEǴ`|%Y XvC n^.`x/bć1_J=K< NG;tCos%nqKtxlso A{N<၊T#BH ޴RJ#~k7"rL秉 Dxp9w1 YvmKѺ]apjkC&B&4 vHfwbNGmi&Hz#2\NWc'r*wOro}Vod̃褗ź>_NTݴh&^tĮ0wF\|)8A#z|;s9w?a^cxfs`7!WTx#ro^!qGl 6*7}@7(Q͹ *׽[[Dt;m aM3ۀaY,UGقnf{;BiAR䭙8=2. ߘ6Gv(α5 WÚa9l/#at}EY!a´ɘ?96@618v7h_pm7t75KPzn GD a==H Y4B|r:?A k^Kar= ½ۏ\'-sF2:{ظøoO" MN9~rd/i1׆YCӎ0yf!Vi<2kƎ̎4%XFtcIMdM|vql?x*${' 5a&HA\WmMNJ_.v [/ЁWCS㻾z ;N6Bm=BH?IK-of s,ȵvަGa5'ZfRѭnoߦL=frc8!B&FzWi6d`W ONϔ gD )ͧ#i掴{rO$Û+e[dAȿXY=/(}={{/9E7hذ*ē]ي~"izAz0$Ly IS|Ͻ Jŀ-7ɱ"`HoG E F.+Z^7;jʻưF$'{[ qLn2h*";>r?Izo>mvؾeu{g͟L I]\Y=3 ZH~P4f^iCp,;pb1vËǸ(zχUrŐDnB8qI]__]4ڵwtUTx0?WEAN<Ke13N. $326l}ݣhst|2^`",x"1 G{"N>\#Ah2ʗ-k2r/gO5q^!gh&/!EdA2Oz=bvmy|V\5O N85\ K-5Ʉu"QxiWűܡv(_$NtZо|Y/=Kc錻{<*xd0R|E,#غ*訣xw5PTmhEJcٝxxKQ(շdp?&KNEkB:I|iZQi&G2j 5Sw]@̓#Jfܤ){bG0اI88Ρ_& 9r粶b߰y~ۍ]mAYN'n9<rw=ثnNRF/5ӵB|| &Ylz-ty䩍(^ƌ˷}IkJZ*v7stwO [z5d[}|;4ev8lʑ#We w[&^%UPL\i%B=Ϻuh]1g[ЉQءfrۉyP|>#%"7K)<=]&";C ܂sz}VŌf_cA=m; Řӏr K *Bw}!I<|FNzr-elƬ7?,;ٙNP>g25l>gT [3eWL/n=A5 2DV/:crzy:y;߿,qz#6*5ՁR"qe`$Kl- Dϋs K1daX-(=[J*e޽漛RbcC9Wѹƭ6mb"㔐M! L»vgs݉2zclcvfVӺvafDkc<zY@A&Eǫ)e@WMTķ>~._nˠ]QgÞMs;sģg2*iOУ ;a8NӜ[0aIёWOn\: )yI9/oIKQN (],#Deu}ɚ!@9v؃&mr~@䃑l|#cKqKsznNWz-7IchȎQÚp' $q=WlXfuͮN)@LQ;J^a#e 5̵މߘzgDTN_z8jkdoȵ&3t~מ"7WL( z|Hsj:O,%jovɋC0Dj$!t13"tmnZ|HL9Vy /;E$z AQbEd'(-Ͱ$z`HC=s|`} "kOϐ)3?xGiVrp~ }9w7;)EJ ĝfs{ u>'tŮAzfR"IdE.q%kz6]CF`A=0GucN$"?Ђ# xŽR#K2.yrwvmF㯹V ]#bԩxن>6^-rH?]?^ ?Ii`1ֵ9/L8<\+FUsxɮ)|/TSnD3YOcRfë|[ )ǴVse)\va9{g~N "bexGz'RBXOB(% 햼i@Fk u^g%RQ Yn@@ (C?+W 9FI&q+ |Э[Rh|~tX]Ffx$8E%"#FA;v}۱ժjluop4qCBar10M3BˀQJXfzPGRH żaT9GbZ\+Hp Iˀ!q3bQLgTJGyU6gi4% <~BR{:{4e}B>!S+ $y$;)*,ؗ-hOv[ {?;h[ ׆ pćE0[.f[fըF Bs+7iH ֊!RU#`4Ak_ jagW bRE J&TUզ|RBN{h>+R>* iYnZ4 xi.b9s5}^=! CxpVt_ L$%uA׏>=5>_hlĿy .q׃?wyqG+byޛ>FQZz?|cBfӘb7LEo:'s1u(F]r5 y3(S~JߚYKTHR]~ݐ{N[˩h2W r4MEs4ւM틏ʯlo =d2ST}ay'xNpv6  [ǣ+1>bM2A:froޒfN]5ۯcߏ mމ%uR n9ScF"tWj6|iZ~*ޕ'K#~)o@Cx"9EĐB7SL RQm)᫓$g`OlkSl+ O/(!qMi-dd۠fCg:5 ]ld UFN}tfzi) d=ŔT.Ofȕl+~È!cr8'vϩtλ Bf䝿u50_PJ [SH,opwbjE N{ilu46Il_В/͹)vo3w G <7Qҝsd'%sn"#G֯ob&͔2d_V˞⌈ m#l#~b{+қ-< rK+[-JΘ (-i(H2 ycG &$g K; 7 vl`23V7u6R&ݣOr(bp6\?ƽ΋OѽN8oocnxQ=ie3KS}])e ΅I,-u,7 d!vs[zb3#:9 H^Kۛ#cLfs ;GTYE֍>?%op>j\z/Sةpm~ok@/=7 ׂpJAO1amT]έ4}wuq1@ W qTvBwoߜ7k~?gՂwy.v?(o.Ae3yvΕ2.k&e%1mvu#5U0haSKŪi.]XHtPFzOpH2QMRJ5ozxqHLoۙT| >I"Rl; u,nnAv #yy'ɸ2$|>^"p$6/opWusT\^6H=Á,ow^9)bB-E RƁ=R!6s B!P89e*qvp(>-!IMREq^n,ڹWYӮٿw{.˓;{ 3D2-6I=Is\N3rBWX:doJ32w/ٽŚWX*FFug-;B$mp5)0n&)fb?s" ҥ~U'snl&Q;ӪH[RV0b?,`tOEr ^Z\%ܮ'6KMzmiWekKBnP\E=8'w8[rȗ:8VdZb}71nȂxL+ootQ r~" |Kk"MSNvԗ VO}6ovк6xsWTs|^*QhO{"ʰx43i nP`p}b&YmW|bYa+s8˞ְ[{6gdVX0>5)PYizo>[zU+t'cD/Y-嵰$~ +lw8δf'Jǁl-V[ ^]>XP#xx!%°^9[2n^$ҙʣ1 9+KvtbG˘:B,G$̀ܐ%Z 2r<'dn g>6=NȪ(=Lutp]h=f ͤ? $_$ n4ޭFa&3DA1ODc9aRKL%3O"?x".{FOOwtZ^![%nѢAJKŸ1M E=B( bv2zJ*̋ s0FZ s!S2jQ4,vҞv#H5Ε1]*&Kac. 3ۿԚ.{vc,{|DFS U)8ApztDre]f,Hg?r3gn\Ť*fM4:.W'ҝn4)/w?Zl\,hϤ <2y,-G .eKn1QBڝ'7جJr%6wo.XV! q6}0b%IZjS4CfY3ndZe R,Y+sC9Sh? t?'1q\Qǀ_sc}fFD9yb3UڝNm;Ps%!ZA\Ίeyܔ3X{4Tdg1oL<KG a. {]~rp %tB55.)wXR?EK`[? !񰬳!"h=!,K9Xr\"b#hm#SI2lS8p[>, &3jN$BU; hwܯ}rjm1X"$/Tn.aq[-̚ٷEި$B Fm y[jκ>IV!s[;[# c;IbJma##?QVG9-!qGF!c|=PFV)Fn$h\ޫ;+`"z:|5~Lחa$j$oٓinzj0yyW8H z2*uf0Ž%;qF0_jײNЋZo?-2Q9jN2̟xSNJk8C%ǻZv¶-&KIi&,nN܍ٚ*6 plaհ;:$h|'_ҋ|rmld+GhcOsz] lY!S[rm'ع&Z1em; iC8"OW|9W%m M0=af~]jZwn::(C&BcsZ\+_K_@2S;Nwts*Ǔn%V=ma/!0htKo>1\0GB~0Tnx8̀q_2kL /!"8IU5"m 4:>Hw|ƜxR_я^`c Q{p߿ ͫ%bu^KzzA-K@"z,h ٌO4qޝ;} >qHr3Jl}O(B*`؛I8ooN)w;Y=#$ _iKi Šy`?쟶`YOQT&3!g'vs)~>[|^zh UlHt~D0)cZftv<*DdEq j69/N9 k. ٸRrFT$ 2_nZSn5pU@_;V jT5@Wӆ p\ڗ鞝I'Gm?k{Y>B-&qD*n EM| ňHDSi<Mx/ Qe<#A R<-QC3qV0=c6ZG;Mv kN|8,u\P<&8$s' qz)֎3^^t O )'x5&_ wO!_&ݰ1 i5ӄyAM-8zwsYԹ[3Md=`4+Sx4F^;Dݵ?~Ue5LX_4+e4sc-P<`Dcj?I#'4x_aTCC;v&XOz@Xс^CCjS I"ReGYӡyX7#|8CPx(ƅxTaM]T7z顫RZWj9A{7ES":2B"U5Ȓ$E]lXǤo o#qXm>xVk~髬gpjޅ}DyUt,֙bZjxJsg 2\62v؎ !kEZ aq/8}%ZQx}L%ZaRijH Y.1g %^E*F$T[oϺ<`F2 mxAǷv;;j'_~;9vZlTէř>?2_g9CS˾ $D_ g9/^tH XKko|].`خ"6߂" UmkӍ c@Z;q5e o:-^u!LQ棡o;{/U"Vt8eoh N>U[R,,-z &j;1z&#)G ̈%Op::hFX!{~FѼ]M̢ӴUN$FLy-3vC&‘%Γ`E>O:w; α5" gND )rE$qUM53H_@h{DŞ%arGnVv6⏺ڳ?'Wwe. jJĻPLLnx:-W2 bVJ3m!LER{fJBy?|[w`T];ҫBNcxѦc9.B*Rf){c =?xL%E|Ak G҅pj'3/DЌ-gp'lJPeF-<+c_-"͋_2|` ȹF`p&bl@( +jMsd] v` F9l),*0)@qah ڦd=V(X:[%dHޝO޴&4'Xdic~>ak]cʙ@\N%N d8=xRpyn/g8VTH[NnE=Lٍ.z2lM3fk)Z E&4!D.raC@;Qg|1? 1L+^UtWqu 7tc;~SoOU}m}Mf:s܅3J tSk؇TPyľ(w\?ŵd,'K=9w׾ l,XJbwȟĊS|&Tp}[lgt[S lN5rˇ ":kB9EH93pDyjBV 9^oۉ=>?R9ĐӦ,%%^w^R qϮ0g#8Sqxp X .NO&M| JzFm'ü$=Z ñH2\#)8zG^65]$릘OFJ4Q/<Hx{gl^CLf2_Pp]Pn}Xuzh^wD0Y{2[cWL(Trp\JiS|ʥ&qSq*':?r9qSv vKJy>q)+ =RwEb d \apڮ鶷Aj8R3lVq3L0lpGe:GbWc3-⾜BRX <[cjǼj:!<쫅= KL8āک󧯲t9LOY!܉}fGw⨤aг%]v57&nL π; c~!eVӫQ]Lz~ ߱%|Z:n} M 0u{k?5z=BJ۳7Ȳpz{+Λ΍+͎y//M?2\N$E'/!gxImM#po6 ٞ0R;!i\kD4WK0+5oRW߰,ql pn\|ȘɕM.$yF㦧^pCUI_t"dLǴkWdԕ<1k.VSX<ù4ߜ,ΥR65 dϝqz~W`N#a15juڦ.Nύ%Cn2X^s1X5Tdcz4S3k}]`<Nsm{qǭd"!<l?^$lup4֌C}2=S196uCKbO>B x`X?}RB$< 2Np׃ lf}0SK<0܍"s4uEgw4lZ͙ TJ،wCsCphkd[2(ɳe^&3s83лg.,]WKHqvGoef9:|["X13S'g,,aǂw_z<->_ξ3xR+7 q&v4Bq@4`Fj5k lkkt+nP hK-]X3,NĊSU]$~[o$s.̼d܈-D.s$b|6A42H(hC󵝋}' tOC3s.JdDj\W[lϸ,ң^PVtޑ+#"H\^9w"zx~lp;_Y?νXEO"^ Af gRӼ 3P)ji5}c bi;zt⍙=$i#gʄ1_ҟ OdR7nɞ==b2Omh0{A^ܰXH?@g;K (|AKLk[%dDLn%n`|~-Ó@-5Ꝛf\գ0,2T^Y!aqQ,aI؝bb8^K1Sh3e@õv'=bԯ`FeL^zЦXC4nڕqٵDDƭ`oGnF"]h;ߕfc)ؑ5C?B}xKn=tu77^ݵ GF 6ޗkƚ2=?Vn{9ZS3ƵLU"}x-nsO͔,JBz5ZTmRws! ^&F692ag#bݫ{~rB*}8kglue#o`̺ZH-;K # AНl,swP} C,M971u ٹ N3b1:27qvfx]W6y5A,boϚLbx%$9mZ\^P##5p"  N=%fx9WW&E?MPGTӶM-ݕN#©@v0SSL2jLL*cp:^LW-Y=}o=夢-_b*ɻLJCh\ gBh[`: `P_iL0({<_C:Pќhc/bqdL ȡaB";vu``>h:T˻r;ElӶ ǷX qPHqzogA.Qfƶ9hzч&YPխ^*>Y7.?.Y*\t٬VWfPb\<$"QS |BeebDQz Ϛן<7+ҩ<)@p|Gyn^kʘ=~qwƌyZhS]zyWl<I:O]gxgYݝs03Hun K=S bq=GΜzp0`ivB8/f&ۖad{}l`Z/,=S}w.W> EofGc_KI[YF: 3^foFOއ}?416c$`#qC`dG\XGoʷ'ɌŃHL*DEfXTnYo`m@ C*f0ҫ{/aLȚ.&vp3I$dK# /KHZi ؗb7X2%(VLk.] x*f-dΈFDVIxf1.{/G%w-d7R~ m2?뼝Ueu+,2R7p"Ms(RU>_Tɷ #/)q=u<{ѡ<=0mTf#"bWރ0i־e #`EE. ،OpECF (<@mm<CڼbjZ*DR ōAk4v?7o~yxg:]+~1] Mea7cލ簧Qb3?a _ڻNRǔC07Z,處]'t ?y U?"h}ڭ~WŹ%f=Xe3| (j0[SB)@!UU\3$0m1eP/c4kAó{uiPS WJǬi`EL ,tKجZ=bFxof@1g-6ӘԘy]gw18vSqU}ǣXCE=q|zC'x CȠB6#`;vC\/}wFܰT-K3I$"#D8Zn~smY?*sYcs˯Oy3 rA(ޠσg=!P2r5ڠNSf(75|XLΛCђ;[2&89iDn }GyqV('L Vy̎Ѫv{{u? n[\~1O?=|1h &3wTcˇOip`Co-S쩠~< ս2Q$ѽ*/zåO92ҷswDE{0]}ۍ\E@0K_O`6+\flW43ܜqWn!c{afrwx=AJ :h) vB&gG%vnókxXDꩶ $4fn@b18|҇QЖ뵴j!VQTZ3ڿ0}(^P9Ю!2y$Po|J&X&,uFS?Boף3N*H[Fÿ8vIwSXk=5SL?Ok=ݱ)-c#{z =wZ8 LFdΖu+dP_q_(%a:'ԠGcNRb(cS!O6{>&c"6@Nms;gұՔGvOԝ+8T/g #!1.h .>Xz׼w8ՑӳqAz= Ņ ;0?C/c#{pΒ lkr*[}*PS?4봙&VmwdXQ\Ow"}/V؋}I>WMrmdP2e~Gc$&=i=d0H2{&<@G L`e:,/dr+R ƒ&3q9 1lM4 ^x%;t3yoIA@ʤZ<cdNLnA,eA\^yrecѩ2pC7.67>`Hzb!Lrg'yWo74_aZ7#[dLn5҈Y%jв`K b:Q<Ռs}LZ9Ֆ#L._\V 5]xD@slB]Zs!> 9*N\5' +W;ş>ݿ9ޞ|:;ōG:gˆ <0cK5 ȍ1^cc8&4deb-e"EܧU&-t2fPcwcnVtՍ ` ؄ҏѿ_1~Vy%Y쬡 zlepfgfe 莇6[B.u D|Y1B+|g부 wV!1YE&sa}=n#Kۚ;)Tx g ߑԹqn2m)k:8Ux]>}zF[ކ x? J۫5K2vl";@b[GE`@4k\NyDkf4f!"8VXCp@ QAsމv\iO{LNuNmS>8q >uG'!~? m㼛yo~GGuceG&QZ5F/.!8khFJ[ۊL8?*O0^b8>̖9]jz"@fg*%b0|LԂXXF^&fNHsG2e5F}o&Uk"sp-(}ܑ[72ˎR-4t=fE4apDJ#.6fbxleEĥ_9ttmG%I0x 5p Z2i‘~!EF-׊o-{tZ=9%Hj K"!Hf x(hU1JIR;*ɀ]g.TR-U\'w|_{:Yؤ;_'80ʬ9If.(KBTJ5㭶&D8.֫:GGiDQ[T4fNrq-aO[ a7yBEJn#p͌nF-*<20?fC*>e+7~d+ wP鷹{qOec0)V@ w kV> B>4䴢V"So`#ȿM$H_gjkRt&KF^hv9t~"_­D;M߰ $bH$ϨՑO%H{b^]!ӿfNİV1*G5x 1-cAzȠ?F 29 :0ؼfNZ&hTDaQ1lHsGKdΩcnG\}"\))T"2LVM6RktΛN޽e8)?!p%h,.ԏc6t#oީ*B,J fo*jV~상*i@5Mg59M%?6 FTdP@ID$v8Bzp>ܖH]^/ʽK?ɠQ^YBS+YX*(@.N˕3>$D Sl9#k٢,wtJ}"Q_YowPRJFU<tXga?35RDQrT-Xu*1{'L6c!/N(=/;\[j;1|l6ٵwrkCn<ʻ^u&&?BzrͽЩ F49%v=P\|bSELF>ӽY1 1l>ދ(uzntr̐jjkC/Q;VF[!I& DR6DZG"1_c!O Ŏ~̎R9J*;-Mi(@BlOkɱ b#Q>&F*f,R |W4`*k2LUwx̤Fi^UBMGzTuy= i+߫V`QYl(6q˰ʕ >$?jkRj6k =WtZb[MnTYTC>wj(ɗB \G+VCպ˜Q4഑j1JoB2 ev'@{gccCQ|Ro9ouLWC껒 3g08^քUzi ǥ oz,b6  1zfItۓޑ84N?7yb!;bVOFV$2@(SBa߅^.ϼi/Il 0/PkCA'`e%LR!ȶ1Hpp-$?s8n SAX.ӝRUn&e3DdH(ՐU)Z.oJzv<.դq4%,{2a'2W +s0x=woޗ4O N!ފU>10 )"fp% _!szkPp-?er>sM0q$Q/̥ɬ)GvwB.Uq0GWqoTJO nr[$4I;fG5-˴h]걾 Gv*tP1wP٠IUW-jH)IL}>LV1^bڴj 1o ƫ '`԰A^,RH >л\*W[ Š x&Fd 9IS6iɧ?r E"X@%wH8^zYYR ;VLM gxF|JQA+/*2B+Cޙ#O}c> 򅢱7@erh2[ 5lm!BƱTgȬrmB`mZ L n,&g?󏐥sjb&:EqAb8H4.T+v#Ne@K7 ،7tScjwuP$ՁT_fWP%}D!} *I'1DޤXUeC&|z`8OL-̤gAAe=`db :&\bkx</{3Qm9R$7H\<2] +Yߩ'=S(Hh8w/{P{B%\]M28-qgv6_ B4*L+LIO) >VaNS*F'&"(0{_rÈaF0YvC٬90帕2bʒ+n+̶fh7|O+A{H7)gtJEW &G!rB!K$SѼHCZZ'8psn46gyk!nwVO&.c (~ ؛>Eb4*PsI\/DjHЃh U Q?JwlŷmA'mZ~&Ҭ97,DjcCGA $|)ط?ynHu6f}-.(K׶U0'|> 9rI+Τ{PcRtcI^,AgzS굵ٽc'«-Wny/d]9xދQqU;A|` .\'c2=Q.UD9X"\OBjUa;DUU/^FKDɫS1B5tjbgD2׭yI'g_$a\:2;$?F[M${tCPYD p!kOK)6#E0Ցwyұ "ၧ9@d~(^\w\7} g- :3闖W?s:?[}+h9ds e;Fy}(vf;A /U(6{P2-aw`|KkWkfEb4bJ֫ɂS/ DL/(&uaF=rrD:c\UIj%FNxa@3J9w +i¦ЋZeD)2౑x5K1Nk]v!pQ'9֤Vpj1NBqAdM|.~EUSWJyГƬn1zZdL&Še8Su(Еá@l}ςRbrH?N |Y /QvQ##ń2ֈ?ZM491 ɩ|-Hgg1 2%8::|oG[+IG{DRN׿^eyh>Qq:o"K@+ʼEl-:u+D;!$p/4zb#qM$L.B@}ZBN22Y{dE <{ȑDҚ*KWl%˲ [㗳ObrF M#29f ւzz<×DDVL(ub?eϣ3|:栮\;_jWE #QF<EBƄ)vN7hk٤KgÌlf>GZ^^u;!gR"m Wم=f/dV-7vZ ZzIOMp'FtSi2DPXB1&ii#ȺjrȄ?zbጝR-j֮jl|`"NHxy'`\0仒em !VkaW0K T.aǿ*d⧴]*G_m1ӝ6ߦ Տ;G~rk`S|je.j܍ OTG91o xl`&mFIic ' PS$:TqLªs%*(E2 x(= rv7%HvFoLҩ_>SJ(|x]#7#y.nƼevA+rkZc-6RCYK|*SI$0"r:iQ,FzpHZ?=hCxbX\z%UІ=|򳖷[fkmdQg5wchbQWn /]X7qC cjP셒N\ߙ*eRElQ-8aY&G'y^xlvʔp"\Cn"^7Y q/iSkIPxj}!2U #N.j%lhL/ml ho4qh}t5~qß{gd?)yoϣ^'YK_G5'y*yU[6N}^rm{yG]H}={ Z}SHDWDLW=T 5U!>*73jBˆ1BPmnWH#ԧȮuz޷xdŵLhMyMCcw֪ZU9ǵsgug7F+U1~vbL#R^CŐ+4~66U:!U~&NhM!o,ckrE f< nmV<38)ouzxׯx?+a+9Ui)kLTJ+.mψTjGFCh, ;dRtxܜňȬ0 eRT(+ZMَJTc 1m6.٩jyE(\{R('/I/64d MbJÍ~7,Ř^i>) K[Q/*ΦQtrz^QIrg73nWB.q7_?1seiLOE3P9 V eal~YAm\|/7_AD]O\\J 23rc,be/͂"c^M-Q D"=x PtFW OrR bbbؖ -}u:T$xKMߡ-#F~ӃvlY@ dTB箙:Aop |"Vi]m{+ʕ_A_XmP4# 8 x'Li}b [.YNhy` 6r>Y|):yunL2{#RB!I<_NC7U"5*W(LN`*|Åwь^m;z+;x`z3q.I+$gKz]A/!ݶ/E9-p3_b!J^CY(ɢ5T.,z\JGگE oi;"DhA/)' zhOքA ɭVp$SI1ᬩk-}l'@_j[.Xpa+mvgR\ f# 5_ٛ6{xe@gX9jm)w db%_Vi6se3aPJ !&\Lv v>ýUV".HI1/([a{q 4x/a8ZF 'H*fE'7;A}}Ak~Y"Z,9G8q#FOi_.aj5!k]z 1tT@a+诫#.Tf vV<<Н[e&~IR)u21ėIeL+*CbڭAjJUc9V 5: w~^(]w3yMtzZbZK7̌ʑYCNV(xx'79Zf՜ ^ve`d߷I=,uΉ!Me2H#kxZ'|v̸~Sʐ$[;9Qǖ5q3aeSobch8>R!(-ʩ>GWu$} Pmww!q9`,-/ =R?2mP2yj3! l'q[cqa/JG%&իϫ͑ȋ=iv顮|%NߏO&՟֪i5|:Rw(tƄz+jT҄VW,tfqBiUEJV-j]?>>Px_&r/gx<OS'\7bKcgͫrOQ?a2˜x>x7}j67sfdz]E7*d쟠z1ךOC*PNp͸CL{ӛhSqxc/GA]6:kkf"=wZK&Pδ%ֿ0q\w70NOȑ;}L&ܿZ aZժZv=?5?aeuƫ7x0\YCK2ںֹBfYی+6Y l3ߙ"CSYw_yt<:g O嬩`(9y˾X$^g8I,dԞH?pbVO?4aOF#³3Wkm۱<=}|~K iP!`U4o;"$n[1F\$͚43OA`A x9Tp ziemqE .t)H?c;Tp:Rgbo?=gxjq?ji޾[Qg;N5Zغ~MaRy3Bq3g~v*$E ie]{`mY3<6m`ӧݛ0$١;d vϳ!AwK+Jyp2RsP.DaJx羥#ʾmcCUp{c*Xt {HZǨLvr~zr啳פک`v߃4c| 쩳¨/& 2as,-\̽=:[M~sk%# RyMӅ>wۮ7-!cű\~xU)O3B?{x(gF1fcP4ysN4DY\/*-I+'}gSgeb`-ѽ#@* }uVVw̙V\nm\N3xbjN U3Y;kӉ}>Nt-{ ܝs{Y¬iu"z:sŌRğo#cÓ٤ .è;t Lss j/U;?9W⎤% 'xed5iRf~|}Tc̫U] X)*^ۚ:I1t4QQ eI+; LsmnSL)# WZ7&{Jmö{g꙾:HhfvU| X)G 0rmٮmAη,#S|ϓ[R j9WߓMB8Ȋvn/Xw/ 1s;vs'l92݁z=Uyqw> Fgnn#gUuM5fxu>vYhXj1- r&zuel_estվٻ}W B2l5xJX0 :< NhJꄷ0 N xq{"ojRUD/}pQZg)W!ydegѫ<$1?#' gbr?>uXu1 yJGTk2L9ݖet0gQbN^ <&)h61ЪC^iDfZ}hbѫtoV'}ꃶPs=^OŰ~P'4%OM $''j=Y{)2Ao6欠w 12!!9N A#ě s?Cw"izҕ EXTחvlh  Sg_k.m%(3G cHD\GLnNh҄k"!u.]Fn,ќO¾R{5feM}dqdt6>4}OY9P̭^?(Vm0֑n<qGU>-=jOàe s2 \O/\b,Grcin$v(k-TT+D6e\/C)(; 1Đl$ nP:;Ca?$Bd>g xp[UL+ fy Ô](Y&d4^I wa{/;&:'"d 6è>5c1Šqt [ǩ3s3lQ94ID3̧VےeWGuhF}f3g۵(i[Hc_Nrt7/8f'gwc>_J#b+Uޗ[#{]kN_6(ph`( j F{G}go0'!lüYh [57"^XQCΞ|Z~_pN嗊 {80qiT̽-+ag,V Ww;/2jUv9ٝvV!$le٩o#J?Rm^=^l< ÉV*xg kM!`kjY'ٵڠ\=`ϯ|^DuzQKU]A{!x]*k|+7DcgpaΡήk[5atwYUГzȍ-9<1\JOْ)`(Zj){`~U욝#4T;J"2vZF+i^mtӷ/ m;G6L2JSsKbo뇐W2$`<3Y.n7'JUNLEg{V4,ym`,יLA,?kXd~_&$˂"3ϩ 5S[,=-cH$M3}pKx{(7tcxjUF|DE#G&0}$ Ehë|f8˦FbKsKBq[Tz.RG+Qlb h:t~hW0m^Vi,!O\׎jH}@S1Dl51ڧҵqyx첦?3#_԰_ï_w5~1d_]SȲZj)}iGSQ0SѸӓ1ƷGȎMTVKTGp}Ǖ[|ӞJΔa40tjƇLLm+뇯~8zs-EJmPq(Tԕ[sL<۱I骿6r#D%G(xꮕYv^Ψ/I[+7!M1Dr6c Țf/]䒱v5-@huQd(bcR^Z3ɎW*zSp/cDqk*V<0^kK*pH3kűL[26AE}yw~Gw_p,ӹ 6v\3:W i;a١&2 {,Mw +9*W+_84Аn[8lw_n,l!YY\:2yI2n6Kh8ĉ,Kw7f 7cUW1؞@2VƆH^k7H*=ޭ5ڎ|wmDU?Vu Y0  +!h9cbGrBz}U,f1%^ LAf<]ۆnniXy`5s߄A0,b"}AG0!QTAkGd ;9˶gyHgOusKZv^ CVh#zҜ?fss3nw\Tp:xྉTf)ˏXU䙷ďi\SaWE675M^8Eߙ T|rW?ysTy]Kцw ~8KT>; 1U_Fj8j;ٜlĐ},v-sfFf 5Tu W>8>>%kIQy/VL6c8۶9k&QލOuOΩ{r9ٜmۻK{9'IH8 DH$26`,dL0?`W6ϏLʣ#4&H94Sh &GY?dyK{ $#kNfc >^8~h H?f`s$z{ Acg NI;"X4} ﮝ"id*Bufoe^^:;=|&nj4<~o*w8w Qc1, ܽVӳ G`J،֐Ico}#iqjy2*ְf>\T~]oo}`|g,䙐_ph`ߣ*:ֹyCߞWOH i%R6Kvu)ϔᙳ;ύMt1$;r3Rܲ{jhv$82gX|Ɩ0[}`^ra7U+_/ܣpvھJ(2v@wߚcϝja.knn`hMHˑPwL#GO^ax܂-.(`όnqa2ň9]6#Z J$"@\1[P)70vH [4X|6@,_Kqc ߁7@qzT#Yd<+~w䠚W10H* 69wb+]=C!4]7Q [@G&7# *97;sQ ` z<]s{y!s D> .:vfqK5Cq;NWF ) )P@!`}-ѱ9-|c1F;~p==ͽE:'q:m7L?xZ蕨mO`l^ƥBcQ}٥u{|%Vgzw\>>8Xd A5OSxAQ.hrۉHF ab.O Z9Tv;~'7O nphq@wsq'?rG.g ff۬*r\[}*ʕFRb%5\ٺk:a+\dKRvRɔ& L"\]87+,ɛ1+S[N0qJQ W\:1J,T!(bJZPd` s{)/OOᮚP l %[r..a[+掠7*7"Ht*՚A:T{\)l-hujh  ygq^l p˯}_$ Sfc( D>oQVL`ފz37yg2ټB΍-i= n_/1;Z'Z;(TёVG,)1ouh'&^{t%}a"n퍥rc5>zjZrGъUy&T/'fҳ#Gӯ8?stO KLFdbZߩToM&zOVYc<>:6m`+̼T7T]&Hҭ ;P4zZi7T))f9vId$1J9vjĄΨto[* e}]&Sנ/ _P C_Vޫɥ줐phKk~/Г ]){NFȽp8̺`0ZV:$|@o¾=*j&Oksw)B4*MA+LwцL*Xi 8`jFD`*Q}<b`zg}P=:;}GZ݈la)e@Q Bn}/ks 8( CFVܙݿ 1'\#G[[>sjwS:]I>{6T/ezC?spLVP̆l&bb1klÛ.""A1:zPȁ\>>vw:t0A1|pdl.hdd{{''Na2fawk5LLҷP-?+2gu#tT|ʖ_)uWH57d&m}G܍-ehwk>rj(66,0o%dm;ً}C&ABC(bHQ0vtUjx'@X +?y-{@]do.U_oq_+XyzdtJ9xTw+ɍ.xU$$kEiHbb/dZq*]2::k=3HߕށpR|o8W$kF3_y3>>Ŭ{b,&c" kB Y+^7҉7fdD]'w|G {TWfjܑ9uc-'<{춙w: o@R#wԳk=뉙s%ތ[8+#^)qw-vs^'7~; 57]v7l-70Zf*7P!7ݎ^2sXqrh9s(^JMN=w>my%UoM^{>ƙ=]נ F`ӾV13u(!6g}8?YnbЯg#Pl'smb uU)7(j97v /37¾Z4w"D?#LߨX>t.$h  L!U! 2׼R, ;[mo#z\,PK~⻍5F|;,g|6DQ31ћ~m("},~wShih kdYn]^ Bhpe O|(-Jru;˹`bK< r5opk%ǰRh؍Gsخtv撷NdqjQ\F@pTO#׎@yiWM>SHL,ѡ yiK%z^sPu2)6*13';1<r͜:=/Q9k觊~k%;>*Δˤ&sG\Y\tw! nmc='g̡   ߧD2@ph=\ryYU7~ؼ[psI7fNb+{)?EfV)Bq#Δͬ;vǁ$eEf.?03tmY}عѪ7;}B໱^7Loѿ?%ΦaO2)@R#S +;uJWnMC#.;gw|*XWU[&]>-]99鯞pMX5K}8I-bT_88b']ֵb9nf%Nޝo{`ɾ]KR+3j7mF2rl--/6o) uML5a[+x;K{3ՆoIo^[ZF5C#.aD:zclzȣRzׇj}N<]!žhtp*'V@84>l(J$dd9{)f>ά䒎쾱+fRh8ܛ5ȰT(Ǻ)2ZL/ƿqlܜA`O쑻d\ą.iѩht*tDR4C43UM}wZD5W! c ꄲS< _.C5`wEFh?hUHUB^MYm`"pRj_keN<'R/O+ɞa3Ifm@ ؃DF/J ,=iܿ$屎{j:3[M Z(D`޿p}(ӣT{q{eC\kH5^;E(@EqNAl"& 9Ŏte^g%PGGh`@$ŰȡGWlW7T:M9˯?ztTBBѨD닙X`:|g@4My##nt꟭o=rg~\WU5NZ5Zޫ~[?.?Ks*]#2<< fgtlϏiwPg>e@~}rxwq{QdaFa(rmdSuB͌sқ61δ0}oI{}w`"WY *Q[pfpfXΌ?;.Pj!Wq`y .u/;#;GD{]'>.eIde`8NVFn)12T.:=mFA%ȩ@ lQ{xc7 ?|# 3Vxyc+ 3s8狁sq͜@I$ہAd410Q|cgJ@&V=CUF0hkZ!&&,QB-R4V!h,Fj ZڗBLo-W `(H_]*d8ޚk*B\HuE!ZÄ p8CSøMaKeW~hzi&ɂPe^]Up 2!x;v1q~v+cBOswV>:)`*^wMdJ&yfLԓQ* 蟻rb>x/t>FTNksB|{uj5>Jg;틲^HO"o9sgG N L%vHZtg5!ܶ*YYSes#DWVctc}]f+iݴ宭TTaWBٜjZ];.}hi,А`KоXޫa6qeȑ%tqtWt4hГ!dL^>:棅Mb$jwD<&^+1h_/ÒM DŢɕ0ִpzOpg;822{NćJ~tv?OzPL"/³/f\˗76ˌ:VBeD;nrMP\;ې0~4ӷZ kw'Nu] ldiå|b`pL`JT’%\!jN==VRdSO_|04FOڂ%KV&DgTrюld/CDz)&-^?!yv.kȵf 3)Zx1N@=p }E*}1){FۻfOMZ,I qOx$zӐң޽f`ci7p3fRg'P{١˻9|@q_) &Ark \^ښx27ΰ9 l0BŅX* c龣_ a!Wou6BW&=q 6Fag:S[p_l~5yM0CYW[%6s3جx†4rz﨤eo RFcoǾq .Uv8c1Gr,PDT}a\l0:iq]?yL nB? C6LG]ݼc?X Qeƞj-=-%ٹkq.vr,ԎQ~Ծ| ̵ ~Lܫ,46 \|`V}lwh+؍)A 3d=ąD1Zjq|oj:!%u,6j 4~=ܟ[V&ljo@݋$| ہFϱ@K -ΚJ$Qk[gfzlXܐ?>viol š3,[\7OEVa(yicũ :&6Oz:çP~^&*煹]tr0p6 |'3s[9ޭHxFr@nfxq/s1̧/BƯ8|w[vONgt~X1Lo Z25ׁ/4qJ.s0C, j!q'Mߑ$|pUv- V' %x5M_(#d< t)ڀ.Qa6o Qm0Z>:Q`@ Yf9@X$~BG{BXAEOoe!sg#;ن0F7vOZ>wBm_~S8ӧ/| 4θж:W4@sSC LB{Ɖ=, M[z! ++3)جly!/͔VXHmX'Cŕc:|d{ty0r͂r'=^AՖ~y>2픷1gZ;'|=<pAwzh4pWk \lk$tJfRf}P,D<=4< ̘]<ݯE$7\qpEUmUH1Ж`klU#r\cbnEz"&& F⶝WѤ@ző;v36O#֣F3 StMTk]XE("sj&Ssl4]˂cF]<шX8TF}$6#3#ޘf ZT*R4߭yW z ?>>z*>-\=0X,Ӈj@&\*t#zC'S@jZ-Jֿ:huTC oBP†a&V3WT$S(;kj? mpﺊax}Wu ×gc{ ct@N&1gh• ?H֦ R4Ycᵒq6 WtZ'R磞G>wp`Hd'^=z XŬ7Lz GZ"PLc'/l}pb|RW\rN"\;uK?whm%[8ݩLܴ}? O}k=sw\5fe ]Foevp,sh0SxՓ.L{w)}\KkZ+ޝ# S؈c#$^.hh͹f᧙M7?DM5j/!ڪz͂ؤ}@<9b-+1C<9pgXf&dd]u\yηzPy5J)}`ttҵ>Yԉ8W:4(V+b=+OIȷ=ïA(`G-e"̿(ҀJ,*Lo/L0wmm6+iەP$zm[otOF:b_Fg^AP7t{gZv[gOBԻn ڙކCj]zZ坉/_mB^uϮοk+7quї!g(ӽ*|.s6/6Ux">Eszw."m]Q=t*4 "> I_zpIƬ{,#m/:bP gжO r}-& oZeKX0Gk~֐0ɴ/?0U:"B/a,cn"K3}ڨACVw-%Rl&f了Mgv23v٥!A|}† 6%v_=\e d!Ҟ<{uarjL{JvZݼ5fu tm 5>C`AY\"ű%ڑ:(>  j xZ;VR P[j6)֕?1ym f6/GӬldL` ,h+C*0}MO_8ub'Rt;dFpF9ߟڷ/Z3(_bwCUMj_yrw fdsxCgμ3O~o=O~co%"2 Er헮GhWŹ`Wl |l 9oT/ zoVPpDZp7||OoϠ뚸koH+ԭuTSR^fl>bܽdo"k̟YڛUn}͔1xT'N@:T{Ϫ~'u[b"C,4Y_e0U}`@EnW?{Ѫ_+6w\G4'Qt$ix-bfpKD+SIlA@4-noxNp3{Gi35cc )CNӽi:}L0\ әMr^vy۽&7{b9ypENΡa@Uqi՟!p'^Ш\Njσ{czc[CaJqu>gi/t5'p3t%wﯮ]|]׭?pʤm$!dOQCbzj ڀ%cC=)!wWCah21..w7vjwQ!Nwx7o~ 6G&g+Α*[>J.> 4CgȢqA. _<}<2Yi}cb4V"9W(!]I߁ke:-Ź6T̕B)bxN~ emô'mþJ3fO4)Ϣtd4$dYq\&E j 󝬽2w'핆L/r)zknۃCyz0Y.7=D?:gN{ySЛ x6};X̜~о+XsPYcgDZPOBUŋKjE10TXVl&@Q? :"Ȱl7AB{ CLYٔ|kv` <x2#c=4(ե&f'ШGf6 ш3^ x^1-{I 4[&۝ctU]i!{!Qk7Fk R<SV4;6;VТ!/ S)QzCq\%泳:z).]A"`z$2ygm։K"T@ g4>9g֑oG\H.T,\He} AfYdQ[xM&t5 ZzL Pʳd$ I8THQ5[0X %5_&h?NEot"D#s9q&,F*eMPEcZgG#w+(Bo, 4QBąW{ A)y$ucb8H  ֥pDp$\5PvY%Z7>]uKFޚɉN$z ޯN@i5 :!%!ٳb%S)fISc2YqىN15-fuju Ņ_ИO|m1ٲׅfZ6Ѥdv/9}QgƷ^0# [x'mf~ |yfYK%^n=̬oA//co{6= ԙ\3$cPmnS6אA)`$mr.MXPT/^NOeCPÝ{Jt|iP8y]tCWoU@g~ch'k@{B]P;&%'$rpcV3*$Y:jJ^lt i)ή&%` 2\ &p?8aFa->\d<~ Zu.'C\YӁ)<Հ.| ZCqƗSP?>mC )A%ίwP W+> X'hJw_aqƗˆdF&tm.fTһ jHaq6\md1YZ!@aKDrYf]HSQ-Zخ=@fBj,-]Ik QdP# -EjwEg| >ԕҵ/>jJ?CEґd IU1ni)MO':.O4miW;h|D'MɌ{g ׎\$=)͹brs>g.Ŕй* 1ն$L @j X K~2;D7('-=( H'E`&s{@kmq\lBc9c.  !*I 2G*|,>)t/6fHA~["ԯex̷x?P$mQ)lDMZ∖Qbi?Bd$wط:~ׇq11]fe;A{gf<]C@TjDS rHrs~~c}7t C0}m#61zsc;qmHNo`lƳ~,7;&QD[WnXL؈a|ô%jC.&NHq4[%G@WCpnǶ7K؋-tn-UğN6;q |2ڔ?bUo89a/= AİlXTٓC4DRLN{q8~}Frdrc.L4й c< 1'5Kry(wCSo-kR{+ ^K{8W?gJo8>O}"-h1)fTOSDx`* =fMEE8# ' bGxZd 35n?M1W#lvoZwy,GmR&jv? FAAv""Gxv6fS_;!|niꋎA,׬:fӰ9S>۴H,*|M$Nk(ꘊ:?qB6Gy(Sel0wd "QW"m>VФފJbwo(PhHbcM 'I:oT#Wǫ|<|=,הa&ubboɠTrF 0N/ %`FK[Fs;Xq!4R%ܛp/?0 R_o$ C !&qA5m y r=6C);f8}o *h{O{k*5f6݉ͤh9Lų/hTKnhTilW~%o|ۂ'aiW5?nqЯ~I.mӈ5ά^uu),61"H2nwDg_q.ܪ;:uKTQ\c!k)gtgŚZ$5DrⶉHYM{Ü?)  \2<N%W:oz Znk鸒u ]K7){{1;_4J&*\09zdžȰ5"AT)ͷq7` SiqWWP}qcwUz E(k 3n1Wc)-]97ك>|X-WY~Ɠ{O35I}J?kƹ qU@à=5Fi\]<5:=L 79;x}el}~==~'istHu7ڿu=!La FtHDt< , I J,RtFAm'NGl5|kPц'UzZHm1!c'?S( ,/ד(?4@~hP9}Ќ01@ř `Y/jiۜ;roxSfby0~L(yPxφǰE+MyS绩 ^RF0+B LikX@K5NH#ޣ=;IGU~-n?)x(ߦ=-Xpb$F*wA_j(X"0=VfRFt45]qq$x=oH+s v8c)}Pr}5SGphfqhA(m$DZnAb"Eن(X<lcŴ;P&->'vq PF] ǍbbHRI4|AfVGcr]l2u¦>'i\00aޜKOřR}e$i$R3"UZ1rm|Ks1Le0ecJB (hUWjXUPB%>,nו2D)ɖG 4mL\eHr`IP LIe 8{/qrJ2Bqno߂FݡaL&[]w&Һ<$ȁƲ묣j\+nsʧ>6Bi7/׸Ҩfht܃EC.FEd.kui=4j[֚:m\+W!MZZDq(/LVCNQFcRm0Grx/ x84T.f)0f g7~47h>DQl:= CjBV(+4%&oPlJ/v#jy5_Bcn 8xjotg,zyhu8#IT.V)4%Rk]$T fαx*M {#˝^0y}tccwo_Aykf|Yъ7ʕNɳg<E+N+SQ7)&_`M:yWRmLvҫ93?G cy}4GSS2Kl*ZbBMFc+e¬THHA% |V+HUH+S($zTǴ|\|_?L$.ƨ1)%PBI k<i*P:39-D 65A}R눗"@)P@D1SA,Kf|ɟKDR)K*RDӪjE!}L#*/ri3y *ծ?q%֑X}aKŕ@H],4=h# | LF<_1 S</S處~O"jq Z.+SGOGe+eBTVTB +O _aI}'lq#9e{H'=V-o@)xeo %tV#&JI?L_CØf4ԟZ+o&LƸ {WBgJ{|td6}iVz Yq(, Xo5xab.Ct'DgwOpIwVbu ꊥFczJXtДH$3hT7-.\j])2xn|WƜQ4u{5Mm q5BV2 v̘ A9Ey{ѓ1;h1v|nn뉉Mk|P7o3AJ)ljRΒ٣D1$K6"Pz2n*i-呗VzzLwPcb\$Ior^H9gK%viWupeM,;3~5ߖ/ʵ2J*mhdTb n9c(< Yml=>==m1MD^f$#*3^KQkmA,d | Xc {Ybwuhf᷈>۴zSl>Z]iJ9ˍa>0aq0#f '6l҉ZD,^w3˳?L.͍GqWO#kɵ1&M`v:\ux)xninZgѩSɵsw5j7cLƍWI?#ȅMùo{MNKZ#|>?7Cu$Y,Xf:ݽ|[iWXʦ15Sn5I_g`|A dսP1Ս $+9`>vk>SEG {c;&}J%wqҙ|1VV1?S?yMd7c}?>J={o6)[s&(ğNs\vbr=.Àco "4sdp?}0uAwީz''rèh6X)bn:]yH 7 |]OVM?e4d>Zʨ4l+xAO E3>_uR+ŝgĉ bۍ`bbo,@1^L>~/3?ڜ2C^# +.pP6d~ۊ$Y[s1km͌ycw*#ɨ kkӱn'y`-^JkpUev4Sw-}ݶ5M2d.+zf1O O߽/5V)EWCnNh`izܸlզ6v|c ,}t؜~e1r!* [q-mCu?&8FbVwm!ͽhF0ʁ3YkKn0Ohj_YY^-$IL}Jۚfj8;=#J偯S$;xe0m^L΁tPW< -UKG ӹP _ԢTG92wԁaF*,eVEвH:Lw?C8͏3>G=2AnwC+=c7s-kR̛+0?pNnS^(dY7kJ;yRє'nO$Iz.DUa(SfqhfVg6fOzgdW?{^:=|z}}h$[\L-gP- oW|75{xW)\.r^Gl_`8L&!>,fF$cBzhyҡ7>|;˫yNgޫjQk&Tv;P?yV!DDܞYk`|vLsw>;c9ŎDxc 23N>uDVN9&F$6 d!=}aӰJx#[}[[)>]ګ獵4aqI"NP|oŦ3(zŒ4-[rc Yj ~rT.纛yZl͉ҥ/l݌d;)#To=|=| |C N(N)s|ܱtoKGw8G=}i Tl6Yjg*'٭KW,{FDJ?ڎKcik!HW6/<}̋v͒ 0I0K='NZ)V'\u:,-.OӳJS-okčtx]sʌemP@ƈuR7n&L~_@kO$,w9n 7=diGD)ϥtju~wEP_|VRLCް=u_jv/5vI@ LറRz*5-dmі<&!kY L&TMfD~hB0n<=xXԇrL8ݨ|heXHk<cv{Boٝ,Q2,M+Jxs^#ړZ1qrT]E_%lG]_B J"o"#G>˽b#ř:z˝2,6\unDX1io06ni!^BhŚڄ~}I:ͯJQuYf#;3INߏSZ ?O-zisSwtg駖3ʮ2C!yF9UNeܰ;Hx ׯiݢMS fX=a)`A. tܖiFjQazyRL5c [#ͺ_]Jfkz2LFTLHr8c"An9 ㉑Oؗ91H/3~gKh8>ɗkw 3io)ɮ= gUdlWo;73d?9|u?@B9ѠЉR~J23KJM3qw{Sgo,mŒMb1.^8 7cR ^<=]cco: [&xWW0vM~<"R԰:ON}Kh;ڗRn# cgRޠs ^1wnU3*O*KzvcVs^N!̑fy>磅sLf`ƥ_ouG5{݈@pVn,Yv/nT70hwxF%-l7?<2i/{qؚ_vdv0;LшB XF q"Gw~;\Zf8B Osh;JrcDJ6;T]Siәq|{C1yn-mifH0&|l?r ũ'$;B!*z ׊/-o̝^gW7vƉ%쮑1s) $_tCvCecQCsjM0wtef \ز&aj u p./mk{tz_f,@;jmRHixәRD6֎w9u6(?w:'lɤˀmjezOi-߅ǐFr!lwVlt8{qAf9Nx &qH[cQ5o>{sG︴84=84iOg W.V[-=|#Ӡ5ϹQF6Kqy~rTd8?a䨩=8&v8rUgƁ\Qo^<ڳBd2yڝaPt{(uaq ?pt)1ǟ?=*HGW8Oj}ܱPb29}l Pyx98|~4@haA!f}6Á,Mnag2LX 4ξح BiG*1Bk0#L&Cosre/-8Ո5aY-WN=0zZwz;w^˛];:N:_=žt< ={gW2aMH!+/ d 5a8|^H,f V8k?KEZ;..'T;1u^D;~k}+Qpu|F~‹}{˘&UC\g((AS\7x'~ha3 i k[Fޕ|\Qm/_65TJɁpSw~QԵ}t(/=zW}/3>ɵ48։8i~nb/_>d֘rͻ}0n ^>/w;ݞ7'3b2xDV҃+԰8o⯞}.~d~&]ݽ+H8ΉbUOۛojCյ*|y)twITD8-ޝ1*%o)ޞ^B?+jЉw2K\xp9j 䩱)ε֬SG"^T S:6&E9]͹+麍trl9j ʾ8SE0^=koM۾$gѺGo ⚊L(HԾaҾSJ<JJ V3KI,H[s҂=A|H NͬWe=F bECÔ,%,'TG5^Lc}hHdf텥ٰt^{|k>ylq*O 'Ǘ:k4K'*(Ğ,FrO h=Jn*:3K754Pԏ[ <'߷8p^y0 b?_ZF]L9}}a*۝]u-@JbA!9|| sz8O 2/%~@_ۍxii'O9'jisCp>?u|4eCR`J%ZL\ \wbrPrRtbJq)oFtAI!ɉDnMbҟW^l&}j#HO\<}cϝ}O&Dwqir:[6W/v3|? E-}lMn|넥kW}\6b+w{J-d[[WmNV]Ûnǧ^u@{yZؗs6IE<{s5̾2ۙrq78gL| :ߋzXu Wc~7zbH0 EeZ) k|ʲ&X6M G.U94Ϥ)]K[Rע!$ezfnǛ'ߋ, !!Zvl._кw^Fb-j?hupU ZDkMDMVHb6_Ihe)6&S0ITh]yd$LIS;`M+dئ P;FL@&[΃=;*v`D@h79>I5V*DK әRo^{cҧ.hOrIߘ5 4-`l{FXj?)OplHdI?g3H)vIJi[ )4~~AL5^:84rk..5V "OSB=BTc YY,Id}OLRO $O4A;ӈI&d,DdZ``\t9rpn:/`Q`bz-o˸2 6؎&eDM )熞 f,HfE$'? h>fZ&vsory.t{V+y}íLD|OBobc`gFf && k*=2]Ɵf/h&[5d$dD3Qs'4$@S"ԢEX @ 'u偨 DA!r8uLNLRHR1x(Sjz4P lvHވ o?TeRBGr0x)XbEO^y.# A%6JW_xES|O~rx-h3:`1d񪠇B߷xLNQ4NΔZl@. 3":CQA&._?S ;\ȭ4O9D"9Y%=.RGߖab\JѨy@kZ)=[ҁC$-Fo>VK+92#21* ZT33*ř%Uu Е[-[ ǧV;m^y"bDǛLel| >3h(,سѐ&}z`^ f’k9z\?CBd(T4 ǀI&Vf\դ8sD) Ɉ2W?=oY$e1Q1Z[6T}_aۜpb ^~W$s8?֛Wd.ՎΦh!Jx֣4 $ uex.偤h"#G,;р/e6'% k܀'dxc7mccq\piJoߓ[[:|Xg2ϫzY# 脒X mUX&ꕻ1;ڙ'%uZeiFU Ǜ\xNVxFs6ug!hF&QoѶdƏ5lhyRaK Y)>tbz ^Ս9^b1r"6H_O+q'U{Nd(ZBAPDdnz"(/s)Ҷ2l$]֋' 5]]h!j҅9Ǖ@3POCA+Q:6I^Ŭ/Uq &%Q&jqj YCp$@܇ijv;LrLA]Vo͗1D @ܻzGUeu-.,9F'BFP,٥BL'kWV z'Xb>l>r ˤeQf* 3y7g@dmERhHR;tN|@8) 4HPՖh! ai/7J}hO_G-%hØy$=~'}K |y5"XW7 2fb+*M7dT^Dɀi(݀0rBUhvjc,LfTy݌;ZhҵB"2( hD2vZB넒Pwr"S؋2dY j"86qGYV05r/ӓ!H3S(&FZA H-4b,VB6ZLe4aQ Q6eDik{N7ʋbh/ } _NHx]D,-. BtGDA ,"8`Ys Rt WXYdx$$ Џ\@F3-F(B%xd4^8IQB(L[t-mx١DzSUn#)y$Td8Ǣ2$ AQ\TͳoP{u쀛n=NčXG( dm^fd~ShIf0?8Cpu$ŐBP< ` "T5k"AEO*qn G?yG;q}4EJ y[QmPxd$2K$`q=OY~`m.Ϟ[mo=-aQDaylL y~q%?"ECf Ps)5 HIj07^aiȚ==诓e& X@qoڼ 3410 n{$IŊɌaBqTpϬ‡l|>>9 2+$ sY ]@PE+!2 6NY-!Z,1&Ep=?D'9*"(.x4zΙ͖!GE7 gMYARf 3;HtS?w1  *Xk"Ȑ6ZmpAK3cșfsۼV0G &xǏAgX.ݡ | \I6Ld&F s/؊ Wʊ#S{uĽm? %e(:CƵQ=U(/}S uX,5d=(e+mdT4FhWϵ.-ˌs5.OK4\C?!^X8qhoBMMwtŴNzp)|WЇE.yyj*b(X?HËgM8n+ 1(IN6@߾m ]N!Tv߂a'Teb(g2n9x7׃LP#/ c/sG>IF$uO?j1~lȿ,e'æqukG^\9n5SEȃLP^#Ǩ2I RkH14YeY+ntKWc!=mH%qp$Ku ى >Ag_Qc pq6p fA%j\;iV '!~V EUXfH4尬"ȳs`Tq&z<# $ Ykd2j2a])#MQy{&F$20%6 d B㠙So٭z}@ 0A*: \u7yuQ` j!1 7!eP8lhaڀQF v9dI0&$e@kDFH.Z|M:@ˡP'*h-gʤqXHȴ60Ƀk}(P)a)>iȟI@kZD1$;%~yjaQZ]<ۙɞ\D}"~j,]J"|fρUc9xy)P%DDg+QVA4 i"? Jj ~K>.(^iY-p 1Lcq; A>-%hX2hXKo_ny| ҜD<~6 T$)a|rP? h(י()GQt ъddY9eք;d2'$(g,mVVOm TΩ/ϙPT!61,d讦p 6EM2큮s4Y߹5īx*+IgA;v:L}a:hŞi2LGx rڳL(.@ftjƀ45l;nIe֩oM=`ֽ֓٦rD1@ #F?D<<[e]۲ido-ioLO8mǛ6SP.]FүP3M+H*SJ[@M\ɳmȑ$:#d i~mT>mw7fƸB|ڴ#(8dMv :_=n[|F @JDKt+.I *iFIH+eGF!?2Ii_k83Q~2} pЏ2R֌{jPȂ,T tYxMԒSaK4ZS;>WOV¦7]qzcv} FvSݒAJ PȲj$U9>c0 cβ$7KdKjԸCO>Cu2;PMaъU1;XZdAC-D-)TػtTF6cI T7zZc!W$a6 :D#cq%=`wFAh*bIٳ/:UNbwxz{(!$ZJij&,aY9FC|My YK3d#麪±V$1eWljB@ uƿU/OJY(=Fw,t V.\\ ~NB=RIQѬ1T$1'B#meڧNhR1*Ŗ6B GX@|U_u 駇;sA;y,RjL(i7oݮMT =v ϸeY^ЋNƛ(`/KD[ټ.7W@ KZl+(Pm &V>>  !)|\G{9#v@;kPƳVAxwm{R)Mٌzi&%]yf7UDך ʎIMP;HE/[w&/4 SO:]wO_A%:>f7~YD 3F[4 23 3hF ޏ) 6)xO%̂D$4&K)>튔nxOANt%!@W֌K d?7;PD=wap>&RԐ ٞس#RuG%A '&( |p 0pXDg6i=!90a`Y73 NBM=Nqye>߾_{AqĆ2\%C)?jP8^yɑF֏]Y(t؝́'A H77+#9 _G;XXrk0aL,rȷ2S0!8OHFl7_ 5yI3&ьHOeG߼`Af /!1JHaJ*jj+W0C2*:e)A!R$<{(NAĝ|ms*HLM3EI$Z$[YeYiF 5raAh 5i69ȴQ ~Yn7"`vwwE7p*[>pAfM!m%Ucdmw%W *ٙ*t[Isj, H(˅PQ4J²6x|b޿R$p1 / dDGiqdd2/EhOg*7!b{O{ ,&At4n2F r-fC"n<ve#Cd {_Id ؇_h*^6fdC&M_/(*gS!h(rֆCV=L+!r Z9K 6/bfS 4 zI'C&"F$#h#=e$":u/Jra ""Th#WB _b)K$O%s!@CKiQ*yt΋5[L>zj#} mt"ae:;ɶeVY;W/A]VVdo1(^QER~¿1QUvG|"1nlxj,|/#.kEax|qXd]SL9eK$jIX{^pd+Dp S#xºTX'= 9h;be|YgԂa FD;&>sTdT.F |] Cy2;f\kQA fyKlZ檮h1On"hH1kāXp ;!d֩+[h& R6`37h0MBk&z>l)r(@Pw(=\O8#Er\' 2C-/[9:r%$Hm-k wZIfHL+B{Y=Й̪(Dhܤ+`l/3iig &@DW.@ j|cc(m궀zةY;Ǹsw+EOַYzo ßN1W/Σ=9ڏЬRY8昼lE|tc֧mG Ͽ 2 q"1ހLYӃ\[0n;Kg+|*۲SRۡ0x"Ϛ'-,sb E UWhKض$IΑT.Kh{ܩ3z<4ښ򉇡U#]Oo*t+si˵F߅!5U$/2sTB(KBa90uA'yBHYtIP01K!a_ b{tBŤVWBhS=D)ȫ_{ ط;<,ʴZ51v=nɹ ּW[R;jeh\yutnl.draHufmbfNP o˿`ˡ*žbư~!;tr#݅$8+dԴYo}?]9@{̖@uv&KU @`j,Ej@: / P|m mi3YzسY+DuiRZװRI-n8u.ke״`Qq]mEo^UEvߞO .8/Q@5݅㜮E4;d>hT@Id[299Tx |)9E镇j% *"ĐugE JrJP@^DLa#|DM04#7WQ ``Ma{e sJޘzV~Ǖ(o%TJ,FX^( #?T^;v&؟kG8_\5<~9։ ;G)WRO4op:i#zѸQD{ՀzɿrPE񕇲ki};e>> Z']/PuA-ci.D(Nw{6ʍ*p>zz & #%},/PfJ){2^bAz_|F72='d~|FU[݋uUS 3?-ނ3S߱*0ّ ?u^BVeʤt yp>u@Ze8C[R3%^V$Io9M ɝøُ(jSHyZhW GGDgREJwEV"=an juޡ NŒ"ZSv[$F'M}h ;xF/9%z7?⁒zyIܶy܃3D*L0ii.̺( !=LEY65*T@7 S&N@a'wSGp'Sly^li:P3GQ1gWV|4wȖO vYΝy:v=\Þ](r1]8*A_`*R&16 iA"Idn1O"|_wA93Dwy6|,gb:$?/J_OnM,7dUg|c?c?bo';,"{`X$Opz EBk@?OΡVZ+/7hHcoD'AV twRHVz ւAS C4 :{RӜ_`п&z]X_%c+_`XUtiu|rꊖ}!۲lK/C%"eAQɂ"l)+`QA& Bl1Q Ģ!^*y,)+#/jӀkژ&*:7PH2VAE\Q pt? B` cQjJn3J%$~U)}}, On@rf!]csT꣑0O1AZfYj#;sCZ$vR*ڮ6ܴ1vL`S]CN)㵷Hw}Pu0.krî^c>_rbKwt$V[Ink1S03A@1X-*JlPG>3s?}v*+ğb;mzڝiqNm[";s7iW6 rOe1,y *u3ϪQ~gr.L5ws:N5.Ə4W8scHfI4F9{s|7]o, Nu57 Z*Yȶ?45T([A|Exh:öîʝn9S֭bkv`vѝKmUP7=^xO}~ w3͏7<=D3(3HԢ.v+p9KvpW74]%w |sC̽aoewTVh7&ʓY1=[Ί} |,@ 4aiLNZY=Hvx<$v;Bm2ZZ l7YG n> 1SF,:EPaj( e9^Dr#MO޳,p.N9%%yѽt~,]}B+~48;7Q$wqe~Lesi$#Fbm6 H*,4|Vn/}RRv@ Uvi;J *1b[a$"Vvg2^ba&"s{Wt7 r~nxyIۦ"#}OXz#a2l69aKE`μL$ꠌ Щ#5մ'\=d:⦦\ ‚(. Po~='֑<=*5Vn 8B}h>ܐ@I} = p)Σ|OdIaI96Iycrg)],ρe,[)s^BPG.ogނHۗfi<: őz>‚\3e? x0/;B^:=aP.`udF4>=fhht]̨y$鴪7ߤ(=Y3#LvLʲ4J3_D!UR`Sû+c]`0.*_r8E_rhyo|.V\;G+-woϗmb>c.9o,Gt+ɌPɠ7-BM.]'u~+`ΩU9f"y7s&?oL@"4|7A'V&N=\dk+Vh̲XY[*(Ph' w %H,iPNX ?ϛ|JY\#voh7/L~YY\M1[(=V󁺤DwB\57n+ y"^hٓx$Č NAϋt٢D?\ԖUґpq1bl\j~F2  ,^H$ ze=ԾߚnTa7Xs[67-*eoi*{ ߏf$ OHK/}ItMpטUʰX 8?w ͏ԝP,UjFކո DTn~&/>Ǔɞ=~LrXُ{Ovd A# -fx߫0G(Drl)KGۧ7WNHfnoK,'u,YB|+} Ͽx-9њ|%^`;u4,1qԳ3nS$hL&ZQGj?z&{+rJ}}ڑ"&Hes@άՏTSž(R,LRn#2RW$Vc3p݃9E,fw.tC^B0Șm㍬aW%)[`5ЕGjëcp-2%8@7Ec?}xsuuɯI` xlHIƝg6"~"|J׾@W3ބҤL&+#Q= ߩ#n>\-FX}"|}iƾ,Qt'=u#WuҰ}*mڝs83?G7aڇg&o,aSڷOUw&Gzٷ0W: tclm?ld@<Ά >Al)O՘> lia1<#,ݸq9R@+g1yhuh+T!YPW@.,YʪPtE?.tկ.*{K) -AǢ{=då*:6M$֤ (EA7C}5::tj?ןƏ:2ͦ͋7=?ݯ'oGSR6mNYaڐ f8:_nďh(:o. R0Z0 Q1L3#?x1|p9zP G# ImNQ\PVܧII$Ɉ%ō; E%7Bv~k Z@i t7HJo .ʤ TgoNL[Hߡ(GlzI/~\W%۟eTs0*Aѽo 9%rF`k5~+/˦h2QxH aΎKt |J&tuZ7uW)t W}sp"JH}(Ox5acXZI|fV ;1 _'$1LJ@}cL /R#޶2fE4-(ur\|,r :e$ n'`Z-Hs\ vok-U+M>fmɐ) ʷ¹̵? s&!޸5Qq4i4] *n`O=K3m2mA϶D X)~jnsm`ON Zj*8fhvh5HَFL|j5sAfAD:(NSN. 4 \:W5 ^u%!ss^t\s:{s*o}Ҽre.|Ia!r4+N7u՟T3/lԽje=H^y B SSTizavQTGyʑMijP\UMTaL>Wl҆K◙q}0ƞd0Mh0c3Z<5ٺ׮߃őǘKӦevg2S*7bM|G7Sמ`MVA b]V Иs5U!"rIcrn~qÄXlp$HUJXgX d*q%KMF,aXyIBt*EPWhѰDn4]=QR0u&`ޒZ꧔@&m[ $6% $LSoOSZ:oPǡ]#muR@I34T1L(ƀutK~~)!W5ȆckPi#Ƨ  /_cw(*LWFHh8d0%2o'dXfy,ˤt+ǶFX!u(&(fZH AvѹٕD-b9j5)˙Zyŵ8Mbf!3ZeT^B!t-+-CUD̯(ڳ߿5'PPgd̵.Ҵy<mykb0R>[kp"w2NLKɧ[aXt1!9cA>(#ށ$Y~J،fA/ׂ^w5|n Z+[OHDuK5 &H`pȘ T qv0܇pاkѣB5#hpZ$Ced v] XKb"5Jdb%5Vh+qmW{5q uÀ i85E{mqHbr=+N͌}V% v:4/JT>ŮXI A#h7lOB E!hh[@ |QbΖA]< LkP 1JP-=P fd"7p}pʴ e&\;M3쒦]yof,]a; wӚj ̾mYjNL9UUPS qn5tpAY$B/ rS1&.mګq!vH Ƈk_K,,@|JIP&IGk(Y&^j&T!5ʳ֞X @gDS -xa Tv<;߰=|%sք/ΆY٪q|r+;`sey5T z)fR핑cg^j2;-s2si 0mR:mX^T`2;Wvȸ?X)I@fMXkkN:W+zwI{t$(8<^4EF}xRepH3B*ɕP,{`Ղ&S|W0* d,`AJ`tBaB®TUM#"r_@X\p=`̄2/+ʇ&EoԂ^5fr;? 1 {Mi7t(l1mxxj.ө9).\o, h@\hs[#m D M@䕅Ҥgǔ%,PI׋ 9%l":JɆ Yr\;Cs@w'I0يcr"ysp]y`9g.Pq/B 4_Eͻ9%Dz3axpTt/F,OwܟG;H!= (*|2@'Ir0DS2X-('UЩ.ۼԜ3mct׽9ܓIߝ|Qt )zmѥ)󒙅Njj'Zcy>OD}R^*flwv\#V'3?cb;-1ea#ʖp_[:Oy2LNl,{Z-H2~;>R$ZyU,ۥ# n:SK]_ptSS@ez~j87DC=z;*Q:b蹣+]|,.9Hv)gMY_ۣȌ&}sƒ;/%YQ'<}b1UL_2֥|d}h8JD=vSu[ $ kR^ih+R<}34PN㹓5*M:*;S͢7J: zmUEJW_Xd{`+d4KAW+,Bbuu%b'3OMw܉~&0%s=N% C鑛`ůtIIJ9-DB*SzJ NA+@Q^v؜Us<{sjƨL7 %@ KC$S HK)Focv>ebqf!x3w}šͣ;{HXc3d7|k({TF5#=oA%<)2^ T 4'CKgXZY'7j{BV& P3y;d8 3,,NT$yt+QQ~%]w8m2|߻k:OfLo S`.l i^ӍdtbZ rTX=eUҏqJr+z#yIu AUxSvFD@qHh]ڭ iU<8ʜWӎW [WuH3=k:{S$+yb+>2~gɻL<?@⨖ 1k`8W<Y)s+cZC2 )J f 2%{4NKx &L t(HH[?.I.&&B,ι/h-%c=Ksj'[-zRf#W`>0AB+~&%`B1mvU8iIG Y2_CD;)rtX3xD(g'M{vHO._oT+3OMgcL1_F˻sQ~ b2glITY"FԞ8sZSI R|ljh]wp]:Rxe_̼Aƾ/Q#좒di=V^_=O"s-e/x1)ϊjPƂ/Kw/򈪻2v@u(͊j#Vb5:?8%s$0BiJgE]|#ڏ(ѴbH@I$TA.9?jgHV^Hh'U(Vm@8+Mxt{GĕHW\QhtUURNFW6vB9] s{\8񳊽}"w0]~1/E/2h)6P( p5+y%-H.Mwꂜ2۶Fa\(c F!U?$gf?}٤'vD&LݩA cQiż"t!hTw/">L&k&ER<,-if.7?f `Ov݈MӉ A,ЈD&Κ&wVףM.L?(Q3 e6t0_#& 6Xƚ󵬱n K[YQu-n^N W q8E'컀Tsfq3%j%l5Ǩ0K)}rttAD?;oa6qby} ~~ܯr\f(k+rgt|e9H2aAOۢƅAn9#;WxeF{VoCL@ilK͍ZGA aĴ[ ;-醊(YX@ *37Tzb(&iehנ,i/Q-mP͋15L znt2mAtFN@ZK5!D./0 Ґ?(Ԩĸ|ɟ1XS<1\q,8%#΂ɔU;*"ӝ\L(͐Gxs$gB#.Vٍٓ.b~2`"B-])hDQjUGiW}_Gդ"i14J2U)=Dt}1\?gDC7;CX$dDM" 4HXHpݜF;&nF);7 Hy< rt^12AFjmT%L:vz-iZ-+D} 0T 'm2L j3r'Nz89HfI)Gz,NÞd#@c.'1/א/s]%eldYbX㛭D]r4_0 ΫiCɢY:f,ard{TEyA? ]Ae`OhE3eXďdg@fdN&F2+(~kV$jHD=Mq`N@tdJgzcO |\Bf1$;GݲTL`!8YpC%g@jCUc S$kT4l(1ܯu:&D@2dS!QpꞮP`_c!~;q!y .nLb,>ʭmxB> r2 d XqeZ:~KQ**DbϪyoE=b4o\#vnk`$%BtVk"|TuQ$=/{Q(3\)Ixa JSy&Q!/ \Z?s]ͬD TᩗOe, 47 @3a,`m4$^s^g2m^[ wN0 xvz)ꬋY+S w1 ?I7CO#;FB11' N:i`P0%Eԉ҃JFTPiĴ1Pc$ȉ8Ąi12sᢚU<-$$bl_iF. fgmvv|}t3u;ҽ~ͬ$7%A2_OSb 4>XF^$JhOXgLO>4dl<2%EUq[ҿUaGAYpaol4G;׾ ;h׍'RxIYAiw8(n `2 {.l>fp ס +Xұ j-q"KH{Nv/ߢv"ifP׾PXYz,SvDd" $ .w~2-sgcSVRo>>v_ziXu`D+:iI*jv|hê c-G?9IysgCE׊zg fKr/ܕ2]hy`Lgw˷Süi.+3MjD]@fr1? Ze2Y#Xf"}g}!Mgn(4{ї/}c0i#c)̵Fw\P6aZ79dψ騞Kj~}bӵs^tPe %KE1$; ηpBch.p$V$(Mtt)I̡ Gt&.xB#[-g0z2żc .ݝ/H2 LBPb2R?VP\HEҭehwIfP L$7cEVhzYTI FҸx(q>'J!o}c1C/:Zdi ,Ýg,awlh=ݙ'*ѩ`s3@Q%}-p04r6O) 뜹b,+zFwc+RLv. ѺJd`wLj{vP LyO f}k Sg4$mJk?_6Ùuv88.ton2#7?20" {&}3ssg0r%b-TʴO2(24Ibx^4nTrX~H @ гlJ4vKזTHjbpo2F2Y(xk?aMBP.RnS> YDgL1%wUJfph Y4S'@ qiE"/jQĻ3 =@npYӺwʻ@6dTFR.p.Uŧ~SL|`4QZzT#(BX[LTf> L$Juseb2AGȉlL;UE=}_l.X&f/RȨ7%^<%lLCPR}&ҡo_ҒA֤5Dj+on |Q%C%zb}&Ɔ)H빎G7eƛ~~2;? 78aeYFmn3zw|c)re1e{t]{sRaα4C|$#NzppDQE'G|8kC~qV6 ehcEyc,Q5 N{ /Ʒv>"3r"#9Yto˭}-qHϻ`-y1fwh/HmoϗI-F&gb=D{}Ӱ5vaVCT{B#|G~ dsIe2[#)qi=x hqyڒ >>QQg7(A@2D/`LrVW FvsIcuX3OMQ@g##2<|]ؙ}YT;x#.Y s]Gзf  o]Xwg66qo6cq>W՞Zf1$O7RWnǖ8ro[D^ 2ĻF)Od܆w򁻴/^yiqI%5xp/єUɋCo"5HH;ۣ 7 ,=5}Ee@|'n-FCz7_9J^X)2,@ȸښ2iQj‚1~S?W/^#p7LT`b&(O1~m4.}ӛՅס2ݹ]g0 ;1KfSM9%qzs[OMDUڼH.JI׉luY؈d1%Kx͡':T&Pu}ӱt)R,jWvX)l ]Cd,hZBt&|DFtu!b{-tե@Rcd.X1d,K4[(X@ AyNrlRK xzF2mUn`~,f?%fo~!/e"膩p\ʵd <)t.s3Iôዷ{d8aGmHXI.r&?nYpDBKF4Jc_nڮ6D'2OA㐀?otsN e[U,[IneW&|e4OPG*n?JOS, MޙႥ5W"maqR;^D'UrәMKsOl0/F(!ӆݕ(܁;Rȍ1]h'`WbG?7\wPu{.k8\yOW6$A.`+nөݩS?OBMGBT?NORB+Sq۱eQA8i1Ps`HXDLJ6 A!N3YTAS%5}2:cVk =ZF+.7l_ DG/}IN}shߟ̭F}s/ޞLU qoL4ὨtډQH7Qc8 /q޷Up›?o J[(*\R*GFkYyБJ`q^Xrߢ|=^?zWx3)nYm\<Cj%ݗM ~\r%Œ[hL̔.iuZ<,`(2zrN(FQfx$>'ox7I$=bW)S[x͊55ߐ5Unr?Q^@`YK\J>!<FXNXw0"ҋY SLoWkݯ&N9v n |7 v_D}Mӣ>wY R04{R@ ÓrM+װ .IVjf+hB)8=޽8y&6O'Nʁc1@W'Y*YFiYN3?z(bĻ@uT /ln.e˘AScɵsI곓c x.`=ƼE&\iurxz7CMDXE ܸmFЋDJiM* e̍!_]~ʡGӡ~_yec<-(O+)vp܅xsNIF^-^iPvW'=Z5=i8qsk #X"\7UleEsyM5jAuC/oW7V9]WA/Uʠ]s>KUO ?8KK-=JLK O͢@Oe,~(U17 t1i3pn!lx %ؚ-p ED吔q%n & n{ZtNalmcҡPɔL0HTIS*DZ7KX"EiJ$M]8w׹]T"[F_@o efm -U]7nO5|֖"35b_c0,t7Gs8`kn<=w!D4s|.>kh$ !QG+G.qHH"9l|6\#R~X M*4<Ȋ]2w$u|QWA A{`Ȅ,ӔWzyQs[ڼSpӒkcW.эr۠u̵bse^KG}Q'.&`N>FY8glX2I{=T[>Y5m:5c.T.PӻhY~2rGe~ZhH~ɂةR\]&P[HHO쳍E*IIt*ƙэg0M>b1;RoKYielBpq~&f`S5Fhj7 ކdmndGc~+LJ:sſr\@# $ RbeJ5)ۊe >dZ8{ƶgx:ʖg8;x3l{ﯪnsDB7Wio&w~:Avo:_#8gibYٝ&Gx"\h5?\Km *TL-PVÝPp( 'Ts<˭Wr@ё?l=HаӥHߦ{axg *bWm"Ne XѨ\O0$?Eus5H;Wm_Y͜.?ʨx#?> +R?O=ҴˍrE0ᑩDkauR!NUX A7ULDΜZĢ ?I ࢣ!>EQhA`r, :Kw8h6:kӷI@;*) 0}Ŗ-_^( sp vYzl(Sv,r ߣUcF$;.w:

      ?8:voC2B'.o sXY^/Fݷ+ XM-V{[Ĝ(^޳ Ww7aT }/IV#a܃=y&9`iO5|I*&ē̂%d.ɋm _CA‘REN,tԖ?$-ѶbpzqK%'hP gv+:Q"BUN|s|9_ħ4x\K+D{_̩e`/g_3˙_[YշRhrs">$mc4E+<5/P@Xk|$D&s8НLEothRIr)-d/Dcv^1(@ܚUXh'rc%y҉HER$0 iqO[`@9+ C󲞟8s_1Iq )SAœ5SY/GvOķ~w/p8.1WJYD F&(K~Q{н NLC(yXK >V]1o i{Yf+]xsbXIe#[ Q2M|fE n 廋_}Lw풫Mb|"2a\'1-E>pʱww |gn 悡S 0̯.jJ# K1l# ?^2F9,q{k<5 [(|)-0h|$*7BRK/_ݚ5y8 XB{J%'Ź.,"˕t IT2%u]aN}~{D2IW@Mw1\{#Tq`S̙:T]x '7 L]+8E\Enӿ󭕗;o2u4ƕ<#WL0U9J ]L%{s ~[51uxikPr-?x|>J(ux-i[R6 La"0T&._)i4li*n*@=yl7\6Dbâ'-WmEi|B' A5I4WL_LC1<S*D¡y6H^_%(RJvctΊ4⮅+%= Ur#:xZS$3F&'e{Ve C%દԄ< 2C$(fH 萒^7 %kI%i$&VIVaC<@T.dN&!'|N\bJFEeMxB |bsKgX`sd#V 凶ՅЫ-S$gXEAɺv(K\OqZv{!nO?_w2PVf$R.6ȍS@B,_{|՗D++uTPqomgAxϧ+ Cq_6fȠ?3  7WVKR@))%h[FwHѽf-{y 6=* G751+zh w3`ܦ/'Cɡmg| Њ8rp5|c6{ $׭$ 1]1~OvBzb:がaڟKY1 fy7x(֌bc@1j#*T 8SQ/ߣye_'?w]F$ p"O#rk,\{N"i|z rQEB!rQ}$u*vD#h(R3(}A]~t@i%:D(kRSph%hS?w4g %@.DNZZG9SjB,NὋ$'ˮ{2J xU;I]|5Y=Q ]P8Yfe/׈;Y-vpD CG]1bv< RZ3A渫jeR<2lސ?p~i)z"@L>mSz=},IPFm% o|ՕJRErji$Ku*qH'P恮mR ˱^IG;J627ucf֏w^l,HF]lQ_klxⓧsU/i|;QH ‰,5Q5oS`]^.+y9Y]~3`n)U0 f!΂>inF$} 79OIYݳ6p yrꄀfu>/?.~)Nƻ'Hʁȹth$JUTkclgx8V32R}G X.b҅:=74ut_G"fWii 4n[c -NfK?sjHtYezF+$" 9#gVLzB~Lw>XPi_#cYS(֌.IUCn{-LNZ#9Nx3b\V#FK$H0(dFY35>N%- .*psGX`#C=v; +tzQl$1SxoUrrf~pd2BL>rs/w^Ul#=Lƛ9=}S'xͦI@s;zlRh6%,׋ ލbiUجk$g\.M ovЄr¾4CnrgR_̖$* }M)??ؼo¡dd*2Jֲn q$x X_ڸpYc^52vdـ& 8 ė ڃyA8@Ɇ鋇,/+|-檑x#{?D7!O!d#t]'.>֚\Yo xK TJ)[>M.Q@2d RTKY-aTd@ #vΓ +Г(H꼗*V(x^<qґ^R 62hG;1Y]&&2~ Srɧn ^؅3q83bXwwz.3B"<]xɢ1؞3(xI>zHgK G' FV[=b(B߽$h /(;UY7÷ *xY"Xg<UMScԡ /釋m" ұg(aI{D&$.g `FV)c JQt-{uQ<讋Tn.G3ؑe\[ ͧ}L q-eC X*g9#S./z(v3Y@Ś7%b Xd(I rp#Z*KoW:u}bHx?E_邎 BJH41M":jc$n{i#S:\}5w>uϰ QBXK ~&x5%¤p0馤DQވ\O/cЖN`` ;!OE\e-|sj(Xb㾃]Ќ늘;ϩ:7Lɧ-PnphMDOެy PL)J 7O;jm|$/"SD=H|zs{k PƖ#۔ hAsƋ."K6!)/ 1kbo{lor)`+++|U:_IzVxsބk+?tx]7%A]7kl|#o*W\oB_`˄t([/;[S |]a @S%]w/HgZI!cO'cN?Τ/m Ef"ARxQ=NerNߑŀ7N}Ї~\|mLJS~#_"'ٍe߄DYSs7 Q:TQħf6y1 $}fnHrǵvx;~๏>tJ{$tl+U]K Q%O'ܽ}{#n69g|XK AxuB80u=sc"|*}$H UVtYQM5#Z/Jʔ85!3Y ã-;$NLPDm["BQ{뫞dz ! {O䰙.Yo--W= ?5bs$Y]V #Ah o~z=nR~ƙb%S&1m3Dc%%,RҹIm H$-V? &/w6c*4Z p˜=h#uTd:xqzn`Ȗu$ۋP PA<]UTœ2rp}hAB^|,BcWqoRa"ITQAg8A:h1$o| Uf= :b }`#htC4 ٴ R-Wj`?f.HޢF9)n\ raI ē N܂SRu; OŶc?t&+cLL 4ѝMtH8foJ1axꥠCskiL|iq*"d|qH+K 5 t2?ryoƉ/i߿&5t_}kn')fk}/E9Ț/R@N N$0lx}ң#'=+3ҭ;_V*usW RXn|%k;o(B`e X4ZDIv>-(Da U+\ ٪Rei BaFT[aTflv*Ǔn'1Gb@<2CXvEN&ݐXy?U>bū;g 6}{o520=C0ۉ,u~ILatsF(7<:LvNA(zi WZ&.L#ځ69 OM59BM>1;3|řG_اM>) ԠVQ#o߆WڧBxr)Þ$ sU#^O$7$CE(ovjv#0Y?Lβ~9~(zQ e"q=k\+?T6ġoS~+G=<.e?XiڑEq磲)c*#)Q-λKp vT<>hQ3WI M4U:ۥa&}SxN?݅wL6܊RwG帲ҲJV]t>_C jwkte{sx'xr1IxConU9Jq[u5 5v`b:Dg-/&q*p@ ga :"b0ZzW\ ;Juhh4~ Dièq`~;qӌ=x# [53\l\lvqy:wD?>xifF78L2qo`.aM"IN|DR9;<\;'M%,ihNSVaPck9!eKZtdžl !ixr6p{B)%*D`XLA"I~yJdZ*)c?28erxmI7U6!CrޔŴ8@d;AJqb oj'F{cS1KSh nI!QI9l#.!^O7.q8l f-a7Iǃ!e% QS09ѹnPdͽT竌Rfkcx4nAS"$og;u,#;gf+V}du+:a̸w 5;P&ddXY)oQk?.MWogᕼi$r1F<Lφ&%|S+D67_W6o [@בUIn _+&hM67u/[^8Uöb_]u}̖b,#[kivf 5?$e CIsԻ`.!"n,OXU"FTI0S⥬W%XCooNH= X?4- 9C̣6AKeYwa(2†fl5>UKbNV]cƗ{hmF ySE$!d |Ν]t\ye[/VYH5fx0^5EQ+721S>:D;('r7x/K"Q2" qƇ.Yݏ"1kkoL F=Nxbe@ŀm((^/=w)ed mѐrc+IJ5v`{<Ǜ6$p mi26o lU'bN0p.@ RAt!"?C?O+VB>J|T ga9qoտ 2; ?DgʻI6MRD⣼VLz&?NEݕwSE~ZBF k_%SOǢmP r.+U(1P;6(CT 1i`8;"=a3 h#uY-zlwY'|hx EN+EF,5`.4=ǚ,Zم$0NxP4X^X?fLS*D^Z,@O@6 ZORE*U R2%m5^9X br+2G*&Em\y;se"#r%DMl3DbňRZZoJhSHyYTyԇKYeeD d+Pa"*$-~DHJ4M&bAMtW@7}l.&m"'~E77&Rh&8133mHhv_- H̯JCRT- uWU `eס*8mV=T.ȶ *+%#29@jP x)WJaMzn)WH@e'` t).=l>dArz f~gFf6rM^%-ZߟzՙeHj"/LEn9IZ" +5EwvڱGDT`I-3(Õs',E;౏k". MxaL8"%xqWw)U ;$7CO+%ĺh୳GsR1$VK$9(ZE @[+"YD߷ܒ*S;5ρVMyq!%߃ĞGB{g {s^4)DGV= 棋Z%u$qLz!I3m(3k˸ZXFV|>'t\(FkJ& ~V0WLYT:絰bSz=rAx֗8a;.!ڒ.+]}0̣kcOh ِy1 '"Z2E3o6jRkxDzOC==k"mM[9ja@q<iL~nKV9b)~Ho%B-Ӭ-q"% G6ֵ,w:ucv~)tɹ _&DSyE2.+9;X;XDP5 pΫ/='aS1'q&_"i'cow}|Pǻ _c GZ{W}qczrVF P0Lr `yVW aEGDZGNV*4c |g/NE@RV qrq% 8k$?xcÚ< pJ}[;K~㒣 +MUM{\- *Ttfa!"w_^Ȥ Ew+$'`BC9ƗI5:e+MA^q)!O<R'H|KtbL'b_cnMFzwT-o?y*xAa}˪znpF),7^w'D'l~q`Es~zsFl"~, ؕ#Fs|Q !r;(@P=KdAT9z^C+:q(a'/? 3ܥG@gV̪Bl9-D PF*phYFà\IH<pz£(?@ +~%U#qһUAGQȏo|t0"r@,6[a*jJwJ"wK3s5?zH#Ѭ=G1hf/cB<˘FqZcZOŘ67ue3:rl lDG/VI{;1+j =ޛBWmq g#3 1Z\wt,P_U/q VaܽxnX-|jfdnbz*4TZ*4B< ^pn>řw?uѲX{$nfbh&?B(mX[B&M.SqU$Cl]kifdwL68h{ 0[rmx>`p%O'ioAf|of=:QPyh{&xgz<]ad9/sVG ZokfδIh_4Kz29+ȾC>54 h kZZJ=r#$cϜMQ'4 U*y6M~s\1 |$:;<pޜ[:Ґ%{#kb"Ô>X&l}{||~&g-= urxK <ҋ*UX{Wu[ߣ]!rC4ަ1ORrY>Zt= Ab$:QT>̤ +I'rC"tf7?0Rl ,a8.It"Q*;+s>iD&ңHQ6c"cAԡE;˅n@ lDx-hV:n]9^ߴl?ցR* RfTZZc~hBu~9䅡.z @pmE*:VJ7e^9+Ϧ>$oKP-*d9N>=j1AJrlR I&&VmV]X:]\'*ސ'CR#\2s B&Ý6<q>HOu~L|ybVa3th3+tO2ÎXZ"t]}S7l\?x3yAiPn<87cߐSy"ː|wAI4'8I.&m/U76 JkxL@U+ 3Dk/1v^ =J>^&B0h3D`\9|3 $=qs @Ϭ^QsX^.ș`9L;i8"/:n ić4w?zlCNIJ"rT2RxZb0E,˥s-zF jF'C7W^+X߯| eQH.>H69;qcMy @cV^vWȱwR?F[.]Љec}70kVʁԘ"!-ҕ-f>:-i]F, 'jF>/B}V,?e+BpCU帥\s[;Ko/[}oֶ\p(ʅ|ETP^T-9¿!!+O*qlt-3AN:^=Y"Эzn})hbNoGHzG5wՈAz7a%6fx8Ah:OM=ӼీጧucM }i@NGYj.GDwvE`+igl 8 _=֦{|t־Z{wUd0%&CG@PUKuDQ9ȭTE`]3 H\`97}lvv AHbc3J,߫evZ~ k7,DE!^ -+Keߜ 'Z<*sEWO9#g)O!%{'*05=_4씙s+> _g{:}{o,TPկ ZhOjuJ7.|}y=Um!mf%a تӹٻkN*bFUlh 6=*lӜe|F^`MKAGt"lFѩJ׾Bw6Qf߻D\GJ I[YΫK)RP)ĉXB;~ -ޅҕM!-iGԁw,m늒TGxFhWUϞ5ݣ3зmQz:ɝYMMRtqZL?˺/a)D?{/cCI&7!{Ӧs0:#caFZ+pC8r LM?\to{TKK2_ͯ|A ]؅H]k+tUgxG/ 7G}pBH@#z# [#waxXTd2;7PJ RaĢt8RFՍ:̛ёuLih9 f N@MvU& GPaJ95Q%YUAHRaYI#ذZ$0DoSz&z~Ͽr3+qklXX倽mm-5qӏB J3oWLx^ h<1%Re?w9K˹9NS KZ7ď*%/e|{@xAaOҖTIDX-K% l (u4Ztsql6|L D`a<:LoD&#.]GCvE-ps)9XZ<@VWNqZP(*A%QJoGGrƺqn1pa(5R0"~}xG=5fb1T zSZrG@ Pv[g$sl;qlYHYryE,3P]DaQ}QS)* ӫCdI)UJSRsţ$cmgf#<>M lIvf9aD}P[:zX͜XS>7-E멚% ݽ $Z '\7{$mg+aT|@ۼe:~lH0 H"N`{2 H ^&;b// h{wXΰיQeQ=) a:] ؋6N΍ q/2|;%8>^.C$ZL\\ͯ*CE^LxBcV}Mf_$)YJ=$>P;Ed$bC n'S皜&l7dA=.ǚ9lҵvoS)UցTQ5H{wѹ6x>d/m`l+bs [&jwZb q蔽V()[]$ 4xCILZ4] )Vwy<Є(R([٠%;I8G%ܗ/sD6i[+7=*}Sˍvj4D"syxkgG<8xTS"ٙ|7=sLE_5 t~<ؼ.K@מlŒ8nGm"ɶy,s;[沰F5tTBEAqYB !y!ꡜ0rfgr{7ƒӡ zv 1|HB0V HaCo}' \|!]Ψ]6u@x@ȁHCWp ($Lzi֨&YLRDT4ECC`;#wm8ǜZg67kYRP۟*4²*;o[rvm,7LL,6d䷘~W^'ɂ;/I92 B.(QAS u$Və3WG~('ԯ7iC7B N:|o_ rH!HB7Év_.kr]i 0 ܨ3s]JtA;@ZsFp|殁z-.('M+(C_l jeO⁢J$,WP [H >SVά%Gz:g`(57G\||XSCcۨ, ]6 Fo V&Μء#7l*c~S=U5 9g(n!:)s'-cݶнh(q:糉 EܤjR_=|dX8ieyu 1FqgQ@8Uh>>ؿd;މ0Z*€BsBid[sѤyH>t=1E+ VAq)VD'Bx:+ON&i8S w=¢H $,WT 5D AwB_*v3B䘎߀XF7:v߀syA b猾+ˣ`J;KppjI tZZe$iqVhQ։i3DkyVcJ:+:Iwhr)2}e#uV>RӃbz͏Nh?}أcD 3 nEgH'%2Vz6Yxpj#3|ur].aѨ>DR- E&BN|BB j9VvQIAqk8rpLaJP }V+WV54_ؗdlZ +Ny]ؾ5pH hYhz C_!9H5HF%!A$^:  KSi}> 豿;ki訑6í@`?ZŚAocVҰJEE#1Vr951Sws('9'u/N5اT}؀IwZb`s r2E%$ I5񦪓6r""gl",WFYanoH2әxT`G%wK7p.Jꪮ}v}rg¬aaAeb 4j .b1&$ʭS{۷oթwyc5Z24a +"^ /i  KPg ǐ1P,m|]./޿\ac1!mgr;MsYF@.l1o5c¼ZvHg$юV哬jۼ$Yn㟼yL,@Ч[k8 s Lq.4Ft2[{F;zQgPˌ")K62ق^mH$斯!3l4 V "Y dq*ZD3dr<ə:H$di {Ձ=Ⱥok?xW"@t-){vÑNάLCJ5sN@QJH-< 9$d偔[B2cvH$2`U,KlY!`: %;K]ɛX#g) qFYx?{V$́-z5eݮZ1ѵ Ц鏲 @3!]=Df<@Q,Q;F=80g'80gfǐ8Dِ. ^3|a{RtSw{@ۀ11(P]MfAP|\%i3j]`ih6SF';W vδ>~װzzJ}2R&k>[DHV7i3UXi%IlI8LLp%¤k }ap c]׍>թ*MƎ!tQb\vtg7%:,Ȃ\HAK eRE`OB%|a샛Ȗ1DDf| RDW؟nz/zV ӈF1IɻˍMqs{6s8V,;fiLZcv Y{BpA0Q( _7puT(Z0qliDzN=CXu>~ c9^'o(zn& FX$PSg?)7BqZvs@C8R[bwI H<`(g͌.U VK~Lʭ1N ^^5=i`M- %(0ѳ5ZYCu<ҕs!J礀6h79)iD3^N4 E]ۍ~\zQ呸 ,%6p09IV?8by/Y)yANkuE r|?lf*ȸ,(@=ވ#[s/k좓l{& ҩ}fj3\apcbJP Y &LиOdڤZ1']\fw)-c(vo1Uш.^ $ G $~ChpL-HbB^u"Vɟ jbŗdI@Ιv`-a>l:FuB|hy`Lݑ5it7чthٙun&3>sssK-(7I+C9m+,x6ḒBpλJDp=+ℛ=[l{Peٞ+`® ;&s,I'k$IDtka8Ǥ(^9VͣL&& MsLqT6yE,u<%#ΈdgČQ$iѶbido&))=jH"<>zE[Aç 7- ߔ24\`xktk"NZLɂĚ?VFP\Xq ek iQ `=@AyOo ^#׿2F}j2'KZ )>pz>͗yD<G_6kfa oAl$(I *R"PNEiefD ž*a_N @b[ЎxƸ$ܱBR, AJv t0ޞӽZq^~Ic$z}ou(F<ʇ@%^6AbL&#%E&yqP/!8 h1(%_>nE~vç_m~NfBU37kl`݄i(E7unlԙ _pqǑ\dʞ}`'qg~J |tfM~(DX@m40" A iˢvyes-+Fd<hJ) eV4Y]_d{C R*iGh"w"g_a(efI퐕҅HGV1A[(#isrQiRD{={#/ޣe)jgzS;JR{KO\~>)#> 0=II509^IFqh VgMKfPg`agN^s<NJ9' c!U@#+pSce_zqᄧ T@ P_XO{=^HYE/uWꐙJE3Q hўpr!JS=1#DيpECVgLS[*ע!,"\m|#}w{.WZ!zkx(k |g">Y? Kwy& [c%kiA`53'X[Ift L"h聉y!rFzy-LrțC)|풉#/-fI3i9(6;&وIV^cyy [cTK=s0\Y( znS 4u:B #6,ٺ? ])_)_wBgˡp\3kMm-%\J U53Ma /F!xUPhMD؋Lk1QxͣFrhqA0Csb{%ah% NIbS Q2+ E#q7ecŠ{!̲L9fʈ8^R躭NB" B@(a,5ne ' 3phU,F>=ew}gV d0V j6^;3s{Ƶ`lhwc<0&3O1~fxP%;ȳ3i< kd;^1&֭iLx׮BAе"ZL  Š6I-,8xT_L3|@8C xcYxc g{2Fr4cM,fBeYmV%Z 8FX%qA&|jAlRxh~%) eGҤV(`0i#d&܈%opF&Q]dwjgW:{V{q-I;!Eiy@ycS[.EC)V0'ʁV1٘m4i :)'J&wH.5 #Hc,za A{Zi+vF+8'Ra N< gm abgh!Tn0b$0!% `٠E(C -6 vmM6p- ]˨8WA9+ւ18seB*s"h Oj{0O:t:eǷ^AgF#3'j51:>o=| ` )h'sS&(KA3ZtpMf{Wggs2fW 3Cp6M¸Q pZy w~v>`|R-alI/{XXZyO'ƈf٢|BBK:3B@-h< տBRs|A6E)<[jkЮ- A}kFC,!?h5jjg]œ_bƓLikUQٓ}}Z i!QcȸiZWS0J$Y@?$|/;xR(# VHgmBH&,YHL(8vd0bO8 ㈪FW WdҶ#XdU%H)W 8l7Q $bɢm#XI\LL*bnΦM i`j :m [oQ+NhvE4c=;hTJdr JgR9MpgNbJkr4M?_/e# ҠB&l $f8M "v^qcwZ]I@(-6<F9ÓUTq +-unM> Ex T.Ww#qBFlTq !o?3ȆiP X'j`y닷.?o|u1;ql:ȭmm=`|᧤m¦V̪S)ݳhhaiGjY9N"nіHB;@"aK98EwY[@!n{BM~_N۱Z?DŅY{ֈHRl|%-Bܰo4BJ@xhF6' SlnH~oɩ$$ l@|-^o0ʸ_Vvh 0Y5؀ O;Wjmd;vV˶d/&kMLqj&s'1gq_zqbNlα v1;_w^bjcobffҹޑޭz |~6O4(D[Lk. )Z^gc]<Ȕ(6;CPf0h#⪻F}MZXfkf.듕ba4EVP 2ʃ`c6ͼW'vZA+t q!m^޾S#2xU}h(Hdp/<&|jt4LDjxgКQ3-G8"kܒ>'7 {qg*fpDp`HfrL{k3}hNnnU&T.氺Jf4)bF2ZHY/Qէ;&OH RItrizYe#U_r[<#}m^TpŶ'7ahr\~}W/X:|,qlIp6N9-q|rI3}>N߃O2bO>#D$bKOaxtw g7:CVq :3_)_,dMN*bj!VϷPyi>& "v"X|洈VnG. mTHn{5OB8ߢ> ?lpb&BBI׆T V!GO%RJc8R,~JxəwaKI]m=_ )$ Z1-615ĎN#Ń Xڔq#;Uޱdy. vGYB(0T370T}^{t"x^}/яsc4ҭ3gyj;_hmTV l]Vٜw}=٧җL} 3}tDsd~b:xG5q8~ ~>) ĪjEz֮í38]#x^cL3%7佬dXXGrGvDu-|ZCL&u9 t|δ3-v.PhCu(A&(ޮa8E 4 FCC^=.ںfBssk9k mLJon_2Zjn8oҫ8#j;x2v; \Ȇ G9j<۾oO=o9 c33.T(=➤>+]cpWYqxdt&G5A-ͫܛ|yBؒ%D*D+ٙ!Z4F19h7+Z9]`,SKUm[_37L vيA$QDA{HW+Pѭ~ᣧ ^?|'Dz+_qyp*G5u DF=?E\:k(ު}\c(~ Ъj7ԷjAoLP+]aӂWZc!ˊO 20dԛ0nPl.hql5CrdT?c ;LbéxR=.TOMY}yvh';ώ `BCTtPb?KOҽ~+ iH }G-TkR?M#QC=)E9n4(kc0ug>   m>~/'=7S+//N9ZB zE/\c3ӗd>=|ą#Yk5?Coh]hr=x9?9/tn䮽| |)S{8-*mvǍ54Q4~@T9o C ;:~}.-ߝl:n7y㓎h% مѺp$ґzi3و&e3F2Ӂ[ҟ[H-zy&ĦД3۬X34$ ":%-{bg=9md^K~׶ dYm<)mUsPz>f:ͥzr; Th(LZNJ6*}жG6~ӝ߱ၗB g>MUBb}͠9>XGbЦXЛ^si|\SvSWK} 7]/u%|!q6F}oZ# 8 uk%!1VEFdDԂGH?)#m*a,$t8Z85]Bi|x,VQ+Hvȫ,S۳DŽ3*5}uzNhy;:9v 0^PLo+/ZSx54Z v(:z+m_83D<={츥 =ܾI@rh3= Yeћi5| 9ٞ׿#g?{O۷ 3s`jꢱ5=m!U9p/?x \{՚x>Pѿp 䙑W^Է6E'-ik.קҹ-?9GA2~;@?iytصʫCBtHwfBA?ZD4KS&oX;iId&) J*إ8j,ۛ*7n:|qqG%\rY"ZhFmvg7ڎb]l'i>S5uW/^a¢kjw9ltn MN 1v̞Birz;[/- z/sqёTIc<"QAüa3!mbSTaBMP[T|qt)aEao-;#%W-rA{9$v\Weꯞ-o*a$#b3 fЌ$q_}*>DU_o8m-ᠷwyMl^Hl(LsVV9upv͸=7x| .XEk{#4CBP'#ʻξ44Hmꮁ/ O_,#֑fKsꟊߕ7װ4Xнe]zmB e&Ʋkkskߵm?' E_ޭc@]=QM r '?3o:8,,$햪!s2MB^C{.}ںKF]ߎ݌ppX ⎭rۓlVɤ(:`hf `#-Zxf >*ƫgŠQ*:@N =QQt;ZQNĞL^ZYt'yFs/^HVuK&5{We&O(߶vT{#rlhIm3g&K_b\OO/ڒ:uDx?WH17>[{32O ];-7oS\=N6k %p4ȉ6 9GJNK ׊:q<1n;.4>v&0Rdj@ ynk=րWW[:&(s C[veãKC>=)cxr%FSvԥak-itҠb5%%5dTEbg_)ޗ? s8OcĠ1X~ݫv[!8O.#÷ƼWcJ7 v?zᄐyFlmY#>7X<)"%>֥G=n[Tm3ZKwZxbnYrPdۓQmc77qκj/WP?KhRx/ǟQU7sz#U=5PV\ *W{/x6-qۭ .#kӟ!M )]V˙ }rHPǏjXj:3>ir˷.V>3[WbFc7m͹Tvyae׶A&@2 ăR`A )5.O,=7`jlIix;`<+!-naW6z-ˍ["\zРzxrOvt7z1ĥm zh7~[b"#f9uҙW Ûnԁtu@Ľ>=Fybo:V+h}/CX‡+ump'0JK+'pt|w? )p0.Am_y/Ȁ^u}x* XP `0" Z[$6yZkDzx|)Sc֙%L8T?6;1wЈ{cؘ\"M1 &S~PJeM}坒%N|3ָv,rY.pK@l9Z^|ƀT|lyۍݲTa}|}}xk`G܊ZwjxDqS?sJ7q s| V&+1 3YGJsC kgV瞑oʎm<jm{K\'7u]x)߮w<>f#撡ϓGP 'Hd=F]1>ۖc6jyhq&#/ cf[m=N/ N)>6_}uyn6tryꎑdž6{w_5΃s2{չ{P*q5uւn=Æ,faƠG~X;eRNk k짒U];Ѡ⦅Ϻ(nI;t}XH$AK/~A+]0U_aBX=Iz c^-j0~5CE;vHf8"}Nϟ99=\hsn_Z+Xa+\6|eu_5׼}z7ϫ.wG+Z_#QE? lX5*g?ODF=S{ipnn6(mt*QHx ./˓Czξoi ց/:ZOTX\Z׊Z C{[Ҷ+[/͵X6Lk//owOC ѥgѽq&I4ږk:5%S S` 3[$[E~BiQ DMf=Js_ᾡNͷ63VOֈCpz3@#8b >ܛjm~ea-<^O]|gWszl aCul?tvqP@"4z|hh>0M8mWհ:zΧ>^5WLL߿?Nl_w0w{$ ??ѳTM{kc[֍d#6!ba>"X5Z۵TU"KD37ɕqawv(abnX,v߹-+?o5#(_P$h{|"k~Ć"D(DOZ˾xme;.j[E$_sPlqt?9O8$/1rj Ck)R~S lJ >R ?np"+lmv mJ .|ur|s+GdoWJQd&Kpn;&VAх6:]R `)<?_xRGxlWfMV~FdLKO[?X(>t _vkL|I!пH#/WR?/,Z'ѭ&Z5+:+" tV4 Ri\wj4gl6WZ@O~FS/_j>39X 2>r9E X $RV`q{'ui2{4^BM)UQwѳgH"H|ܴ^i!| [`MUhw?>b 5:|H =`ʇo=W܄Gvjwൈ!GBuۓO=]W$*%)X*['+^zbDM+@kR딞j+dl*sXZ0ܢ_.ƕHEcؚuN[ڇo5;3~5 DCcDρ+c{+}F𛧾∨~U_:_:u꫆$,?嫯&|j ~Pi1@6v7s$ןu'tw撹Or57I<- x>I9ا}P73Ü1z4`D@0 `ppܲfX#M4a$h d(6p\f ^DV#o0s'w:VM+yS`ȭ,8Owp:==Ou]q:DR2D$g-A1nӥxk!ls\>&&8fHAYL`s&72YQBܫFVdU@Q#F3w1a4Yu*|0$/1 #)Y2ZN&0{5}];hF?O@ѥي??fƙҳ=P.DPPdHi R ?i?_@Ix4}$c]r$ .=y&;M(L2j1yhTgb+d\1YԞh6=kyԴWkxU s?i.E5҆-w©$ S<:KcNQ4E[.J ~ 'p0{tF1%d½_D~6fdw&Ym%BCIdk\>=0Չ;K= S8@:Xˆ͂-@IayFL?w??!_oK5 >Mm:c~̌M G"/"ؽFseF=qp7V(eqܿW= oPoMEpW,s˧"HkN%>t4г2*Z56`J牰v't!>< SY֨Hސ:"%|6sm~šԓUPkMM\RkZs^;ޢ}U;׃_)x?FU3'~5GT3anHty^ Jl0{YkFZ /镂iehpmeVmqO+ۙ{YƯⵛxg6 fW:\+.:ZH/oG2kW^覡/Ḙ\kU_<\~&Vcx 3 lH} ̰w ( q N"y _h(b!3sӿו.9 $6hVR >M_3z1 #>ɯ'h ˉ1=}Q2MChx3ƀg?5+25/gÑņ)BOǧ"jkآ])DR#߷y[$${®\ϐRX]B^ G"SgJ.Bq4vw8}@zC.|A{fm(u`Ju`H^a:<{z_bqBjի&7d6B~xɳL^QoÉ\jQuǐp$7$YdW2Pɺu} NI蚿 >tInĐkq ?o ~ <4 (89c2`r-;sV:=w!{}>U 'bh?kv @z3]g-Aws˷>y)dUz",(!^2smO~’{gA~@sp5~xv-+5 ^ 7 ܚhF}&^ \ x'~ ޛ/w!U<1}.N >)vkh6|! Ϗ9s5& QlݓnͱSKq.(RejB0yt~C?#΃2p<,ρp(4>;4[@/)oQkf+dd[tԻ|a_e[ɨE dv2D^g,>"KP#s $,@KR>6)~zmY}4ojà]&]߈EQH)ҲJo_@ٮMlܹJbÑ5sZksXlvFN0Q>cQao+ƿJW nax+VA)+ɄHZD$NAxĤhlxG:ֶI<ӧvx,~CDF`{Wo6l I4&*bhKc혐In0:Jo&Udj)X:쇨)ZD2Mڻ5vآ#&L^\J[;܇3S:;ݔilu7KRl-rm{Ssz*k[gh';U%ݢUZŌ+)lD?tșMʈ "& O~:F/u7 5lK.ȕbNnuQiFrsci%'64+&Sg3'i@OCLe%#4Dz44-ف Ɲ#WsFhzudն7(db:W#4ghx=hÂobbA~k%p}iv~~Fjuͬtzum^bu%nVsl\\QkYEz@*oVX\5wƻOz2G9Щ]f<&듪G4,_D؁M" b&S]OzqOˠ5ߖ>'B'>N+Pw6}?%d$ @"J蔑6n-ijN٧v UXBӻ:'}#f؆&eeȩCXgf11זM(Rn񊓷5ݎ{F -/r%v!ŢNGi%MY$ASO3_}),+"!Za$'bkC4֦k!MiB2WIJk"6O GE*d=JzS*@)Ra_.D]~zʩNE ݀u {/< dѡ Əf\pzNlF*k|_~=]3B[F|[Z 9CG2 p7S-^ MEDZVZ~i+gōNN/s̛Zz=XQY:ߠ@+<t {`L`T_x~bfݫPeVC[M=Ofߊµ+krЇ9Y9lk|<ŚL"okTrv5-Lڪ-gg,>w~GG*{~Jבz+5ft ־3}'km}tR2R;xñFՎ}Tk}ȍkmN;慱CKVBٕk<|2@m;MJfQ}bgaz &~0{x/RKcA:(.{H%` b!c {ؗL+ )6Vg1G8;zVHa R{lgol[ %`V*#9SR%`z$FOL)9jƓ<^K1-AdĿ)&R=2"lC*3ssa{,gFx߸CvxF3p #<䣟+`P6<zI=Põp(`^> >W^ X9 M/j5I(Md{ $RtR-%N{um_܁įx]:f $ MbcAQGQ s.wIyg^A;Q],{w+}+YFL@LH#DIT|TkSg<}㌩3gQzVx%i^s%cG>To?>?aJgtx$m.܃_8dtL!5;A-f؆]As)45"e&ʦH[HLQoDmvVH\]bUw.mY:3FBk ieZLѲP^\iEyYVRfd|߼ao8vOJT3}d )ga;ղbGTJCuD[VPvtxe1U$[ZLܕ3O |gɜ/\dn 6JS YZan]w .xD w[\;Ѱ̭q[ST%i/ؒd '8]~c<tp'0O/*RI5[uGgroTց);qۜf=sͮ_cԜ74xg|$kF6%zf_|WWcuTHVڛW^㪌nA '`d_^pv/Žן`2`~r`VǥRIt֘M+{8khSO=7{Xr6`q4g h?} C" $-aW+LN9c\|:u:#=FUELa ]}i <~zA͚^5mQDaOtwV:_fESK9I :3UݝMIlkLgIIi rݗŒL7r+9qL&4Luf< Rk_DV m=]5`UϹ5OF#-h$??@5c4zdA vXVj(G;FGV7v7To,|Ӏ׀sp*- bBfO+Wjox},&>E,1b@QЇˆ|9˦i*ޅ'j+\7fb4wu]2 餺@:`Y\Uo`ьࢀ'Ϫ2qYdܼ&sr)N(§LGϭ*@OI烧MJ%2O_Yobwje0iN;gNuMvY]m"펐9Tb 2}䠮RO )zdNj5hCm llnھUu=ٱizTs: :VvH(l cM8CRXZ`M=Dg50\x]W'h׿|Ʉ[g,Z^쪴`)kSچ>~ F\0 @?­.,DW<5[E86gtl\*6eꟷGMZgdpb@m8sn3o3oAUwOΙLD0FM#C&R#I 5 l+(dXFM͹ڹ?}V.c:6|.Q5dH\N_Zf#DdnF4q1dfKY@T>~dZؽ|.'5#r'Cx'W)Jep23s rSnHlj$rVѪ4J0 Vۓg] ͮnɕѸB1Ah%74FA0XIJbIRS ڰ֩ŹE}qĠhcNF$!A=[O!5߉hA"~Un?U_*н|LHP2X'EPL}Lm2Ќo4TnXOG( @ ]!f{g qx)*{ϧ~4^ʔN@ |"cBL迋Z~/kc@jvSfc9p%?(eYdӜ6--RXt8k~ ^at8?jVWM1⩦Q 噏,? #zE_dzGUqξ- ~{p<1&M/;B¢BBh())u'CL(y`-1^4]DG}{}١* x"2X.K |ʴUg3 h'*(vzq<ߏ >0yAJJ˒?R~=e1Oce l6[ }Q[QUS1C/nSLYD[.U K{fƤ0[G\F 6zҴOl>9jHtԪ3vʎGB=^` Vk> Mwe}hV\ *]5K˸*Lu#[P=XyĄ34|;{yZWTRFᕆѮSf/46uи{Q{9Cj:˪aK$ʤJc0FO   I&Ǫ{WvrpEmP^Qio< 0im%addF dO'&| ]Ni(MEPeLzԗ\ZVU$(;ז>we죞Iu'0]@gB9 pBKcx4 *\tOʸׄ 5- m-y,g a\$9^)u4?6xej >:02>]>ʎ_?v\L>&\d|wʅc^⪩CjӦ/?|)a 6)7^ˑM]fvNsɣ `")'V҉*fSw2qMہr3T-:>[fa51= #hok:VF3½bVXߢD,~c"d0$w<_0on| G2̯Q2&\50S3ywVT!u,H ]CDCyz=KptŻ=% j*\ C:PBW:_3˯%9 9%k)=)>3]=Ǘ |%žf7?_]ƗifG W"9[Y_K >F^bs8zWO:_?gZY 1:12cc4o$6]U~Fm>z\H=Ϝɐ<}ĪQD]M:䴹.Bf4Ȫ D9ӧrꪑ y# Gi5t"16%BЏ6,h6%exRTX78|5*Oӵ)]B|;vo].^]X~v<$YzҤE3 ?)ct]toG1Ue{Weblcaw$T "~ bcaat=a? T K,;Op@Zŷ׹|}'xm>~1OP }%g>{9;>m*{ CJ&x9#{{?h؎̄b#2 ,5֪z_Tx_͡/'2I^ȣW s/Lxk@oӽ6mt/3LqMQ~!u xP>&$2o4;!.|euG՜9vN6_lruL71 ]Xt6w\tIA֥uU ߋu0KWcv5Ip7K!xzc. s0>v~'Geʟ]T%y'FV(m@(~/O!W>-W"ɿ?O^C="= 8y"+gM?bvHX2G*I rxx1TSϯe/CMb_żE ޾>Fkm|we#_:C֐68EEzi3x8zǔП>s|M /{JC|>s$Mzawqՠ F107%Xfz[kZ>[&崹ݞ @oY;1XS;( [kU(z<^7uخ_r_I[#P`o(35 eк`,~z07/F~gnOMY^ruD>gRFԔyT?(9j>@.N4/S/(kKRyݥ~-us+ϸy8+~$)/cJ闓~U =.oikŋ =Y%%|?4__"=oA߫EzF$P\_Ak\iȕ>Կix 9W:/?_ MX Z^lg_@;`l5Pd,(᧜)_~@e9=v.\cNcwlT:uCugݏNZ uD4N^ѩldEerM[iɰ?<#_~ֶݿeVi歷\9>TC.AmZmRwJt~Anh UP?O?"0{8 kG9WsQ_~al/;8z?GίďHtQ F)>HpĶw^Bo,wу>>Ώ={dD#.FgpR6BC!s ,igŜӶqVwi蘳[FFU4qsRq&du"v0M֮fԏ`tlW_3 %/l^-6*2Q~ ~׳S_K1P|mQ&~Ddž.4Ldž&al[&oFof8>A %iZJ#z·LP~9W%k؛o~-h}9zocX O}ć_N}v c'h}[7jR+rvQyrsNdM>w5i.(Cf֫Ukorw(П8.|xBƬԮqkx̣9s5G% A9OidG0g| ֠➓Ij)N1@T~aW#ns~[Ia;ɽmmۿZ#2 ŃYPm fw 3{s CM^{^aߊ6΁Ae+Iךt}pWх?cVwu$bsooD[X5:-:V}U垤H3zFNۢ*-߬y2 k?(ε%x?g_M|97X:zt!sc2Imp_W}8VM?òx>HӞv8Nߙ]`UnNϑ5u>r-]{3B66Ԓ o?A o\?Nd,+W:R٫ |76MF: rg2ϸخt*/X*+g{(|՟&xFiw~޳ ~{ qMU=5=sꪣm_Ѣ}ym\ u}JxbKO6.|GEx1$nހ;jPZf5HPM~6ZRuZeDJmڤpK}aP_ ӎh3`隯+O.ŏcycOg'Yܜ-iu=BykW1YXA:s atoo/Ͻa@M_s3XEe[}XD}̟mp/7+Kʿ@?X|/uV.yyhg>0|>g-Ͽ({EeٟGGbw?gEQGxwStQG8Dlw/S=ȣBuy00&.S'MAp󛀞~S9Gngk\0O_+|%+kߕGub#}8P~z9:Jq~ VM?#>uef m(j.3-hw~|'o3_l_jÈqؾ}R"?n}5=FV| ̡̋ /GD ʧ6oeC}%s>JS y )O-O!gPK%df w71zlFM 3AOj"|}9~K!wYAd$П8Ͼ) wc@ɳu|P>Gy CdκkJJ3(/ǩKy3C( >FyiB\}Q;fd`ߐ YrK׵e 4%'#?Ek4)"滇drf`("jC@,jҹ]c 6\w&@ (>3Bפ ۬NP>Lbj-m] 8jrj'W8Ѯ;r!lhD(=sc4obH2܌ඒ-n˷w(LL7K<ɵVx}=ijFsmN0آVnaY?I~h,)ۺS<ؒGLtwT;ɧ5DEx*ۚ]΁†{Bګt9z(O1܃5ѿXZl3gQAߠc7d-6\6A%5e5`FJey]~QNJE t Tz!] ZcG M+W%&eo s~H xSw'yx?b܎ FA? ZV8Ȕ|FRu7?Q+}f/^ ϧҲl? a *lyzsIdG~_9n^qu{߇x?<~%WDc%/zaMr!_^'Me[o.RLe:2 NN4WeMŞ;nA :i"ֹ|9C`rkFkiSo+.|5ϊx:#b? x$r9vbro DqzAt TG4_(܃B߇k 'mwSY iD\\J'>y ιVᭅm,~H xSwXs ?CȎqm-vjG%N*濥v?PAR|7&/ϗxj|7?ud2/PO.e{T-ex2]+ũ==G- cPC\=[cЇw.yysQ%;Hwqdމ<={qt7vNF+n*#_^'Me[o.RWoYyo UE9{0uTƖqp:˴O!)s/n &MQcQs?Nuw0$:a7}e}W@+K{^Ǿ.*˘q0N^e /{ے1%a e_~,|<3 -[0%_|]7>J|e(h% }#_Fe{T-ex2]+ʼnx7SUE_' *Nnܣ~9 J %:*qͤ(F_NWyrx+3݇9wR7#|3?7#|3?7r/-}%Of~ 5O(|/o8 >h#TUXh7=Xy_'Rf%iPBqD/RJV5=o9//2m-Ë7 x_)ΆeJpsx;9^x{.B>_'/3) G8zr){%pNv~`EĞn8]E침sn_ kd0-+og~pb7^?+9mme / "K+I}ާP[7\YLni\ϣ/s^@۫\a}vYf?JYp"}~\bxs9k~,ߕ?gb$з1T 3]=22 Bۃуeh=j4uT%qs] `{4'ꕂ_o2xڴWq(.k>~3yܓNΐSdn|-- aa):l$naNlaXEB9|v[5/ #B3" jeq\ǼUpyPIJ1 xyt%KW3l d~Kd$>:6w{A= evnS{Bc懁;)7=̐w [h[ -N.&a ߥ459QׯhZtZKi{Z^RGfQ~Hڧ'4?-4I'~E׻]Ngmcql< u@/{~bL\y+_)JOڋXo%qNtx9?C㩛H$&+q87弌Eh~Cd=i~[DWv*'||z\q'Ė 򢔉0q),C>P;<ǡzGg}:ɇSLawVWla1T@ ct  Wf#5˞)SÌEb2[!;>?VW1m;-6o*i34֩22P~ iBK# h9j' Qʸ@VQZ"H=~24U1aY2 R*zUaqV64; yծJrX@F tIDu ZS젎hOS9<4qgh9rnttZZ{U1Z$.HCK>R}!'qtz,UEYt]zCbX3Х_mvæХ"w`erөWzj4+уi_)N"$"%(ssə-qu*1%0SИJgAA +uN=?d05\5E7VS&=G٬j4X}ECР; 5$2@ %2n_6 M4NB/Mkj6-8Diڿ1)dt(Rߋ瑈Ah%L+e0E-!?^kmbF}<1djkwRo&&$/V")I*Dn8*K>ejU鮪p5:י*E{OP#Y==MAɺeM3kfxgHA?d3y:ǫ^jv鴦Y9)<3f[Oo~>Wi:'E\(RȈ SA^i 1kA:0V@#$/~ 'TQb!/Wal*$D. ϙXeE֠Ӵq02.7=UNΦBO'StJI3)eu:ǣx?r'j~")<,r-;qvŤ4־[WrDNwUD'$ zy| G GϵzBIDD!s0tdl0s8: prw< <}DuL':ĭ4ZFCs"-^?3MN^g9;ɿY7* {5:~fxfkp*|Ūr??ޕ{1Үi=AzZa9S<բݗzMg~;yR)( k7]7v9M7_՝] >jQsg>RFżB<2!\|(FG5w.7xY94kEOƇoȽs882"0Cͥi f2iS@]] =mKSVU٦GloT꺺6dF 93?\!Ҋ|>iFA--@(>C{9 {[\Չ@Ƶ-dk+4N Pݒ;.N#Ҫ0"T^I19@=GrPUvHd'Q;۝-Cct39 ꟦ڳgt[f|*w2$~,$YNg/0KG{S=kijl$z'yUw$>4kM w8TY7®B{8j Z~lP# _P;{Ϙod-JL ԡo߁JO9)VCľJ+zSuuˀY))r -T0u Mxr5yI˪{7"<~6@(I@<='`Ffye{Lt)JIIȼKVYv`^0;`K ͽ<,"{UlK9;6y3u('`:(6,` [0qSБ\ ?C2".(kF-,T!-,|povi֞ P^,Zh5"ci%_mf6zrƅY6ZQsW8%dfKv,WWiFv,T —iݩ˕y0T3ir b ?; M 0l8>FEX@HX Uzn^4{MLRK+1k:Xe uŽ4?%p?^g͕tn{4Iy yNhw!gǩsOC9nv?[/gɴID@v 󫩏8R! ~3K2~Ge" } 5c0L>52kzWѪ5,=b4u 6r߻#+^\ut49 h臎*d]Q t<^ukMUEVմ5} ԓ]O] WesdЯ"ÞΈ|7΍Ja?Yʉi\`>7Y$MSHN!K]c-)rXKOhuC_PmAw-љfG43X HV-0et1Dn-Yͬ4EXkTmHu_JqC2.lt#P)DO6 *"TzJ 6US[5oTX^-F ސ' RuK{'\yL jNzӦ_9f#O;>=hDJus̸lY1w tkiF "peF!qL$`"Ά\A=~첻3fz+qsbtuP'FdO茸Hj6M%kEɡ{zNܰĞ+y0{),gNnut8'}QL7:H=q&zBf&R<=KPNhUiwt.å3f&&R!JkHLsHHJ[*"o>Wj,w֤KU<-{`zoxb5n7JP ,$l(q{?bI*I15Ba5'b6YLb$0~zA3 Ʃ$o!)-WHq{)I"s.knЈ0O HCKJD2 XvT Z|mHU;&Y|{=jp!YEbh,-w$b2#gc6K{2 2ʠqnqpKcnI ҐW'M>(hv3@GK.#'H5d Xґ0 Ƴ3:A5ݹ_Q̕ϜJ65u@X99{ ,/ӑϣX?|C LNLخsāSђܵH)kaA趵/de]ӞH s=;";dL|ٯ(I})g'{yXp1k甾*NGS Ϙ;!t1wV}dEmMnJꨚMFyrt̥AtY0P5 !AZq+r{|$Oމwﮋkަ͞Qorzۇ 5>l;W~ _sMGz2Ѩ0PkIXn5eLR<} 5\/겳.m7ۼgx]r;FOLVd,̀Z _03YGwėjh+;d$/p(9%$mL8C,hd)DR5ă䥂Xuɀcy5޳*1ɣ*Ukz6rrOj۵}J1U0"l |g/vH+\e]м5[Y+Vg:=.{埋6s !pv,SyY;bzQ$ ᧫R/kqθZ8&en TORĥ{ f]i;w@D 3X2II1$]l VDNiu7DzK B# ͽqYh4I:*MʄMߞp>i9k&͉N>!{I޽AЛJV_O9p8gT&!8Hi {\$ Ljk~rӣH9aӃ7>ۨ~%x4Hè V*ŜXY2`hzWm r~7^. I=M&ersah<fIY51Tf2̆mKզ=*TNwKOI:]S&];;sw. ƀzo!;8HB sowC褷ovvvwfvwvF@ZMYllhΣONM|Swr q]!jEK˳݁ӯ"] # q,_I`_>7$F x *Wͷn;O;c+οYtcP"1`AB& Յ@4Zv|QW7vAOLIc[^Rė@`!9"`/ܒ;?a|?xa"9!zxXd E*zo)q;Fxβk"DFyolB﯂;,Y@VU׎-;Q=M3o]Lv54o{bwGE9HAiQV{_N6/S2l!#LEZ=6#ׂ+v)n$0!Ϸ"5T1 w\i*y?׆]VEPR|$Ś8nX0ƣM(j5º.XM;P`[[&8:89*^q?9[Jm=K*ܪ߱w@lL-_VnJAAO Ը8ןO@gG}g߿`S~Bp,m M5^;=1}b'9&DT(+Iq3VN܊~8ۑ95ԏ#qɤI B ?VkkHo?($g? rYn+Ԕπᮭw=O=]wcOϤ|xFkJxdDX pu$+Ev$I5l* X+߶x҅EKt"Qzʼ9f 5ZYoΞ%:S,~սVu?)?(VdW62(n>u*KE&e'.ȧ Q4]T壎2Ľe2uaIȿp9<: oά fV VWVuՃXXGG ΋uߛoE1B.. /sg=xXg'O; pj448"% 6 m|B^6+k62:PxQf_ TFRx9C9x Fr}h}_JyE|swrzІP&QY @[8x)N_jRFJod^! sLWp;9PjeWj X]99#WXLP݋{iv_M!#3;O;\TVww?E#c:4iL'0d^b2@"vdV02LI ?PJIJ@ 8kY2C1=y\*ufcƩ֙zEc`nX@3܃l&cgV`{ut9RAͻ{v$c߉Qj9G'+ qjAhS=D_žCB ;4 _0Ie+=5oM:C.~K(--wPɆV (ui[9_~tHm3(Jkٵ+O (!6ajTE5+;P\mhӊeZ-Dmu|ʦ3&YZv7.9EGKyE_ȵ.[4%.: [bYh@hI1DJD"qia-MLIpdHSK)F6b۲|Uݑ@{y{ڦj vկt;V17e f]^1XW[=֮QðĜTwʚ d T 5XIpҍ^U N$G))R^k)%JI~G&Y˽fY |Z#kbopUhHV4VTy[Zx߭k:7|ۥ:1h]:o~Rx̂BHY%zuC) \?>M&;l@o֧8 %"Z{uf7JZL:Mb`mS!5C'@L+^SS{U;4J6{HS&0eh>x3{,ZW٠FݎS*1:+.Ah=԰ Y9M-Uպ@\bjIbd5)ݦ5B#hKuW.Nf`q- [rK0Ɠ%nNS@SoB n-?e%j@*==>aI]K_jR˖.Ύi=m\ll_cSEX}PT>RkkΫ޻\-᝔B}<.`uP:IeĆ}s\LHDhp TjJDMyx/nƚL\6j Vl T[Cee'Mu'\dk_JQcg(6#8cht#}8GO "iAM9L 0ʇ?/EkFk |%MVW]kټSKҬ"{ c Q/wǪ#%]3.&ܼ[R,6.fNZ˭q*{*a[Qg(%*l o8f@# q& %4[2 dhpOT.{[V뚛H(ykEf?*6C[ᇳ|=ax<=YZ?V;]^Q,h) Z=M ][c^Vc'{ W M4^I7!?i&эޠ̪]e( Xc7:˾(swK[존E֐eae pLQMjΚ*`w &.:$*FsZC4KAA" !hT+C:L-Ok^աV?'ˡ7bGZEӆ)sa|iO nlpCσG,Rzu5٥gۨ*15z5+(?F}BBjoW]zjd(ֲȚB- 0)=#(2x=S,&rF*PvFӪ"I-F[U3Uۂ}2F7r&)`/o>RTK NUn[gdR \HtE+7H=zߑGJ5KdsvXYe4F zfc-˸OU sulTc"`TfTGk,Q?2*M|~lc,SXơ1q%BuyN=pSD]-j4j]XV$#vJC˺H:&Ν.oLJG`ROUFp>Vǀ/ɾ0|q{xL̟xb9JM k\ސΪ:DEn%X>xN# >2z&̤$*>?kN_o{wͭΘu #]v_>.{p YO=Hr/q/ϑ/~zۈ $H^C,ah`$"FKq!)Eňhc%? +7MgHjb^yhbTN]=Vg 1AڷΞEQG·ְL}镉m8d;UfmYFL)-tVf!悢lrFC\)hu3[duZ/mnޗG7P33hΪJh#8O) <𥁂q ?"4#}p2nlptC!ҘS V:WgJV֩tR2PuU7§v 4ڲ:rz*$6p0LĝVrHpU9j}=PU2Bk8hNގdiT3oJSZ߲ؤss${UR/ԡ-ՁtlE7UVT$K^qhX6yjhu'ٖ0sxhc}Boxxt'oN |yx"e-b"3gc;-v׊D [w-4ݩvQ;dIpkJ\-u##˚i\ >ciހ)&rNH_ b%@rQ#_$A2F#Z;~Q)=^ucx B^'*<,bx=|~^y7g[Ln;Y?(.wv>v:c|OuS38Lܤ{#؍Vu16T@ 2m?*@L$9V A*IVR,TҤ b~4hE[ XquX!jYn=šȵ\mDGF+]`[jupZҗkQޖdZ $_VKNl>k1`cd/<6F *߇/<̅m5ABGE,=RwhK㆝sօux ހ呺/~\oӍIמqGfJQ#|n斦SGSrթڡ/?tS.O;W:hVKX>c˭k ^G 'є{NvP*PF&t_̙oYuh,jX-N6J(7+tFd#kK]*Yʖ֨jn_tpqfo3+k3HmΞ+7?x)^C.`w.bW{t:pgBC)k"Js L=9il5I!+=v[kXI:%a&(j@ȪgMf-r>䑾H3!/ԅB&U}gu7]QnIU+gWrLpD\*Dv31mWuҬR=&+4:E:gF{\2 muGH]ψ;,H@k%쑜,45š45y ӏOnRX*_[L7*g;A2,] 1pÒ~ Oo[4q~UB[UW9E^^?]ȗ g/:EC4~]iUp"Li$յϩ0gr8OضO[5 Or~veaY{MDeg-4sT5t gFH :|M Q3T֙GdiFuI{htR qg"pםвFS\`+{z^G0TɇC]98/^ql++ _6wl`<@g0̗,,KVhWfF,0pGhin25%3Rޖ)qU翥CG6=.O} PYE|HR ȱxzҞǀtloy䙞*:/0馘R_{Sˆ jJNitD&+KLih6Eo*` +7lowrqo#]*!GZ]Q I*6/\FL2CH&J BʥmŠr`U 6lEPU w?rx?%|A HxY_ TM^vd '#@Sm]mm+pb 0lk8SmJ2rGC WwlF=OTOST8%AR"})]i|hEᘙgB @b ;FxK9v?XfhlOPB]4u7|YԄ5CX3 }49ZvX2lu%c3T8wȓtuZ-(^ju鿃F %ɩSc ۥ,Fێ!=2aHO֝t11 o|5~jZ_3CV4lp,¹gh.K|j[UAah}HVg޿tTMG쉢AY]ǓwkXj_$xQeSgx>#0(ML[ .oKL|FrϓѽoՔye+w%޶`ѬO\rݒ΋fD~p*b4LрQ!p%ʭ8)p0:-܊n>6(\/C#[} jSw[ a{#_j^APՖ]ƶHG,R܏UrkSK4e-/]y*JF%u) ފ-^j+86/By'̣ǃrLF g*jmqgF*Vi 2!efm*8h.XɔzOzE `c"q?&M'Ͽ(ʝx@ \KU(,SPWYL?BLI[3܎=YMS-{tys'W-GiãB\lxjŵ^>狨Bd7ˉ xd >N-<)W+T!]O<#A ~8(d8<(Nse!+SceخӀO"Id?'8x+O(?)_7>r<7 1 . )7N,|,W} /g>~ =N&%D@Ea+,4 vK[DF䩩pMsd}rY{MmC`t h?|Nm3f7BgT͘jj'2eCf vx!|&obOYIBMήJ)ܫwF{:tk#YB=ȝbF+ݞ L#T75 hw#Xݧx;>;АVbg;g*wк )MmYdJ,m3:7E4`C3w@'#M4ϛQ6NxM-[K8n=[<4 _3QsI|pKMO(=xoV>l_l]áAec5GΙg_ -a-Tb\yt&`UJ_efw\$QxYgi6wܪëg.ۍMlu`5 iv\ȥԯV.V^eW>0>|3w6:t&vF'ħҸR&| ѻdGs/; vx0Ղcܧx7~H?f("ofMO$z:m7ǒ;Om-CM[ 2ͺtLEjw&S^/L ~5L5Yb#s0И!>a]8'1 Q+uYz 1+B Tx@ ItB̍'>9H\7rKq3aϟ NNtCCmi 5e;iSQiS(uA7{1F.#f5r X>3{r [ݓuZcϵsA@|q`w5!,w}a]_ys ب584d_,OOAa>^?d U)zӮ͹ nvx}!\Y~<oDpoGp]Sߥ%FH %%2| xǀLMGI }J{~Ay~Ԟ;ۓAiv6jL?robC֖E˸Oƀ`8{>&5W\1}B "AI+\_6n`tS+30zk>ǍEQ R<7X)0Ik,StⰯnZ,Uv]kVtESSŢa-vSuT_>껏72y33D  C5ËWF˦״.]怳˦մpoБj\GQUËS:Z3#zyDŽmyo=$9c{$59m9~xB`xRzIIZ'{Cߛ(K9D:^$*Ԏ?v##r^ǮQZҷUe /CQzi@xqA㧟.$ܦ*WĢmqq3d_O+-6QF]Pܨ-/N 5;>(|TbVF1.%5VC--;X1@&[0O𣥢|Lwcc&)rW;h\]N/=>59> %ML4V [;7^v~MhDAebD^4}+%0t '"}Y c>g󥝿s.{{]k]ǎNxMkdX$E,PdCLT7n91f)7]6T lmK߾o,hM>I8ϥE>}B,|RK?ao?qt@vIn5Itu7Vz>g'`_?zhg{x`wc?2S`&`)iC1ϲ y 4{N_Y[)>&\/Nd[ԕhN-CoPW71Km9JO5p J4!sC_{D-`wWqokŊO9H :}6 I +2BL_ȽO'D]#\Pm)Ԇ5A^,TFC?GpG6[F݄+ri|a̋ l$QDŽ{x/ܟ몯qȹF]ywjȘl Էk*CK'&Tݩ)%` r<:UܤkJN8FG?qWK۝9zH EP\h1|M1* »0" x3E˓4/ <+ /Nq4v 3 wvEp/9v9\_;1ސ@ίyZ Lh f+#h foLLݞUr67[Ų`(5gEAE _OG33~mG-9NgҺNi *!4ژ5k8h5#"W)1c65U v[sRhtD?>N1r(,]" c5# 5/}@x%Kץc x;S~cbU<̫>N'I_$M曅'y!jcfiK]+ץj3p9/{$ɺ"^"0,4^LBjJ 6{zfYta͙{a9*HgNjʡ6х6AL"*8QgOEo8=9 -M-s웼BfQhVرENOcWSyHR]56ettePuᝯMڝ_M-܁z2{J~6ãt|]z 8RkFEUrnw_aӪ"j"e$I)ŏ"i |kś77o!s;Qx>»9g/1UJyyez(_C`*=3~rV2HNodQ+Z\cQD[krX9ȼ{4e!yq>k!:X20d;D/$a·:J~":"%w8}X_^,jۘ_7<ȅ3o6a9; _83 P"a~|2<-l7L5A 4P/ +دکxՏ;̈́c1:._GH|q$ TUЗqHR 1)RMͰ{' ^ؗ'OΥT&2 ܋Kw8f,o`%)^}ˀh Fo̓7p KY#'֪ςq wY~59]˖w͕]we#Xw._Ow׈q$p9-=MV]p0hu$[ P*Q-){9lwܡ{όׯcٙv`m \h܆@4p 8XpO: |~Gkh+n.q~uZ\K"XOxu{+Mgٷ~ ˽̝5./3/kQو] jSgd2*0ؾVp w}{KGϯ{~<6}]p7[sF%>tTbɾsڽr2֨ ZXK_=x!CP*Olk8 ZVSeZ_tыE:]KPGp9j5 vrϻΫX N`B`dвH2R7кfҨ{WIlQs[Z.Z&zW 8*WxX&1VBU؄U?%V^{UkXZn͎K;(/mhN 0% a @4rA0'mz %A(w)vjBM&G'8t:FyQHE]K)C6AS91[dƭ@U~ѫV =Ȫ}N,\jZ׉Jv n| Mx)H-6̤q|rǪ*+ъxnrL*x[aIIz3`h!1ᓣ'~_E,hY 7@s~̟_m9et4Ç/@?LpTdj㏾:f4[|gn?Up__oİ;ؗX !߿Ԕb|,U7~*sؠrX}|d_z#spu.ۑ,:* Κ"q &ԤT#P_Q^ +@ L#ή`` 2'; %D8oP!VpLAL^^>_[1<,綃yӹqWO*b IrQhMd@Xu+ƫ/B84M{4]֕{is :=$'AXOtT> h~I76)2>ߡKn4[<.\gmͲKU1=CC#T 桘2jy ⫄8 ~8~3)0;Η! |5F;pVhwlSYESS,$.†JAxJkG%h;M)2 esC'3Πh*Cuw'l߃BMMO }4´4hyJNʿ_q$_I|"oE|/'Y'ȖבrJ rG y@7*NpgQka"a >QVq\ѯ-,h* $ٽMMhjr8MVc,+?zh/{J]P3ng=(_;TtMGWY-̤ڐ u X.C:wW;eo_' 7GQu"QKq-vdzx.񻦻F{!Mh׀ȞbD,|` W>55=O'66/ V&lf#;U9!?gڵ&n& i'h_F>ph(M.1!hzUlYD!oٷ&YxN'!XDcMy.'jLx1=C:7ܐⓅToPm|5{诫?~NNp @kO>x1 Fwt A?W/7 '``j'Mb tE$]$B3خ: \PgeV5o]?M{cM;i|9p,9bdU){/ģX\thͅ+k.qX'8V)Xf JAE0Y~{Iףג.cFpI#H!h{aْlf7m%M6[ZzB(( Q|JQPbAE }ܻM@`;9s̙veC4:3x71URq eʕ삅gMXEM " sK-^_Z8 rMuYzyFdef'|d!/ەqiTJA8~Il#PA1P"(|^ O(j*(z/p%:wֿ2XSlԃ~q[r|i^n 匤6H7ۡЩͶ'^0p%Y5w+;+9!"rhnx3 .zgUءS4.37tt0*#0s)/uD}*-x$~s.qk33I\~>ͮs@9}ޡS0/w}fnD#$hc^Rwe h~T|aO^$G|N\lҒorAn?s`|M^7˘~(eLVt*_WOűAl_l7kUmo$ B5eB^sZ]!0bXʊ]jaSQrSvgb[6Ys/t)ǴZ$d1y/H[#Z}zPk#(B㗩/ke/!뫎+_/ O{{K\ˤ5.8:f)[R$SrߠJzO[rZ9:BwuD66cKc>nVQ>qR.wtW}=ٵuD]+o݅:w/a꺷wuA-nNfiJoꖧ)|1(OWe^yMͭ*,:] =iӑM d]n~rjޞn|}'̫qǏklЫq\Cøyolƍ]>v1 {֯Iy:O;tz`G ֍vM%m1dFdb:a:Kwjofb;]QY[!WT2f?M0oi71wt;o4lۃRXսt_ch@DHrT^B~%$zW.X!ܑ݅pꞏ ӻi陰S~RV (W r:WT ~h0ovi!};߾&)v{jar ݮ!4̰(rٳ,̃a+;"Y3[> Nqc#gq[j[F4&2 ")J ao`tas\|1!Eb;5>);SK㐒%zœhcC?!Dkf=RJy~JbVIWr ݱdyȕtDQGyZ|v|ǔAN ،عYwÛZ6N'<2`>lɔ#l9_6k"G  /_)m_ba^u3;7r-tw_' :^d;+(~b٠ů ,4xР3o2z+ c"f*bw S-Oe9J٠|¹\lsz\Ao2rK+sEEo0lCiISc7h=eyyK Z|!?۠qbiq@~,'i M iShq{:`1!LǀOc|#^sH_dxIh509ioi| H֚\قcܯ1Ӥ Θڴ2DƤ'7_iMz0 \9.r*`wYZ`8,J1'& M:br6tPC͘{w{9s q"ߔN{ob4lq8M]&Є0o0'lDz7o|/OBt9zʉD2i^cDžG,! Ϊ|^}q@=rZ"dT: y^y^^ /o/M}܏qLDjГmX>/*9@غ$G#lVPye7L޷Nj|F{QāP"h 06T)\f o;8}]|gY\3`N[Pi#͗_:?w˗Z1x 'FBrI>_`ۙw{x<|ζe;YT-iz[3%d|kR)">@T>'.90lIp |ڜ&kG=CvvF* c(~y7J1)}Mc}t"!m.U:!BN~ ё\ mD*),,!})yl{d +ƕIcnRGuͯPbL'>^`6_d /XUXv7;*rKz|'6!V w۷:$;i&FϞf$GdML8" :{_9ԕml ۵fїBDG'ԟva_WVΒعPP޻I^0^{_lM?d?XS=3BfZ 7#p"-Ri]c{W-R bij QdpAj[ 3)ꐼN0qˣUkG5=xU&/)nYʖ%OaD+@_)[Y߃M ) "%u/.x$+MZxCFiM+%)f]A?i6>?)jTFʿ3FVx3Ĺft`S dUO>(.fCmJӣ"r(m 7w9ch8790Ym ] B%;vBY6憛Pl$.W|RSFN[8!k{/Ymek24Yv_izOvNnCZj*wAd2!}F/?Xa4!.maQ5yf4O>/Td(e@m֞G:k@R(J:(y^k9JkNT5PEЇͅ^q=d:Lt$4aB3]{Pa8͍U]M.yS;[R5>1pVDjZ8K;1i9)uڔ'Ѥ5]"SyjkB A|Nkغjj~|zȤ؇]/ ;%<_' Js$Ah^[yJ4 pfJx>(njUrYK7d~z[)pd2)"ABD0YN`evUYNۥӓ3BnF4'8ZUu[{5T._K,&4 \ C0Ω~oe;i-n8Wѧtjxnb{x'LbYIt+3lI6@7"̥!lUꦤWt?c:/~ɳ -E? ^8pzzOO4D#3[(B?O"}S |.f{L.iJ c7M?6E0j)2& 7ܜ4esw[W EL E)ogA`E\%}ٳ}FO=M2'-`y6~0B6,w!",6il4tQ&p Pѿ' c#'N~?mzL>I=<ga[=>iñ>s])d/\8yɂKY>ﵺ:{q:`du@En~G"NVZpiƝ_nkg7m3B^*_fڒwm~uE9*?9#Xav..*fs"[DՃh W *$dw2"Zis'O6iv^sZp}u'քur/ l2Pn(XKT9ݎBsS~;<rk#H*mʵ1pQ$^qr9,L& Ȳ &I+03Jc }\twQx#l@yXL xO73o"2jֱMY?'ۅܯGi:oy<_yAǜ-ʶkf`,'ߐ62 Z6?~~®tzE<_weZn˘5+b-:{6V\j;ӚS6Oعki)'7Ϛ%`0" ncI|lW{ja^H32+o MQڄ*wq-<<-*Ue#E:-;M/m>aѤí:>zڷo#/V &9I@bt)=}f7bÆaO-/3­6nwV0 ~ &NL1G:ǡ ~[Da5g^%|#" |XGM0tiٕȎd;B.jFZUV[ʻ/?;,,1_RZ칒hk+sfL̎<.O_ : r \][W .&}C0<=Fn1: 3$`\=fcJ髳8ZH)3Se˳/-HyGצ g rSoPEr_4D3Tn봅d6gxx>σ2?%9'bJϐ L\EPD&UxP2з3x/M0Eލt q3t7E~l؞i3FI֡0g) = \أ~BmH:.;r^!Hi7ǴjQBOWkO E`CU<8JsW{$3jQơ,}Øyas Fd٬X\v= zV腑ТuZȋ= yZjH>EC_Z*>1kp(lYؒE Z)ijJZP6A)$Ę|(b5L=4J)"f0`E)$y6ra"7 _,Ưe?/d 󄫒A+|[>qQX;€oI#&Xک Gy8M)g)bm썷Iݺ#$V:I}#~-dzoAqۇEs3|2(«E4b9EE:fǹ+P~/w`r􇞠[t` N=Ȯmq%Ef5AuYF3kL*J_ZCH{qfa*8b[4T9d!B1v%d-jg}6a0d'wp 8aI @DY<̋yXJK^͓ÒpP3hZoKK_eŴv"2ڱE*U--ʎďsGMDl8 VFP_0"1 %cG ͽUUӋ&Զ 9>F ʿ\ћ~Xy%c~S/^HĖ%Η6fqEхcՕMi N!Nݷh{&z{T>OΩ0cz7y3fWĎϧ^=aU%X,rn{[1qO4wmquX{s|EK] ~hK !=`9F^guC:3cƁB89%|F.4L=\|PD'H~.= Fds+cfCǠz7%8r؇ C|ٕ[zs3Gݳ] fȌO<$;2+-ArDPĿs H]v*Qtff ]19zsAv }EKߕi|aGYNM1ÉO5Zz'f"?A8 0m~K=CKQ P[j,0o gY+?e8cנsL3a/R0vB f5fiLDKvNagu&]@[J&Ch"/̶5pc?B*0mq^f{Y=<>2M\M_\=qYvP,ȿv]>R.W7_ޑ}軴IgB~>޼H߄^bc%%{΋@7x Ic$fҨxq7z70Pof0+ieԖ ?re}.CLGBu!*<2]ƒIH3!#?H1=`TCh;{뷟!ֹ69pl$<#DIK9}7F\BVW0j{R{@n dw2>^xl^d4ƓEơ`@Ww u89jd|MӮA ]KA {cl^´j_+f'K 25}(fc;0G,yeI@,3xb QaG0IVA4fOɓƒ@A:kyzV-ܡH83 ZTઊ#i_/'i#|‡҃U+sW& [+.6GiŎM8nsaFn16Įz%1) aR|=I~51JnnL+=H~ 0H\&,QƵ~ɏp5y브0Aj(= (nbk- aoTU^U 0#aU6fH(BΤ[Mooul|Td#P^B{nJ|%<8{ ~8%=p'UaZJ<<$Jn8`X w0hnR |˻OG}VJWL[XZp̮`vg4Φo`cn]z{[G@I0)ȶeG{|V{|~R qez$ #.;Z8a::y܋G8b'je'mu&o9%.k1E(@A/~ 3#>ÏwKx<<KcaD"`+Xz,\ v$^Zi{J-pIW-gy)$+W |D %HuwK,t!ǻRb8sx ůXBxR=2LX WBxt6֑3DcHtv*Cg LvMSb _;?Sws<.)?I'V"FdxJnM˚$|;ȫ'4?i>L B#.k&_TRH|2? ǁqQԲBprJO05$XTq$+}=C둌Y%j~2F;Ȧ' dD\H.qLʯ~ ؼ‘8#{'MFIvZI{B8YQ&Du( vտǷJZ$"_5񨜃1nDbblvD]q嶛U SʲR Ir, RS@}\vK%kReY܅7NNƿ)u4yʭB?,M *W?Bz/h&4J2ϥJ|rO d}i?. 2DC$/<-}؜ sRj ׭ 0JR?ٟ"#9VRq::zge: mzy{GN9EO~Jpo@/J<]>RdiO?;G ʠB@`N]`F 1AĮ)n/MKH&T|RV 6(λ8EĆNN\=[GV"'Сǿ ~쨁~?pہ?$Lgkh&L^WLFcxl N;>uɊ͒ ;gÙ1|)3*σ[`{P>/c?)ɰ'i_>nNQynɄLFC|,l_\p^OMt: SR9?5%y$x/k:qL{b!—S"mG;0LYV42FYC^z-,#Uט9CIky؄?jS>NHFei#_& Nap'G'gׄ7 _??  qT2 }M_Ij9Y;.U{GUڿa +d e=K#~/X$w>y*ͮޞݣ;3we$w76NQAh `a0Z/L 3"aLX!\"\!\%\#\/l 7 ۅ[ۅDŽ}s!pTxG@XLJNQUC0=)q?= D9 >~ޔww4=RqJplljjLODMXOMFe _U O;H&/tUS?[?=]D;= ~ɢSN3mOtkj3WBRW!;Q5eV%:ؤ\U؁XN/2e߰ (cyI~LI?z;wژJtR-2@Ҟ-'cS+fY{KJjzu=LZ%\z_JSG)=N*9D"겢*pƮ! cJ̒'#ݎ0gɱֶ6:3EmAl6czf[abuWZXdT4z :3R/g~-3JB-/L0Oֳ"Iq^rӊk<{e X}\+=@H=씻haUV?}Y)F\p\!9/^^KҲWK`߱,=07/Xq(iX>+cO !_)@Hm-.8A  (@_88~!0`8> >w'~ogEooemA'ūQYgm>9;Yhqo65miov}_bliП.χT Z> kڛMXTတq?bROVW;KMm/ =O 3if}.kCtN7 #GS3mn.8\]$\`Gb` +1l$X(X U`Q!)S`Bw]'L yȡ -s>",,ǰ1l()m}}.ѵL]+L%93E]|UV.8e%7 :ͱX_E&ǟ$fZ1LgHyLØfa$ձW]Ckma0Cc㏰})4,cqܜ%գ2^Oq%q>Bx onmJtyN t&;=0N)3?`5.LBXLH|g0 I@ Dg<2+t  yM"- (X XLz4a|FQ;hD`Bh0шrL I',=? a0[uFim+at JV a0J24 ԳbwxĿ"ưE8<$a "5!(fgOl\v2>յP!*K#}[.Jޤ:~ͳZ6m#ZӫV>S!0ZJrVLM%J-DZ$)e;EHVD;4UR4`lEPuHhlŦwy4pl֛2ǃZgDVi4DU5Z4:=q*.]UT 'T|"DVZU,74F}+Ӭ4*X e%ڧT竔A>h2EHa iNtFꌌ&`cNwu-F؇jLETJYߑ!G#bʤUVnAGn9zt֣sk]߾K_;8Z\Lʝ*,U8co8[[6 i)cExlga 8/(S9)aN]p1ei7l%39Knj;.m:m֏H_B&qt]Ƒek͡.|8vcG}k^v<~sSԽIٕIƟ%+غ,J8w"" &g?zzLԏ]yqєS݈uopN}:53wwJcU0Bby _pE?BF< N|>p9Ϙdzinn9v[Sms0]*ƽ\_UΗC U ᏔnX"_8axC3gDh_;dX$:t"?6eORʠd#fU$;ys*_x81F' @ /Ȧ_@ cQ)ŝ*[ڵIʲ(Slbvg$m vrfECt&(i;3LY 8ǒC, ߣ=@pƿevؙz s~CV*vȏ))[ G|| aWkdR)G+2K5K壔Zrt]kԶaQ]$*4AK@3e=]:>>t;PK3K. x@ ξف|Ȯ23ңv6㯓_n'hم|2ni֫45Fs3R ૅ/BEl ᨒ~ >*['2Ǜ|1`B AY-pG =*W"ҵ*KsO&qn_u0ݭd٘\-:8zpE)\P:Hp;;l-cdD֕ $ݓo9w1vh391穤 Ҝڡ6~){0w-|'w5l(bܳ9E}ge fA'e0GѨSZ}ٌ_B+TP?% hjP~z۹m e<>m8D)>67yBW(5*N\R cQuoT*( yumم-q]4n%0hӵi>#}]Z2mFRQj7*JvIBjN(X+?/\!՟E yf.4_ _Cyt7;r8"k^l )7Mۢ[ՍZo?,۾7𣍷O^)Q͠{4'k F/Na')#3M Eavfk{0~JK7A.X-ͩ̓?J~1,>d lu+¶E\~:R IbLiVMA\+.% 0#n\j ӥi f1f8]mE?Wxtf:EU93>ilJ8d ޗMgqʜvU}Ot^ďאg)IB #z\nר0zf*֍oOeAg/Kfm)Wbv HHSӥPI!m*KA*; V4UlN~hU&gC[F+eFyіoQڜi3tEk˕eHd* m}N(D55~_2+]cAʰN#epp{;6ofC&Wx@Pa4$f\WU2[ %\kR4ӑ*ʛo*-=]gf͠P^g#a*@U?ێ(A c5Qg{FA (tY+_j^D,‚ \*h,P+i fTejKz-(4&] 3 Nת2RsQ EP9ևlRY&\( >OL}hBv) V"\\ÞӪMMylTРS+C;+{?wsw#w_)Y}(9S~l:-?s!3K~qJ> 3p. B>UKҿlOE ZI͟ŶUKdS[eb{ ۺP8P1G$ (To9u\JU}+՜7ϰi\Ay~JJ ]壝3.:f:qb̨>4܆^*6P<6o2?xwM9\225 opK"َr4Gl9t+td4*¬˷fY&Dhwص i=?Oi}wd:lm@Sd} -,аc}==tЀO%{b*! lJW_a%qz4>}ZH7)*@+ߓɣ؆uFp& ez&6l[#$ƖMؓۼ|ߨeiJu hK^Ai[[Iv_?YgӔ:JFE9KaWfo|yX4mb8S͍աΒ6$xJM8/-teb(FnMꕙ4TQ1_OTyx/%0K^S 柒M;3 fiX26k 3|\sFAQaya2LRT;IV?q+1y䞶2R *ftU{s|YB;03&ŕyZ4gd)śgLZZI?В,^HT(b"3 db@qWXVzh>IUr&TZ6ݦ|k焉-\mt. uʒB?\Wӻ|bru贌MSf&23ŸhI9J"(WJs+{J.U._$,AiQ*`HQM:c>&|Þڹ/T;T3DžtUzؕoIˇrcՄu^ST[Wg[Zk Gq% OUtOO3=9ݝi6i6HZI,$@dp c0 0q>sǙq>|9hWU>K;^zWJđ/DaժWVAC9alAQ =fV#7edx:ȨAS-. 5B ;{7@K-XhFJR%%(!̆xC `e3c<,wo d: >6M3"֘(0 ˜3Hި;[w#낕HI1Ѐ z{x*@rTQR6tP#b2(yM7%luI( \gHlv`ֈ(MvMi~E?"WhЬaC.]mSfאHG bO9ܖ޸^OcUЌ:VK !YBFnՊchrND5bCKNԅut;uί#Jz\ʲRAEb$&ieܴD3FP2vlf2wRgׁossm kِk x/*e5ͲHsH+2Իeir>KOGhdz3rUXT#C( Vp0?=<hNd^q/K/ȑ]&Ƥ W|.8YbVlt.D ">GV,d_jOL&F >uئ<)uw ER]^slRֆt2 !0(<</ Mo{MP' ,?uX՝ j-jx3t' b  Q0 f<8(b ٍU 54Md| L5ikY6ôGJ "TTO&&<%*ɦdS2 bQBc!\X*WDVzY-2[B %RxU0 AdD#1Ͷ"nXElfsMUQydrWDo4{ .{Tq~wY}Ho)ⴺ!0I/V+J "zC0YdQCblX gNL)3gL"-u3Mv3vZ9Ţ?!  FB=<=CN/ؒl%Pȇ_'>Dqbyim\F힘+8gCCc-ѡ.^| XH_XhݥSaoȉssss'N޾pTߓ-ÍuV xz!xaBwXDy#ɡ *W _ȷM7(xbV<*nrߍᩪϠ0{W>v_Xhdgm\u9]C|~qB $u~O+-[Yi$ D~+ d`ׅ*AJ`49ij/+'V^]veO&qC,'81ZۦOT̔6og!Ďw #VBYuoX<|[w}-@* xXd **[/|`fJ{჻6^<韘ý\tZJ^/\놶6ߧFp_JuG-u7ԭLAӚZ%$X4 H a*2-zlH_Po9\4 hJ6Cdm; o^42r~59rZY8yLQ`I%<k*q"}Bhy1ϋ)ْxF+J=yы0{?b 781pY s-{ŭJM6T{#Ll↵^Vr! 􍜵3M +>'C:5-)5gәڙBRQSfC1ϲ̍jj6Ax\7Yh@¼:r{-[=) _;{-Jn$k/5ߏ~`E܆e(nq߹_r{%? /Cc'mIM:]@W[5۶$hݙYƜS 6})8 TUˣ I' 7?ԎoNZ,y)3Zpzw*k=EJz#Ɂ__Żai^W6mVJՆG_wG-# f+rD;LeUbl!Ƨ:R>T֩:!N!ϐEȉ@"9 -]G6 "3e!NDŽPluր+I~lEW; W `ݴrRDUa;Y@ʄ+r 8 z]4n|Z&86g}e$es^N$2cDa LpV sSebaoZ<Ǐ>40/F瓵^hMujm=pӨ<ٓ2q$gL`~;R\?M|{~& LMk:^7>붦sK0m4,>M]oz6Qw c㎡rw DXh-;}(_\;w~f<:ڳGFvUD_ō?_ح[4*X/{uG.]p|Q\bKf \>$X''i \j.B3\ó I`/НaG\|/;:0 -_6)~F\ `3ޖ/Z2ÇO틵uC2jUm:>CVV]|[EVKX($&O iႉPk$  UQo5U`lP/ۀTק}󔆅Po Æ`c ~$,F"et=E/5N hw^c%g[$4A#>d=rEDbJDpO@~tmfӷY醑5G -=ܰ#jƆf::f:2Csǁ*#+g;V-Swם4W/X^ |g*ޑJJ6fi[}݊T*׾^tTBЦ565~ 0K\.]OsV7QzCEIwјɳ&ֈϺ"ţ+o-e'+Н0QLTΙWm;pzpyjN:1~xC N$*]Us%fP$˘AhZz++ڐZzD6|i&Q) 2<7!;kA;0tSvTsӔ1ٜ_);׷:1f]*߼Uݛ>X+2>vrmN$Iml{h7_dOTjhcM^ Ae"GťTɭ$A!HpzmύHۏEpx%@@f3|4Ehn-VDiهQ[<ӓlp0vYDoؼk/#pKgvx?\% ֘X =1qcCCFr,T<Cツ!Vp9|\Ev\=abdfΰ 46?h3 Y2 \&1}6:$- U6TK])x0f|ڹ>.^Y >ce,/6/ a\O4ל{WKےk:޶|֎:׃/ 2bH)9kl)V@|FFX]>kh~*%3>¹RO&e9+Et[08.KMW2i qho,Kg9+V"AU+ƛo(hSC-?#l.#%L?YמgHQo -KɷZzGKOs(uNmCe)^K!>lV(`v5vmt]\/0~x3C_G,1[ |K=/_Пwf`GlQ_xg50Y`bwU1qF]Iú]/(J VT<,CTaqO@ UCQH EKT9s4>“/Rt( dc1Yt-m73MYt.)rBeh4=S~#5}2vOd؝>}I)=pjll0ڤ:h<u:txĎÇO;a1-% i=Ñ|;sz{>7g^DDNwN}uq&(o"BCVv9HKR-6ĉPQuiiUP$sG,Gkvb(.uzDr ;M̨-s48Xل%A .89r͘~Xj\{(t8LPqxB*^axk=\%ѣ\vYyN#ݵPNw9ldH4tZ \q͵ӢX5 Ɵ#ۑ|FY#v~M&Zz]v;/ J(msۙTݾ,%#R9kl mv>>eO 3D4mr^m_MV*[<.Tkt9nڴ%8x!ASstؿ&oqSN)/z<bcPj 64⑵_ eC*eg#j)P/jK;fO;Zx>pNߝ^k-\裵CΓ{[?'wHwoTZщwcӯ/ YӪs!+m}f{mpAxƭH_&l0P4CTZS|n7{$Tc#C^1Z0 ,㛜1LSSbd&Hf?XF!upXAؓ=C+lFw5xn;`L7X1sNػ6qk˨4v` <".{?Ǐ"-TI>~!. {'˵~KC^\+\y-qېppX?V;2&ia Uޗ fv^cɌ #DlB,#ĚSj1-,t xYPѺSCl?"P>Ju._ H[\a~{$DDjr&6?cٌ ƻ}͘zuLad*z\A;'1!Pfxyrjor4zpyH}:#g™DfD"*=^~\po~U;a"dg6܉,Htq "|MLx=R*Ku$m bj;7bD{OU-4Ҽѫg|n{<;t*; ñh]gY5ov)$(z&=s+;pV7ݠ.$:V1-{ lF '6-3 5=;۝o C.ۄm@mNO#үb;՞Pǭax>Tf#֓ %rgwB_?Н UMMm檚oяp$uzGue=fB<:8Q>g=KZ|I;/i݅X?#xkZbҘB"^5:dž:b7tOs1ۂ$[OѐKրyO9?mY*CiDߠ6WQu8/n2ZV(-x=-1yYdaIQsn5SM}d"bȭzީ1Yp6DB6ݽ}gt~ r<鼩&@ssjgZ ٩[zSܲX!նn;/4[>H{KSsyuޕWvUyWN:*umՏEu<5jzZew$쀦`כ,YVR',(8my::qх1X@g3ѯz.Yh> #5_9ІqM`:YzS<_8f)@6b~*6!' Ca텊o׶F[F T ֵw ?chZH`s{[ jUouwdZ;2)nHg3e61a{9\!Z5,uInǘ^k6@eo2/hD¤F@%ÊK 8тZPT SRaJ@ ªH%6B k8>en{., !Ǭ@Oȭsvˍ?e4&[_ܞU~a귶)zĔ5*={\~g;ÉVcsVa'oںޱ?R<{!  KvɽeݿLC:z&X<Ԇosn{I$-!aUjqpՊ׭;TYU)h+1pWiiMXri_%pyNWt37}+m;d!`e@P晞M}z*`Uw8&>:S`gQGV}uv#嬾7UQ|X>>eƭ1tޔ7>MHm1lu&ĤA2 'We:lJ-J'yX<w hzsFk;A$LG=U{Rf*wM[lg?xM5aĵ *UPG =eo!RTM";kf{_uHfKG&Ȇʋmn-c?7P"D<_-jΔ$KLOxKM]}ɀ?߂[jmI{-Sp6&gEEZr ުY*> -Dlͅ+6ol[4P7.mPw!B*in%7K ɋ˾{]e#Ө EV^g[6 Uͬ'rW4|Mgtq$F lQyZLJ L ބs%fRƦy=JPuO ޯIAfz÷脵ͮ~duGV9OM̿OŬS!c=df;Zg)+9ս9& %o+L?f~5rd3mS~@6ؾ"1B{P'į'Q0>PcuHj< $-p0Q*b! *^j#I#iìZnJ@Iq8.۶Pyu[M)RbU۶Xoi=!ԃRVbLAj3zvꚧj|Z'~iT VR4mtz.szO2}VCkfΐ(8R EfA9>Kщ#4@2<:O~˅FBQK;ՙ}aw#mSE &s[z ͨ1Oy^ yV{N2mC{S"O obZszU&j}NGp g9cp*׬uJ=G_ +L-wDfʊB_(=u7!k?v5*_|9Fݎf݈n!b*]L!_Mm#Y2+Vr,v=h82k8UY{x-csqN֐;Nݑ"0i!M&x_G!bV p]6eJod[&-8M2dd̒Mx^\?<&N2: |f7/B)kiI;Eel\W_|?Nz얓- ~׷ l-Ua݀bIT-Ŝkxbuow˳vNgNꢪxT+# {޿rj  XlZ*?צgfm9>J_m1x۞g}w}7':̹FQC u)HHV ޷Okh5mv֟+K+:W~ByVu`NfZj_vRG|r.KƏ,'{s>ݸn5UWHH$D" AVRs^ZPRIFM6+@sJeMXofX i矡=듦qC~|ZYp̟~|5p+̦;=f&QtS>i{¼l^qi'm)USk4 J|9Lzzd\25kπjk^3<OĞ Hh#+E*R)J0F6oe3.:n=;tnާG[ost&j<{#Qo/VW+_.!FUJ"d\=LEz kn,D1+@>wT8p h,_S+-ּ4s =cR8$YdϮݹvv#Wk_y֊ai)5I+ +ZdtS6g (wn>k̲]:}u=IZQ1NԵj}3EB;xl:# r)GcOHп_Dά<`pC܏tj$IjN[a,OެwV7톸 k&a :-T:c^*&gj,6f(=MӐzIvأ° RKlV_dF}0eN }h];JwٛzP YKةq#$b*QNX;xh@NbtH{aeLPᾄ͚6ʔT\.>#c6&rxvk&na ~c yLl0?2f\=Ɂm[d>ڿ}{.ow!)HppWv mdʕ矯w߭7;kx @ SF=U'~'{x]0|Z dje"d/xӣF7Q#DH7)|q'}O8||tQRs9NazCwxЦ+]!!tj;DqC^k kIlڻ-dHx s])ʯO*n%uԜ*Zն$GWcp,Ɯdxddt6*A#̎Xgrf Ʀs˷QWFb2X-4dx3ֳᗼ/>3)ZUf2S?F,QpXDXqQH\%[rPVDG.8B>K\ʋh)(rb!ˣhнSF)jwB,;P4쒌y;;ny[nzXDBN(J GCBŬzV_u˶oٺ{JiQ O8]nq5?csPĺoND9ǃG6@$(1'u!KB@DHqe娺@U9nWc4osy6\!a#8!'DYW$'|)?ᯭ`z[>fz%fId)֢[~vNY|(]kHg&s ث:~numciv]Vw.'tnpag}&/=eBGA;eoEY_IPlyEi4$`O\ s]j _((J>Եbݺ͛ ֭;+vm(v?,p_&ա &k~p4@;^?ㄨڑZAu,;;l2d]5:a4ͷU*)Ju/y3);ʔGoZ c۷o3=y#;O>i>0Ts#w1Bn_* 0E16uDQHjq\ST>5ޟ"M|)"ƻ㕕s7^"a$C3&BS"W7{udBCk~5 L"%/ZthuO8R_gز@"ėQy=&,cyt5ͨRX.ԝ}H|uRX`IJ] NJUfs%sBN_9W9jF[cbvW/$Y0fl頸l!3!_3odm"/ 宵L4<9NLrtoyuʿE 6dvZV{̓t$gʗ[V}yCX76Nޚ:(wJGuXWAVWCM `hB>P'>8r0;e :{xU4-(u]-]Ej g]u4BNk(km{r0ŊK,m^x󵏯vJTp9pꢼBǝw%B/n591 Fйt^uPEwoe%؜<ΩqƉ'AE Wӧ2+?2:wҵ? "? x;-]RWFzHc Z0qomZea8"/Poe@aȾ657oڴbߑىC gslޱky%fr+W]qg6\\lH-demVˣ-)]DWu`K4FI(JB-4bl҄IDYzd6̬~ڻ*j,gUzFϱK!-[<k֜(%Jj5y .ǛǾKQXZzm84Gfh6 'O7pлu0i}G= DxH*8Y[R1+BsIDR.b10x篑7MW=]^{`ui7Wml]%NhW{~W9 8_UgwߚCU n30l\m\8MQ=sFճhG-h؈?:f>mz[/O^kFG`gB_B=hbt[~A=+ jeͦ}텦V:WF1"ІCr_;$41.ý]zdbXRrxo][EL Z!P %b,[om* J*%w`ݷr~i~^ތՖ,f ٗFdGziڰ!Gp^LFEwlž0:ܴi[睍A01Kc;GktT7AZYy$cŒP+bY(LJgPs6 {k/>`Ӧ{nŲʺ`>3af_ V-7c}]~ ]ke\2'wl#0>;E=_zi?.Y;RɊE}Z--%*9p iċWH}`W㎌G:GPWîՊ].pķwA-``d{P}< oBq $u*YMٜ+$󌖜xwۖt.›NK;vnU=]JSk:݉S7g=$ļqAl6duMAv]u& 0g hƢ !?&bt[WDԷQj/Vc7>?Xuxqݻ&ӗ7P՝>9Y8NFku#aBRN[w:)m>P#}%ǠA$mVl#ZJT?UDPn|(6Jc'x~cOM]dݽfb~y5iVUޡUwϘ,@)fF'W3Ƿlݶ%֭MOMMOw%r2 ~gv#<-~zxĞ_6KPdr"%@?B[##RzRm9Y-'deUoQoOUmd29L۔ӧO Q;$\B{Q\ÚYI޵.VҪԥ||R]16ئp0%`:$ @ fH BfvgVio{o^ "̗ KN%(.DSWr&ɽ%` BƄa{sp%MXpnl[&9LZ>NXu}kC5}v!Bkzϩûk:W,P!CK`a >hFM)1a>N-Âw|0x>h:n+Oh:LGwۂ#fVZq. atz !"/&a3An,nݼYf3An,nֽE.B7k#oQm6k6v|گ)XV$?^Z2I܈ KR4E2 ;{&΋ۀItox8~VGBF0B,)q<G .qhT\,S$qmJ^WL~5)}Գ-*.Zpfk82 ë -vKnɴ{ {r:odO+Q)-h4CjaC!F0 (M2lE4l4 ]# "9_rɯ$R/48½F,@,ɓ.̏ bǞ'|Ox֚MkJr˯h4r5Sԣa_~{mjr( >u ?"nMiaZt DZ#q_e$Þ=orn)9/&X^ux R*_3dZ<(He2-zR+!h x]seZz90aND.g55^g~]q\&I=[i7L['vpqrn>1O) /%-d&\ٚbVg+Qdoqg `q 4T0zX_8CWJ5E) UՆ9\IN3*`F>COuwnAJ hphZ͟4Œ%/eKB]r\iq$ uk: -j|{M\FoGjJW@ORD״IɧhF&E0 -D1xx?HK:<Jc7uZ,nnɥHݭtsqRQfL&LQB!#Ǐ]i{0Doc&h֪3>듛=R^)O5=ߛVGROT0jPJ6LjOtHzzʛljմ Fm ~4!}JBDO<8V#~ѭ,1hbv/>yJ+|UjfQhPE3w/TՑܡ:}R};W[Ӕu{=B d&zHG?WG&.[͌{kϧ%8`:v! hyJNu'b~#p/ L$]Ho]0vL\{:־?s%ϞZqCÜՃ\yPE#@枽o龜SOټg/ٳ8xJ 0'~N8/i` $R*U79v1ρ̮4òL+` tZ^ eLNPȼ]wyeY] i=k3h0)f\S%Rgy)vtQBCj )W卪f +`ωe6ߛ1|V&vJ:W_k_V;^:諶6XD_ߢ~v>,E} XnEń4IΓ@ / ]gf4"҂/6mBg#1d'kvl=hV6X޷th߷c?`#+ ĉ*K1:L) _ eUy/( B[WՖ*;gd-R[᭴|sɅݕBZwoKU5LID ,BO䄟MwQRW[Êm_J )Z'E-g1 @~t)2Ы|N[@#eBPɊ|䱚j)r]&ʮM]6q`cfj9UCE#Ji:WbF u-294dN,mպh07{DQFP]GtkpN@@&kU.m˰UpWU*qJi; Wk*X:ˁ,C %WrM~h85Cnցi^mƲEZGQzF,B\B@2j94jdVB9kdSJWf.ZABC3QOOaP4ٮ6UZ@W! vTN J |^ eCyN*z6߾{GB]w㻻B 8~c^k$UzPf"9yBt5) Wfsqep@FDJFVDjʈ.+)S9$}z*2 x2Y 4]޿KS@TDHJi' l l[! T% 94U8 A¤ +XorS`<VaY8 &`_f[7{SjB8.'Ė+5>m FdrF Jz:T*tLe|7ɡJJ-ҭgD[*Lm74HQY2h" ҠٛjAQ24NhUt)C?‡.thpO,8s?goiO?ر>c?رs-ċO,O?Sx_?TaOX5 xիOEםߩofWB[YG`8G_~y#_C#_~ fl_cxϹv>8s$"@ʫ'sF\aG}pM wvwe`GO&~k6]9 ͻlo~MXs.xΎC_|h]|1G[NдbFݜN~w}=Y_t={^puL؝s%- sٞ59}^K_6C3~V$\b1t@4г3'=m|qctI;?.+MΚeJV%%RVfNCZ7%n6i2|E&Gz7Y*2:oQ<0dB7^TDyׄ7wigH/8#ɏm7WyuV]ϛl;wԿ|oC :_y-|>>[;,?&tذkx<-fRsY)Z6pWgu>U P_ !H.!yhWS{ӳcSNH!H (RH:.-:5l!\7)u|dь"ǂf#IY\4u>i ? 7 }օ/gv~#z? -h8GhEm(/@{˭N}gw߿m_kaߟ? 6k]}wWW_e%yD1M(@!L2ɇ{{_=k}wի_ x/*B{`#*;|7Z 玌މ.GrroF{qF)ߕiA{T.-v4hfͨxD pm ۚ' u 3's gYSfljgD<2l$!a KAaqYXBIh6=2?v7@k) JF1 إ$ţ;P:ޖ2܏xRV(#]o$;Ʃ$"9m8CV`HhƐь\i24GUM]m^Q+~[Kfc-_ ~2?^ʿƊ?§9[dN|F?UEcދHy]a;BF,nWzxeRB^92ӇdrKm|>&pT$1iuGo]wqT >an_~w1+[b bB)yv$9ܑVyﶇv/I~]5ywޯrv`i} Tژ12Cbya1f@+:^_].`?|: yq><>X vY}(߁Bf]P"MqO gt iteEҒS1 qj(@qjf]+QL8@9g\rrw;b#᫮f|1dXNcFYo[mUƢuL4فn*ܯSq`IZbKaefQB!qY)^eXB)B-LQMkjom!tӎpD#s*5$9ؠ\iVjhr6vQAI=X],ZXg**%$8 ThXAESp2l% <+i8ըVJ=f`Lc5JF&& ҘW0H \k<F!NuI ÅO aφh,* #)EYo 6'L 46,=Nko Hì'͢ĴgʸPj~ϴ&zI4aav:-c1F+dQ¬Dۭ;llD,ե aLR  0^(CҖ(YC,pܶYcŕ7` 5J-mpk lVS`%-NkwFмrhN^̝BZJc\$3WӧHM!{纷d( B&tm]+!8]Sҕ [)~˜p3vE"[5PW =rVͥvV;_[I44$<~4j+C9ٹ;ɘi$T^ͅ*5lLJ*a=.e\ɹf*aI=+$$$II ,,ψ ;E ʾT yӒ縷xHJZSq5oб w%A)-W m]BUآf1FUyhhRӆ :%庲YxY&e%u&/Iج5ްZ%~ZZ D¯/w{Vf(zrkQ9TT66Y57THY-\hb2V)>/\hcRME^%SrUrqtn SiT;Vx]%[K{>NT,ERdtJhrJ/̤&;?X+kL.I݂ XI?n  \P2ɨ2gݥ aN(S㘃c'z@kRZ99FO Cyҭ8.1݃}?zUEJmMmyʮh{B+j>OF~Oh_ivjWxѡ'JzoÃxdִ#W/}x%*f߉c:Yᩣ#wgP=dL?ML#j+rc_VϨvbߢAnɳ#9ri3ƠVW?PDkPFly(Yn lJD%Ά5"͠88$7ηi!TV9kQh@>bS=2K<]i=iQ\ߗls+|^, ެyKӮ9k# SpT.ce0Bto2)ǕemZT۬MC\:XbUؗ3nhUh-6T"x:Qry\-^A'":@-r3+:m띧t׭[olf+B[J6L 3%z{tc) Ow:֐lPj[ւ[{/qȄ_ch|,'1w;)} \rsQzں R95a!*3xT`f,-q+Yʈa9^ZvGsۗHMTkUv |RW z z[U8M"[V x)>kKsNyuE驨VJgSτzsEkfgkhÕU)61i1kHX}Z69TZ4g7(yNaҮ^ؼsiegOͰ4.\I2m MO"0yC51K ; SB q7ٕmzoUG%8+n ZCg-=)dH'cT)N @;eV0 X+\SD( +2|~U:Ta>wJFIMzEU<NS)c]$au* k4OW`E'rOԓw-TGlָɈۜ2e_pTs3!/{V#*Ԁ蘎X`/hŔ݌%K|U4EFF"Mၡ|JMU JD,+j+31 ypCC3O? >vXw ->j[ΦSUKypoo^<=YaU!x=N=OfxȲ% Kv05(uĬяf{aYP׊ VTPrcg4wĪb84* 2kI)t R-1F0XAJIj^O)z @:Pj9wU.M "]bЕɛ2ԹX WD+7=]#SBWUk*{j^/Q+S^R1A Ǹ:AnlyP9ΞӇU@5Tlr0Te|Tl:50LEAnU<3=i^G(%d _ S.U@3^p_D+ЈV<H0i@5m-q%HͰ~}o4_O嶌>au&󠇿яX!=5'a{)!+F)Mjx8Kd]jiU 3><{Ԕl\4yRW\K*CMpR+'B8RK'#vw8rR;,1eN5l|rmO'pjK!<)nS Ff5OYG]#VNS|m5@z,mJ[hɯe*gݞ@y:"c7{4Ԃ;O歈.s%Xj̅)#1q*Wc*4*֕u4wCO+vW2+  _6t-UM ҝ p:.ɖ@zRlԺ UY/vٹ,ȱ99iY76̩:󲥽-^YTuS-ogLbe b+8c %e??;zx9UW?pRNҌR]G5J5tt:= ^bV^3=q=k%vi#G]GwBa>ӝZ62>3K<ꖜqsy0ZUdw65OVh'*A"-x!UYM0?7'Q@=,DɌP Q<+?Ͻ{ؒ&TN&Uũ ZnPU秇vnHҲB4NU(kUS}Iul#h>CGX(ݟ_LU= /,[?Sl^>+XZmHJ{DGIdOh6mٝu/ P2drS2O̺b,7ӕmkTqD0c&)p|Nx$QDX +4qqyr'8.(&I$B0}5]S\p<Eqt_f-BT sUԥ U֫0ՏuA)!c ᷊"GŚ/wxt}njEnO{̭Z}x~^a(k~ͰKX,mƃ`Wɟ˳:ł9" eDiʓhq X%#W# &w3A=+ uoMH3:szFPl,9℩6Ԟ ڊ$$ q_L FAhWVy;c+9SG*"`h3@IZ޶^6GBl'`|45݃oO(5"ip~ Ļ;>+~H[֬9~U RqÜ*NLDhgD:7I^;%fCD84+=֡/siۗLk2Kc'V0󡲗ӱF40ʅ|9IH䲢 of9Mkxl-OTNr%ص$iY4uVdfɴ-Ă88'&M q.B^b핱2?s,hl40}E#W&\r|R.;}i3pH<.lBYe@U"Qj͟U=67Yl6rh  ׍fu~NΒ^ӵ4i?m։$6/Uri$1C>hEe{l,NM|es~{Cea69۶lEN 1nD"Z Xl .?'}.=> Ihys0</>hrB^y =S)OWo9<wLpT@)}zRygAD qY*h=o4ݔVz= ^-z05͔9GL2L2vӉH*p{*?v|H5VԤ`?1t8828s}wtX?Xjy90yB-(y`GEZ ([aSS++glOZzOhEb|;*|hk?`߽{vtN0)f38R{x'~!hXpoy66aGXbwЁ6?=y%Ђ m>9@Vg{sS%0Dߏ LT\"?dSAwn X0v:\0L=TuLO|$?(oA4 zOp/;f2ꬴD&%Z0\㘥eH+˄wdgwߝ{.ͷ삳v}i'Uo&dV)KH?^Bü/ c#"fU&&oe3\}. Xk׋WׯE7}s2melwN/kp7ee MTmelɓ 7=knW<>w_>> p Dx$<5;Ƕ}|տx~ /WB.r9V"bNg~=\6 <b6D3ǥT,S_N+n ؜CMh/Tkk=4G|+T> .hv=S}[XL(ͺ<dZ[[+Gwkok^m|}y+1VcU+#zaoYur__"[XH hlFD\Qc$DedtKOA:&?Pq~n?$F$5I<81,I$$EtXkϤw=ҿ.{_WHZXeSB XO(:s=^6<.@LB?*2&'יhlG^LRœ: >E^#Gh|Laehyh&Գl/47lOsR0>8F*O}.?g~H^JE>rXys}fce,sI6ҩ@G} fLG[52@\ˤy֮Y#u :p0Cs34 #c"H &q :e٩%= == -NѦD{|RYO)fӭK8lVX8J-™KV{}ug2^ .WRji76 }XrH\Pcxb60ƜQA [ȝ1Q0xh_c.~e&S(Gl8VL誨)t[$!/1& ͗LD,p%5JZE;tV' M:6,I@]:ͦIM&.ߨ5]TR@Uj'ÔBB@q }CХ5^ӹ<,6.6R9j]F:Ņ듵=ELeULckICJ\v U.ɥ 'pح*iR{kΘCqҫֲ;94sΪng%m] 5Sc^tPn5X0M}X4?D#eJ6m~ g|]=l' Y/68eڕϜZ8/{V2?\\]?.y|182px܏NxTz$<)An w\]~;wo g@E)ߛvṨYy|[K,'J 4 4/wF M %=|o=Cuu]SF(P*Ӡ7[!$wR!wO'xV Ңۻ ( ^{ W^(z`g蓧\sz%7v}{Ww3uT? .P`^(r9 FQU<mT^[{UoZwJBh[L\]7.Wh8q#Cim@O6-?8 `&ms9G?p88^uMU|2\G)Λ]8f'#ŹsPc$C`4}$؏MoIN[i&1'+`vŅE}*)f^Y*PzG,"~O{cm2$t?]E:bƖyG ]O| Brfx'n)L*'|Oni՚_KuRbQ/uM%9a|4ڟż޽?B%'tԀB@>p}ѝn1cuY4\ı¨ R_'(6y4dh@O+7$#R}"YM2BDa6%%K~"H6zF SnSkWsJVr-6g[ΐk'lgh@48ҿEx!Y0Wd?L4pAM3DA3`R܎eQ>?k?Vp9~h"_ã??r=Jq̍j+@8ʽ(@[WN _*݆xI[V9;1/ק/Ӷ!F.9i/iƤ]s;g9[>):STp˦]ܻs) +!ayRᴙhՋυ3IgLE1+k_N?0g4s˭zs{ݫarekiٳ5C%bYPfq4L}!x([—?P F;ѽ; \?*\wBGCY=;u%C3iA |H./^||"ߺy/ȟvچ|zbzz1GYfs@p]2iA?dPsbTx= 8ޗwQ\kfջ}urwUl;v6`1Qlm0-tC) $ Q!  oݕtI>;;ޛWàTrD/|],WPb -jfU|噎QRɌئQeD H-ï1D*FU2 }B/q:0[WUdDCRW]1=C"|ML-q[DODǰ!LGP@cO*H;w7Dˋ`y.KD|8@ g[BhS#R%F[V ʐBK}PDmq+%@Xcb_QG VJcԀ]`,N$]&JNnj1GMJzM*R{Ja>F(^˫V_\ffGVH~ʬXi2gpp940D\zdbͧ&P{'So++)9|ѾU*Wu(}%Z/8K^˝rx _ط(95phS䥀3p #;n(ɭہ _ѧDAlR}0uNj035V7˜$'K"90ߖA|"1=9ۓIkF;%_6|p쁤:d=IفИ>05i&ɞ'vӽP||޼mʫjx!; w|Eqoe|3zu7)/^s{9Ͽ]{<`<1GbdIuN'in>FС;|;8&٪}wwĚWs{q|mY+EL\1[ϸs6Nu ֥sk  {;g)V:{xkW|on d$-4QV ԓX鰷<|yyΕ+: +;Ϋys\} r[_G,TBWWi۽jgxvyzg?K.YRX/ƸJD݈u_]d Zq7zNjwZMKX ik_I64N5XG 7(;t{ ܕ u|-BR.T}m< &]칻зFe:.;ޡޒ+J0Rq6p5k἖yүͅk2:Z=x@ͼSF7>o0HDsmdɮLܙqrq0?{ϯZJZ~22 K_h e5wAt89PY [6ĭO텬_]xyaGEmŖY-jͮE2  K4z3]3ۮY|V=/%P>uB8҅a| ^`0=[QB<0֥BP67\c$e 9Wk8HZ6c)l[  /݅hz]VSc|»_ˤq#bd9b?a*wU7Cpth }iMj[W,GOC>qfM-w" GlZj(Z o%{ҭBtF<&wkI@Ԋm[e6XIY,;-"s-sB ޻Wz煙 ƘL=afx5O[<EF3m+!6d'7mGWnFTS Fg~sEv }@`g"μW>+9M;w]9r*Ք*>SĭbΈ 蚌B$7@b 2'j, fd )B-ĵ!,1/B-A0A`?!N#/"0t2x=>\k.`N ͬ䡙M`2_/)(~;Upn)#1!xȧ rҝ8%,#5>s%CM7l,Ң&Ӭ|UFg_O+Bf&q9̋Q>zU#Ӱ̞g4[@baƬ+[47f];rTJFO6j7T0V\Ջ{՛^kfo6Ӵ:?6Jje` IDN&t!%l 9 [SG6 ,ǶG0I`\*a=;rM4ِ~!)rg #K y|5MKjJO`]/\JD78&0K6v:W Ξ# PR=mxٚy͂WTmfW|[E+DEL:$ G X䛭C&fx14#t0z935& #m5)i<^ʬ{Gʙ&+Q^BIe"{{9R|G"s\ӄ{š3Jr7'v\!|Gd4>#d#JL 竤!,+8h.'hcckBq5.p|8ekWv7?Hf=Rz;~ !{ej[# jwh,aB!#FUapu<e/M1A{DUgs H͆0kW֜@rwX"Ka Xf{AÚ6XdT}?ӆCQ ܸT:-sm,Fw#9[ `8WM=|G`sGAL)`K=37Z ' Դx=1" b[-`1se溓r57^\OF25b~Oć3ckw<$=R-G?) i.6p<;BgUI,@M $Hr(׶|i+^]h޳/:-R[fo]on{j\&Y:̮ÈP MzRf!i ,гV`8c(l;K^8_*V> /"&>H27{ykH@yjH-T]g {4N,5W]F%jhuMIhyߣɐǬk: \NKZFJfRj .xlD?})qazN57_w~i߽vJ79A\]('qS@4$Şr}".MuIyz_J(,"aʥ!.— W;Hz&ʃ]n_(mG|?s&y$)̥_Z>sZxw0٦x%E*n0@ CX^oU*II"a$Nd[ȑ ~##de]|M8l pxPwcdBK.M9M {.ف{\8 G/haâͽEnȍԥ-Z>R_Ern2,si+c. H n w'Dž|`U`Cf+T $&O5(Lݝa"eMzT(*[SW8+Fml]}x|o}]1('e|R2lS]PA6Oi7MPٖZR)·CqR)Sue;{zQRo[}u VgO>RF("eԕ sl甲 )5 vו Hٞ)r|+wϛB?2RvĀ-w/|HdRo _}H__ોQR)rRo?);4.S\?sÔ噴 ZuM%PM~ɬҊ[9G!%WZNȌ;g1o֣:7gs*GΫ&4ٜ\k:njKVm*Dx%Lųz5q[6|嘝Į;9@N3xsi2DV9 mQm2I@63'мFoTی? azo9׃d75|\Af?K|2#znګ2:v3&x;%gk56X!gdjЀ |,ط~#Gh'?e{C+l%i|ʦ&Pl\֥@WbxՕVj=%nTX0''HsRǃ6V)Sowx=9?a$e\Oi/3yb!Ox^׉yx=Y7CW>; ac4hƊt<8[o׺iGذ$W \O8LuBSMqDxGZ7W$N'IRB2*B-❶H\yjRoQ;gێG" ;UWnfl8P ;zӗ#X` xgH\fh4<07t@dF DTzoSn 'He8 {LraVLnH# (^c91N'4Ϳ}3 jy"Bx*ErOpp>W@T!܀236;:!mj1]`KMk +kG bZPsR/%@ )'iK{}5@Żۚo#VEt_=V Bc>UFEE8?\ ~ZChd i9J~-5p3[bs,^ҍW.`y[Ÿq5GwcXg+_Cre| 3Q~tx(W;2P]KWu[{ҡ*$̠n#v􄲡yF#;ןqpҎ%Mt ϛ繹+h$|[:d]`y85o]=/fQf?[G> ;\3Ft79v~p6ǚ; @| (8y]Ry}Ct>as6nD7Q~-*CTVF¿')~O;1SH3EGTv sƎ[@sRfU+s 3.5mg=fH w{f%mM,hMdg/O[~^1cŭ!~)rBd6U2L)w2fu,%dnȹԦmjP[4*nJ`bc]CݺN4vt}y3me~ˤQ+tSbTK`8ӏH0aAS꿨?9KyBZEgԾsfґ:jԈmZ@ F_k5̕%a580Oݟ1p>JAݗ&: C_P/#ǂ&7,bI{֫Z6l7b N7g)%ܸ,u"UPLU @+5@`M)/xr)=HmRۜ O 'vpgBǷ+Kq{|sN#fu FeF֦ǎjv;%&#UH&A՝^n);8Ѱʇp.CPfo`K1 %{#1:yk{W䲢3e:Ȕ˗6g'>w"|vNpI)-w6 -C#t.ퟻLvM]Ywh.m͖d8#aT"霉e&Z:L%涵w.Yܹps_^^9\8o#ewZ޲jk%y`79񽾠-( +㴭Pgw62xx~֦B L_mhKu5cQV'BkÑp0~sJZâh1^}]cn1طFP&!'!(,׽0+$Ym1GɛMy ;4JFLP$7.ʕR E֧}gU(HY 8.( HG~t0BsUa0f +,[NgBS/~>;d.Ȃr2 0-|+fc4Vl[daxWwyVW?~?FH/_/,[xm`~dj KHTȻCZVMp{W{^}O/Zpٿx${rlZoJ=E"ѫKxfidF5T>=155=a7$xN7 un>rqK38.0f wM/;1]`jvi~Vt(A~?pЎ 'EdVd8;v68:~wz3Q~VU~s _/'#"5fnen&`C!s1LӺ괠qEs->#1'k,n BgVx}4LX!Gvӥ;q`T @BEo'NYf5"AV)Ow}xrxtJG +h<&L8fl d]lU9,oM;bf0⪌KYJ3J"p"3.^.ܩ_+'Q8RO&WS7L@vbMiIm2-*ksġ@jh(;}hvU5k[XT1hS2:zzѴ?ACvD7O g3UMbKdJ!]}CfH@`c?\TKVγCzs&#".7jH;xߵS joy7|[cfi֋@huJIY%?AȘfe촙} CoTsTP=#rMNRҢRRFQK }֕+QXa q>IJ6W -S0h|]z)5c<8[_~uSTx[\ ٭[ZZeF2ւ)bGo/&šr+~Yo2۽+ᚨiry:]~#hς"fM Keln#aֱ :>pdf ʯױǎb1q}x]K݆佫C"BɦCVRhsνNݖ=:84*tL16;wXGخk3]͎iOr_+Fzgߴ.f_2YYqنXOM-f=u˛c#W!hf0q5J:,* ?4K/3$KC Z4Dhg6 ;z=) J=гƸi ?ې+%^x!M\VU|[-ji΂`*u|K]Nڏas~1O Kp#?Y,bKEFbC9ͮcAj>ioAYow"TJ;odokV < vld3l3vufG.;&TVCLE,ZMsbeK;|iZ3W5jΧĠݱRhkpddv)W&Ʈ:0*&o]EG|Q[W7y-p&9\ 2C'<7D<`T`ng3Z];J172cN!XIO:Q"bΫݑ5]xyZYc)gi*bWۡ<4tOH1zv~?gƠctKVѦGo\Cy%Dӆ޼J&EseOlMO뗰UE0d7X5C_\ѳL*nb7wyLrBY?ms )SSymy|f;돢8? 0XK`8x̢FhWvݢ3\+LV!/_1F7lNoE fߗ; 뢁/ooRnѐh^E15Qхٟ9(k9(e9"a5]C~W8oD<l7J$QHq0bFX3vWc|ɍA9 ~M.6txQɲ>pA{"7w#Ex~`Zԃ=R~2xnD-XF8FQZ#p(QEi#J-ڸ0w6_6E)4,s(Slў/B O)^(|p&3]C2]C|zl1sXmJ^'2pM}{(~*Z,}&Ԓ]3S331ݩ =6dzMk)ǜ:_O]e_yQi$ӾIj#߉'1Svp/:";[}7_r}c >9UחAKjRqWLrJj4yf0*O8e?UM/Cc #]g]g}Pb?ADYCAg\$$}G(R!19Y]Ğ@ďu ۿK=v-\Pbx|gRJw+P+.O12zE˾;|[V(qrUb3-TgEaR o T\럤܂OTVс=&TF*{Pw+gퟁ_oo>`S"߰oL}ٽ1O+Q?n)wTeWvT>w*a-)/U>"|Xɢlӆ)G a;~D6:_7!G*rh\b~丨)-#/GL缣7׳:dX^^۱pbvo}fꆾ˖wLu-yQK7g _W rY8Ǡm3:[H[2ZDp!%̑Lg)N9^i)^S gd\$7C=x^R[~!ZNdPԅҁ ㈿+0LIń'tuq;K`pՏ?}PUL'uV~S5_q&4-o2fJ*bd6fKK܁H&2vClL Kz:,d0rG-YoZf-aޏ8Ѭ=Z)SH^lP]x㣴Z!{:@Y;&BU!rʥ8&^DqJ-sh}F*$ӝ)U Ѝ{/]'m\tY㍴(]M }Swk )FL[̝֝{dcNIMbY --/g~_ydOVsȕ&A Dkt$lL5mM+W^[.?IޕZӓXfpۜwF iW̨CNK=Y"R&m(7J`P!>шU hf`*U$\a'&V# ozV)yzrhS'p ~C.>ۇz3z׉yp\W+Ά#V%Z++.d4Zr\j !%J)"shn j:LiT֘~,t9~T8MC[fiܬg0#dҗ D!y.~LpBG:m6[zE\*2h5׺U.Mw8N F{ a%uww]'-Fc9w[Rg_՜2x'(w/߻{=]U "Xʞp$YKwüb8"w+r oim ֲirq=YniJCϚObO'+4 -l16s5o~~Cy鼛CI֍2 ce!c>F|0k;FyAv_ŔcQ´OI{Rsk;[ + #Ǜ,k3b#7GHbR\r7^ΙFt}B߻Tngݎ)e c ohƶCsܴv)5k|1M챟4mgvNީрa _e*u-q"4Y'@.#PSDuU߀<=mgM_W8q<<ԳJ9,@fxءa[<oKBe3m`ru";}s4>qjadʆ_=4t{?x..gGŸ^&>-=>RDsW+MI|Ahq@EvN Z8XlE G2`gDL4VIA#S$sH&>̈́w&`KXXc(S]:_3p_ 59{s˚<<+yr{?&O𼺤6 2tLa X xc_'rY.!W+$8cƩrՑ&nb unZE) Y&%8J%S+UJDŽe]U*iCxĬי9TXGVk`ڠu  RiYvO¿"ZE(Z Z),.@tXtv7E?=9.$_pΞIj/_,5$@pS֧ 5kxAc4j8 r|O$UoV[o(t7N~-CD?Fq |P؟T"]~IW#/@o4*㦡 `Xlvnswh' EM%G#2F>)K# v u=j&YVxl!W&5A6L dOsT2X_IQepQ'F&4p'%/pew~Ow6W[DeVaqge"ȾYw>rr[=E c**r\Vf+|` O%utA/Rө(<({;ʓ!հRGW`y[.` x̉5-d@.`V ix9Gwut,SwoܲiӖ ML& "V˜߬EXX? `ϼ|nY{N厔f럵P)2=PK시0;d$;ߧSG#z5()UJ.URm*&Y"֥KBazNZ9iUԝg;gCK1IȌ,@UfY|֨dzRCy7aoXV~ ZL ut ǎ]т xa"nd <^n\a-qdcfZ!{HO8Af.ٽ.'ͮYO';Om-l8NoʇJN"2\f>)דY=t庾Jl&ڛ˖KW 5;{pvӂ/_Z85m#qO92?fJOӡ-hեs;D|!)?B,O?y`zE|\ ~!ZM/WEfڀe*5M$@+O) Kkps*RA>[r^H\PUM{nAo(Ԗ#,KjDfr6(6\!}Y(.yU[R8n*3SeFFbs^UY QE~;93 `?,AqjmD+1!_X>&uA?kfpC˘M]_]zw; 'J,6qn3Z?dx\$jen?|}z݈֚{,hr:#@D̚1&EIrT07zFraFh/e{#1eOr#iN/;EE"kt'CB"P&Oa (N9< 4V~*>+Ԭl } !*o}N0I0v:9gVysQ}t386,LV Ԩ:Dsmo&R}H8B`_Ȧ Ԍu-SȢD#oGNege$h6k DP׍)8m jꖶx$b萿̾^e6)l y6l87c9tNϖ{v 7s<յ|pv$`NUuvlFFf}$^w%̩o>}SGW5޽0警MomNCdNN8mf;fe{cEs}1nwMESf-7`#vݺIExLնjk0+I,8 XjDk6Z*-nfs[xfžhM&YȱVRti-x%ZUⰔ1OK/7N, $QNMf V<j. ǣ ZY)ϤB^"YdVw9>c@ߟkre n[oӡ`ї6Qndh>g5FF@ۢ@- cs@zݣG|#W ߵ73}lڿlf;o[tiՖbO+p)K;Gh,cOQmM|ihUb}E @Dg6,L=ge/ʏTYxKbP>o;+ZӉo6Fruz&6ͺ-ynT0|nv)li D.(H%ަ/2jY@\A"w x*𺕻ͬ?kSXW1\ԌJ%<"NwO`7YN?q~p3ԯ -6Tې^nzGa?̫ 6-ov#\y/7uTxjx Зaj2΀iuT u2'YlEuk6/ ^@)P>4ꭦiJSh4%pJjwX%MzR"2`(uJi*Ui oį+IO_F"[L>uIǢ_NI::vueq}=?u ӗa?jiz'cE{:^z+@e{QWQ F@q`+P=;Zgn66>22.WYN*л7^f:)ܳ/~|3-Ӟ}JE'wzJGgeS>]iWҮ2;3{UڕVI'tW}6bC3 608Pl%I&bӶIk8F+|}}gJJAO7<{˳tydgO4A;SH& o>0Z8NH} NQt Qct;ȏ3 {U f* Sbs7<f 9 5gGEP:UPoVMC0plL6ZEv=Z)8Z"O8m{Ex }ŪX̌ΛMa2GC/w#ڻOwcR;22g0"S6;Ojꆔk4,ʎ1] =Umv2N}Lqo.3Z7V~dcPL-D@K+pKvo&~|<7ن3=Mg dⱙ!W!ߕذe.Fdj!$'V?4NYiX˚~1g x&#f/]N<⊂ Jzu78QKsVLuj0klE+@!wcG)HI'N@_?m JXb]GG:k"'{6bmPUm?u,pSwc&aoYkM?yL鮀ԉGÆJ  u_U}g,hvdpP4@>h]RYPK-IY{ȒE+{EbD;CCnFVd5 GT6Qm34¬eVKnG=,4/B[ 'AeB G FˇY蜽~r*{Z91<;Uz}1uw"Km_P 7o/b<HkZM357߳XKfbuQ\;CiL遣f\VMyGaմIBvIL8{ae ´&v#hܦ=h3 xRNLDxɥ0mC:pw!= ĵ5uGE۱.C~4F;R)6P4P?<(Ooj>}]ب%6Кok }e)V8n?;n~:ugazP82,pV@ *R5}p4,/pWBn}lM""b`c`{{ܞ=nmޠm `zIAvܜA$gMeAuf-3q٢d:K0O_z1V{TP!?0CD6I>⊇$4/W^62:*tߧ'"pB7<15Cٙ:-T*ڮX#F U%^۬4KA9.XNY A#HP]/: #ýWeS6ι0s7aÐ!7o[`^y.?u}_[@:R*bq]?Wl2ymia4Xy͉≂0c?Cc|qXKx1`%qFˎ ^385 ؋<0E`!"Oy~HigAn2 ?"}‘o8sDlW!jP]io'QM`@ }wgveb?t790$<\c[s)mp9?@p;aǯBXxyaho\%Ӏ{4:L¬ mǽ#'wyxM*েaFt(ĜԆy/z&g&O ~ZԮ㉚3X5(؆u)yw ?I.C-4%h9s`a!s!2 p@2O|-&e>k7Ʈbztgf_̼TY# Ϗ; E-0_eO[Kc^6 {sdl6Mdkn1)[wgy|f:qm ژOEng蝥u'<ȰY_V8w7e~zӌfHWu4Xk7Vn7c;GwSvsW@6(,yƭ}Z8…~uTKAt̋;M2<_A{5bwfGNdQ%=4q6Y(  7rb̬ z%)@{TQqxsȉi|@B(Wk`/?)ZAv=Jt_ Ixb+8SúNih<% {zd{+4SH߀gL:aw @ L5g3v;E3dlB,G[=' Q>|o&DT q2oR:/J&!)7.-lKf{ |߆j4VqPόn+5;emtBXA{lhCݸz~6}K$ jOꠧ(@Zjӟ+迁RV YẓUҹmU?,oxZo@kbR+o*8z.P@߀zm  gorHAPD>6O'1ٜqMonYr;߄C}+%9b}q@Iq{܁%x0 z/:)_cn!PG ix*xqi$s,A#!JN#ya<(iJ-ոG!R=SA%ps@C ?@  ӵ_'FoRi|zXES iG JBpB/k=%1D@D. iR MX!TCCZl1lt}Z1*\؀EnUzB"֡Q\jF'4Dd;x}®9 .ª*nK˹hHY { vcp+@ zX ͮu񂟷Fͤ2 &vn3S̎Ӹ;^yk cQ )=kU)t6l6&RX\ݕCm1P{49k M9xB% CQ[qӘLCjlt6pQQvF;!/m ʲ7s%>[~=#uE?U{).5f۽3zәe ԈP"bCYCf+鹜>ػ|`q\SyF/T ;Cq:i|,"N-E+=2ss6ڕj n3=JfZE-sV;J@y}wjߧ"ef` FDAũ%CM ,5AKkƏG;3&1H'dJ@nMŠՏ}Ґ?lL|.G lSиMi}i y4 tEِei1]uHAL,PrdQKilO,>f#/֢/\U[͓^P#oYJLKmpAfxNEj,O 䄗Ɔ=.˴a:);m7(bh6Y|iW'G4n0ݕ3BF[}:z>]}|V6X)>~f׭axH> N\<9fF3frvw%{oGr+7KX>Aa,&SS'<+i mqiSY:|@" AG,J=ٰ4 gyi*r!)1MMRޯϞ$q5X귡ApЃY)MICZ;sA0b+Sp4(YuLtgY_=$1$$RE#5QS'Xe /P|ppp=wS6m ,MhltkfO `Dc18}r$k3J.^/C>O n<g'F1,̳8rG-t㚹g<;e~v$G;mKf`i۶aj*sc_67-+˔zH pM6|}rۑPSdrX;`6FYW+xW|{Tj61%;GjS{1aYE`8\ް2 , 33T\x)Cd.n b/aBޫOn޻>k"htw-NuRbW==67%z;hɻS1=$6xMm`^\Getl) 8gx);!Ԛ`;{wm![fl]8Ak9P0s<7)%Bшճ`M3x-QX] mjqXX oBwHjS k< _\5M|~M?7 >¿<>měxFd7ע _@a?=gto^lt\FπpeYѧ`6]xpi2+"@tzj q=}L3Yb7T> 0"Å ;at A/2w0`q3 ´M|:4c>̢[):Ej[s\h%Vlt({!id]g66l#ްǯ 2UhI|%Z/. E?%joPX{PQJzoو}Fme4c 'N-:ؓ؁L'7S!ABm[pƌmg-@ׁ&W @c1#fK{8$->m\qiT H0- :NX%8pȏnF?m&E#&~FT hM&KvF_ jQ z-1m7w# :. Im LSٹƕ63Wvv0%Ļ `GZd @j28><戚Si2;W lR|.SMp$lu{Uq;aԈXb#jngdqN): R2p%c^(BւظO0W<ʛ OT(\\.]EqBg@ &VR7\oq =,N7mMj?'.z`k5pq0'^W̗TY/lqu D=j(I `_*( i/1;&o'zڽzMUFAul/ U&9c7) DŽ[Ŕ(er^h/_ uJ=Q#v%5D :ȶ%4*ZԔӵ{?Bk d1#=o1:tYs.Ɯa:P/ {w2>[6*-M#AJP^,>\ɧH^sVI =.J Cph2ؠ&:B.>x,;2*[0 lcRWEq*|g$lDvK]VglD­ "μ[GYi ̓nh^nܺu ʋd<₧7XU3XB8'Sf θ@H7pFV( 66/j7QW0J@m^H(nǝ2YXj5 H +t2@gSpa#.ssq<xYrXL<"W^ڝ /rO<ٱ/DRnM0lR.pt^Icdv/JDiZvc =\\Np7qlֳR^;\Ēū˕mo~MM? Y8+3.=, VKj-ԧ` ZCOU %Q'AnFcj0E #3F n7:˜>cd.WR.X8UW<4>LA x(l1۱u(eIZiԌLܹzx:n P& bx}U9$[p\G'kJL7 ؐVD@SHҾ}Q_pHF _ e6ϛЛF$aҝ gzouçSx(>p+h9&65erǘ#>/?JaJ`<X&mn6 NsCTkB vF^+yL"r5oxo^>U"Ļ\&Q֏ǵRl7vwM=pEqPGbCE3b9vQرxbQc ͨhQy;( 7J` e87CA,ÿ6yvzIo]Mrܣi tVr PGnpH땀BU-}odH]dܱ~Y1/-~+o^fcCVvJPf1GbJ`nip@ 8OYQ# .CT׫3C'wYE6V;oZrbk캳^Խ'^j=tthꐯU߶Hl>SsDn"*SeYh}/sO Nty?>|3Ţ܊f~O91bgz;xNh J _f0%0bylAc}?u'W^&svlmwo@jCe/POٚc]@nEJn|?idmPJ~k3mҷ}Sw.anĬ΄ ,0xI/3 Ls3Y+oݓw-uɎߙT2Vߒt4mQȝI(N3XF"xoh? o]ru$džNmY6?%l],X's[4|L};0@f%0ݭM\*:hݩ/Ʀv[0 UZ\0VɄ 5EE"v*P4TfGi#lChN0m;E_YTy݃/d(۳2X'0AI26,qOI[ie"B^54ҙ`ܗV"B,f?|ca|.: P/׆chshp?~h8dM꨹5M:Fa;M-%PF=΢ VOx_>4ih?n~CɧZQʺG7L %v0p&wTPt4:/LvE ѮdJ*r!`meL>ۀ.2-|h[۾mH[eܣ*h747$`qOf|K6@lm ߄*uSMFɥEເ>|~N@90hdwKht&bmĆ CV!a?n#B|kKF=kLBաHيVɧ)̧  $:PWZ[*Soը8xbt,QkPd4+Pqu9oHU^ʴvs t]u(2J41wmO3 ضo>l!(XVㆨ*MX͓;RӑD:SUvdAf*'9:~ 6e=@ t,?6gx^C1/ɋ!iеnCn% IPJS!ZUJk_ <6ӭH۝ܔZf#Ø1(k?wk6=[@/w h{(FǝVXF,־^"~+'zZ9Z뼹%ks+uN}gCW%=b{cXK-0ŕa굙(~PeIO߽8=^&'dkϢPN;LD\JyBP +R|r2AWts H{2&L2>0/ FjS,*}Z{ @֚;ct\6#}%1vu%SժZR'H>;F,1znU^"Ɇ)v 6pxmTh' mFಂ^/4_뇁 vKܸ[s^deڿ|tH۳dbBEj]z6ۗB` GOkH&V&08p@/AoZng8Q:݅o}(L};#j5QFJۨ~ k/aOfAƍv"=~ 麝 VlF``eef7CFYothy YG  ϠW!1;d3ϞjV-0.W0 )Hs-dcgdgsSJg-˃v8g_cB]/.c?m`&jѥ‘h8fP!*ÚR/<76>{RGO)<$AzɮaLOm*=4u&Y_Ogqn}3yYƝ2}A73v֍N.gzl+<]')}xnsw"+1&Rז-Z8m8CaJ̦Y|[2t~#bfSaׯFjg-8wҘ2rET%[' FD$&臛.׶tަquWm`:cE~ 9\-kJ4l{WqOca Un5ꪸVͅfp䌋=W'@o_yjO Յϗ %6M3_q)J8fg[U~˘k5ʁAۥ # # c+h^`y"j#LWlE9w+~bw}ԑBrwoSA. w,}V}_NXۤt7VQGàt=xzPd&1EFGx7l'hIڑIkTǖy38V K\e1{t"+e3~sv N'xGUt[ad>اbPu!>4yڧ j ր 2ԽdYJ#DuLAw|ީ|n*-{Rm(Tf2 /wm(Ѥ}+b_C`QLLHُEpc_/6!:WiJweb"]DU5|,FA.62nڳZizKu,pxijqζj ?V׸pP.R=et؉Jg)7zEY*!%M~~xWCM {xZLӝгɲھbl-¶ၛ=D'rR`4!%x(c.w&n vyiDKL1 "+ZT_D.;U\)NCݙR'\&oz67Xc/lSk6s$behĨ+1Juz4w]ٱ*Rc)0E"!CixPB@ؒ!)dsQOd>TJG*r>\X%Jf2´ll֬~kPGl}lJvly{Hݞu޴pS^^[|5o$dsgN=t\fz6h5[rǞ;#/݌h5NJ=hȊ.de2uJ.jaF2xR)\U%'\&ގn};!~d̩]J{nʦS%B_(eI>㉂+1BvbwMXl,P(/+ѿQC4^' z+eoma~~nܪv9cמouYV+2 %"6/0{L5+#00gb8`{ N4KHO/n8-J8\H ŤѼ˛R+PWC/J=]{5m:=LgpEc 'tQr0a#t }N`e dL zډ)sv$Vr-m|E-5R VOY+?i ɜDQPn#c3 )_7 jb05o;>Ы1l_K+ :2$ ^<+ !;6]d[^Piu\:X>Ua CFa'Ciavt?S; cQL9Zƀo 5fJ59EU N[ X mO!o\v}nZII0! J'cJFk!r9'lԯ]\_0<UBzv$#ކPeX~p7PgV y1d\jH*E!eޠl/6Q>í Fӣ@:F1=sD-+I8Ru>V%twĒ 𱟉cDXru; E\b1=5l 24:c,h4ƦƟUPMW=Hw- ~DF*}Tk+j\uY!1˄31c1,7‘)O<}G|^ɇwWgg6Zso劷MNRS*;d)oU@|Hc8i)J2cĊbx@']\)o$|S')J;.( ̠'~8 ^(2rh,@KBW`ͤΡ !pЀR8D hBJ']+lGwo~*0RHʭړ[:s(w7lW}k_1c6a{rWgS#;N޵x݆Wk LrUe utJ3{1vG"e3ڱ_a tz4xlƭ-,% bh1R,=U癹 ̔ƶ^LXʱ-OEb9ik N.kKoYDv| ^L=] Nՙti5WD4) h4ŮTV?^3:6%]3I'^9Y䫼1_k}˞#_6{'VνʵɡX*xBf N{O y;oL?A V<Έ hRTA{!80ΧFRߗIOM^X%D=BJXb&s>E5 2,~ξ 'Ėc/bѡϦ. #1<M &}cP)<-'.['o hЉSGuj/&L4!AI328\yKpg.z2&EEB轰0|A a7445e]!~V5lv[̝b=ştSdʮhNqf }E4#,/hJϸ3ZKeWDHr&+ s 濪z<_J?XNq?-D[:ꝩT;V^VKI_cα Pc6P^ )ݽ-L<yr'8[Ŏ#l'/yF$\m8DC?m$gyӓ{:U9{r;a66'i@Z J\``,0h8`kskctlP9YMO0/k˘@x5'^qTw4X|jvyPc6HE>]st6nFȅI敭Iޜ[&5h}97]XCC.Oŏsc‰AhꕣJK*Dz1רrϹ/JzӸb|4]zHtGZwX%ݡH> ޫSH*^fl.6 ClT0X Mӛu|3DDkop0 lqv'h;.ȝylk؁b4&t{T=˄Q;(>:!vTCR\IN KrG]'n5<&l먛Ao=@c7u[S_jFԤb٤1hP!C ӹT4a.g JX@ֆx,4yl4:5v{,+;q';q*P~.97p3#vҷĎ`杉m37bll͗܌re3)5fP*U 3-~|ڸK ;OkN>6]TL]Ő׺ 6&zmO:LEGz' '}U9K3SlY兂ΚusCO^FP^~Pb=|bt/829W [yu^#tZ5 Aع46\UseWj$Vˣ?埿I:L8bn_ DIw*XR]b#M_4-!MXc%M=w\Mjݣu߰.(埻2ky魴cT5[*PEUnF\z:O !v)Pc(bvv5G=(} n56 ]Jy+S !P;C82Ź=q+,sZw=&\o $h`x\$05I] \F DjlH}Z2G6v?\n7փ" Ş'mwP}m+c|&{GP>֗mFvP87{ US\4aR&W r'-RQ~o*T#gfJq$a mt7a"uf.WZdS544)wdsFc^6yCuIΦwLlMWpgb7QHMG蛭X{DHʋP3ROФQsp@u'I(+frS<)JBҏI:V#`.2 AU >V`F¹S\ӤId'& Fd8@| 8 g']O5N .!Vi`;ͻ۝ҸoRzƛ ^D:&CN:]2~:5ãq1;HL&'3;%ҳlݱCiriey0'TEχp6 [q[@V0d<󮊒ΣĔN37%V+K:f|4RJV/X[nFyvu1ӻr7{)'`Ivg>On=oPh==fAH3G=A4-6T  yↄzO윮-_\<'x]Fp>\^BhadhH:,lt =E)@lje!YyoX4PNU[Aw5 &BBAfPW8hwyOZ9.+WѴדA?u{ orpzȹHו˹0>Pz> ȇp~RUS[nFV[>y:a@FeR͘־bB2KuIMF5|<ð/ί n]IoӦJ_v|#$lk}A&h?&9Vxԯ:>ArOn6w==[teGiQ8\͉}5 #A%l06:1YP򖊾T!([= M") ooq|u::^:0F5vg6!0f"=Fό ܕλrTfEM{ zA:%dd3AMOhI3Xe' Fu atd: `x7{_v;#t]ɶ9wlstv3Q9X ਲ਼7MC|vӬ68 x5La9 LbCϊƭH&zȱ}O:i T T-x4M[ig"V:j^70ĭd?PQ9|ŸO .ߞzG+1㶖}>rqN2\Ȍԉ9*b0̠HhSy3Jv4+ƍjVb8p"d=K~M py/Rep>|M7hUҡ xPvwRBxA*y Z+o ~{(n{QVn{aS7+ߏ93F39%ƻ!ԚqOeȠ{= %ӓ#ʞ!}/\cZ7̝~X52M; Wb0I 'ׂܠ:t"Ak4*\β]fQHEJ ~xY0}bʗ˝v;aޣ>pҪQX.*>>[+73qm}{$c-ESSJVߌ xCUZȱZ@X*&j4[/WDp.Tbx>}lFVT3`BϠW4nս--E1!ݱ܉Hò䋳*SW?6Fׯ"D(`,j%춸>x2Xv'Z8x<0 9Y<ge3Xep\-H0(Ju9lv̄Hssi@/8RHAp٥X>X)ǥKq:ϝ37Mb#n^^V_P3̘:WipBgBg;Փ`yq>#O$Bx|NAϏw~y7({SOn(De}(|n,Gm)thn< ƃ hEj#r_%X2=FFA`j@%hW A#ʒp+꯾5A?3o=~g*&@nnG P@B'j*f:FO-f9uƩM4a1&â61陿A R)x4We*%R%Sr4i&)i[3궶jޚrR40zEn dLGd/q7ԣRsK+tuǰ2 =}J?OfbZd'Z)gl.>t lUG#@nŖp%X,7AHzD j?6r0oD$ǂ9~y4Št-MUF^ ǭ]UT\>6 g[f'Jul4GzB RxdXh~EW~J.!>NypHcq:PGB{d.C~y|Ge`|%.UzM,G'f zD;r@&\Lﲢѐ==4֢)}5ǍJfЩ`#kE# jK@ÉO?nGjp;5*JnDJ) ýa0YLGHEQ GWi@W  MD#}*sL +0YF`/gmuaW*^-M!Tk%dxz4dRkAB$0w->@(~>szŞe@zPt|Tr6w6k0/K0Y尥Y;Y{X5-{wݴY-[@w/GvaVp*qzիbxt{ v[D{ t.cnd:rZ9>aCjJZF @Ge%:Ԡ|^.A\W> WL0ǻNxKJ|i1 B"dʑFрJA!cf<:Eb5o='X^|D/sCB0|Un\bmo).;~[L m@3C4iGƂ4XpГ~bJU8N=o$eǜRuB8|ΰB6s/+`hulIJ0*$P NOk ߄FdB[3Bk:nL*_`zxҳrs[k? sk"-Y:ۭmfh(p5|RvN?> +\}涾Npꅸi#;8P)J^ˠDSVB[8L̏QAOmVҽ\K'ɯ~ ,ܺ}d4+Ueml;8_*WtI eʭOQtD+!?L%1^>x6b_߷G 1!3U/s E=h "C!Grگ3O?أ%&RS~iO LqW@mt- 67s=}\?/ %auTw];]ŕ1l ;@3eoy˅)vКچ恠u ^X fF4?QJArgP6`& _~<76گ,zA&`B}rrp71ᘐy, f1Cd+?i2^chzdD%(]0!OQSnQt[ZJ?@VeTRU؞&HI2Bx^ޛ$HVFↅt΃;2 Id\p?/dkYYLaa`SK8Ĝ yr74L=.V>zop>dGT֕ qM}&w3pnczvzjqߢ~[2jIɼeEARz$wL}ܘƪf56vrk>p~YUW(79'oU1폯sS) Z ҭr{Q}S^P*t'-D8e G%X08 B˄NqOD8H44Ն!qvc=;DD2KP  mM 9M^ΥQDyJuF|i^)ʰe% W8mqؔZˮxOClt*6Qq2]8#>s98 ]/آ({p_rizu73aO[g9X5O;NR>N,Q\Y!!w}dϞͶl,}#j-@ե})K2]N#CgZ1Z-@FcbAf͸Ѐ;;4en  :Rc>~*Azhq'GcW*@J?ivGq_mHt-YX%)IY5y=ۜ)mp;H:]]%v=Tveo3Zp_g儞N8Ğ}ҝY1g_!v.F^| #´yJ)yZhzNX& 86Jc VΞ)[=6N\{lY.\Sh$ *./@ߧ Rn tȥXp3XWw'JcMP;qg\ f c62M@eu ;s(C`ˡqo㡅KqvNwxB-yc~Ω~Ѵ7տ;P۰4R c\εUdnUJG 81,4>pvX|^QtqAljHFWHv3O=Kn~ɫNr Z LdiVB[*Z5bBuB˘/PJQI$ P:NTj گqr{A?^֤r^ݹܠv.ԟLJT^NbC'ɫll>XYO;-@˸DYm[?:d'ܧʓ'v^߱lTM3+(۸ {'O5x=s>Q8SjaD7l2R+v~wΧ]'%ҨU;̎Λ*q-s իYbd͘-Nչk^?Ǜ$5zrXuA>ja~@U&֯n'KOE5A 3gTP&}k&IxCqF=n6nYufЬƆjGK_HR8͜*\(e®@aqV4Vx˳!Wsȏ_s89˗*Δ"V`UXlqֺv|&x¹Q]pG5(wiQ+#+:}G>~2YLtmz2Q'ooyR]7iow>F`~(m.ez$?OO3 @M  -$b9 (SQaҶ wxϧ઴toTvŽ=YDZ(a*DDu?qe]R0<NfcQre+:۸㢱F?nWU/;Tjgtl4@ؖ#rr)gB<=t3hOrYj5BdM 7ƽE;>]*&=LϷh9+jCPXs]"WKmSBpeONV#{;Me j40lFP#&Opp'ʍ,,$㣢{Z_m,6H!9鵢wv r7-~يmel'IUئA-N|hg["Trظ^͘k5"Dhr@"@gkjI9P*mb (嬗6[/1 Ħ*N&>}_n iJOi+^fQX7 *u"hTa%&'%/L^|bvLWf,/|~ik=ڏ+!z5b&':i&O$_p=kx{FMN{Azчn,}Q>+syώˆul!լ s#;]82^>0^92Z/kF9 Ƙ*t}xq1.!Z Btilo%>w?#x/AsxmGnp'gʧL2WG o舃L{[擷bFgql}r6,V;Byof40Yx)]m]{!x^᝹t8+9O-y 4e>^ldu)Oة8T+!gdf&<&c g_i%l.4v4&KŞhwXXU=G4%g\6,T/VЙ[#{ 4'5e: E0[#fk)i/18pN)nSfш# Yd$dwaN8 )>_}Eq&.5߱7=$ Uhti%s3w;BsNvMsnfo߇v9 #mFHY{ŏC8gY_v V=0򰒸1V!]c8IEb#cfB 'hը辍ԖLÅCƟ) F`_W(J[7)läW0׻ǎ$Zb*P8cՔgX\a!%gjbX:+j+*.%TﺬA9鉱qqY3 ||÷ݒ=hϳu):bvAv B9&mZݰ#zR,aZON`9[+ZH+} >oAcLʏgc6VqG#d~ٌw6ESXDyGSUaB!jG2Ud.Nu?DO ?R]Zr.{} pifYIRŢMM𺟆iO@ :j̕H4,z.[u5h;x˶nNp7 v̒۝z6N>3ذǝd(fWv޹q&y.>wA$Zۭ{hȕ#(;Z<_j:FpT\p;q7F &lRQ2{(S4o^…:W qP& k 8B`ͤPZJ++'/i'@㹝,>-Ǽ}vfcSK:>e8#SXmGcӥ4je:wdvl`(Z\hЪZjH˳ EIcvF%pxPEJnISC _fWj뇆J > Fmo۾IDufzAsԛ cbφLBCBfe@iѲGdLEnjQWV}9z7;?pOF!C\}ی\ٜCAPbQ}Rx cg}{{t,gOwZYzZ=>nQ 25w-R#}E4Zp!Hgyјbl(/wӈ 6`?]3z+Gs 2ɗm瘖. )&OmsL2F uh |U+<~C@fbۄ4^Е)Ç_͗ipb K/zɽ>s= ܬSt{/n=(DG)ާ5j.R1j%fcsC{fCFfu51Yj̰>eF hfð7:XLZ*ue^-lKQ]b@lީW'k7(ocsT|77"Q<㈅ ;+k>0Ѵ?I]sOۂS$p>N/H2 wi4v~nW/h~l ^c鎨 4v3' kdWf1JQ|-;DF[f|&9[H_51i;#{~=קr!j*ᅯj41ԋpL|~0`w0.Εc3J:ԙWw򂂬zkSy̅i%}cKi%x[Q0G=n'R1`QڼSN2~#6-Fi9*!θR\WC6%~ B^-G8>&яYi=vk>p>MgXC4(=L>عl@{6_sP_;0*ߧ}Z"͓dB\U0$0GF. W* j*$8VWF< fr4o1’ϻQO[4Dnhh}6N/;7 PĝՖPETsa1ɀG 5MŏZ] #GPaBN<[Bpc̚?}Y[r]sUk'OTq tY\'>Z"$iM'|8Z澅27 Bzw#;F2.T*sjbDgjqmBScNʯurO=(.,W)$^vOw(ƵKcR9pXoH"!F_ͦ7b^noѡDs/S.&֨=]ODZ"x2)iS5`I'p,sܸ@WiWn=Y*jd0,>Mor^]p6 8cD8[w j̾w> aιA=]wÿpW >Fzoa[N7R=Β8nN@3єƋ5AOPP{JUBKe=T uݜ?E w" @A*m 6:Iiv_ ulwټVg/7S(&:"qi-OL4|c27_;sh'ngbgMn?&N}I MŮnΠUrs>exjfQA^BuY= 6YfvS#4l|kݦqsW$)oo=IPTnͮIE_FR) j[SYޟ] ν5-!s/ܽm]%^G4,X;i&D$WIG0"q)k?uuK+wGINx|~ ՆHlLP2^֠[I|5:7 [%jd J{;H3BB⏞y:p'kN\e)Q ](qW;D鄁W8 {CG럻6 *V&6Ft2k ^68 Se0z"cAe.3&ߣ-_ZGcM,#);%yepA Kh&vjdkGg!~g~Hwψr.ZӚ7"$ nR{ɂX ~k'>a`ߌonyn}GE%$83#lY>]J4 ։x0L}4`Tr~"rleՉjcVԩ:M(]S Yf±:F6 ǾDk]P`n"m>5 ¼y#KFf1rd Pk/- <{N uL;EY`:b}c(D\`t ^XWOõCTDRbOW4$P6oH"-dܵqk9`- %|hZ=3q"{ NuyJlá%ʎA!4zϲ [vUAWk F밎cL"D'Iۆ1X?}ǞZoˏ=5ejO&h/dK^M1G*<1=3NfQgO\L^|#'+cˌ"MAm3]&Q|dE=hEO"WЋB;SxQ<51ny@ًI׬02b=Ox\ow0QiQuQ)c,Od G6(Z nXV-GH^LᗾdUOa&#AM\n=Xw@c{Rŭ[^boi_/}ƕ$MF<JlQ=|Dql1[o 9l4J!XW(n~آY˕x#|Fw7϶vgh%e3E3%cvLO;iZ^Y >V+F[ ~.ˑt.d3o Щɳccc8o1qQRde@K)[|,ιggc 1gc fůbOc\Va<1j[|UwҺuRmUu_ 0,(\YW㫺Jy3#b&w<:,Q%b&(/_5G8oP;ޛc7e,B@?٨27xˆF MPE̵8.\,ld/8^}vf9F*\t"nO"חNQ7T֑+peܮ>41C7hWMeDblK$I(цL .qT nݲA:cjf-u-!=|؃:tۙA~ j:M꿵ba=zve7cݪU7,}FىDK>>TH|!2{iҷ?˷_y shI鱩em>0> 5 MW]t7EtϒvAd<ǜ̒oZy6qZeWb`_AO{;;6,<4}e =a0@FԤ0/Y!d1mcve7\d{U/dL;~+TA ʇyo<Ž,vVlȶ+@BjO貆W'WߦFqw* 7C( jmA-k |X.u&#jo6w/²svxtph%ԚQϤqwϙ~yљI0ț!\] jT&ں!1xs; x߳=ݚ@Lir"oFY1Hޞ ۙ1c 5Si8Dj +kءO)'dc d+[XTN vE61iF2U"|ޮ["4=3 _kd_ 7df\|g=# g)6,G҃|']C `-HHH_fڤδÿ*o"VHS.(Oiu7'[(idmev|*tD;wܺîhݹtpg IcXtD;qQaKmݢ's}4>+itx0HGN&(k#|-F^f.-èMm5 %`LR WJ/ KḪumGSQwT.3d S?$ k6^z+=[XKmunWzFҨwdz /'ϟ_b6KDW|7y FXX8ǒ fag8GQUy,DBP4&uNFzoG3RGl{v!Trܞqܝ|C{{#ʶ.&m\e^퐽6#Ee;U]#QWL#*`5䠐+N\k\2@3OU*Gu՝&MܺJxO,cGye ?;KgKpI"AE;0omz~r:sT+pX+ٕTs"YHۯ,h[EP*c Id:kI- {Ȁ=fҫ}6h jP͂ă!K Lj[, l5џ= 6 1";<['XVq?K@|| `TlZh%PبE)8K5Dȸd-H[]Մ#F .cx{E=*f٬5lOeY)VH5yAXGi0ÐH*T[Q250G3;_|obv>gfdRFxe6g?01a?;v5We6vYSb/!nedqgg Ck5=sE!>}wbe$H M{Xױ-Ǒ\ډ$;V_;33P@MΒ1v]ɤs[#,/6H͠UȤBN 1/ժ`N)[OQi (%\\|+嘧aDh27 kP{=9rz1X"%4*˵P|_=@{IoV^ⷉ7pi͝jEjY`|%8L_rCvTt9*#„LkYًMh'Z,_gK( { A4ТW&Ǐ57 WH-:rmuIU 4МĪ-jnܐ:ﻥu3嵭MJkxwm*>u&u~y0"!1jqŌEcў D>"]ȡA ] ̞J+z&^naQLzfb%L0OCO@/4kA3+::<7/5|B7̗ M@pKW7G*S݁3nbfA,m!TW߮ilo5B#ʙ;'u'!{*$c@͸]8$j@C !^s,fO\&Q}Pg%R(͜$8-Ok P{ X(3WJU{'yV+iNs'3&}of֥&EVMq,m6ΗY"Հڊ6[pHvcwN)`F/T)uFquC_iO&E~#Eͮkf1d<,iqj zj? AM #/wBV":s!_?]X͠vD!L$]r䱃3Iy1R T u +yCY3cK2\45 @_$4i>Zl]e԰Q &@TZ1LaБ| U27sLqXZxZ=]WX Boȋ,Q/z17Sl.908:TvO!KϨL*8R;8Mϸ gZV$zIA8U%͸zGX4ֆU ++:$X^PgKdzAF?ts4"-+\zͽ3W OXpzKX@tU rp'eV?hTmݗ;"8_,mxXNm$xmҵ rӛ_I3D ݿW/B;tds܅,8\RЛΙE6M"V r5@+cY[ZƤa@~,yjb_Ol}8>hmrNGX^^Y핺*O>8};wr|_-SS9 VydfV"sx.|^fuLvE0*n%M%wL6VAjБ?rv]oOx]QaB9lr# ꅣ>+0`g=6a6&Lе7zh#pNr|y򜓋N&ç#+=gj?zx'.xW {݀Gׄȏ$Չ;{g/\[!Zx AZIOg&PF{g6"Gͼ.B{%N.dG•{pNݑQC99/KWGN: T'-HK5zqoJmQMnp/QXWu:O"v40T9oA}ϟ\.j$ၥU(g,.WLllMIy-=R*Щ'so -]d#PCXWz# M0k- q&ԇRŲ;;ܦ ' Qa N1.lAua4}nXy4:}gB ^_E&צu%>I 91:{|d?{P3?WJpo=vZ;F=j;[*Dg9zf13D-#29u TWeTih15j}JxO|gRvEAHŲڤ [1E: NF1&赨cY{OwaF!ke3fQ)s剬=[F0mof:ݝ.ݺ b9Q`s{غ,1_'o';[Uqbb^ty,X1"m>R% ƖR6Lj?d|8գ/&bN8i0bVPҡ[O+AZ8=0v_,4o3?5ڜI0NbՈ.rxH%ljZa]%\& J+C+(LqܽJ Y6衺OoWq,4-JmTpjI>4S7~*?x5뱌^}RRLoNWتJt"g؈w; ύ}Gq|'x8wƉWMHL#PNN0aZs@;4Cd* >ZZw0 [gm@D9B8aןmgG&/5c2`~0թ"ּ_h<2$D:vQ}ET&IPC ok ㉫wz6V`Px NW[>0l镜gC3Z*gWM*>O>z@o;ɸɭ#?ɞ.<t3{Q?kh2x7Ⱦ͛R_Gߵ?[{/*W?'K Úb>l8~?2?t?;.?^>&){z>vRf(*v.Z+DoWǜ"DpKNz]74j)˚Q+=~jg@kgHP9 \."Bŷ;kz >\UK8Lt%nd햪9cx ::%АXdU<щ%97PCK&TM:1[B%@5VĆ7nbMaTҗRlh|-MA6)7jzwτ2>:P $SA^5px^}>jJVs ?͑JPcIKzcP~7[ xAÙ7}{0߇Joz.^OccKZ09|cɤiDox4YFj(AV6DGP-ЎuoVAݳQj@Gt#y߁<[$is$ %dzJhGv&sUmͭVv$jK%$V^q h =1 Dp0i0LaE7~{YaX*D['v/IP'vw0X0*]/s}B9Uh?lLAHʗ z/ҪmYĝ7`U] DN='nSzKjWRdb:pW h ?w9 Xo|vx4 #G<+#WG3%2mrqp< Soc6tc(]r ېdb v%:EĕN ^H+Q`RB;wvu >?RVfU[fEԋw1"Qe'u j^qeZC(w"'~d^-*{ H[lx }iL)}֓'cv+O~xОl?ЯTmIDJ2e"~׏0*vx8|ST,9l^s2KiQ.8>?d|zt Y cb+uS^ʿu?@_ l+R{>_Hyl[cQ둱R*eRH4ܮ{(G#EXÃ/e Z'd⏉GpgD=|=W@TւS]7^2gpgW7; в"vcw vrg=%~>Z']E|ޢp^t+ΏRJ1Ԗ-ţ”֓C2NgZQ{Vٓv&ٕ8M%x,s:NSz58J7Ci>ګt/Q)c!#&E(?$^Y6-bY,Fz,~D i oO/«- sbh لE8SrM,X@.( I^C-OprG% }DH9<{m<T[sEVI}f+ij )~|.߭&'!LK!B9k!.ې@"NyN^iX>_)dyghG}ݲ}ŴX",w̉t''5RLQYv߱䝐j\g7U.Ȇ#dG,zkd0Q!b]||Jphowf} wxZPʣzߣc/V/ ],x ץ<I:%ht9YMWc0<ė}՗צjO;=aԾ s,7T\Zo2Rvga:om&[(\+a%SVvIIHN!12"80Nx`E3o>Gt"g[eBv)R_| Q-|ՏBIEQ+#k\ i]Zb MF[72]u$A%O&*Хͯ:Z_>_ϖKC?R`N&4OԎ4rk}ET(42n@ >)MEh-r([ poz#3Yb1{TJ WR,1omL(HѐHL3 C| K@B5pH]y*%Z**HlLJOtiRS{Ot]dU/7UM 59:Ubx.IH7KWa.֌Bb{'2R'}0cGNjk >EMx)l1mh4HШ5j ߣF=MG+WDc;l8Q>Ts*|s_ԡ&? diAut孁M0i෰&Amv76FZ?EݫFݙU^(^21WPM¯0ȩYV"5"J<sxSݜؼ*1Rém^!8Ay{m`/1>5L6#lo>ضHz4VB. )Cv3@?ΠÀ.Hh>|*ⷆ 8QK̿};^k`>t>ͣt @פ|XkA;-@KJw2ѷ5-dP1n~[Xx_Q -'cwBQUp;(ǹ\RN릃 hBcIA+ 8Ν6=a;$Wd7{[/")aXrR|Sb QG!5bn.#>)KDܾpK J8#K*N Oz^}PyLS W"4 aT1-RҳO+P 3IjDu#^k;NqFpj*,ڗe`lHkC vmGٺQ_x'ibѲP% ht*=,Tg s.-9xAZuL^;Kn|Miʻ&uA곦4%~R.z섟-w"PL+ zA a-CejZ?I,N: mqBq/{jR?RU"Woz碑L)h x 'StQN ă:'C?ٰ;&Zr:ӎ\P^$6t">;[*G*;6iϛ솀=H4% DBG DHmO؝CƵl"Ғ3pQw(Iu}itc7m8}yF_Dٴ%Z[v{ )+tdfE[ӑntQ&ra77YT_ &fz__~s>~[gQ/,S$]#Ӝ5XwC=ʑc3`-r\eU==6DhXwBv%g/ScD]^u6`CT|,ҍ>SūZp;yүBB(^ 4uFKD!Dթj {;n8s:NbPbf4ǢF_&KgoK㟐aV̞6&VΖV,d$7!\";ph,)-ŕwoFD^ d¡wzB0QKV͵aBq0Ah6t>+{MĈ) ҩ9ktb"j33Ҏ0;qfN^!* &ԫ#AN*y072t蠅6e޴Sl߆ؒS7R CZVՠ9nOȣ=Kgc@jP ʩԡBu*0COޙYJ?]%ԛB3{iރ& ՟, A_sY}s(|$7KLYoH?"bؖL}679%Ϥ|s'bW,ٰ`D9^̃E*M6P5s/+dg~ˈ-);#9Cգr:&P(b.L'ءėA_A0׼6QebM9AiQ-^3i5Y|Y@vܥ4ʞQoPaR\khkM4tIx] m2AxGS=/w(HUdI4 3/+ALe 6lJ.>LvyzX(xKV. sЖWz08O]*ozkjoS6pC5:.ZJ7ڵ} U9 7'f#»}MA7vdfTĬ׵gͼ 7#ׅ?_s{XB4g7C(U>L^R[֦ui?'%*g4[eQ6Wsyb)ư`{D׋4ED [1mO~6g;v&Oqj'+"aV "[~QoZl皌'˸D ,o[:7ric c\=-Zv3fzjۑ]m8<3NATI|m6TIV.uwM~a$yrH*wK'Vc_FI=39 )AlDu"[}zWܿ,9PtW.|Aq◄ hԾF1"ʭv\K H8C7j)# گ${r4mvt[=Ak zJGcc`zw?,Ư>* 栀2G*xܯێ`@P92c7i_[w [Z?ÿ),?8:sU'Q<6NV18ڟ:8 D< 4Lu0 fX4Ji2>$unh~]<Z֧9bbY8X `H4;>;yU0 eyE̓1~*~=.S'{pyd1_YGNށվ pRD+ q??@ ϸhy.S'n4hJy=[SO!{ NSů2GJo}z >ջ><.TFaϜ-2 0MKsWoOʨgi,vD,W_}'W:|iRFL&u q^]|ZelYZ,w/ŹT,k(zh:p0=IHM'[@}fE 1-/eU3nKC {2Յڿජd1"~7L&F oc{Yl("~g8~(7p5RAL@2l٪G훌X_t_TfySwOHjX4OGעulƯ,OAzN6r[>6h^We0#qZtK8DVC&reKhTOw}]h 5_0< $Ѱ.FF rFS]r18/L-Gbqwp.XXi^ȩ܇Fzjr`!ckjF(J)vɁ[X$q+UL'z;q -I1 9ǰl,[.TץOMkJŤ0aZRnnp2 MӞݵ釆> ( ʕRWX\AѾKSb5;4uAZVW&O֖ǭױZw3< %,vį5MYRiL9rHȓD 0`v-rWiU fꓮ3w8zj;KtXPzn=%U*zX~[Enz_3(H3߃sx 7[Knie18rhǧF‘i/;ċ]Z|Ӫ'? e.bV e qNx呢7Y+/M?ɷ,y s_^<6ĸB+e 5e$H2b}8m(n={x 4m c@aKw<]nv  \:b%pp=0X: C[#y*P~qD>[16o ձ+k%pzźMԺ+F(+S;޸20wwlOfT*1=^iѐ6VD-\d,[Mw+i|c!i{8&%Ό DdvvT4[{p O0ѳ": ƬBz{F)%9=PNaubFe>wMз{bij$v &D 2nR528{gRqɠ ]z>S}}˙cɦr?\9V_qsc@4[~:8%?9G49rU;w}Td-bnQAA,K/}^r9',4L1^!r6}&v1*1zwdQLlCQAtc3cCO/b#׾~0?9+vlj`k*FZuPAG.,Idcsj%wGxr.Ơ*0@@Do@O?[a?k X iOwmda' U͜=_Hv''7pqֹ#hZ%G8+l^f$ScztTq?Y[7+{I(uG: 3,=1sO||C_ȧ44J N%>i8OBA42FiUXybm\ؠ7x>npWV擕OfK{U޹wz푅]$\i٪E8d"vX)qT*33C<7ma͇D5䛝q&ՙ(ͅjCD<IhŸG+b2xB줖ZMZr?^0u?94+(uG< 0nQPP4%=9fE\e.sh*kpnǩߚK;,W3oOw,5)~Z`,~\#jrGHQ)hb6ԵAόϮ fƲr_Οg]p5,I;]{|XzxuI'B\k? J6K6?`>Jl!0_S:F`eK3/}z]y@nJ!ԑs Gw>\f)Gjq|XSsuրoy O73~yxxY@*GǢ:DOƮ\!^_10|oӌ4GC n'.~tę&*[e!dXkI{]8'NbG'$sOM,{#bk|ěOFdianunoႱJ:po'+^2YT#+3L?' ǥ!=wfͱWy~.Z(Rs+rǎ!#q|`u1^z03wo7r.A2 FQ@H[%055VeoؠcU{㉅Z/n׋Q;AXa7o X4>φet4_hVC䎇>`ֿ#*ߦNV#C'LM=?j26]l8PPpҒm/oa'7JŖc>ƑJUN,| s̓oZ [vO"Y5݃oo6mTT4 DqQJ},4bUةnJ!O D ݷ<C<7іv6Nk?y& }odu`zO>ٕO}Szz}Oy I="-78´Be=(c\4vGkMEe}]n Ov̮D.dw &O!G\֝e mAÙ4ΉEoP2{@<ȧzOV<񱉨Vѳ3мBQA= dԋdͧZRX!z"AԳcå;kgVs3gPՈF}xdpL$l[-m.T`4`¨%3zf*S_Co^ ڦS{֤ZV2'd٩NjEX1:i)EQ z}!B8K#EO^kcdiKӷmb|ep3L\&1hOsXTJ%jHZXp *E<hIVmڡH*˳ a onDԵ2rrm@Fg_\):q:QTgreNQUNKXiSN27jm%XE.Ő8P[-X,<j}lŪ1a $n$R4=H ,' 4R{[;偢ec|UO,Qd3V"r&Z^au'3,[ DI: X 4-h[ 1^9Be*%TnduuÖ>V%R: `AQ< %, wDƲnkY WU~x0Uz!&2WjE5[^Ed> Xp2JqLu 34 aOig|'h^:f7cH⥥G*593:Ћ" [ex>G5"-{&}%q S,B" Djtg rZb# d j@Cz'q_{ׅyP:h]:-!0WDtv]dRUILԮuma8ݖ&RӇ` Z`1w70 MQ7Y"Ovn߲zz Gw![(a>F>CBfBwmCŧHTʸ%6!]Pag$LdyJgr,dۑm[;Z&ժ[7T̨.ٹaĚNHc?]b4o6r$i,_d>0Q4/7<)vd{zCB:7W4HܷޮuZ*vUQ̅3OP{0) *g)\PN*XOjS8Ȕ1IŦ܁a3yJF|c<޷U(5$ę&r VO`_I&g{( =?r$<#RO+Rh5!#Bg} c ^f.>M=WNRi$~ͮ W55qZF9_%Vt`n}\|'dB/5).wF+A+Zuf[k]; wӨ}?9fO 1zۛIf7؋8ћ/ x<&1YOWjD!aB\,L U(I;8}xt6=A5ha;yj!#bKRQ谧8ht z^'}NAO?%0vctvvWA Rd|/NO˪H<> Ùh~4>tʧ}4 XvGrMLOQxx;iuܗ58~.߀kvy!`Jpċ[6UQ}8 ?'[th*hMtNwJ'~;I@|ŝ:3j6mĢVwBRj Cfi{8G_#J[343.Q]{ݻ۫>_vg l0'ЍZ( M!TRH;ڕyQznyhpڨl:;`0:jt [($~XvQ;Fi+UTFp^:SXP CZzhf ;[qǥɸ{!62*e&Ya1iZņF. m.q"4PJ%zQ"v;-,0>ǝ-x_$jA|?ؐrj)|j taDG"_grKy,480c /貒D,V(s.MY@W1l@M-ACB#M#d΋49)D$z"?⏜-)gKs]cRE$//t鴼Ⱥ6Ǻ^s=Bbk`iBMN8q n7$Z E/JcKض@>сA͵tӎ[ywyMn)6aI6B>PwbT}q&PqPv܊r wϐ3 DB/*,нMiv?iCmtHrj/>C._:֐'3&Zvsߡ1(镥rJŲ[q:FlW.v;(gJkZfzv-sÆGAl.M|MK?s,ɥ kP;FiACuq.aT(X N\g+iƉ8ﺃ1CnK)+e# X=KO*|ԟO_;S2\ 7Q"۬FmS=;IS.oEd=҅Ex@G;=H.}nl]QN ,Fa#m<[,N%:eZQ6(Mޱnވ0|O|kn _$3)y}Gj`G&[/C!R7= 24 ]yKh&.O16|D(3BiŔ6q`ǸJCke' +NnNxh`1XQv[*IhwuALo)gPaqRs#fãa׵!I䥥Qws29C_.e(Es$bF_Zzdo3NKmRmr6LmTO2thK?~4:ݣO(l!硩bܐv}hp_#펅X,dZ0 7촫*39oJb'_x߱cwO#X#noip-FSBy-F[ljXอ2urbrօ{~-O1-Cp)#0kQQ\H{<6ClJia躄D>s`UW >#3zvȈ4Fqʛ-EYbaȢr@|չP=xtTd"b144r=}ZImA 4W55-VxfnK8;';IgjHأcޜ3-`6 L@bT!L>҇yӦڬ0HŭZp7pb֐Bt&ɢ9S\L #Br'z2ƝO$532n$L cX=ZO2hkO#D~4BF`Eْ˞ܤk [ɅU,HӨ5P l ' nkAzD,:l4ظ9 >\;s@h A nl9ApXZ dT :M`-Hdvp^s<}t'v/fƩzxm7;ldm~w_1_J{^ \@…X ,@O5^ Q%'CmCVV㬣<{!cD"'<~^n![o!K%숸J9hk'ڎ\׌I$kإ:!"HJ\cJ~ƨbgX 9CK7em?eЀa)J%؆.mݓPjHvS iCyWQ8Z)9_g xD:oKwa/>޷%$ڙ֚F۲4G4噔;z ގix#":ƷTz)mhDf\`U$ӑ AA,+~7ƑPvr&,zF܌DɠTD/3iRv:C~5Of4dL*wu&~sd [q)9j_ISX]mztM M?7 &R!xWcĸOUMsFް-vHb݃x4]q6Ҁ`]A6]ۆ5#(2*eE)#hW2w0=e|(G5CʜΈgԽ;sRms:6ڃv&^?a>R147!!RL#EqnK$L,B8]^wfR5rU9{̸C! $8 >e\3G%j Scw˶"%;w'%x-z8HE%F~QXFHDqRwIN4ڒ6gMx#2Ϗ* ؄tY۽MtL8#x.c]|WFӸV)L!Yi{JCCw{ i4p:dN&8ӝmրW*teM 7K/9w؂lHl[ 4k'RW-Qx7Z %_H\a j 4;}_NIg_\ַS Yͼc{)6;$շF*6aAR"^2ٍhR9&_e,b{֒yMl7;lRrͶAJNH} Ԇ 6;t)ǤW>D' @ wrc[u@.q>o<04EZJHAM3؅mfkǪ̕2m&J9vg[EnA77F\SWAEø]`٘u u;՝wbjtAZ/Ejgl#6EIY:l 쥑1y>ʄBΤo5T%[ :~[_`O:)6?pWm`5`OLd~@eW:z}Z|EwpJON"3Bn8Vѵ"S.27u׳ Mn?f\.:3Y[\yyѣ\*\Z?^-fCѳ~[ ĻeHB {v*`NoVr c^Ŝ:))^>+r:,%Pk(~D^?dE$nIBQGf+,J1LE(P6^r8h.; zրK)6lne OX8k!BT(~FNAwU$G6ԃJ /"*X=OMU|ԟKB?nf^>{٥nwso9H 7'nGd-)cqg*p9裊jM(|^xbjRU Nv{WZoI.j_UJ zHRz<==b"$4(a-ɋW%2eb O7߻٩Iq):"iRwU`či`"+;Z͉c Q^Wdajlf+:?_ѐ bjLDTjD82膡ȵ=Z͚Gv&/zzB;. B;,D d?Kh P³) f峮As灹d'@<2[e*ށ`\Q渦ۙ|qR=SicVX Lr$1]?C44lf'BD9OV&(ũK{`ț sh#ݨ "Q2OWkĠy *M| ||r[oTm%}2yc+x gc%̈/e a_. ~o:m0 Y=je%$76&Q?c]׼Vfo,vRakԜ_^ ǰiY,#IlQ?0QzA@V{\ЉUŷ!DdK0FM%Jf3\C X r^`OÂh4eG8{A<MiXL4GoW)HOU뷊_m% )-꠨zЦE}iЊ;3p52o_I/ `P3k^ xy1Gݙ! #oXg%u<25l0S^/q':W,#]}FٗyRV-mU=S>}>X$=DžJ+xxEGb( AqLpBBXp'jd!Y?/~x(jDD!NB `Nxa/ 3r6cHN^ʝRKZʤfȠnDCzrIB܈t:3пe& ț䴔Z(w5_k?5-A!lo@! |eysV.y 5}(\Jz]T:Eɽ}|a-!ƾXleJCb칙jrh3{nkنEVL̥,$( g1+CRf}싃`f鱘3/4N{hXj yi|%jIp вxD6p'H緟sGgfnrzp:jzܒFTMq͇:!K*GzM^ر2VRk+ 憥rjdF[\x42~~V&,Sԩ;snz8QX0#UrVJPR-uRʵ@ +5'}c&w 3 $1Hդ7?Xx!*,9jjZh{G;8"-GnR9(:zIl < LY_lA3"ʫ ؜JNM|8 mcX:΅a~'Mw6gL,} 21:؉ʠ3 v"kC^6{ҼF:Lo5*5(Yl$ jiF}")e7POGziVD ~fhU Qr~3d ˥O|S)/޷ULcȽC U^" |$|d\ӠC ևV$ZD+ :}aM63jx92:?EX-ڕ{D=B4JAAޚU1~<1hPzϡ|۵w|‡Q?,;[DM,F3UŔ7; Xx̑Y_Gh,j?y qfk#G(nJ:70=T b'׋\c[G@X}G J ^VEDJhŸMl+)Ξs c5@>PdJlƤ\ԅu]I pfDvRFU龰y٩[n)Qj}aҥmQ>rae"ȧakOấ|o -r9m!@ʇDÛk((W//d*rݍ~d,4ֽ&1OJJ-Egfo_fLt}D^CBQA!l]9\#ﭥ-6z巅s4h}9M whݰG7@45!V:au3~L P %B~J!.cx? 25|Yě>.j*N=rqdT] A iS 5Uc1O%UC[ufN?šK$9Ji{U%ũuqJoJO!RP~"0<\a>.0z6v_4"9񅙠~&"T`jJyhj/9o)o7PCUˇrlbN19EfƉ?A {##T9,+ N2 :m߽tG>w-/|:Ã.wN-k`F@N'5ur5u>mf)C#BqL\ݓIi_S֛/ 9:Qb?~/NBH=g4GTaJgh>ߍ䳣pꗡtsr>h*ks7ǘ~smKL><&H(ܫ{6 Z.'q!| G2ę㽯Ƅȏ,LFX#ܤч棱123gEo&@l~ 7Sgo&:"13ZWTݤ$ $v3-- 6&@c ?{IO/D"ӠB3g'X$- ϽO5{kBM唙J'vTRsD4%q%-%5y3j@ICmjx%'ej栅q;.Nz-ҭr8NGKBq!=F>hisw{lti 'F@CΙ!Ea̓gvSi~ӋrtrcZ*>9*h,` c##!ňEpK; 2mژM.BlA L"5D}AdnΦPaJYt&B'Ű儷2_zDw/qq|#1gĄ4꥚\k/١dqGCAiH0m>.Ro|/WG"wY+NՌHu؛]ҵm#c ԓdnGU#sQ; p?7;e?('W¶PK|]y&O߈Wl .8ugN U]Vα,]\ !H ,tF# u#+wd ӷ]IV++VAZ< ٨ٍ;>7=5?s@KR/C.QR("A&qF~~vCdw시\P]bEdq{Iw/Idi7~uJWcbܯՃp_#f d@ml"ԫϾRw Z^>P P}/T`) ẞ!%`?'}TfҸ4&.m47NJtHxk+_|ǽ&~%coC`L"I?Y> īs{gWnZ|IC\lftlL_l@3g_ 8RUi񻝢O5)Η˰Ql#]:Vjj(ڽ>Y8,$0'e\Qu ʪ=ג ZZ~i{vk]Ŀ ؽ Qs;:׺JWCx&q]6j&56JpLIZqIE9?~k}ڱY[[9ÝG>W}0D8r׿36 .|ƯO+>ӡZȁ zi_߮^<]>!S}}bDcB$OKvVeNؾtfv+wСdu#]qY\-e#^ e?T`bO KKvȭgrQoMLWC>~໴-$e㻡u͍ Se'il)-,ĦVg_Ϡ47thdXm w~]ȍMzMqzo\MZ&6jvkTwe,R*-c]d,88X_N'{ 'Lxj!v+zȄZq\t0i%#_Rrgt'H!z̨W⽠{2N"'1£}4{@!br |?=|S 礗2c4Yew7[*EIE="^zv_Ϥka vd03fp[~+J'h5olIGzdThijev fJ9 t7xNjh%h(@va9G.`;]~n׆FN'|rf==?Фz_f"Kt\ʴ % 5V|?crZjXh"dlg>0>.W7ԐwX ,Q?7ȿn!R2RϲVV qNhZ!6eNHf,|zd* EjZa B ’:˚JxB潻ޅ/k] rtA;5 I7FP^ijw:R9LQ2BP\HFsQD)Ԙ.J 誙Y vZ^'Wtʠ,u:\Y7"3q9azt,E֕ ciILmS3&+~ˤ(vN%@+:$i~Kۚh!n`f"AIHrq!t q _ fg=$}ᰢ4Bg}7 N$t!6ۀ~ύ~-j2nvÈXѤv X6N*dacC>nR<҈P0s @2AwШ`&?Шp{S>'ꠢ;4kԼGa'4٣>j{O?d5˩5+jA6GI0]iP: FWI돎ʰ.txx,K»){%.,QA`\O 0sݗ }cnu +8="DgNp8xJ'B([ '"̒?)+jU $tgR %j\ɺ.kf5'wc9X]RCIr[m ԗ^]01xbnS=<@?$0phfmHC)&3OKrF)ս e*"U>(7(,Bt^Arl*vwI]G==]շyGTb6NˮxGq1CZ_%35vveG@qggFԾ(K_йe3򤳻wf{m#: ؓsx΍lG}34\qN( ygW~THgYa"sH=[(Ig!cacf[x89ceuB$.c F6~P/ir%ΊWk^h.mxy[Nx #&^f)3K頗#m5\*Bp(;D2r>y$?(XIlyH *]yaoWWS ҬH)M;Ӕ&+"A~ND]SmLdA!y}i97w:Ya;=31b44ʹE\ UϒW'5g;5||g`@$oišj"*ٍʎ/ѡ@ a@:Yxx^,-p9pj:Fa^sr:p?zx4 87X!sM>0#ʚ(oȞd:OgrCq8jFcj1Sa}dsPi|nMr?ƥtzCkx߻.+?XY>5.fࣾHO~>5>t`52tnmyC;ML81NN%%19,w-eWH<*G{l"q;K ۆ)geRsPsjWq 8qZщuJ$QZÍ܇oH-Wzq sJU5:D]+Jͬ'԰ӾskAQz7~;^wvD2H| ٣s,kĠt( ʑ ^W$~Xw@Tzu.J&,L4^Jw؂mWPGflߣ({-n䵜:>8$Sh"c{_'k% aDcN'sW_ (gԸfEn{tL И7y5ȸU=;e26q&wTJ; {˸=tlGiB*wIyq=Xc;7[9Ѿoz9bTfT3/V.*^$^{+ێk.y<#8WDU!tƺ`{af~mY&rt4wG|\ˍ߸Kv+YLN$ xe]QaMccWϻlvbsۥĂ\k_6ih9j 5L-*S [u *%AI͓[/Lp=,{ ~ĀOn~Ķɷ:e6Vw^s?¸=}oxN *o` M#|rn:Jl*󳮾Zҝ}eYS0unvs} 4fw?:հ?C7vQ(d1RM L-tKTy]Nq6l"LsHjAޏۋpYKז6<܌LvbX*[jҰow%l+Y-V5\YTE0JNaJe1g=g̹M0A d,^>IkljWkԯգQ Q΂GpЉKXg?FKd_^?{Z4XUNL5ދ ^wG{_?0H!}X:vX;tRxwe;}Ƈ :qcBѳ#D<36Zx@iz~4BCr^Ө~ɭ= |ASP}R=mORH9њ̛Z],~X 4ؑDzXe @2+f;T|p8 aa!G%\ƥEsdu)K@GM}}4ۮ:w& f/ rnM,*`+#ɜ{#d\}O\Ƨj@bs(%iwA_v#0^Ն # [i;yC9|]jZ`MņGn;#si62JY $/i/~Gib޲˺X-B^qX />;A ^q=qroKRaq;  g0?Ѳ넒q"rRUZMjkK(LB[?׏ן.e$V# y7™\C>3 A,m=<\/w9aLPo+WQq7\M.9hRJS_Dd\#<%^&nG$f_[b z9j:YXGƍ ${Lʗ SZa#6-2Rd#>K/j 3,hVEO|7&]&0 \VPﰘaHL4#1S 3a.m;i:A%Y!s!5:c3H>V=^o!-h*R˝ȕ \҆tkPXİχrcB*]?Z҅ehA…B_o)P^La+IxʪTP=w1{d[qT 1_'! K۬)xٺUu*1؂謐Jn5-%qZ 5!T!<Ѭ*r9m< @ :lc2&9=nӁuEyMU3GjĦ b#չԱPBMH">1x<4@py#E-,c̫aܞFؗOwgߐu#uTvF5tc[Be[am!H!o_SDTt}1J P=/ %Bh%*!7e4+]O!UI ^ёV#7i !s Ga.4Yy.E\NTO1S ".p3fLE?UJr)Untl6KZQ/[+) X?( f8 0L0/O )sߠ9w\.bBt<] /U|pC`FsNmVΖ;H=R4z#K׮FSYM2(G=BfQ+r?*pOi0,h7-cAz Ɏo쨢_4[YVUOڦ[ -69y*qKy( ! Iϫ^9 C!3HE۽9|/}m]yRN_!,;a*Ax0_ız&䮆?ڿhucW:ut̮n̦ؐS_n+ JM^ᥚ /.9ܾLrY9Ad-\{[A|Ůn06]8}edTgQ+:c%.)TΉ$xf35nRN}rQM1\'F=sq'9!K3:*%~#rBU\[Rel1i.xh✜rM#0!GH02hy{V_#rWM43ͨ4ޫ-[n^첽]vra)B I` %6 4+k-ے?l;>x3yrO(C 1i >^Z"WOQuXuVg9O3)͈dz5t ҫ!WDn?~_J Xe'(2Nbu"3e&fc Wj8%]RU<ېTì@T+pI;׳l?+l&fݟ֦ t~9>Y N63eEZpxz׺F٪rg"ږLrN#D:Qm>D1.4jAYgӍ6 ._ؘ,ypEY,d 6|[QK PpBN/~t4NIo`Iw& EdKrOn>d@j'[=%'6tʫhmo&fV 1 |Ezج7.x9D?">Ao"1 C5&l,;\1tK P[`7D">-JD،{0ÇzZf R") X_Rɱ'@ߒzEQp B=qw ,KyP9lC9:R[ψ )dזmy;|g}Hk~)+޵ˇ6`۸b~X yo);LѰ]rWZj- bhՈF3MM'P<}C՟᧭2~m#&9 Y3Wnh "(/Mt"JD;Mf/*ju2kꝍbeEIosV?o@G2Do a(dRq~C(c!0HG7'WuFa `!SdTxǽ4\aaJ>+ V}iŢvzYOZ-)z{VFc`?!kc :01γ7\ X߂ F+M#.'<6bgYؘv2ay3% 3Qcghm,I\djg옏g_^]lܭbթkArSdrfdFΔai5PZץ3=ђַ^lR7/V1{?Mr,بzI1pTgKP"v-,[؅tzˆ2 jo7.mDVʍZO-CR6$؊KN U{ݺ$&Ehvg%U kDT?q[&bܑt-Zk?99)Q45rK\|%V"S"3LG|X2گFY]J)uW=e(GVD7ݾWmdA-26ooApaM':@EΪnܵ^߹"wvy3o ӋR(L3y1"Tw/l{*vS,7-6`OaWMTVW.2U \]al- d%6ǽ>nBߵrs;͑&+3iZI<^oA4t'7ׇȰBV[?@ūOEj i6[<Ym}ARG B* JbL-ӫ {-.qmM ޭjR(q٬T? b}ZNm߱ȩ3 oXV0YWM Y3DL]xƥGdsMBʦjL|uX=>6WÊ vn6gщ"玩\`17 aJ̭#@~b{he8^ \tgK0NhtddesE_Y}Fy,"wmcrih}[0snہDS :M]%<ɏ!t(:w&MN ( mu=\cF} U!JC{$ﱞzuuE3+__PpRoLOF6Co4r(qaCOf?~n*u "wLxj9I.BrGQU۴[L_3o8XrRImZoq׶>ȱ.ua&uz_?L!kH7b+f ,}SIT\/饉Cq)^xZqse430>gq^ȖNϤ[m-}Ϥf]x[2LWǥl/^{t-OUR7Hxr9:R}ڹɸߘxxCU8^{-̓3\#$rVS'`~-wH}Ҝ$zoﰵmm-әa˟.%Cy6b.M˕vh+#6"c,(X#uFsVK:圸Nt@kZa&r(A+8a:7\8sp5˻==4o$=7 S7S\L>cgxjOwۀUero{46>Ѿɽ.tea/zxgwےxo ]ՋeWr7VT'UtZ7#{Jw%.G0q1RG֋o4` bҽ 9;O.L*IyOji:Q2hKCo1M[62IuE|W*W9gy6hUw7k_{B7CQX9'|˶TނY>p0TzҋR\*R*[k-I5s}eij4;CaaѠ/eGZ? W镜Hё3+ SY2\X8CbS&GsT*XLlIFgSX6=w+:$A(tbLJWalPIsʛK&W+JMk m#eWZBr1QׯZnKq!+g'u?0 9Ҭ?o+Tpnc'o}d.;<`tZ!0hjz# Ĭ/KLFGx:x܆Wrdx%Ìq;. KܤQUZ$)>^%Pް+8uŤ,ch5B8- zPHꦲT\TWO /7[eʝaS3Jx5=zĖʛp98x%j%"ʵ~/m[Ru[GgEh+Ve|ڇ?lc`B GzcQ-*_J 2YPm2TQet{m` $ڿ"_}MZqZ&h2=wHkYj0˭ؘ 35702u:y=_cW RuCWԷh];j?koGґ'K|[.'OJ .CX쟴)OyXsb5e/TsP"Zy 0= r]*'ldLM,.&,}g<|hqrVg"l\n{&A 򇰜?&29hG#ߐo)ߣK1`{-#8 t\TxF|*ϵsO`(t6$p$sVL3Åw]LCĝssWk00AoX ezNxJ&;C;?6S؊NZZck0}Va&4'a }Hn@H~~f}G׼o}{uBDž6M|Ta!yqJ_3i>?eOkWJ4T J tM5;FzQswaʡ'/gСdKYN|_b*>槷y$ 6Rη:9!:6W;5@\?[-fc,zSɛ!k)B8rH;/ct05#hfgϕ4&jYTJY䖤G%NlxcS8pjnv~"t~`S,ZeYwh<8O.K+q@u˷U?Av>2Q0PGg+͖ F zbkCWTެo)j]g^PgS 7:IM6Lr2I0.frKO1dU6wLDB/yZ}\T"h)иટuB8ƸL&`]v$?J#XW35q|]Q-_`se5YډJ,1t?-D=~/^s&eJ]{qFӭcJY@#Maϡ(VYAx{$= o.ɦ0U)-d-qa@sXc,fU[]o/k B}NqcvKZd0 j'6TU7 Fa7+?tC+fL;ј*ꡚ!jC[lR3L;Tk@eB){Oّ%s=9Bk2פSYT[`gØbNƺdH3g/~ `Qn3[nm~Rx!(&^.О_#[WXYx,rZseHM07=xo’]v LlWKc^MlVk5~I֓tWXzh: ^s0yB*7Ƽd y~D?Vt ~:!իUo Po}Zyn"#mIzxFG7k`,̓PgC ϹB*`J xLY0s0]b^%tz{!,mCROqXOŗ,M轕# i+4G&ίD#A;sk{CǦ_-⃁N^;!)@M.RqaS~xұv[,`|"Rn4g` ]+vb#ckbZ Ze#tXuxxr{ 2[c>!%7s:JErj,>xE"7w~V\K?oe2ynjNPV@ 4 PLcF.ãɶExml$d_Hў&뾕^>kwߕߚ]% Lz^z"69K9 #V’f{wt۴߇-0e+i/ƘF踎+>Eu|R2㋲n}xSU#zM&^ә,)Aax cf aCy4)XnW|! {Ž9x-)ѤC $O &WS)QPVJu|kJJgmkA|~Wku).31F0و'(RӤqFヌ>40_&p&jd4{M}rr@8oBp{lJﶙgUO^z[/ġmʺ[+D>lm:I{fm^6(ڋǬMG(Hϵ;(nAauC[`,ʾWЃWgݻoE[FbN-nn7)C#dA-Fm3㖐DD,C ZݚsJqeb޾jǷY &EOf6+&gxazwN3=EI$P7*cתުCUا:Wj;5ؖ6$zb$OT P>~ 0!%c8 a}pNq3lR.9r-10DM1. 8(f>K[dMI| -AĭyN܉5_z5}yRqK}mxH@'<֥0Z';ՃO}Ӱ;Ɯ D;D8<]..0P7}S{lS^4Xlz}#@ݘݗ #8Fd.&ibŃw2vc J R#gEjҼK!1yq "zjϰn$v/,֝khx념[xx#(e>uM!8m{P &w(յsŚ7.Ly9z[ tGn8/6)=Sbp/=zstJ#ְ섎aq+Ƥ]vE(Qp32˰;Z;t9k̿bcVo/ÿ!›HxaK=ԁS3+~v*̴͆a?Ѱկ8a9gBa'ؘ}8?YuW(==;CϦyCYSDd,+wgY~O} 3%1+qQ+G׼cTM7=CڬT<;r;"Q,Vƒpj=w?u 4pzi/mnXZc4Ŵf=9el؋vzN?>`ԬQF'eG|>F1LCQ1> vF[.;AeȚ'h(ĉwGF>ZN #8%sUR [N/3jEoT- Is3yzCuRʐ&@Zp噱Xx 5~;5NIaHͦfd,'x+2O\=F#+X\(Nz=d(hi Caߡ2k-AgiH$F'I="8o2|O0=ǬAqڊ: 2֗nK>{լc^~e] D̟d}/{{%/i`ĭ8$6ԩ܁sKyk0LG"ɳqEuc:a -+5 [G`~UӉhaf":5SٗQf?ALzT<Ю%X6ý^2yOL+E1UFMpnGZ]ߕx>=&b3̞H~sn~&>1pXj~sWfby|Uy=u6j8[ttkLR2Z6 ?p59K^Imo񗉿l sW,9-df1l#0Yr~+)z%ݪ}S&ctm_, M0'_h6WLã6{BA8ngŖ.E"A#>F{9$6r 9qj4Yߪ[5РSyo`,.7d̃]Ĩ-mk)9 `8Dž/m'Hw5˜h#P<0GjQBd)X_sNb,3eՙЭj8{Yy^VݑnklE퍭= ;nĶrC(ﺿ}HHfT%Uw99(eWگrķGÄ/6`yvʜ.85vN2$P4* ො2^} )BwiW&[m-'ҝVK7~{&2wGC0{n.cy&؂Jܽqo=ҍqYK9S"R\j-vi1`{p3_K[/Z?qK~vƟV-}zwmŵ ]kқ6kZԥiwfFZkjVUkum9Wzn#.{EHExԛHzV}ai VUm'Gp,ZM你rXt.VT'Xdq @.J`?V3d2^2486xj9۔~RƪeFn]e~?ˮ}Gyo6Y7\g%W0S}s{ܶOLq4 Zy^U w}h=Et U8 ˰JIm AYc239Մx::')c^O𠎗|m Pwpr%xlW&ЎzP/yPe2J%c A%X6`^/!w\, `F+okej:LH/v'mE5{Vt7ɫJ8|dɏsJaGt$S1~e߳<5^ͅ<{(9[v=uUs>hyuzI.9͸u$hS|=~%f@/*-ʱzsqeѲz "҃͢K1_y+Ȇrzb7cь1s0c܃ sP8[C7~d+-jfIیبs"j ( ݖr70=#ʽ+ݕ-vNhc-M |yJn7*VqX ӯ y"p`h3+L\/El:NXNVJ\^N͠5ќɳ36._+9>;cr>W,NOp1/O_ZW5?[zv8l]ijW\:)( wjдȈh*cZ3͇g T~%*`?|z42}r [1z6j3 ÔÂuwƤ.8%=^:xē3쩳>V'K9/$ GWd6d&6Gz+ׇf@XNYyU'e-'ώ4;iL4i̳YIu.h-T,::q̱YGbY(x"> A^rnP/.^.t"ɉ8qϱ%q .=hmTZ_ “ T<;xX+$2$,\&,~IayIuNCòNq 6K *9Dz Z zaT Q\AHX8qy¦}l3 T8tzHR"dGS⹦3U}MC|G֮6jˀ.-;Ӵ~R|z2xP`zTÙ>Fѐ/ bȏ9MgMFy2`101g6ulP8qqZ*l©ArF9u@WU7uM*4F&5]Fi5Q5ٜ:W H%!zKk[5=1\35̀@htHs*loGYZK45ݝ4]cvڐ?,Wf`c{fyMC`[H$\V_4RҙQe=ٚzu|\Q2Cf u KuAg`QU0[aj0w "/(>xH\Gި}{^չc)u[jTwWNmab0 0D>G T~=Z%W#n--6/72h!AMT K?eT?X?]t$[ ڜY?xR) ou鵁e\7۾7O'Ԋ0Jt <r&CAܿd̠b8,e⣥ŠK@'"ZA혀LN.n^HZA" <˻iDN1>rKdV>XGv'bG+b$,>q`"˾ʾUoQSMZǷT^K0ej0N"ɀo\aK Gc(Vqɇ!ft2[OӧǩͤRs Rej.cQs"Kq)E?7J+tƼ;4=uKY_ӊ$Q†WA') ֿcWpn ^8|󩒝nXN1 zںKcRוIpm{$V^پ$iEm{]>y'{>)B~ǹQ#a"気 x3$fs,`Šzwᠳr=\L%Ɇv]\r߄"Ș umOARq|#/'GvvC&Bf^GT?P:9Xu83zx); be[pSQtcYŽbjު~- Y}V@˜`Vm{pd3^'g̹(e^|sYY6р'uIA g07P6;|MŇR۾|QkZhZ#{0M=oߓ9{oqX0"ŀ{\OCӉBgIg|10Ȋ6;Z{+!39'&J-f·k b/2l#˅]L_ChkRNQ+K{MGU{yh s[}C'+7lC#*eV*n|ܫy%)ɦ^lD`)h9tZ)k-{/*z%]<[tO:K$6_l_'WoK[$P8]J޸caIc| $Ql[1oyEm>][%Լ^{.6I?a#Z3w{I !^tY #X[< g .۵زKj]*O{DkO9Xm{J8m&w#)+RhjYۉP,vD7J4UtAuwݤ)έMoᆬ7o-Xv+Y ?:T"okkJT9v @̦rCay]72džΫ/^B|63'P [HfX=53OrRr)%?-H2)5qS >yIY~/US Swњ{ݔ캂q =:G_Yk͝ϟ.'O{nj1ZNGS/ȑ$'=ήYSd` #L #!LFҒP7]93>UYZO|֨;5߈פ;'Y-.(.@Ar^]4Buӓ%B8E֦Dz ](+9Vj%ꔸOv=oD?"] OPr JmVO+I|sOnT%IǾ@CDyl;sfmv+jlųd4F_cxn9[ks.B$9YR-rySI\d%kM(MtɿMqo#z8aĝȅRTɕH裊 qLpֶƪ ܝ`*]L4Y@[BPV"Y޲;|f2_<:{4BZD}a; ÷:zc;uf 8Ԣ݁@thTÁ +G PͿ4wZdRY4X-Ws}-r &C|Gqo k_n܉rj3@jL9Ӥ㟵B4FvY,ɰsfCSWa_xMd.:%ҝe>p=wj/3Ϻ |=vA'L9t\i E0E$ A]ISPS>y ECx AKYnf/Ɩ8o&q3R0De${9w9T43=9lFVUN !"<?d&<m`m cAU3;y؝;5]|'s 7rAW/f- pWz=?VG| hj%W:Chd\s!fP B.H"ԉ˴Z)t_o-+b}W"z8U 1R]o! "Xc(-ȬꗸA9ȒO֑vnW~Iw2ȰMy{ogGޫX*/caU+r9bnvy.gpNtJb+s0sqZr =jA?.Q\SM5ҾFm[/]V͒M5pp/~vBh%+" _(. snM P3z(y<8 1}݋BywaT4Ei)bܘlNztlwҐEA)%>.-c ~\y2SZYgv`;G}/z _u-w9{_ [gepuW+[!_gG3;VyFeX.ԦܱU cCvL: 'ȵ[,JgVw5źJC|ɣlvrg_x˦MOyC1?_9åt1VȹN.q4ƞ^;`d_c,Ej#< HImASq&)_uT$'NΎZc&jԤ?^$hZAX<3Š>2-Fɹ6 zYű2^] Z7Pk6N]7+w hcuԂ\iÐhvt1=Fбj%:j ?ۚZ*&|Ց7ݲG-k :jkzt?@9,``LٻsF^Mֺ^%*cC<[V#e3~m 76νOɗbȵ~ul]3ۖfoAmJ;;g8YTWR:sܩGJŠVܟj1=ݧs47~pj($ͧؾ{yIE3⑉fp0!]cGԓw{`jjPKWcg`>sϝ'L-G޸ML%DF:5Q⺌KǣiWc+E;NػIOu25,604?-6[k)sL%3q񡡙mzҍC-#VkEςnM7 V7^g UQ?4PrsՉZ,8tڗjloɔƶń|B0L-ݓǾ=s ޗLM̃sǗ#I-p;XngB(]/h2w/X%[K 22蕹Kנ,M)SI_]|vVV2exgHN8Sj&)..'j==:SuJkIJpyn#vF`np5ό*G?poZh*L33Rz<|n`?Kz[QX+#>FGt }_fXY0c٠eָb|+P) =R䍓<Ɉ`V,eŸ4 ޷sh\R N;bb@6뽙7׺@ؔ} R,:;}:6 YI8sT5[*q*8;)}{N*2 UٞOs";}luT+yf7~ЊiCtRЇFqЋ)R|&O~d/0CY7jԁ|vprUtD>f1Bs;P y~/rjW A4mpdm#eae{UOYj!Ma6 ӑ=xHϙ>cҠd·X}dwl),]H0[߿gdtq:>հE>]IΦS,ԥLpn1*q|ߔV릹Bqjgue׎y{_wgZ|Cnת=d!,gHgLN_x1Ի6\EbB?Ah`gq!zb׋j1;<7#$n"a9 @ހ #7 N;޺b(0HBxNPv"އA o>Ucӏ"'Ei`z2<qG.p~ R6Ƹiٴݯۜ *X*l l`Ru6GIp'Jj.ln|(}PJc 7g/#"g 2izg" d+grdLik35#7M䇒j|S5xֻ^bIjpv4R٠  6 4ҥЎ+ Q$8AJԓ#JRӡIN Xm 9ZEH:6g,(f2r0Z&!Nw^ft6(zѪOg9K?Evӷw%+F8pg1Ezr C:>ugZӝ΃GWC/EM5uT-r!ӫLO ڀI˩ow1Aw e-#Tfh3IUphd'g>n`ʧ9Rɶ;}'ıL{۾IЉmaF,J%!AN`nV"O En&/L(SH(wPIk;+ KkCONIxLu{/Jr& {I!ZWyJs~_ᝦl%64z$r7ΣSlHP5 z3G.Tj{$Q_RœxD0]Bq&,K3"k ]4Mo9$v@rsy~X? 7.lhQA{#"M4Kp3%Q *8wҺ 3a6VQR|Lzd0e} lhg&]EhRJ]c+P/Y KJhoK;vlUՉˑEryv%#Y7,/#=fT9aDm(K@#z96o(ku8l?6y_IymT&Aa,ZU ƚgGYæQkc7Fdo9Xo+0FS:EWt(ڋ!7@oۣ}$$\%$Ղ(epp"{i@X(D) Igw7{0,MhnʫP̫B7 EVT>O'|1VrcRk|8Y)RIokpNh=W-/Zj\7ޯBѪ:mm2mnEvH-;)1Z$&3BKhI%*!&xR\{+gw/)Z{)NФڗܕ}dGDZ2ehY_JZk.\ѐnB, :њ+.@ n60gUB/e7aq-sh\\o=yY$mX~v>D(KyQ/z'JWWMMiE Rf3}aS2x3Hoq5Ru7QH%U1-Ui"vÕK=:=٩.Gk9R)Bi13(y܆=I&&s:&a`BWQWT(-| Q"SXy8HLB}&ZNL_}aX)!_>Xݎa(DktS]5`TWRŪܫW`>Q}zOr,-Es5Ք(=>1:VK_3ahw0'W#1&"bT8zԪ$'C97." +ߩ7^>vN9sǷBt`m;s-{2<.'U-E3nRNxܘ Dh3ى/)!A4I`ToTR̈ӛJҥNlD-.Yy3rZ 8Ź+:U {nÎRh떱ރ>z9|sxNukpZ+a uRE/KL"0AQ^ 3&yŁE/^XR~>PT_Vh۴.Ƞ4IYB6*N{$Fl4&T!lk6lݍ=0/uYIfQjr+,LaD1IӛLczLLw)[lY.N*Ѐܸ {FB0v~/ 2!& 4!DDJ̗,@G(qxN?gYyOҋkR4fEr`TܙIRZ'jE|ݨ;f._땿~ FHF8%ƚ^N4mZ _rBc,^+3r-LgCuE_J?ǶRWY2/7rۣrf 'z7k 5*y S)| gaPΨl4$]J4zˠPej)|8E :Yrxo> >"µDlz7T"}c]y`=CKv"EC.yw.¦ ^*i!S`Y;#*{b:ϧڇѰgO}pF&Ĺ'#q5mǰYpvLQHjT0?to.|GqFŵe*/W<-T<\^Z'>i{|f~m+/-eؗ?3*Flƫ æQ@tb,dy%M&夲fcV0 _pX΍\7< ͺ:]8LrDj A40=PFzE~]*75#6pt|ef5\:Jz~牘D3L$*^5pq!*aL&yi􆸜 "\aWPH-Wzjra_ťt:qM;{4h*6H.PF4Kb/}%!ZJ]y!iWN6cAVa3 X]|2!=*g ̾6 KWϓF!d32b {x'f{`[>OI1h3M%|z+t_BoƢa8qN!Niܴd qYŹKTFbRII:٤SO+q;/ɑ\a8cbDɖG=;f?ѧyfHmřG^4K#%"оf3׻iCyGf0-CoBGB[\ntpT >:J092ǧ做t5[^] @r8 36ٮ6'$ <ǃ"QJ,D9Ø;lybJGcl"2G,eUFB:Fkdž|KQ1_FchFRJhC:>rU}$Xec-[R1{_˳BZ''1Y0MAEv]wcXGU.Vm] /= _& eQ.<qOm.DldnHCkR\Fp6ҹS՗革ު7iOd 5R޷k4r\hǓD8Lз7RXo3x6_DLp-~9WhOnKSnkbԽ೧N>?^if֨54W*X`VA=d0M~Eg.O/ޜ~I7?W *{7ͻ o4T gDhv'!cfvN{FDŽA=Mӌ~#犨\,9lE|6ٯJh=0t,Ir(^byb4|y$N )uv| dڏMI[+\ A$pdž\eP8@173:ëZugt8UHuݎ֌@vT;ϛLfc|~[㷬oB?bBIcNkeqwscT?1~Zjm0_O+㉵;E|xDt081~`4ݘ m18~` eqx`2y_nO[ 4^ǃ5_^1oo3|xэ2:>]6ys|09?>>1_!uuyr1u7q0w6o- Ɵ2_˼ZV SQƂ)zXY Af@с?l\֯TihJ _=A= #;bg?zP߭~/a6oUܫ)pD%>"ր#s 1Hũp"`g")HE hhHmSuЄԧÙ:00>+DP%\%osu&B#1v3&CR4MmYt§N{jDmA!^7Z3;M4&_1Md7m_5lWY{.͠RtFYC>w2kA.)(jyEsw*bDMp8ϵ_ehR-e-׶hhDFs*Ga'%pS/nVԠ$2yrg,x>Br;J5D R޷}Da2jyM/;OM"R,v684T u2~d(!Ĩǒ)@*Rj@"!Yd7X Ř78$MY5g+Ӱkl}a3JQ7'1MRq,Q.& qXv0"vQhhABrfJB/) jȮjQI5 ~\"Y^ G49U \bt0+D=Ah_s`[އp;t?7="ySX!kQmvEW&CQ=W.-W7F=~03EymK$vh(M~:;nGT(vkAC 5qjZfB+A! m=߮?}$\~Bf%' A>kӇ"to@wdX2PTZfv  cŒ_; G2?OsZ(S"P\ & piZQ#"szQM7q3kL#PA-G>I@><ҫ! P*z3ƒ"y'9CfpoZ/ۦ:8mų8y]z',j5ەbvZfj3X^ϊ1Tŝ{==p/v*ՍM&Z=?(;2L)3ecLxA\vM{eɢ>z}ś́Lc*1&̺=4W2KAyO`ǔ0fqXr`8\d^EVN&46bjf w%HS/xtZgXDw#((%J(ٟt?Ô?t~!rAiHxq=.;e)XH{hR#P3Z#SH項7q܅7(ޭZH4I|[-OdƑq{3= m!(ڬEà\+T(ЫgIf?mq#̡$H2w# 4u ,^DSI]ӬU|'fy:faP(ٝl P~?(lBNG&3( tBPI~V*[if j΋M-oRh#0 89Rlby 97ҁl~)x95X?@ZhsX7Bu/ʏ $|TJ3) lz$ "% JYAV4P)pd`If8-UE  vMZ>5zO$3}fc3Q/-`ód3Q9ś'! ˵w2"ԥlPB ҃d QH3gDLUHKVZH|l9}0Վ9=EYWCٿ #^` p R,_z'&_p]P؃{]&864p+8i؈āއQK0W!bš{vPJ]p9(^\a?Xx1(nG_7bw#t>UȚuiGcRcg\%aUR, ,𙚏su&\VKgdwXF8q8!Y=DlwycO")n=J >0JYjhAL`8L1T0i n/ COiwHˣf|$[2$qÄ$CN^l؎g:= F͜;,* 'k}ED8#@iP2D~RLyH>Nc}.7%)\ju W-o_{Xꤽ/H"IM{ ,"p@\2Ofn D΅I@ ^%}~qJ'Ӆh aH@Q@siGr5'2 9>/>!Ff{vC{Βaf i>0[A,lW vpP4E.9.ԁд01h$%[@ 6L5M.pB5oW`Ugpu3Ritxg H8$zָPi:^NϠUYoD= cVfroъko{+p$+4I3׶a-Š I3PKr`L􀂤"&"Σv1.b/~cNԟz}^9}YfH8VU8ǖO2jDK q}۾kCo>?9 ; .oR>Ok:EDJv1* k-0E)ZXL8mEV'd7{aggZ\o7I[BVf bMxy,+auyF gk@Vj]:]p,*&oD6N'z_I- шEY̶>0vMhvϔ8 cG}JaM-W.!HI`.SArʷy4knog3HұG6C/ M૫(J񝡹8ao?P*8ON8 L#9E3q#b"A0X1pc7Yd*`*Ap7w<+u f践o!NF B 4jM2Gu#^f[ hgu/0J47{ 5.9^OqLKwB oŜNXr2ey] h6we(b1"& '$9G?X6˓&=ӵ_@^ FLgkM=];6J$9:۰c#%.t^"~xpܾrK"x<-{ pW'QҴ3se"p6(igJ1*<HsN3{AzjLFQ{ٍN &}JEN 'kcL:HC:jub7=2[|jZDI}ѝdI©ѫ_;~`iİSzXկJBAANI/F~LglHw[Ɨ}&xGl%RZ)6T, n.c-/{^Hr:.'{O!p=&8@ 966m^z0w)ۓfծjuv2& -p|j8!bvxY-F~ $m7~(]kMEuR Vҝ*qlo+v_rHxC^EKr'aK/1N'rZjFjڝz:3vHBcXE:m͢F?Oaۢ~ |{"y0Bj5w'%/V*K$bVCl./y˸_z lVc]W(!JPz;y%+J+t$RNۿD8H[o=FW_xBĝ4nJmd xm$*R}ՖV=.t(ekv+<3EpZ߮0 z@,bMd:-t ~zFNWYWP Y&p_ %ژF[+ mgIbV\M̿8toaL-6I59*@fMadѤ:> -MZrtĖ ᘑ먚71 ?-2#v#Ǐ8%?MCZsถ!0¾iBf|b%` 1+Zܲ梕PR%j)P&X{Aj)XYl"~Zo'<}KX< RM7By ;Wp;qᶕmR9}}|Wq쮠c"rj6"r9v@{ Nz`QqGnՅ4UֽPSq[Jkn碱't#@" aC@gFqKCHoc:7nkkxqff\ϯ|3dglI 77(Cnςk|E\_4wxD릚8RE$Yy'MMu_ աF˕x`ik[a*򋵯 h?ix!9\HΕpsFU* )sHNfp$Rg e=/ BjC)nh(~]gb{}daNs_hHk| ߌ[h8u5H/ؘ&[KAPQ|\&Q&\{9 Mhp;.`@=m~lYpd#r:VbsT O$(e=6%DFNBrbwV#xLS=k_Z5 #`M{),D WV7͎-4r>; |6O3?٩ _ |M#-=ڙ?؎Ѓݻ*ج=t.*ƾ{y;\it|UU/k'nd1P@TA Hhgֲao^z4x?eoھةaKWfR Ѵ"e92Ϸ `/Dݽ{QcdP0T,|==i)Fׯg&~rg 3WAg;gzz{%(s=EP6=r(?<Oi~憬.dCD<T&ZoGz+F'ms}վ-Ҋ o,'fCf 5w9[Lh8A!$w/t~%ј#LqO(twgޅH^S9|L[׏ ߨηݧ)l=ۡ6ֳwnas/H&"Z7-p@(5J&7-6B$)7#t֧eɪ-Y)4/!xw%l( 6T,v/ZE0:fM"5øŨ-#laU=iY|ka_9 8cXq{h}8W4Q;lw!s,&\IBd \`@Ӳ~|z 3{uWTu8kBQ}%<PD (pu|z_Ƃt#gl&33$"VZ(a `ltSn3S$XV'G_A?kȒz$b(Z!0k t>$ЀPM[O&: }ZϳTezD[o~]Z$OxH8aqxl5ףOAL%Ɂnd<, )9nA ׵Ug(E8j7In\qGM]oU6iƁό~[6`84&$gRKBW,4L\ʬM,A}a^5o7I]C ~"PRyA}¸qq 7 sű\ID_C@w\^㽗&s-/ZBwsTm˖4qGCYt$l<$yf6!O"\ V:9˼d] aVN 7҈T"+4N()mjU#, )i폑9>LiQ\_R. vCkyV=yi.&SߛF,@".Z:N{}vǝo\9'=v {i?62o``BӬ) {Px/3i$ߝCmFnç@)KWgy#~ X #rⳙDqW6Wej'S#Rx 2i`}/@ 'nmV_: .cn̮ZTM+۷eClF]92_Ax!;zd?ؠ \*K3IY^{yxPfz48Wq kPNөxdI]qT9$z`vޞ\(_83?`%;6dWY7>!,i vXXmˇ+=P[Zy^w+ˁw卩7 w|Rӕ]q iY>g)ȸJtVYӳZ:=s^y5"WL Zb5aR'9BV 8t_#\6s}x[ޘ̇aK]JgW"%ڕdfrD<#sZX*o3sA׌7#QJ6d,m-X"mcʹMrչ>R]<3V$VB\BqQRvT.ڛ ZUǨi;Zhhz.r:CtY9K/%sSMUR! tH2b7v_(~rΔWK1ktB5~h2kA-_)mϘZی~|?TE-;H 9pz=_`Fk 8 u#4(h܀7&Ϣ/zhtBƒpJ Je--S7Uߪ&ef[kOz|JwRɀ)#>e?&BH .*p$h#!܋ d75Agsj1ZE/ @:M4G3'[7ho^IIκbX/60?Vf$F"9JT'WF¿d F7 ϨMf&1b}/@be,\P92juPx2߷pZEո;_*8.V]&K@am|Iri<C(}$|7Q$ Iev_b`RJeLߋSUEj^(Rꝗ.KvAe)Qide]LŸKC_]Us'ƞ1޴=vjR5ɚkcɍG9vX[4w$UJo+R&̣WE%ߣ2/Qm>-߻>uEn<7w-J1|bX[mهeMmJvaaLnM0$wf-J9扒PN(sYHB7$Ӑ ӥ!TT02CoLɞNL䇽Yq>ԚoyYwVnSG>vn cj WҎν2[/BoxVoT$?T/;۳V2m>f$0R*Rnip_=i6nlVK ,.~[=ZvJN[l`I~D UsEGjb,A΅凅d,0j40 m|->#u\hFgK۹QSzs>/rC{r[,oF3e].ʷ[:CUhykl'k@]+UػI +LB]um sfTY ڑ㷛N>XܥNw;ʈzC"sk2Ў-z d@+l \;G(#BzpI>ӊYĿwf^V$g yL"TKx.Y8 AJ"~J%1$).YASfy i{&`=]x W0 Zd{~l$b`}9r(,- j%9aU< ݵo~זE٘>LvFWiAIsP6,“l Q-..h~6_KVLq-oR@*t +T)$sCU-ۍ?.xI!2 tK^[fa-8&?]*a3:*ė_m9,\8b&&+qK o#ء`%IiUH,]yq=Լ[Uݔ3|p9kJ {`n߿ |8tĚC?)jaΠxxXpUD#Q)hEj0_+곊 [iH3Jg++y_?Lrb+~& , FIqz" >|9EtRJAi,ŀX:wB򁠟qZqK$@VkG,T)<*4iԜ}|{tcJ`E)5uvYÜwI\lA wWY ޒsȲ+ժ'&/BpxBZ/ KodGUBuִo~ ql7elZg~z)R#xc^IyȕƝZ(biƫ  X2!UPojl\#h!jsceDžW{_X=lxH#A>o-TZ$RT-CdGu&Ӈ?; 2wcY)->H"7 M>g O#&8!Nٱ%Yh{$ YWlE7c0(V4bq/_S߲!c-ețr"| 4RHEST x/  z|A߸?~{ѭ"x y;4 & _䋢Az?BfyXҀ xk $ipcr 0q!&zxI9!]W=ʊ.#Eux`KYcEAHޭV yk~f3oZ-ZQb:n>$OS\J7EYi1"5g2U l'W" +Ix SՃB AuQ!!3$ Q$$\ʩ1YC:0Z ZiPSRny5PZC KESI5ЗQDA6h=\ϭZ?iP(TM y_VPظl@9΋3o.(SW F<Pji񬙧(͂㩷ѩM!#K8 5AQ,/~}zueS@awMKH+kl/t4!.]?BUpoe0ɾ[9a9;!/e78 f= {*NSЃ3$C8®Ͽ qց˺=Ojw}ӷSmmDqi `FEW[( 3"7!n%m7IEZ!Hl/Cq$a}>,xv FNTVu-u; /DΜgZ@*DZ吐A𒉷acWz"fD7I˪;r@r FC|b 7?LҼVsxo%=hHR`ObJ:UM,A E_ ;v>p$exe4r̀P+x3EMΎ9שZJhEV8U춞I1ڃ}7-bzS$)P9J"u61߂L &0kp:?D sض7MqiUU7舁ث$vyH1 &Y0-ݠq5i\9|@b2y-2/R)|7'KyBShXTbH+$i#KI'GPqE]suMeظi@"X>@ BN7 o99 2XJEfw?1vl Yu) r=r#'nZ UF  jxR]RF+J;T!t|0ԪP="1 'Ȏ#-s,!q q0/'#G?$tDl&oA/#z,ir-HBZ9&_&џӈaO\o{y35#ەR6e[SdFg˼.2#x5Vu"2Ks~FaQd4Cyy`aT>\=0Hh9%N pT]G"kRy<uC,}3UМ9!!J5A1L(RX"n~, ԅ՜ҋ=~t㰪c N8, 8pdHs2jovSxeup$_8Qd"uC"J>.bB,%,vmfkgg}wb&4HyɎpU9z 򺤩Z1Ybж\Kmw䛊R g#j`Yk6?)T >1~Z.42P*:zv>f-!dmYZF?9/UՅ٥o9 8dD0`[,)ӠRrޢs-VPuKܹyqB_~W8+zqk~z4E 0F >$9MJQu`cY*>!>B+߼TPB1߱\/{Bۑ'uz+|$ȜC/ k"orU!W, vnggṔjofX$TCh*#WX^M$|D8|//@Mp/&C`"k3&jݲگt\*nG5fE:PZ} t_Q^d U&fON<57 4Nֶq{YLɕ+ۻj"35H<#'+XR!&"O<ޅ7۟;defxq^S&eN!E K:lGD0<-&|;uVg.% 3 yЛ|t '\ux*]hR$>;:x=zWX2Qa6872=|Mb, %ɏ6R?ZiOJyJl}/bڤ[=E T-gThcj4Ƙ ;<+3Aq\FPXЋ-ѪUeyFVo/z״#&r$8z̩||;)fh|o2؈g3GQsٖ3x6.OCo~ +{}+zS%T^2FlzMjOj-framYwݎU4m2u#q֮CITam)2ڄ#U?cDٚyv_8= ?"-Dz-  H9]v9^+ۆ\Lz;4q.(̀CbGBBޮۃ8^KfF6K !y_<>iaWp~ѧEӯv=/߱ (Ȳ˹vMKKHk6b߭(eEQ5h?4(/Dp!_υ(npbI`DF(+W[(p(EtwyxZpL'7]'9_'wPAp_*l;+BYz6 n =ʊR\]:䪗y;s!l-L+b`z,VkɱlV̲mܭk@X+o枳X*o}Rr/:3]']3͞C$8J*pF)9/GK8O 8=[@ Gb6V|a,}]rBG-0F|:ƻ)?6Վl Ips%zD T<nߗ =4ZȚ42.Dك&#.^d}tJQjv1țU׾q͊mEAnP-Ws~GAc[);]-7IR%bxFW#˷p9o4FV\+q26c8s3qZpn\rzH`x~ tE"٥ڋWs"wTA~{o @_ tϘdybf됎@^ hdK:B{ixLb0 ưGG xwP #/\*FYfqmB])#;\K0{x}Ǔ1ѢxerfHJ^lQt!+zY|~xwNPR3}`# 8g>|Cq0#B_QR\WMЋCJb79:"WqɯJ4NF9Yo1% @vbCn\Ώ[ cZA2 _R&*u y1. %{l6G[xZ$dw[8 6aa>u! n]5ȟ0QqrR)3VB b_.&MN%d|*50u̬n \^biS[hGDWy[`WER-۴QcU%2AaIi+t" ?0:y_@<6Ek"D]7Biiu:'^OO\-RiLP 1λѺʀnFޥ zH@x`zi\#*J`yTOo& @\.C붬4 壑q}f ^ 8_lf<om!.WꛔZ wn?\X9d{gٻy޻Iԑy7&ֹV]L<zY5y)3PP A{P}ι&<m_oʭ<$PAVXM;PW6;Y7|weD !Z`7wٮY5r_nZT%!a.VyRXdwkGGz)w<(aZ܊wVJXl( zOә\<<|h om\hf0LȈ5X_wKyWk0{YGjq`ChmTךyӔJL9^Gʥc6ԙQWEȊfE"%pmY_ quLc򁑱Ȧ: # 8U;֏ 9x/UOo"4H8^M'5٠& oѝkR7G!-FoA50pP=X8AWK] %Mho60tqvd?[)6mJCѿ'9߱Ò㗄uV;Nڢ7L܎>w~n(N't4i^\`\2 ؈ Ű: ?oۑ?o.%3crr}` tA9wQX9d|,~Q쁵-4lEQWb0?$@XJ+^iFlz>%8ޯi6Z8NȽFB΀Ѐ/}5Ydp}AVu{x|g!5ImlQ7CYib C c$CD_T,7:^鲜=5b?n O"%Z 2giO}7+XX.v^wWR~p6iJ d!SHZq2gd"nruDa*y[Gv|p 躝2;>UhLvv5 }_|VW&o)xy8՟Vr_IM{$(Nl̽dį$i=v.˴=b =\EeUMxE~M8*,f+htK -E}T/cJEKY6ںY^U|O bf5^p4z]_5s^} X4^X?c.8X? щ$&Lijˏ#\Χ>nb9V!nqgߤ2!!ˆ{"gܮTmELsN!n,aĜNKǪr+Qr[UfbS+~ }BÜf }O+󌑣[ES2 $jI`l .-7,oS-"otӼ/I}[S ˆ_Z7)[ҷ'/ilHʗ%}]ÕƷl$ŧgYvߓCYA2|EQռHUFen3Pܛ7I=2̱TL_GtĹ/Kb˂ƠRy^8 R=&_53~$LG]I.=E.SH4`LEQf1/4ܫ8"YG9 ̅z-{n;0Gv_[O< Z=dhG -\Qm9Fkz0dEj VbawuPd^V5PH=݌!9yG: QC,Rg]78>%X x9y0E~ARɼ0ؤtC[@HS>:U-(s7yv`zAi7'[.9Bxd/)7!C:8e+_XtQs{"m䖹\E*~7[ <b3. ʲT~}}OϊDx=vkԥ{*UQ(ɳ¸.**p ʓU;IE/<ڥׯC> y( ~A֠ŊY5hӚ42j('7HYo=VRf29x}λg{df'٨g{e&VHg/}F37$o\+ئHGȮJ?e ݨA1uW27Ь~sPk~swrep # jrݮ'z á/XRKHXӴir޲0dX )_F0qc8I)N 8‚0yhR*P@֜hkBwqQK'9׀9;vh@p 7vs+' G_`4ĥQ=#[YnB $mRI \Ea;x}_, r0:e:4ܲ mxFs S4F|1,0O/&0 q°]Ef>'qˏRcF}ڗ(u}-DhJr{|@!IdTNW^yc ݍɮ%Hdޑ^NΉC~2g-+,\:YHJʭfd`ZeO`P;|Kd-Ro?6?s_(koϽpAF:T {X:  lB>H7[>&][- >Z/ڌ yVHxm2{"(2p-Rtm(!&(Φ|Gn~Z4t8v`HؑJX+\&]u@){i{ ye-LjyemP}!AaT؎/DH쥧fyԻϽu(RLfa f* %/ wRr=6|[Yp}xcrs@W7ȣ}'IOVcrBq/ෲE. ~N/88mf ɅIB*IGϙ39%+ *ڡ&)NORqgY#۾Gs5H2ɿ軆d8?ӤK?'$ SnYh㪱e7[YVPMIZȝ(& C[B; ݏ]< 6\P԰ڶK9LMgCr& |R#] gAݷ8IJ`-BSOWw@|!+;G*ԧ| ^ |,e]x&E{d(!)=Ib39 yxa2F߅2l;>*0b}JcMHv]kHZ_b{P .47}^y*.z8&ڥ "I&GuslT0sVח<י]I}KF2F݋XI/e  udE ! #W9x DYwuv 7 |p-x7I2l?QnmuN0nIRm•:M7R$HI~t^C2)vkV?doc'MfЄ]fh%k?g> у,xL;˪_^tYȳ:$??`z-Zfk&Y] Nm<)nS;G?ڗ @p#+i aA+lSrU P97^G EL:xq,*QAu7=v)P Lfݕ8Ă~ۛ%pfDM|`\ssșPd#G~|g>' > 4P.c ]_9ԵX^H]k`^fjkVK834>bodIp.Mг!잡Hjdm ^d'>Ir,CiŠU|<vъg&/ȼ/ %$Y1,iWYPƲU &u۞E_X:08ͱTL]_teif(+UBTW9AK3]l8=:^Ό$C)z%Њ +Re ?eRKH'Ųav:ŧK"|a5 [(+u)Oi pY9)v{<*Ãdy1vJ[vҬs?vfD Ӽm22CIӽKՙud!n%Ut(tC<+8K"0?r9n._ܐy=+bՑol-AUYQ*n?apRӍՒmQl,KQAgqm~pL\ۖ gp__kOu%0JYadq)ydo~ȁKI>B\(32` 3kg.vtxr+.iw^K0^3E{ExoK.C.:ׁ#7.鴜 +eO8btUUoV-eA0T}-&Rk,T]EijUyEe;[mo.U ֞yW5gTՙNzԙCB !L!f""* A (N^}z1U ݝ'$o/.И؜܇ά JS]Q&.lW X>8,[_N{9 s4b{I IPXeկ0\p>D؞HZCN`'l/ \ωIl8Uq%zG7fnt2Vr\:bH_`+}0VTUϞRsdIߙ.cyF=d֌t:-]Etr# 6*J8p!iU g4ILxBTɃ*b` r)t|uN_JY)9aGxptLcGbs/dx92"MN6aPLZ_LI,l'\[_p_ï63j?KL歅|4C0GfkVoYC8Pi4[^xcIK'u%?=OgfU%iP̓} oO=]M2ifuNd֞gϗT-,Mv@AS1<4 x%dU/*7t7bK9%M:λ$z>X\eCTLm o~kE] goRs8;BjP~y5![O5S8@-;+H|Ǚ-U0}:0/׋_߸0D:>+ƷoqJ4JYx&~D?6>m1,NIꂦJ,|{_y'Vϳp='`)rJ;U/WA!{<"J߽ؠ52-J)TmIhM 9nMӽ-Y̮[O鍢νC^z g߀7 nsPv{TJ_T_,(~Q x(5-ށC4\󬓁qMi;BF|ݩVI 7(BN捍^6@&Ά|*/`Ni_nZesS+DNuS֭jֈL>tx ؛$AFn=χ%+IvgRlxm=zɘ˕PsY҅.cP;N;*8͈-( 48j Lm4;Ɓ-L&X淬{݂Iv^f58qQZg7yX7gfvU@3_>"\k=K}׃"֓'g2O} $6 tE5ExjԅNnhB-&hHy3\P𫷗@qD42Smdu˜ipl2r"q?W0;ӮaN>"'?7;Nya8υ9P$,]!8/ǰ__ OhiwɏWv|s?~w{d,NL\+1-9϶b47]>\ǏY`1(iUeV5 ^@Xq@Z췯9N΀'UVxKʼnś|F))I4 +yAJd12?#bJ߸4j6;Ofjg7ް[KB9XH2wAXvϦG[C?{] C'Ymb'n}hJGeffm@sv;w.cw7`]9Qr K$xpK::%u;ysH:E'1Lzcة>xbmQ[iBT`dHő)> ?k;%: =!1ٓn1JҺt,BmL2děQBIijtK*B#qxAu:3%t_ޓe.O +5ZQA ǥ:-}ˇJJGGSJw !WSkXʸ0*mj9)TYx *i9Fu퉯:MƄsM(vj0:=)Ϲ&9G4^>%Z' i +kX1(@@2`aGl3[; a^-{5@fsgͥH[^5_X/xEv2rjF&slUW,fmw{W2 t$dt50+ʙd(r\\, yDg}&1;e48DIYuDB{۴ Z=ar`pUSn@ Rcw'7|u&O.rbj)4{`Gb>wϵwސ֬!5tFۂ~BdS<_|CxV1\>oIATp8ȀDrdeӋkudWrspg*ܨK-mR(˒'J"#Q/M7_JMA࡮ ERpRKez Mqye󭴇,dpieП4UPA(>v`v'y tV@o!:3@fTkP1E"0`W;l >FY #9R!0_$լ5A1!;’|Voj!ĂdQEQqkENɾ5%j_TI^oi(Nr?z6ƝO/P+iߟri$ٸ@)m g[q|j]9kE dmWϺF'?'E'yơ Q4̈$FBJ.klrNe;1[MXLVr-_#v)Kͮ&!pf#(Ag>U/BPg&KX8CL^\C{|B?H°[%5~0+.hg&t`((+{YJFe9'e_zPVLv{5o5* &KCJp#\T N7F9iNxWd mx8>]gϪGHWxMY'VM )ri BI ,*>hv6z)4u(9˓Y&C}:K!TW#T'Dpѐ V%!d5:.f<TE=} S ;U+ITߣs8)[3?G/= Jz澐~U>p.1G>\s&΋IEpSn^D>v嘆Nx\Rˢdˢ2m .g]ǑPMI74=Ԇw}Idj ~"<7\3}/=/u0+/,\U=;߷"[%dXpovr {z]+ʪq@6W )73SQStּ"#fy/%S"vE"GvxZ.O2=u!!yj6!h&V#87-,л9$ V1֢2v1̮z E>%(#(2[0Fpo^-T" qDzH[&YXNmIхMjyb,#WYuAkqql;% N/n.mk.I7D[vjZ:!6(y<>F&=e--aZ}i_'Ey{p(gK ?< #;L{s/HW(B,l# ֑kprAR nV50Yz<ύHk,hI^fj܏Κ93_ݻLG#cNP4d\?퇮v+%5sEƕԔE VجXAfRH.㤋"kdGf=(V着jTB#`y_T@Zpk WЎ:L7-RiC+!ةV6d#Zw.> 6?# 3]9CBkXq27=Lk&z5Eѷ̾q]{9ف1(Vm%$cZ\.G>O)JVCӡ֜hvK7tV3)oO 㬊x~;R9qu!;FZ\B!t?Ed'Ӕ5z.N)$GSvW= dҒXU,JbAIKI[w/ꕴk| ){u29K1glz## Ja@O4^Hû z=Lx7'qD&P 'lXSsR{כ+ESkymՅ?MڥЬƠz!Fy!!A)((VJ͹%xԯ?fmhچ2guAL)ٽqWWG d59o98=K{=.ze+*GrjNyQr,i{|ȍG1%U]NYy UՉ_ .rc"9? 0O ~ Ƈ,_w_'`Ԟa_-Wc:fE815XbM QiW`IO-JZ\ISRyfNvFN lюQ.]O$s#9ݾ\z 1/g+FK 'm;,8 {rQM6,|[bߜ]~T>0dW;uQd/@55 f""[mC̛2}Ow**]80wX"HS9?j,Л9LqwR I`ƛzKy~6 "_1U^ĕMrmrU'L^}_qeq+[oVG2VLE3 9wCQ%cd6TӆA~G,l:k{VNg36t[={j _1@E26du=U/Z*q@AW<K5ow_`= voɝ%"{@2|pF5gh2 K9ĪF?Q^OzAa;lД<'aE2|˯-?t^u_J ZpR$Ñ(\# OBVΧƺ7?Ϸ. 1z|@*Ru内d?',X_+$ _د$v.GJ}خ n,pN4z;qmS$)Q.Yg3%KUzںD 槷G)VN1HO1ZE*z&`6KOf!:bɝݬ͊+ʎ F2#q"LoXdk &ܛ 4:^v=-3I!IBn2̈(<\R_Ay4Wͮڡ&YSh:+!{e9Ҳ^u5Z>H`s t}x뱾^S1XuZq:{h$ g_O?Ϊ=;+AVT 녮Hv_?g %}aP]u4ݒ$$V)3)OV(b(8?W}(eX:t?c4]M.?%=!OpxChl؇8dbȋlIb u7];너[KR4; '|pUbISUft!I:PhӮ3b`5-Ͳ df9sX#5+Vt˓bCwyAki-֧'xޣiIt8^JN 0lʳ#Qd*RJW+ B8i/^zˡQj ã%ckiBJz~y{ :#6KISK_HF)\]aqr;d'vijc5p9|F7{ӕ꺬6,TS; Z$( de\5E4…"hfe N>ܵX ]2 TҺ6sCHY@2|N`SfQt.N"hLz,:2vO"H{F4Qg2R-VR #tBf]Wy847Yr;aD;^v2g3QQ,#?guzFECٖgbvޫȵ*61C,OKnVgP'@w"kO&gK+oN&?)#pB끫+ՉVD)wϟM~he0^K #.t]X'/[g!&|3JM7hs)7Eɇ ʄ:}3J]'\X'(,\\J[.z#w{vwכH|>1KH4X,ߵ?W,-vgz@ѵ:84JuLw98͹'fu:qo . ;c΄9$\/e'gbK PB 8Y %_~ X<i75,B$ S& NB92k١6IAf;ֆ,tLֈʙOKem] w>75I1NA٫W)5b2EFqUbO˕Dp*r4hԘ+q%Y$ / YFޕ4WJЗI$M&7Y_vIdn kYRs{QąP*EoƲ`f̻b%5XO?];n,0+-'xoue2sym6'Y%b&grݟ&9{.-Ӷ$3 N;i'1ZK;fBy4׳ ĉhW/\IY)^?7 CcĮnWRfefbge;b/z;&`/U*ͼCM2~oIРNb$!F끇.zyzY˹լo"PZ&'A@Bj 1&K,j+ ԍ>b&'Wx^Q E˶m}bPHEr*-Iy̯R̓IOce^cHL:2$O*إP̨|sތGU mhD19(# [*/z__+䟂sG/.|Οq.i $'>2z^%Ltۦr3"{ryp Oz7L0t&"TV}BÑikaLz</?͟8s҆bFdEoؗeغ$ τK^F$,&#rcBM= #.>Ƒ27ćVh6eN<1QI8eG4d8ŒdETlv_͖J7\Goj'SG)ԒtNENO(u-Ɖ`S;Ņ7JH7W=Ch6'j[KysJG57`V\Ty]Y<GC1SH UJ#OSX;AZq}4lndS4mQU!|Ei_z'{4Mݣ~C6gqh#6}%Ɉw2و|613I=5Ʋi=!'rOf5m{2/`^ bR2"ˑl{53zS`fkyCY9`zΗV3 \VR*?K kPu|Og-D+8>H!gW/d$󐅶 .n5-ohG>7/[覒v+pZpLh Fd  QXz%l?**np#Th뷂UmYj^9a{,X?.$[Sc)(_QL Sx{ ɣ׍|h ٢^CݖsXp|柞Q vxuF,UPt~,+u${'}F f|Z}4ڙ&fγXl?ۄKp𔭳^4 Gq:V7% M+q-`(zQ8[X3Nv|6Tsi2QP- ޷KZ 9ƺT~ld z q,2*Vyи[ez)EX:!0R4Wd`u`0|͠R@La߳B4=µӄ祐>q \jrf-eT^ l9zBR{,GN\R)+>^"ΆҝoO 4 7;YYK\9ؔ9%plgWU+-z@3u('W_),9LRJYUl8_\&^3wUf-u+/ YSQT͘&V~V .*wdh;l@y02NԻڤ\y}Rk4n4oZ69rk1;oL k~n+ȩavտصfxTk,6]uc~n =i3_:dդw;3rW>$E/Hx59Xf"S8- ly Pv_gJ*cb,FJ|b ׏gÝ g/0ހьޤJKMS mۨGŗs2 Y}:w\'^Lhk"Ǐ;TO` ׏~g;t!}T`S豕9з-@!-k)KE3 <.-$" s#/ayNg+=rIᏁ76 #|X1X]WeSЬ 7󌩝J蹁%*A}x(^\;0?6|?yM̛E %T˃?NXohWt[n3@>u e(+pKK{ojm:~7 {!cv#V>|r B~7 BۜEk. 5 ~P=bq"yӵ*Ykב(ut>7ju/sGWJ)a嶧:vdtŮ_/bB;Y¿ X82X8P w<ܮ+/Ӈq!FA9MMWtaYA;"dslcF4~ljZ,1j−8Ǣy$&ym}r=5ko_V +f\$z&k p9|-H7('Gif6jvP_!o $@#&&{L-FVg-Ǥ]Ʊ2AF+s\gk_d3k#Z]hH]R[\f(_!\>iڏ#G-o2H;X.i<. 76wbPɝbA^\ziMu2I h/`0'!pz֛lQk iv|gnO.|>y3Tx`1ok-dTI"L|ZA?ƙkb7IK.)ҷќ8tQk5W ԘcճJ)i4Ůb{vQ2t^3 H}㢨"2=UcY\YiU9X.=E[~ƚ91^[R{\}m ;1i۾/ûo^|w3)xJB:ƒ{NHc㓊d >Ȋ˖[ۅ?f'~{:m*Lf9CVNbT ^K8M}@?ۿE^>8Π׳Zcx]Utg.~W3LDYTCf~^\!AW'P ,IT1l5=+W獳Ex6ؿ>+?dWV隗ۢ|qcu>\,Lyc[2&G:Jo!zb~!!~iX_q%,C/(Amle`ZΎȉp| cy )l4[.?\Q_֋ftsAiL *zD+@uNevfZsw0+3)ʔӵ(q5{JӔ(V* hNȷp8sl#'6 ϛ&3rWxt7F8\ f~xR=^f?C5K"_o _rvIg8HKX2$SKwAJ6V' cK x4KIwr;\w`'םq;6X/XBtw\[[&sYuFTvŐ25QҟRLuy.*W$xޞc*$MݦCXC:a!(7x6/H `q/zFA^:[S+l/R{0:s0$7&E^H_BV6*"/G˟a7MJ%Y82[,;phß5;zVujAIV+~+o~q!H4NOJo8L处N4&*,Q%7nC͠l[;sy]=(>\5ͷAkIr@%M_/ߑ-Uh]#I[Gյ,DH<ˤWq~cow@=I4{MUV%D<VZ>m3^i5ܪ<`t+O xI9u/p}gg[g~TI;YCqcgU6o&Tdʟҧ+IM?ɦ̻`Uٙ7`_EF*oԵӒR}>ruL$GvW@eNmc\~CqO@dp[w:+j#U8ß}zȓ^邿ol\-%ĖrN_{8Wޘፎ6ԓ%J,_I}gB[LR\jt;9e6,Jwkzr2답F}:ʢ!ě (3+<&g]< YY2D{{&B ?w7^㧝Ͼ8h)?mc,_~Wloǟ׽xVּlMn7ev8TBr̛Ad661"nufblս͛p8.417V;M7|L2y3?*,ۡQv%QrJ=|OK#^;H'#nh< Ӳ^| 80d!OƽL טי$ݮ=V6Ա>45Z-A椾a"[C@=]A1KC0:HK0I'/z"AĥVj~!J{nR0NH-<" x2˚TS鑝A4*ÿӕurϲi|?uq3 R}yb>PdKӯR+gE'Xj4F\߁ɕg WtV'7F%&u .RbR;T.MN B]XF}< ʡ@֫K 5uϖ:V?UD Z ז;/8z)ղV%IKdλ3jh(2[nAjxXa[-`!l bLbz)i1<+\pXx`[Y؎0l_2_>cVҜʙhC{QosR5OB Xx?hɧ54/ UkW<&hܽL,UGH$PvcK~JFqVL /?B,^ # +mv}||jC.u2By:73C}{k6ɒ+iLN%kz6(B ԩ"'@4=; n/eee!p|Ηsc+Pt 5r>n#[YCUɞ}jociS?$+^LfY$p*BzTD87>jWo@6dpt}2@JzԌ5.8?rϝ+ߢ Codd]+dO9]aX U/߹IRNV_˕hE/װ-$6G̃EX]Dic<+B;pW/N:ӌa&;z ~<뤀vAfs+Ø0;A@džfHĕ4q10sc][^>?@ބ!Y Fw;ʍ=(1GOv_8xva,X|k[I?\bX qsy0A]nYO20FVM_w`I2'uŒc//s.v8,[U~;XX?(YzޏՑWpo-<%?)hy8fo-b[F҇w>)+Z܌'AlxXGwgjdߛg2i$}12B^4bO4MN㡚Q:/dxWtv^gR:G#sfP$(h.i \J266fZ5'ՊjY\sQ׽dp) M5gE U%8w)HNS!-WPS%\vCV*,Oa,+[/7ʳ:"njLl3 x 7OnzF~t$pWEm+q"Ned:MG&x # L#38 }1S4s >r3iőÖB.7 Z!Йv̱N_ҖAZmc˝F. [` WN2yJn驈6(7 >+f?cKw`i{y0C<3 /~;|pFy2w@Dۻ4y!t$uW;A(=:_0 E V2-vt?G>&c?q'QݏOU癞89癝7(p0 ٢LjMΩ8}O[FxˆG [eoCZ9w:ډ)TF@lGѬhUCXVmR_uN'%{ߐׯ"W^:e}'d}?:cYށW9L7ߠfgVjeNH :dȊp7ܠ8>yIH-➲pDQ+_S+G+],n[9:z2Odž~13#OSq‡,ZP"3K|s!wYe#GsBcwQLB7V d/gޣprnU#·#ʖ =a e6$}<+Y ¡VE]YSi}Q Ν+ iaH}8ޱɾ& #nyk9󭺍E6WOWkᯓ'X5Nt'T~ EIEg¹\OGLnh6MO6귫p z@.x a?݊G|/*n%k\?F{ρnA7 }R)Sl*t:UͅM!,pvc~K"5Mw@ jˣ~E2>MA Xۗ1|!)1a1X;l^-Ń )ƚԪBw"XZx,T(/BMe[rmbEJy8EZ{,TYu*:Ia:3nCnBD}lY.Y{:*#zl\LjQir:Θv p춺\g>iEz4xe|%棭6 > Di TT H OI8eؕ,{)5E/P\& og(PHc͈Hfhw?cӯy@Pt'| 9DR5ݧff@y$wbt*XQ.U)#3#gn|:6x jhu>*ݨm'7P3eCi8n{2w`|2y煛q3T} 9xl?Rc080!N}Ol׿!5n>#W ns +%/%3A !7LZEFDC˃i; Bd.xgElE_}7Z3Q۲ۗ 4y&!:1#ł,MoC}IJ_ZuOE!ToO=cC3v?g?0pzׯH;A2y8qW:A$;:R*a;A9bV2;:r[D3=w=fN yU!#-Y38:۾ڏ81wvs$>:exǭRF=CVu*avAC%dIxichS4< zy #JErE)q^bZ3EϷVM?LJD >@{ͺRxG A` +M_1ew-@W$OJ~͈0Gza53 5rʊZvcnCJl2<ammҊ'WaJd6O$*I[& '$|CR;1j-p}4ڻg!׮ߤ]RMĹ`?@rt9k议 O}h>9~9ܕ}p _O8zG;Lz%}K ~2Cw7{Γ1^Ÿn:3<T?:^w=a;33>36j?BݶUM}iUdH˃.ͮQb)q]qoInċ ͻطW^sxsp#mn{or5lNn›u4K=bZ" 3T1xdCN!X1YrMά=1oL@mm>&'&YM+Pm+4 n%zf `ҿu{vOY_\)$wf)RG "0yGto4r BMSV[bnϭQA5o<&DGc^ HhxXtG.g1ǣ :wf1:ֻݞ5>\hk)3b>A[Wko4 sNǵᤎm^G9Kh 1KIO⥠'XQR!vy_ 9O}zPfҤtȟfVl`_btE~9_8ݠ[woƚ ~q5XieW.~ W wbڧYr&`}VS!C:=W8oZe5}eu|7IeXz'Q,/7ԗ-ߧFWҵY[ `t>vvnM'n@5]qlvDN՞Ɨ%({~ǨAK~A1HLQ#afQ)XST rC=1<0"h%B@Cuw,9459.\hxof6\gF>h)rF:2b4{j{ҿ` rܓ` J,YH(f}+{FJN$ 9߂žc;]ʚ)_m"S}P᫽;}F͜Th8>N Px gF|B1s~f9.7kc39&φ[}& g%u=h4'f"u/ "ѡwGgx"Wfm4b\i+M4vfd7"OIJHYWr.D#uw9L3ka7 {WB T`7}gRĕt+Z`KhL=^b,֝[EN.u˷v4T=`"\MwtCZMy$X?qraA-A%BJ'ВY',N%I=LL#8g扽okx⦏68 +fknJo:RWu AvV~y<@ٰ7:xZ_>W9nswoI⏪50@";sZ{`cnZ/ٰY*Z 3-Uv3DftH$cArA_\sf|6 {'{b/m:4OCՖ3طٝlXyU_L&r_^rU؍A401Gƨ1A-~CBx*l$2Ze3݅^@yKwD18DH1?wi4#8_LDmW]{&^߭DRrl ,C#yNBni/L_ 1GrGL0u}n4 YX=_>#Z#k&΂ځοPںcN&^5/Gcz~cK1z/lV3?tY0+7}{)׵Ύ7n4l>1w&ۜ~:%ͻm˺I"xz͍IױG)FRb=>wxp(^N|9ˊtM4OOUoq#DZspǂJ^@cf|HYuR_)]d8\E]Ӯ(bA^|__?MeF+9 rEF)xA6z)ʍ'ʪnQԬpԝ xv7F y3U<-\Δ3Q=ۯ0-;g4PKD.dhQ8ZzYp [ :`-|F?k!#xRd{rWR%êijV%v F-SyŌ_421>qv{IQ@mk4j }N(TY>W̄eym n_lQ00Ǒۭ4Ee=p=-S 4N۝knVK!'*!0iNH9ͺzٌ1ԁ={JEޭBi}BXLqBluƥ\m2o4L֌%z|pܡɵCp~vnrb*[>VWXJ"OK$,>.pr(M!.")fD1P2Z8ܟJxPLG]V}$2M+sv NɆu;kfꢵ~q=f= o&t\8Fpm>sVם ^QG\dn(f7t7zldb3KJ'F{rc鮜;Kۥc_sNW[ #@ -p)Z?n64䛟d, )ueYү g&[ڋT7٠bqLvD"3M9QsNӦ(l2v-NӇHWһm6v,*LƣkT߳i;(fe֠ø3;! m Vq^EswUAdx288 Ӝ J!N h}7zB&(Rbgh}zwf՜u /1*?qQ*5rH9pAMnȔK;%M'k vu%hU)_RPk%Ma_0o쵷O=7`jjFs0]? CY9lxf("B"]Hncb5_ j}LG, |N LcrIw<}ub |Y(/'+\-L:v˲eYuM;1F m?( ޥϥJmPMȗ1΢Ż&8}RĊ1o%F":lmE,tjX.{ӻ /銋s^xƜ=8`SO_B 71{Cx`A-ŋ#G3m)cwg0+n&ίmJ @^w5xb8Y3όF>+VȾR"E҄pғЀߝBPEJWXRRN@Gc(RdOѝ0Mp۹%z.z8$Mh&"s}u{&Zt\ˍ^榿}ηë`qn7'*pAchYLˏ8ko-{pRM=\O5c]d:螅3kt3[Vgf<3M'ZbJN Yb-&Y#-, ڒ8{;z `L6s\h1~jXB,er8?hI ͊0ثz ^&F &glPED(/{=Qiq>%XN3z8{W҉Ǽ=!(v{HuaR`)X|vw0D]`f+pcp[,;E9meY<;XOɽB]#z*LL<dv_ c&CR.gᲮP\ѶS#5;֫N[0͢}d:if³55GκuE\فhV뢺Y=ݬj=PQD3K:oD?UI]T;Hr8-hÌr8xK3LNPiN3-aqnT$JLU^:EUѲn9(g" Ts)MOffz{;b,)#~=< SwR9W ma!CSB7%=ԥ[|p]j"P#)A Gb#f` ڗ8Aik4's0ߟdɢfuPihణۖ EM/e%NoÀRh+6.nh1-kfUu4JC!}Wِ-ͅV4Ը}k&; \i3s.UZz:H?sy]aWܵu ɫ Cak0EK!P.IU _E2c ΗIqLȞux`D11"3i TliEDHMG"p%*Չ\fN-p6~oX ݯGC,IP"&)⭈׍)]U!:s!=GrC0<-ʠi-2f[&q,1Cp>(l X&*)M R@e+Rbf{r'-u)/;^wEZ=?NWQ%M$P ȱ7&zW q[r)] b=~,g┻2;yMVFH-]>G㮰*؛"7 V C >E &C&a0FF.A-]eQhY/4^o0v##"z |LmH|.7,q3Hx=qTrX-:Cv( D0n;׵CJ:"Y;Т'AJ@bMSoF:x|lNEDu9W.!ĕSHC:`$(*ʢlN?Ʌ s^m".2USnu/P\0Ms`z/Y .}uÕiv^@0Qb(VoAYM^LYG4/D^QD#lΐ&>M4Sy D{ )_Sv)`Ĵ]2zѧ>j"Ş J[\SH\XWyu 7D#E~SK\ؿO1L볮Akkh96H3*, /4k`IIˊ'8ܠY#FkEM߇$5XHyσVK F= THݢ !o%`^@Pa/Dz.(5:nWAN;$su2K*D3 ;ijYU/{+#WPEڒNLv7WM(U՛F$2uXmC-@ Rm'XDJQySqhLi+ƴh;o~PC{8jiOCكAA ćNSvNgU,!Q{HD({hx .Hɝ^ `nF`;~0aM~.xQ(TT]9ML)YI0#> 9iXW՗m7ISIye I XXmNyDeH341HTmL3n-T:@NzSS^@y#jߒ &X,i>z9vϦK5$vŐGˡȤ!t'4@'Gk?5" iYDw+-Rٿ[}Y-A器F]:5g/u]82zEߌ&O?jqaĘh67YWZ% ZOMN#GG{Fm.;1:d@ێݧދMnAvRi酮ѻ Ț;. IDgl4QtGPU%KcL!;ʗXi4kU0ѥ(JR: ZSYu|#5W,N nk'AkX!w~pLJiE/&ӸUpH< 0Z;Jq3 0˹\\,@rbɉ{g[-]Oɉ`,[8~!2cy#gډD ^(z17!p%yOǷT3E^WF䱱6i/.ҬGbLoKB kN(4t6Mq?>:N$f*i $YBz< ݬxZd!eRxlD叕on5dCXeSԣ:O"}rUi+&i pr z_ #)9`8gl ^f̴T@nV+; hb3ec˖>!zr(.D*.C:fS5#yA eIވ4F*e8&+S͢-0½fw&reI&%Sݨ>StFj{ߐ>SS\ki #P/a0 ˒( wHa 硈\A/F8B2徽HtEūH('d%"nCvm"g@U)ʫv ܧ:kT0uO .(aLlǽse}:k6E!9&h|vă:tŠBk _ \: A#J& #)臽KOq2#~;,$޷|33J,H{ܧFCR|& r +;a(˖ZF;Χ*0 .=m)RI^b>^l䏝2wfCSkL9R'#чCFK5I\GL*PygS2]}#=ؿv5.sD_gm-ZGMpt!^jU[ͼ9r ^i>њ۲ݽ~$UpMFPHʐ>2YsVn|r@ u o_~;/d9;.Sr{'&3@_bj |X G4fTU M)Q͠WkiutG~ ~nDش5SDQWYHg0d7WEa5-&*^1hK$<џZ ub݀q{2 KZٶ-5f| Fy 㐟OR*0ֵGԈHvڝ6n@lr *Q'݈&ȁk;]lRP+GCf>3jD.f$Y9x_,r^W%ЊGj"ޑ@34!^0+~E9Eq 1ӯrP%xx9yMqZB9ƌ[r`{QTYRw>\刼4Y|Ӯo^.{BJBG^G̈́Jr*Pyy/;ܘxqR86 fs*hFsHbrhHTpHLbD#ը5tו\}]ɩ% @ {|֝-7eይAF%<^\p1FQ;i%Ӎ >m4MW}Eh 5|kI ʆ L+$ !AA8e9AfVrSŐ7åjnxc? Q nOq _S$Zӹ?Eꑛ DBEk"ZbCҪm0{t{ӂ&%ONjqcI N6;Z եoB(pg$R[W@LBŻ2X8r[ENȼ?F+uUJTu3K-@jr$-1 % dU~$ZZD/ 9nd^-\BϷ:yA><&y{>< y!o^<K=J&+N} 'î`$P˜rCB!LcJsJuסE3eXr0Yk@(_n!?뙩tvZJǔyՒ%3?@nQ$wOua}Sjew5pZs*vND U+V{x֋{q Nk4Ø]=Qw2uw eSQ_ysƠ;Y|){QΗ2Q&Ro"1f ~㊫69U',C)G!O S҅>ZR^BlbL0]V/$ޯk5"7 P:y6z{KTu)\.:Aicu6N6 v*H# P\g`(bPxkv"~OX,VbysG;f^~渚5K̪ܟgS{sS툟1+yyq;7c+.ar%C;HdJSG|gĦ*Utm6n_}$ݘ.J Nna^W]kK ]zze.[n |7 }3 lkإhmԚ4q2)zue! ;sW\6ٜF5@0ldxZN{I|j*[Nw1A@ f8*/s;.)6Zhr`wqbtZEYSk`7k~9rzCoבN<׽7:e'P(f:8FXc!)7n('G.eȋNtXmu;xdE>$o.F]_wp4Km>SXv4*  9ਠ.m~6 N)t^*Fǧ.8t>on$dˊHh $4R=C:WsLTHCn}ők+DuʕՒklqf\/΀O̗m󩂯8I@I` Zi@d, -[cfHڔ7"=rU2_ߔA#%)CFS7B^}˻Nu^3Y[R$$\n9{;F*},h5 4zZĴ66ԕyhalA"6 sz٩֎sbr`{\5 Ŕ*UVusӇ{Q kk޹S0隧9YC /5/,kh+TMyc0`? R1}?S9C1!i!=6^tUeBeCcFWM3icvf/6O}Sx`*,w_~qQ,߸Z̈c8wo[ϕnz|~JXA)#wɶed|xo@f x!pp=T*|Ec3@- id2 pE07ߓ Vua 0S#Å<Ȟm[FFnI>^KdB2;| Z q5*3@kPm$mp2-!?:XL޸|cVDekmոJ"r`Kr2z~Q?>k{_: . D>¿W }\uow ̻#צE(\ s0=2V+ge{W CClې&KGh.epz%`s25K \tBB[#=va r`?&z''V20lIW >WOJ{Rp:шY7P/@ek2 :]/-*EmwPMiUin ENlhlTJo]IFP4y3/y|t{l>u|2HJaĞ5ė*+1zމfBRzP-+E#.VbX%>կG [ی&1}~ps8v^=O2F#vMҳ0PyOyQ$oh:+llxy]ArFv~ ̱ &$VDx&0qv X61`ӦǠ*]xMϜvTl_nK'Myn*at/VNɛjy^,oIȎp(2g+R^vL䧷)C{'FsIʭx:#vJTtuK^݂gf 6gKElfl |0P`M[zܓ}?ovv ǥ(GTS[KČU(zi/z}6@9mV}1" љLvlI=p'_FZ2Իhأ'WJs`.M(+,S+S;/zP1v>[Zfs`y-wY+,n}FV:aEef?=AoWQE'gSmV穴DM9(Z'c)ޡo;~p޶噭sb*Pߞ>*l[8%X8xsYF->7<'CA+/հKRMqZHdA ޥK"8ԵcWflT@w^ETA*[#WpLʴQK2ޞ_Vr[xᅡqi|Fn?a[EOuz/00B]NVVY VF$}=u|zݧݰsƙ$/\sg'~/N;z71/˧UOvΤj6%C?@n ~Ui0 c{Ms>28b )i4ɦ>w#wQ aɫc)F:Lv  :)rsr0Ij"{% nF)]!]dۜ<ڧbNkXA=;HI;D/bTj?eW}Z!51E)>Yx'.f^߰.гОAz I!sL,G )N!z$cbq!Z0Uy'4)bd'Þqf>\)s{/Qp3e3lGײ_Öq|ɴծb~˧:ڦRu#krL}O; WF;篞Cr G ɻ]Qc$yxN!#'\=~#,9:ws!^:jnovrq|i RA\ 7⊻f$65[NJ1B89b%o>}NbRyǀ<t{k޵z] {x7:0 V1g摛O$pďEPb`ZƈK,%drĻB=@G]Op$,NwطUnKR(Tx89M2*{JZ'S -%į7;YS+.ܩtq9-ͯ]=^ڒSg2W86V =tfdGN"`eM3u݉cm(KqcT#b<4φƲ_E|荙3Y|3%+$t:9*h*9+Nt}ȸ'ɥ8"¥}ͭ cF'qoDJ)/f_sM׎kT&*[*זmȇn{`Kqve2@Gb>GD;!4 \RY^}ÁccH33"L?|F8Zm!wdzqLaVrxu;gFz_@n&hGZsJ}fѽ_pBdnwE|suG+b݁[2ov]"^zn@2Μ9.pX8;ud8ZP% Ӓ?Fbw5' sV#Э u{$8j"ZWðw|qCteY\,!.@דH/ tܺ•;r"r 8VX6QQ've'%j&$o{K~:ןD\Xw$0$+2؎ϽWg/Mysq~T ?L \Y+K=p3ښحqНf /S9O;.̫bBǨl5𛚖 L2#*wp}GgxcfCkhkfUwZs]F!ar`a f@ʵM: u9~:WZqkÁ+j3;F9cs""ޤT/N,Z=v6…w䣄~nE"#|>{;+:T2I <(lnrf3,<'- :"k&alӝ2a.m 2u|Wi6ɛ"[͠m:M2nnW@eUOp]miJ>۝F3uτ=>]BӃP®N|M/v j($ Ryuoܯp.;mZyޢ2X( 2Qx@aH<-׷p^ 5-rN~cV;m^[ClwX~fw,5yl} &Dl_%3AY=@&ݟ#QWeՀ"\ZTJ ^t)E=r}hd0/!\i 67kڗ n61Mt2z(u&bύvH`׷"ƥєwsfÝ ,Ʌ,jN&O@"SY\"?"|\0¾*¨I4lGѲ{C3lm1S)D-8A]F ?߁ۋ oxۉ<2"8oP]r=S>xY&ӎTjXų[$f_Xak&キacǓ4,kmUjRo_AYG)Hɘ"?'$ |{ >BIVBl|"l}sуϱ7O~[?̾w#qPcTvWfy=??'8=13F9,蛂͊UȂ\hV?rXUqGb5T >I|ȯHc7<_YK3^,3fbϾFT~TNy,Ju$r/kxXX/ !Z뒫CMUWEWI.MenN(p}8j{V{ %BӧޘhWiQ`U&J>\Xstte(\EuZח%/iLlIzû87B"9"CI`~ǎ웬Rޅl Բ`P>}m$Pm htbp0Mu2fUZ\Z=$>kV@-s6fK=sv/8 >O J @J uO!nzp7oRO%@db\R~N>Ҧ81aI! :t %M'XumJ4Oua!J% YyPGWGn r cI$c 7̾vCZBN"7#O{C(q$fn/S"Na:b$8 2 `@e6 OhFrI8nu9LLqL4yߔ0I|6YZ*zIe9v= z]MmfZ:=2PyY{J.kO4r-iE>^wMv>QN,;w@&>}CF`%Z 5Q~h|XwbjDIX}GTHCj qStBk_󗂵R^%/6Q fw_4Y"v u FCERMIgVTZ-M.sppu2w"{~ 3┯R\qpun\b -RB Ge>6OZ5-m'֢6.,@J+Ni5,@ PJ e҉Q֋ta͍ {Twd9iںJ/_I'qhSLwKlwe?U wv&_i|EV=z:hC%W 4׌D],`qwҪ"7ӱ8rm#Mct/j ZMj~߭5!Kwu>˵ehAbdJJЭC:F)ŰLYH! p#&IQA;ٟQ*hbIVӊv78LLu)S9,PA Vnjv xMF"O"# 9-DQ0EaCPpOZ?j D^j*>+5V˱;*˂.=kb㷞G[dY_/ׁ_eK׶6݁d Jy',Qr/V~#߰7l=YOxRy 6_F7 fg?BG"nZޕ2c̑3vyZ4vE:ui3_rKA`Rżd: <'sNi)1>} eO'<>3$mɛ"\'FnTXB3aO 7ؼ֧gʘZ?vn I_I4regw5 Ss 1fdQ3o9lk24w6K:ݮ) rYP:ޟ,'0|Щ1Q̍cSS Q,9>D9-BmC)gL+c8ɂKc'{V^L=" _>Z VEole}?-jmE)g73*٨HX<-k awfzDb` FB+?<|-Kk \}J'(WwdA,ᰡ?0s sw91nOƘ6Ӈޜb𮩔5ox0[~O _q9D+<|d6jտ*)YchS(CL cGw9#g |G磹N)I#_vz>Ea N-oύr;V8 wqFC':ry?&s^A(-.8 7?{Y ?gDLZ(v/`WV}DTnsiKP}*6$9#S&kK55 y̛|6UM٥ɚ9f" 6 #WG$#YB&3(9q+B !f]H@@gm."ISghס8 %\TeK X;W3kTbHF#*4>9pY[G$Iqwj"Kי><}c`!1VKD:`*5Hh:Hi`x9ZtE8c|ܝDMFfO=|#WHtidi1.{w̖Г9O.ug_(s(71 ̤ZJ)! IuMzXhuEj eR):Qk.bYYS||FC I"! X躃-{Eu-{yfc??DVNh8W͚oU'J'5ydWi$"<.&Xko8ı&Oe}mIj*zƏ^>:<^K˅ٻ,;ʮ,{$~5|ܸ=;2eDƴ7ܣTb͟b񠣩\JӻEPrC4̈́GzШV*A)-$ D)F؍OH%ii u:C(Li7% J+{s%t A{œDQ&fy݋ =a/ vP.8%*GaIr;9.`LQL:lgphĂu;{[gO3soፑua4ʽ={=0_ИA2iadxTg}8ZQK!veeTx -~fh?EZ6(`>-tt4$Z`8#Z7iAb-E}MG!y罩^6h汴Rg"Bnm?._(3)xWdOH Z f$$7@硿 ^I4GcQfh\zo+lt $T7PPB}qW vC yT/>uaqLzcFc FW.SzFf}ǓI]SɎE|#9 m,6tNj?6jGS 6 䳑# ŴBy&d2LņA|h8oʆpƐtRǫSN6l׀ 31}бP =,Fު&:M^B#Bю _jf\ 1wӸ T,PFe3U4ϚO5)&CyT U!l'r^́O4fp9yCBAs8T%(UȅKn{5Rµ6S TD'/C`LIPːL=[ f**r nx-J*wwo{XBvV ̜q5"& +Apfs %`&EAHR.(hz-3}zWO>iҳ&Rl O`a,1wh~W >- qj =vFdfdyb\>&,Dtf2sl&nޣg-W+XҒR͵Vh ^عmT٠LNu+ep/P\3*{/])ER!!'@2ھJ2&// 3"j~r\! S lytLd>J< ŖpY, Ch͏Þ}x]GHʱkZ^=: - X#2[ epbx棷z]-#*XMny)G߆vkenN\2kZG¥[ ke<] Ai.d#toEAqc_'Iv:™s3nA&kNE4eMs)}5LA17Z6Cp΍5  |;spcǟ9~iZz], NMEscaJe]*A=}K;;{Q!# tKI5QBpy(b u%|!UA \ y'(oJNg+:rcdXHx%?VBY֣)-wd~.\퀾}{O^ʫ`n3nCb(:רzݳ':%D9ɻj F7s:7;m^}u§ExbU& #WF) 4,zrqҔT=ج@p:bf|ٛa/rOK=!_7@p.g斥[;ь{_##x_Eũ(0 w}}%)҂a) Wܰ+O# \+l$ر{G4V -"E.aj I,}J7?_tW뤿tʃ~/DJ;1ר U$a4arqZ!ߟ?|o.R"0Nfi '>}r>ix"˂TK": )qp$Uǃ}htS;(,Gc Qc 294F ^^gjY&&JKh)ˊ3Hjgi{k&Rc qnܲExRkبnQq3ZMAo4LV̌x=wY rәNC"MDvDj1@CjVF>ՠͶvQ/tCTط:}I*CaA=7Q:4hRR`䆤?jASF>/V@ ֐$a|ۀh0hZk2(ALġux֬Q'ĉί?@Lm>qf0pk݋&`Gwbĭ֮Ggr q짤1yȋ9KxDD jk+̘6)YM% 8_^czyGӳw ,S . ޲T*i\ܢ[d\Zpb-???¼9~[LTE5!ʈt!]4}K?Eg-W'UGIMT XE%&ݨC'f$8 LIU@%&uT s{qN<䞋) tb4 TVT2 0kեvF& ܁\&SyL9bDp nWe6d t*e6Թ ^"nQ;b6caR0IPGKtl{:WQB/(0ETby2Vd X\E+y!r8̪-Kif #ьd-,ZA(?Ӻ'Y77V!b-('kԟ,rS rTq2E2 Pg%`Xŏ8 sIyoz`@Bҥ2\8f5EP݇'I̕tɜɩ՞v6n9 m4MHpuY^jnd>.,opډ8F гqBnNk`j}g^ћӫ/S>90/Z6$rFuCzT e&W.]\Fz- {nsEsw葯 C)wA0i]Vu.v* uc1~ w<Kho=bjHy,jrȦR~A4Ĵ>aTm/_ulOEww;^xiZ&iK bvK~.^RHYi,(? 5a.#qEH!ƣȾtE%H8%ưUv}T:18v"T91 Uac<[Q~"_yͬnFTp'R1Ƥj v!& caZt!E̮VGfitdGX9l.f!=FFJƖ-IS|#jv`%])L'R".}tvѤ.&Pe$oYkPIFW(w,^Xko.|\LTPc$|X'Yg$hIH\bKʨDjFBrt|Zŵ[ڤOB多x{ r@Õуe /GaOMYH @ƙޏ Byn޴.vx/~KPGs|N( m XqrzoxaXß>L`Flh :Lrk_{~TBI ¤jP:DBE@oZq˘Ӫvخ YcNdˏdp eV{< 0(#`j;Yl{C|#}9Ȭ9۪}Wwkޘ<"߿|UQ(@%i\ i$#1kَvo?8 {=yccˡWM16hc襎Z!gf~;/edyUDIȹ҆ٳLr x\._"6sYƾhS㧺0ύ)oKp9Zoqaě'>e)9|l,`hdE2#?v!` v*\˰ <ҭ!@F{L"U:)YZB\9Z$Nt6Q+ɝxXs^ ؿ' p U?b>_"@h3WPc %n^~A/YO:qnrrى 0K{- q88]LM3I$R9Db{ vH@-KÂYf4$[S(EM H`" ? NY *F 4Pm5 ^"ʫP: yIЩuh6 вt5>KH,6 IH}W7+*L)*Xgښ \FiGas?W~L*ѩA\NTTO,ł% iCJяOH2+e_ uALys0Tқ73u`$-"UZ^ l\ I: ݚSJ֕gn1p[Q/-O8P*ONxn @iGBACɘrPB`HnF_~VGW2v`:73}>rN]^('nb4a&\;=rӁtئiɾ#1qwo_fA÷g+6܆>?-a;n,}L^ ˫ϑ͇ih}`!3ط0-W01T,lc~||dZu`nK >SGN$pjxC-hJ$jC ?kfolj=6b K#uۈQ_=2uD S8^`~W0W#^Mݤqhd'6g{9yc B }rѕy!rH}6pY<G.uq]_=\3EŨEHb,L89 xAOՈMhQ%o%t&9+ Т`FaC2iMZcuo9D^F`Z WN,r FpŦ;G ɋW S wB}SEif<:4,_cU"5\.xxtQ0tn!GUu%_u,-Xvp9XHsY:˕W tp;FN1N]o>:Okxcc7j$S ͵{)R @1qlZPkUK.O(k UZ|ۺWB2kRgT«_>VuŅ_m 2꠆=VaAokU|> ӽdtuK[Y^ s[Wz%_=-؝zIZ}\,. 6W\?t 0ӮubB~0w&<5WD [(E߫ : B![f=vxjUY=x[o@"V3& bvK̑sMxiUOѢ G,SGNnd UFJ,ގ'F`:G<{|6@-;.kݞ6B<5w,KIDU0 &GzuxЋã+'S&_V}lM:.-L=}`MҲq湛w9O:}bՐd:ٱ(~ (U-4,HdҪwgUuA2{JN"s>voSEcQ+jO5(Q5 ;hz F1S1ɯ s킭/김e4O;uەOn=&XRXh*;[P(}e@KHPЭquP?bvmmk9zq⥟$]_Ў#G|딎\F1u$ovRIVN@'x|cH(Ҧubq8eOtECw' JQրE&fڭ/ast(6{g:hyvr~ꑄPX,+KMA8o-`r_iPINt*^f2ڝ=˳I*5g}sl>y&*l>DB!ܕT"XR%j\6WaԠq_^mnCr$XljSVӺJsQFu^+jf>PQX1wv>Y%}ug18;μ]:\R  rZ9(ԓ7+%K3.eݗϽdgAa栻al^RMlbU-^L2yv[pJ&J69EȻ9b&ˋmKK_x( pZz fVu/x()^ R5`wTyr(tVrSzT8L'5s=n+]䮧>>Hs7M0&X &>L5?eST}Cj"F< hT,*9c xc-@*h+Ɖ%}P~@K14 l#*6B%S!EEx`@%`dJ1,8Q!Rtlw*;.a{1gr*CpJќב#*UvgǑǐw Ђ a\_2KMEȉ+HOgepߡgˁJb 2 :io4΁!~.k2_3>YӆhNtu&CZ0tb=fc s9G8톋sI?Y;NqvǢmJKsd&ɗVڵ 3}*+{Y|JzÓ.#Cp?0cs8 vvz嘀J+c'!H+,s[ /=n[S5xSN)g80y}}+&s<<"#1s0~Tz 9Ma  YZdM^%+?pi'qIVbߒ6+j:%k[eA||4aׂi_77 }"5ydTe,UT0;-غ\=iƺ@o9rp O:ٵ_%,so{ijYR&/ >9Kym9A#GxLV`b2=]%5N5cdөPQiFQmƱh F5ꂦ Zl>̨y8@-GC04ZQuU|Ԣ"řm\-2uׄlU" E8'dΪMUl!^W3f## 12ғI?LFr# Wjپq\߸J?x5tߩylK76>z`rxr^ƨA$Mb$şY> Ʌt }%H(KXJ:}otZuƲ }#>MC#fpm/?"`б"8;yKЦo}6v G (/1vcބTnCJYp/Paշ_fkC(Btצ¨,ߴn-:afǪs?]ƮU;a|Jq5GG]e^)t{cgo'x5Ev䪠8h<ܹ\o0%syMizֽ!=ỦwC lh1gW{ȍu5]<G321- 1f{vb*Rغri# Tԝ-O@*Q0[̼ҳǧ1i(?Y>!WyUfU%4'tZG/7yyp^¤9#5)pϣBS^#C 请UflI 3=Vb%͓~CUVm1 "!ϙcw ӫz<mMRP7j/1 l~=7gĠepjF-Ԝu3V@԰r@=EU~bn(n*Bh,8,XRHT0ʂ게̭JkDVI/-# FmnՉΜS'GZddZ*KvFs$y@ xM1jn 9biݰz0u ;agNM凯) P/4nD^ÛGSx<'%rdqg6x߹Khv.:4,.ƅp) TFІaKZ'fYݺPZ\f0+څXgMdMoƛ$:{rr<>5 lm$/-o9%b>*lSľ$ޔMPS~JCT4Ph:(V2NH|t!TqAm)hr(MwSxh8ۊx%2xi2]ь V6"zVɂaub(1UR Jr$cXxޤ *},nسj>J+t7)@r1#^89x(zkk׸db7j- [%<K~uU @??7 uv5F߫۞s| g/êdGyxz;1'a/*B *MrN5߹13M0z8{G T950af(p7 l(h^6R֭R%_)Q9[wzkm$gbuy=L5XX^Kcjޅ{9m.#>vӉ2UUO,>5Yr`P.-ɢ'FlfkK4GM0#6$\Bk+nI9a۪5Jׁ源Ldn:=2P;ǚ%\npn3 odi9^R&nFxM EsQ\m$'D]=MH&g99q889!lq[wK&>uftD=!גV*sEdpBMz7mLf+|O,S-솚p Tβ?(E,yA΍K[ zEJKTW^~k\$Z?)D|Ҫii˸=rGRS" ºr 96q n\F1~ZsXt B|_!ƒ`upc% 8NRgbo%b|N5T=PS4XS.h}8,A%/סsHC;m9QgadN%+|Fm0a~u P; jm,w @T'IqA0ȥ4W Ro'N iJGL@-}:ᔿ"6}ֱWjf{е8W--Mm["Kٽ zUB\w:Ё9EfY:G _/ hIī>+}8`jgd=6BaՑ*Kidl{0C琇Pupq5ƔN n噄2(K E+2&ov΢@%,CN:}(o,)ʰR>녏<9{!^F]6N1)>5624`JxSfWVJ0=]3:v$ɵnE1 / BekBl3>m@fj Vn8;MUx 9܆jD4wmfT DBFٹ\Dx>\D*,2xEqY|]yzCNW/\\v|dɋ`<{ bFڑ!d9"l)a!x31Eq?{ȝ` M'c\*L~ߢ]W3`4?P `rgӛnC!SuKş׼peZ.V&5Iހ}u?X'.HrQ; 2ͶD,hUhpCqu IM̋aFd002yX]]*rwz (E?IUgNT9́M恅Sdͧ&Z7}4/B.μTSy<2; QeY9ėc1.XF Z#rOP]DzvFm f}{G-8*r=یo 9<65r|هucVZ]Ď~:@gG_YnuuF QCqXG Nk\]*P~]i֭ Id:Y.h45pGa5;i& ez E'Wzv&Ĕϳݠ8z. 5b[G0y|\}n%OIō~ot蜮io2Unr`vSc@D|k}lr6s{ F|vGOPo?y'ܶg*x(1گ^}jhzS,| `]ÿ}<E܀ VuslQ~zέmJ=(JO6xt5NK/\썧;nYN:v'uXPnL0E" BD:W1p6ϯ%ߌ3ssaO96oծA32Xk]m qhBߑr%ktZ򋱰O@СLځk-%6ձ~Ԓ4r!Vp'ˆ)1q,h\!3v[VXrt˚RdOUD}ʼnݑ{L7(6@H\L: ~Qg_C :j`FptxT] Jo ' ؚДҫz?~B| Lڝ^`{jqrO7V lƞeB2NmcWe(`t{yqK8%':Dtu K#W[ 2V&O c30!g9 lw7|̮sJ*u] 넗v)lF+TP BHn`\pGom9H;*a>Fav6cu UpbW[Hr1 ]lkWCm4 ·\;] !3q[ U~T imd Na7|{+XB*p}62pXPW.(+APWS+;/xס -=/ T0K@SR/D <S7o4锹.39aI\i)L OdjMB[cQv45yWeZM*tpXaJ"ԶbZ<2;qݡ+v=yzBftmWFV0&A툱>G6PUE Rou Mxڎvǡ} hG of\=xg5(V_RVs1<*WWL 0,d!CgxBϸDS2q]0 &v*ET&_Rg XKWmDuy7nIo{u`3'QXlU/}A-ȉ.h5Ǥ!td#%]j64# gx}Lfkg.pqg얽fEɩgn]G2)iPDh< Vû5q~g~ctyUT caZ/pigyBvd6.TeLf?~.Ͽ/.ф5Cgu*-G }}Gb|v4G'3 7iR8L49& ˫"a+0P4!dB%1kdVw{ Dʉ6w|u4y P:M0(L[)DgH_ @d qV+ V,k)w&Dh7;c9L=f_|Urg((t+Bb}I}/`fvfʕ˽,jMJg'\ 2=mEٜTB9{i\ <\w g#dQ94soᙶ۟Yflw6jD</yoƙvxP3>/vg:;ooДaA—<\ *tX>?Oqd?Ĭ~,3%N? P, ;UR ;c7.GPǥ]׀ 9}4 f-nzӠ.Ea>(^iE"ˎV;n c:@EƝE |ަnǢ?q'Q wU=&ޙMa]*U9ۖ,QXml1&}cc &{A>HGwpDžgYi%K}ꪧBUw _F?ը|0Y6JɎ8f/@Ae>qpvZkZ2~D4;z6LWȤ%6-/!A.-Y-#'W833tlȆ1M F4=j'-y'^S"KhlP8V=O6a@+5߬-nX[\Oe\[{ӪcbрxmBz2>{wa`03x>ꈥr8Hwp{gVRbB,]>㝏fzm ߕHLP%8m'Ns/h#,=s!̬ͮ04UpKaV!69ȷb>t(oZ/fUo 5njs7X=cE}ϓ{ޞ0 9u`>xA򣻋F*'AiڶX+6#/?{^Dbn\L8SW3T# N5# ɉinbB ="<.zDpN_Kp# > ;*W+KF.P&-p ]@VےyC(>ʤR) [:W*zj"&ee0wͩQ_H~_Q2n36 }N$3#5 s߄I3sDꮵpY'T%$Trc,c^뼳6^d.YcğaE WhA6_y/~!=u +?c#NgalF._v5ϭ}g})S~g]`"xiਫh];6]?Jϔ۸@ VGC]x=`F'c^sg@/^Wg"͊1%Oc).ڭ=l-%i{ +KH5p8ekպȃC.El+:ijZq#q+q[C.ߋ?՞n O-^ɵ"&?"ά"^ٿX'/yk|em|lPWlkL`8$|ˏ;& R䉃C{?gN1dvrI6훜283,պrf 'ox޳v?8VHWOmy쉓۟l6dUs#lH`X ) 890I$$G L!PG6*i¢L|&8p}7nwþ=[ uhl?YDҟ݃Z3Pyײj׿ G~>yto`:?ꖵ[z{fDl)?7uAK7#bXyŶaˊ,fυ>+Rud>TRKi2Md;/nZp$ku@΢Ccѭ8ڱ1PZթ]kd椃i;%#:9]JRc<WgV.gf0,k%T4I!EFTG#F/=}| U=]TDkW¸֥{ 9U.tfD^LxkR$ȫ/^U\<6YVj ֪ N`I0T?/獷j&Ry[w T7|ܲ9ǢfDUV\f,̎ŎG~Ik1GL!ĺ7)8 Wig 7 Cy_D R$Wu8{YE A`WZ̍^ZxGȞ1jjpyT-9 |ds>Q[ēj_,Bg\i"`bPHZpP6&Z]72(1Vj>jGUH1 9>?{1Y=8UDu\\: _ɣcg5ڮójMN5J "=Uv;-" u>y$MJL|ܬl5. c޶q-mr 9}*;YH*ݽ=Տ'-Yنz;zc.'A,0d7alB6o.rn>Ao1񀎋 G\yTnD{~O]vFmXn }jX-+ŗ3hv9_^j7e5WGt~.g.pL֔+5 ߲g@X[LϹը /'j>Sen$^K 2w%b~E.ɶ30x: V^H1!KZ}m*uv_&z[ALe~ U⼷z4Gk\vg kd;wm'r1z/Nd2t斡b|ؒ)(s(B:}ioOΌp:_|'vƙ>c]S˟<؏Ez}s҉Q=TR}dPw֔tx p1$u~U&.hSq0=ˑY;A pˏ+./5T~nלEK*ۄM>KRd^ꏦHHj{[q=nP˧\Y(|bhH0k`Z`Cv-6G ^Id *#W7K+6.?lۋ'ۍS|bH$޲gQΥ9\.|G=RR{Ű]V*HP/bgύoƱwlfzxB\`A fqadL ꝏ?>IR׎4}qlKinٴF}wt'k̉j}mQ+j"*kϙkH=Tժl7o#I2w"/RUW3$ ΒX Ah1p_ȒWn20- [}l J;励OBEExi!/߼ܨ(y%k_Ġ?Ӵp>Ar W:( :z 60]CFvd P-e-blk [ k^?DasB 5R(x~rXW3S7J/뿺td7K{\˖]}8$n"DCo}.09uЊ;Ϋ֓(p 7ХEH j<ǻ-,"OC1ڂN~F Kej`Γ۶[=R[c>ķ"̇6(۩s6G_12?k?~̡6ĴC3<7y-:ƧB#f[ %7w R]kѸ,.DgUm1L운KlIȦL5n_}_${\][}櫙|.u ,$G-оn. Zc.)ȡ+`5.Ί"FuW%!n>e¤VѮgC$V/Nc@WcD?A72N. m-n"LJy8f` [`}׶,)}M[,;QD/n|MK?7OyC؊ٓ`_Ià2SY2OX~!:n/e`x৛>S9O%]bLsw^pZmxsy%D"`u.xR:fd)եA6tF%JX?=fSsx}kg\Ө>0H6\>{Raþ"q+H**(KA޿iܬZ% #VHU\=tP.rz'Y(gv.L_&VtԒcg\3V[꿍nvJjsDk,ώY0LiܶuY0woOH\늂HTܶ%^#F۬Iǖ_ =-䋑k{UO_f!OնZQ'"YVLI9*8ȾU{h~59`sYᒥ$x t,",U;+`` ShT8Amj UưRtqHͽaS";4W슘rH*t'StsdCe])P} r<ސ@1 ,%"ΰ$A=I;=zog,ŸԿ$ܓVa 99R*DkeK]DRvczIۺV5Qp ab$w[DZz {q=@禭|>{I>H,ט3gjq5nכqpQ}{>9 9w34S5gՁk;w'qtmx\CwZX=l"L5V SP# l"CtgcM?X$r:b't<*iu'U@e¡XE6RaB젱K_lj,>?E`C끮W?X- {݅pai"A5Cz{ 8%I$,sKHLcd RRf"2 } ɥg\Z>Y*C[ggIov^9:#X%n$$ޅxl$C~)L7`}tX}6 [l5T|rv߭rn-ߠ\"TG$w.` B)vB GjiP2fL)2JIHfFWr =WQB=,q4ZCc:=bT hQ`'S-CYdj:GgF65Ήy5.;%B4瞕ƂFa Jb@> G1jQT8%03Jr>ҝ$Ih}?H0$#׮x!>` 2wD.o-YKټר3D.^\V8*TGNA%Jy$~c]Bg4ϰyPb‚HRx%)$"fUU!F@gAz2ZzQKJӘR!iD(1:A&A QKQ?W(_%"娴'pt  $~)b,D u,NY7_t:y(PW6ԃ&Ze;ke$ƊAZBT Bc5=Kh2KP @MhNrdH tMFI%Tl^:j8Nk]%|2͎™?bhfenf.> i_d=kϽת3!X"'du)3@%J4W#A L9Fr6^ح$CڒصQ+@M8WItz⪤-,^Ot/gȀ@2 $n ,Yb!'451G{A{83N wܠ/"ccgD#B9tkԆ a,,Fy$_U|i U+XƑBF u!=oIA0$<$kS%,aQEHm- ED@d^9 ;4M[NS6y^'+tJOR@)ABE)2ۭdMQlx'vQiАFdVxw!2CckPIX4 Z-PI*$0<fMVge Nd,ä) IgM2K@'Co4*tHd`Yɉ/ KT$K JŨ:q) b&8e7/5gaaOL =ߜ{ex#$A+eTѲhV^#lf\XWCטs~W6o|llEFP@ ee(-l ETVIUtSwB1d$]f0ØEGHq/pF4aR& գݪ(ǐY@D" 9xcFRT mL V p3R^K2 >v2 D(]5֒ cRovq-uC oZ HDרgՐ%upHvFb SQ{aRnh0 }Y \m.QAN$4^8gi% fs4AJɷdda2 %;@8oT ŃzRP8ha$ 5p c-} Y̛`3T^W 0;@$uхZuJ5:\!$FI@`+yg Bj HQԝuʉ B'j0 RT;" {!Tf";`hWFERH=ߒ1$8 yJQqxeB,Ui` c 1Dl!O8SRAP\k{g'ˆ &l XwШX3k#09 *]Uȝ a ͽ$4s4سĊ9ɮ044cI nv$@Bj ,<6_c!hB\UVp; )ψ$5bYJ:1pUCM`N7(&u]5NE q])DFcRKLry 7'R ! 8h)o㒙U3b!UגYfeqUIGX 69{l=˪*)ԕB/)S`#?3RN?H1kIއ8Q )!@\~M˂r)5h.e>U d,"gFP؆R^pmT*+V#a#HԄ G0P`M16<4_7DD8 <\B])0A1l7bw) {cCPU ky.Rf{MsߌOEIIh.yO">[_QǶU-/hHAlZ!C"6ܹ2bR6m; y:e3|ƛ|[co}5>۳NݺeI1NELEN%=˔ߜB.`l.7ت):Đ0A 렖8f3#dm4 Doy?}mG}m`s}w׷ܺ[7o}8 'TʅGG&IiNaBL\Vmi?9;!iLN*>NLD7rҎge3=';?Ӵ',E -nlJXH;f'LbOaF qE4˜|t^im!:ApJr3#4ܵ9Aޚ3,ӏ_yV9`4$&)< ` I YiMp!*T4}D3h9Kr,%hF K05;9ҬdVdzkҾDZLy#} xP8d\R Z75 U[[X*RTd$k]Zw4= 1^sޅP! | œ R5d  %I,)o*c,3V_D.iTonHrInr,P%UTjSHh ,š8ϭ/!2CG{ĊY5 'PbTFĹ \kB#a #6Xe8i&TE*&ȖጚB*F0)PVJ,پ1M4҈2 J$SQ. P@h7HеVo_қ>60FCx( %L'T"(K7$dđq`dXQ \hW%b! 1T`ȐI Qdxid9LXZq)%VYF!` b_U CH/"H^o2dHj ”-qAE^g$`")4sųUG=*Os:ܓ=21tuw;AX( O`uЛ#0 l<ƍG6xa#H !2DG %E/^}Hw0i:ުР3=8VC:lcBTf!H {E#KQH12GBFOj8'BABL!2!$9ѥIWa.R$dnڦķ<'ze?SjfO6ͳhiwE.a($tͨ`]S@f.u@f<>G|x MO $A QA8nw14$x|9 wf]qaSR8>#)9~7~l+׆M/(c;Qfzζc0@]F!q 5=à0rQczyv} 4@3o;aSǩJ責86sZ@^o .HL8J4u{7[r`j|^x ? )]|m$IYpy$Dx)"Ku!K*rXM: B))4iʵtV$(O@D1b.믥d$lAL d%y$ 2;}Ɋ.w ESFqc ; ԙ2tICaVwOi+m^3=wccj'RF}JULT\1z[C~%Ipd9=NsikV ܻQCX,~W:ʏ=ghLB^ჍO5ni~"e\1tV! )3ݗЗl͟*ۓŢ]E+"n\KZ!RƬIIkDB\VX--PidFAY)r ~L$gcYGMIaZby%$R7Dca-N;г)GJCw&W4zP Y kN(%(aK,Xmy̹_1 Har x// ⰒqDj-I +ZҼN GΙ~@ z6< ȧhE `cL7!QUXh(Rc G̪|GW*۝JWQrr M~rVFȠy'S_ɿĨչx^d\E PߋUjQ-5=VfIW3V1A'%)Qrv0ww Xw6Mbq8FHFKImmlUh{-tGf9vG9R˅mݞ@C :$2MZH7׿?X&173~Q_vTizg#(Y/ی8E3r0WV_Rf2s!\e!$)'X7 G!k2%N?X5,ͻ3R>3>!߁7(b([ӹ_)P-4|0Zñ0ǟc5Hux{pJĀ yY(p"x1I! mzN*٘SSKsingBbMHS6pd4D`-EHi 2 FտHHJ 5<z ) SP+wPKgݠ8F8ubdeA2XG6،ȡ1ܔ.RbNQ Gv6xQ!GD t^\"Lj:x?t:}B6qk,R*/^{ѫRbkkMB.gw=SfTL%zBR֢H!oJ 8ORCR5!}*aY',CPw ͭT7_fu\hYuˉ[/"Ȓ;*q@cC-fQ/r#2Mj&ЈD-L$i ΉecG)mwVxz6'NW{FԘ  77Ws [2B:#~KY"O}pl 8,Rj4L-M但PAR爰Ak3,_u$iS}5_\}WZQ?e(':5&+w9aOH֪%I#(9ʲy48KRI=#?ʐ9NWN56:AaahPHR!ë%,PEitk(Lդn J&ܥ+u 1& Ls M@tM^#:rX CZUNL$o(4CbԨ-|˳1* ps)9 QO)P8CCďҴ9g#4T :" җd]Dwٌ9Nfs` KDbא( MқI ?!%B ס:l0ѺiE:|XaHH(=:wVZPd#7AxI@ڃpwtԏ, t<='h6ȟy6j-|P/K:Vd#]v񅻲'녻NoC?O=:s Rzq򍵮_ܵѻ? VO~xs T)YlIit{}/#C'h21_߂Ӣ꣝x[<V.6:Կ  s0fЯIE}䰂|x}8Q xe }h+/LÍg?χ>sg@hx5֧q6t[t;yܘ^IL?PMgαG>}ݍ ǴOv>{_,L'v۱E֪Z-袱X zi^+L+4+IL(a7NΟQ28 DND~#߲Iw5(~Ƨj1-?!}|D &&lÝ?V{hb[?Zy?ij|;immgSm͏?6VmniϵlikXjr[GK"Ej]mOk[瓠u#m/;[m[@_I! ~ $8%m}&zo`Gֹ]V#?;3C?-޽*;]{ˆsPI8;nI3T`iuwx^ذdەr ΢qS#XmpI VDI F~\t[c]?,%x28MG;ӱ%Y?I*+WgD#LL7O cj ǰ\HI$s1{"V;eav:ҋǩK1sˬJk`8==<F#!9lV]~mxYz壘g|rBpR?r뽔:~*qϑa% [т tb? +齀 JtAђ_.T4?|*\d6 +-NZdaDntlۣZJ۬jDq$~b<I0&xV8쉧ar͚dOXR[]]F5ʚZs}3}G*+Th#GJrwW(!FT\PfןH#SJlHzʼu%NϏ7b A=o.3[A >ëO9^%(ق8  'cbҋ]z(w&2;,]Wv5/}dE uYo.mߑe|׹0rm ù\1 9߹b7rthuw~Ssgc MYL^d:Z (y";N #`)E'gjTHNoTwyESi ٍO{Enѯ=lP\VˀQg2I`o j>q ֧w9('_w9$S4Egj^b"0)t GcHsxrR"fo|juȳThZeto%$Ƽ8 X$C'\Bv?T@?&|Ϣ6<;KhXѻ%,\z4Xw󿍝EzX~{ޔ$Ͻow֟_ pzPGo;w?#~{\n׿[j\oo+nޏ_oO;FZh0Nt8F?`c6~%|uvh" Iz _hοpol=.\}F;v ~F{7n\F;tpn~~ݾ㷟^+~vJ9hw.XUi㇏l燀~ooEk^H^ ?cNXd5Y|^)*q=FS̰w%+X 29nvݰ"<:pl#iꔦёZ׬wMH*-0V!9,I^cug݉.ØtfO,8lHV3$ Q`!w.AЬW˕Ыs_#&qRT8WClOmxPOG+GkfJ݉tdW3BArAY=BV`wƶSMXϷF J ez=H'+ށEѻoX)ZvM¿mʒ &6So.bkTu\:qJ96Ȍvd} n\.2:A鞊qGyhÓ=iKE-bLgebuQj ^m};Vĝ?XmpbS[mضZKKj@F_=mHkl'D$]g6V}b=\YgV4BX+=}ƈ6A󲚧Iyh@ [TlaX*僖E3QKKnU83QNYw4vvU9XɌyFjzoz?۹^Se3#l Ukw}05Fq0 ?KY6P,a~U߁ʺLdWch[?|;غ{y\K}}֥k݅>8 Faã@C߾F\t9&TʑQj57O3 l}8A2sγ;d$ܵ$qOwotV?#kqh۵Zo.  >^Ԩ q7Ṕ m 4V `v{E\lY3%IkoD~M!o=sf7խ ^:DAؘ}ď!H˅08IȘ!)SG7?n2&CWq]ɾ`EGcԱ'rj0ppc@jJ/"F֑zd7H"(dc`qvmcߩmmO^λv3Sp=ܺ^#x>D_ډDx#̄h`)s3LoD)oa.pVU]@< Osl/vŝ J/ڎ-+?, dpƴW/l7xq=\doHgG(aVLE}ymᑣ#{(B>WNVR^Dm=t yMLM7:4 1Xn)||&˭,]7w-J{gXnMHş;sX}?/<!直.35C~|o\HJݮAw ]6eڳjI'giӎX1V# lޤr3@-oQ"!ѵ ?2Ccd5nRܐzEp]yYc'_Ϲ'E-G.`u*O2Ek45gd]Mekz4zW9kߝO;xW}_< +N.ԧluHUۭ='s·ZqBX][۪ —C]ZϘlVDbt-G{&|[\4]Sosboȏ#v pq-d]bzdиk[;o@p UR̬ݞ|(]Cq݊iEY3`=[Xݹ&4E&ޅd-CM0Xhv9[lcgS]+Zw"vց uY 3=.- !gH-1JWd`Lֽ9=?;ZFTS$0|Oy'iZx58źk19k=Hg[*G-P05q9ܜ=0b(lvu+ƾ-iw}-Pt,X5v;} (j*8L1zzo7,Fo$69q'dd͂Cΐ&94#)jf-(ڀ_="vv;=42^vͩW/䧛>p >rTNrj]c2iD/0^lYRSt덶nGL\Sش)7]{@rbMWX}ּ6t)O9CwK% t$vȖ#UBC+VN^;dn_0 XS*΁3OvsNrH8@cXs< ⿡o0 gYU =w%vtkp6LDfrSu^. WnF%::k͍cvM! tf҈6f^Y*+O/Idwt`Y~mqt"qd=zΓOzu9slX/$w2T3]a4#uzp wA( ųvtt6a̞osf{}<{&\57pw=viG|֯jwצs2]B0>51SZ`PHqzs9BINrk/NyS72WZU_5lV:91 4 hOy:Z$-Ggf\ jCWuG]y!燒:Y X߳ݕ?;Ї=]b;M?Ll͖gJ&ShX\]`dR p!bY`p >53;n:F ɠjLf"m`=0JZ`-[/O:lx0ܳ!6k1&Q`:}ҩOon/MTwςnobu?:>9G4tSxjRT(EQe]7͸ɓZy6e1:=ս퍅^y}:ʯP(|+7UZ 7L"挃JTt89K"v/hDŽ&=3S ܵ{jpa7|) R,`$3}378 9V*˖P(^5T@ڻ*VF\f ý/< y{YfN;T6)ЅZb9D0s`d+D2ޘJ8J %3@ 2ST+[> '|z;M;b$ .@qi̼K:䈙=5Ț*1W2iZS02gwԑgZV>;Ch_ 4_sr+C׀rɖ2nKZh Z֬!ʼnIƵb;R@tpxZ]qo(+XF+&o_x؝WN׋WJLNZq G;IsE ɞ 6zF|fv#]Ȱì䩙MNs:>5YSomןlގ}$i\N=۔C_=V=?p] f`Cr#@;#Ў)Ei߀ǓōJH\%χ{#&*\X7I5-YPM-#]޽ߓ d9杵]/G™"cZyP;gxkȏ֖$r]­A2=.cr]׫. .`ε3+(,i[>c<8[ÈkBgrrkvr~]J ]GW}}Yd^u4=:KDG6 *t[']ƐnP/|k쥕~g Օ+"^M_iK lGKm{"T9ǚU2.0ZoO gpKgP6^t:8D(C{淋 djsL9Y]ow468/HވtǷ=DFGy|YOR^ꅩSQ6yp5:M뉋dM}#m#1 GX wĪ<t`>Qbث1ΰn jP'g% [J?RT5͘ԅR,d3P m}t|w;CyDzoPh/1O3سڭ"ZlW''C|?(](N<]c9Mq*svnO @go{ЭG?X_> ^s.|8} ɥPGn8{}p" %϶>c} ]hQE#^,%^ORR[-bu>s.o{~'@TʡD5]LqΙPz=y^9GuӜt1)! xf v*>ͅ[OV_[ ރ1pbL4yG^%Q"0mvkvW/tx@:^0h/Zqr~{栢ZUKs/5-O?@lRSn /~ .]6+`;$6o$wNg~_w=P}[&} c}t_?/ZO;m]2IC.I\&kժ1]~Yyݮڃ,]6.wJ9=owhǨ* 8=JXYĤ_p4Flݔs_+ԑrZo.6ΪۄKͪAjY,2\np۽w\SM^b9/=Lʋ'hQㄊ+W'TÙ:B #Z/8V 2ܭJ;g=oԯ[H'׻kw.ȤO0*S>AKTM}rfOqf@A.ԯcI]B 8U_ Pr}^OgVR}m,yA tG E+~=ۡ ;{Ad'!;͙ڶCZ zUʚ.dܠbyֽh=?Ni`hYjC! ڴsF&STY_ZЕ?p#aq<;/sȱ; pZf: ,d⿁ߢy; #6U]Ԏc;Øhx'wk+BMI=V 2QϽ¥WϳRtd݁(ے?@Y;1Iq:3 <"xV8sMwb֊"0^We2SC鏧۷3bY iy;y<`U,\,OvU]yiD0wt&],Etub*~>bQ.Ěeg/ɗ=vMq9!]AfEu0h:d4gs3&β!(. R4Iް;2П:Uo6],\"APen{KgYK2~U/4l\|O]sm\;˕=yeoxSfI:]6d}k5iwYے/Dv8qƽ ssAł =H.U%w 24s.ME L WCȺN_F=Fo}ζ\WYt_e{@%c)ruV0ҟUQ_w}Vt=r1!N:<~UKdapSGGKQHuPR$/d6 ?hu,>(v3+31cDҡ ~I hi;Xhv>oڥQôJX!I[y/hO۝C:fiKߩS?MO9;Ӌ_l[l3/QIus:gjw :\uQSt yƇ׆eJrԌ Be&7[#2q 8L f\'u nD%v%qm݅x %\Z=ƭ8ozU ujKeRhܚU;gz@׶7rkIj#\ #YN'A"$a `Gmd-+^Jۍ/F iI`iM!DR4&l٨ӄ,I}`O:w_λd{[KoVGJ_;enG2TGOCl!؇F1uOp>t[}6?zTC쩥. T̺>Ǥn}J:}m6E?\:|9-Vk1\8LPΤf<넭]rz_(Aӳ*>4qL m^mGj:vsj(`{ v|`c'_}P!XCKs' ^qNW qL#s#B!Ҟopi|:ҹc-j^fRwֺ?Wsה~i _} mQ]E}73DlvPf"ZrUqn|u'vf30Hd|295rG. #\߆^AuUIi}{VL{]%EpGùڒAD(T/xߠCpHOf.t:'b Q/idӇwނmo_#$x!ۿ>&0 =_L ^^_8CB 4%YI+\rzÎLniً>٫.~ /1,h[H!9'=W~wrRx637b(w3O❅ 6ku?|ҤAnnG#[dUۢ@}Dݱ:U捇b ߀=r "O#%Rk/ j6d-RVϤ# DCgps1kgy0e Q/z~wl"Vߢ {'r0<Nz)3'&yg;B8~.T)ģSR,X :pDw(Z*EbOGKt) X:Mt [l /WNyNJہϬW*Lc3Cv=$/{⽂Z_cf25zj߽l.{Օk;[?X\~`_ NeUG\JԬ7#!2wxݶ|pOIq}9)"Aie7}OLxXfzV_z읯: ng4=FIipw4RھWm0˖EVy8˲s@*&]Xmpq"fy'ء{wsd=,Ȕ;$#8%^Yw` VG3fwXpsR*12yv &A;,8*eӛ^;eZvleRd%NU.Gfm2N,k+l^F߉]x[e@#?Չ}4,[5O^vҠ7M\ߔ}wvYMQm8 c87UC)Nh$v-6W$8R%b{ӹ Q 4f^ݔ s>&u+>)N!ݛDxJ׶RU!QC{8ftJީPG_CA4۶v.ll,G(l=$d4Cl&9ZYit nȃ4* xh=^-HIlLbXf>DJh7[zy5iy Y hH3s^4ɯb/[G(A NsBH:TQSԕ=s牖uʡS'c2${lϖ 7쏏k;%V/)?Tu$'O4/Ot_tLK~`u_$|I?Օ¹pW$Eqlgl :*Hog%T),~ HwvKr䵐BȺ@HZ*qf,$uqo t珝Lǽf(V0fl$m7f;Μ plwvmd8JnWX7r%qJ`3„;3U,jBCrbd?xc%yS~Tt>M g*ލMkۉTvlIҿ 9I57QQDVf~/TYErioĊU e<@+I,ٓ)|Q~IEǥa7~cg!Y(?D5 XgL#IУgЖʳ9Xֹ̲.=`p ?p58udDqGn,̮ѮF }30p[JA^T/qh'v vkKe+åv>>FKžFkj\ @Q5\^7*fh^ʧMbh_,C\}93Dp4cWL͇1Bq' 4ؔU\#1߽wҡFF$Fȯc Y$T K41A]Sg/ fP = jG4i>1WZe%3 쏳FWx8(lԳvn(wɛ:)1`I>%|aF:MI5К1HnX ƻMwI3+wxP.q#l]ӽR._K ]FOkr]nZh}z\ߥ:㼓hǚ[NfpjR\K} "+4PDovhGȍ卆y 'G:sֆ܃=dvz҉߈72J{ΉN-L:Sr#y3Y}D]9 !=mdH['Xa'RFQ)@r$cxq@3DQo\KM;XՕۏmNs>mSkF/g8hTE7VQҵ搝EC"#%GxHE4O Al}ߏ{h@S)[Y#W8(د%yN'K9V:geoвCMtzafc)zgE)lvn?h'gսl-$!-#-d 9:[*Z&)# z=XrhN"l=q+;.ؔ&=xwn{ǢPs+,O#Xqzsm [t G:q@K8?mK9W]+R!_[6QteH͝GÇ#!<vDQ}4P؝ve.S?Z.kvXqhkFN^Pj(Q6&P. VwXM{zЄ4;8T)`dCz I-am:vMNA a0D`49qo+LkGSu+B[G'tzowz][QܟU#':6\iH0&fm^M]\kl\pj8,bl#)mZ J3l ~DZd:xnk.ePoT W*osF $`ݐaDZb]ߛo=F8y'9Ur:b#~豉ҎdE- ܣ֯azNH}QV ިq]5;<([t׫N$h ?=*<աQfqv%L7o볍hE1H,@#ZB,Mʲ8R1Aֶޮ3ΠOހK[RMO⌠+o5 (^Jv6%[ڎ;a){}WtzbF u1N$GBhgo,mQkl{ڞrख़n`ڷضr qk KiRVId-ۗ,şG\]#^WR鄱#;/C7skG E-9CxbaɛH#ENs=T/xҿu7+5#%L!YA z'$J"q16Mi{σ ۙݍgSZX^zȒ.GOH]MSuij9/^HA!cH9Ϩz"T;ҟpug0y|dd-vWi?O.9]3 9KQsCe48ԶX9:IW;æ ~L]kw|E1"_weiwvr{C[=:~Ga_93dx3؄ X:000u7Kh3fw\"UxStrN hbg$Sv^ Ǚ[2VQ%cee݀h+ ,Z}F&N o:X] np6sQT9. =$a@8*M2Yr()>~%DU,lɟhM =<G $NZԝ8=|*4>v!2kH!ס;C=&s'i +;'}/=^N8g ctƆf;.0kN5|dmw&V/a fïGو2/y1)jl5Tdr0+XV|lGraϥL;Gh*w HӜISW1zUzMawcC|ë.V]pE \rWGtK)hj!ږOk-Jl\`yV-5S R =xXK:a8ihg;P28ܞA/It$1jTI!_$ !nlA‹5 2p*FbƇ %0M@q%b÷ b4.bm._,>8pjY}B' \bj2jc2Z 0jg! ͦG`|"jz@HDy}|?G?vi@Qk>t8u?8XWƓ mȇxEΙsg|Eg.KM\R8_;Hde*SD{rb N!ĸdQ\$ yW2+%87':wWkbA\8<{Xµ¿Wr8F|?;;#;dD&"=5FuS>G|$/9_\EtU.mQJ >x0 `Ux;KZKo}k65_lـGgpޮ A6۪GXB3maԐ;er FJb^slq\}5(OG.Ǣt9Edn 9;{0UَhtLmM.3o)ۼBfgہvh\Q% Kdd ೂD]u4i&6S@0]rCJiȍWB83ؤ$tvg aC+S]],E83=<=2}Ln"5[7ŲPp@I,g:XJ#}_&'2.f]Rz|y G҂+z6<͋UTpkRhF 9.rt&_6*-VuSfG"'pkSgZfe9 \sw(Ě%/cpi$^],t3pte_TT3&2n;!L *5mnk{miЎU\|XFin%gi[ +q }qRSq,q2j:{QMLA$:y_>>~LwϭH]m!@mdc|0̂!c6 @8B8 @LHXB$Bb{Uό, ͎4=wT;{~loʹ 蒧d$E9.3ϿT?)KgЭAA_1r&:SdLu^4W1#%|ӌVnl}+HUT+Ip%_p`MJ}|ũ|,ڹK+3jPnW| tQU𺽖[2ż7d )6jp= /#{h.,&?'{ nD$0ZldZH8bJu"$܃S->By6fq`k ^+a ɭ{' v% :%`GuɊ6k&ƪzBkx]WM`Jof[@iw!?0\* p%u4k/`rIl6"Y}Um9-!5aCw؋~. NJm)V*Ŵv0mUC>_K4QU1,c*њ?+a,JR@-.IAs=m&(fvJK M&֚r= mic^vraic:_)/  ?E%y aV2HЀ ʹN֓Y sJ;1=;!z"z7Q똠Z *GvE`2/sT@k Kn>(̞,/*Zb%v Ψ *w/a wT*wdH4m07$4-zfʼMѼZiYb;\cAE+YojhP= |ĨfZHFS \`ƆSbd}aATI"5 aXa}wz\4^w%T:c|q^,7%6\8.]xl> +LEmGEĶ7eh7[iIn5;w}ݩq|#;+A捖1]<`s3(@zdm?,DN>M}_O~#HX-g2OM|U\9T^+$Z?=ܧ ^JirO "n໘,T],0缧䡸zH PGr^ʚkr>`k\t34;xGᘸ81mq,rD ;Hw %6_ 8L̓[%Â<[j;=s8_7[FhhǨB$%bZJlc]D*eC2uCc${{ѽGn0&0W7jHApSvxN[bHmp۸ a<9OPj<ˤ߸|{kX+Z(H[7ud_6<˨FT 7#nD"9*xh$%u!R?U4J鏜T3la љtZZtj͖ ^5% ";1dHh0wKYi6psmڱQHsy̡7#]?A_IV d7Xl\TmbR]><:$ax< ׿*vJO]gŒ5c$<ꡗ|D6H-l)q(N˗f:i-`}'sBWֳIGsNQSlyz:qM`.̎ˎL9};}8 iDC|-rqqh9a0xGbLҎN8xE00|;,ิɺ14 9H~ueT+srf,{-/Sm\A*)4} z b) q᫑+\us`r _HMSQlmVpuȕ2-1T&m?4*=΅\`=rK9N'0̯VF@oWƛ3aњ)ŕsD* ]dj2\ŗj]g &x99{h]*D|mO`# /V{dGx|+H2{;RKlڝvSͥ;-Y?Yu錎hFo-lT~",Q8-DӘ1p$'Tɼęm۩kר%_ج=u$ _]`8T2onH3LɿeuS3ap: R1 3LN$ p6EFAp#)z}ȣ{{~]ʖ0ٔz &n\|9[go̊*UVG|[ԧS@cUFE8J̨( CEu/uQF$Z7!1D0}H.#?mr e ΍2(7gB/Si,4 rzAwL惻KyP%L[Ɡ5`ynDIqLψMÖіF\xa4mXฦ~S$PH -ҢJ~tb#.CKW9o"0nT,xʖ6slTףӞp$xڨ\,Sv6sSW<2!'pOD9)(h(YhH7^Ǐlqy++s2`)/wr7b#dZ.:m!RfC{N_OX+8++F FX!J" 91w8أj$$$tSAXzs72Ǘ}.2^گ|JK_T\-A9K4UCX+c ,8k= Tl2N(VqD)9M_z}r-9;|'_kް҇XEil*^ЅMTUG/K[>4{$Sf"1o$ZXL ~!G#{>)dx"ƴٷ<:FA9ݤM\A')F՚zKMSy^ ~td 6(hY }j[voլ̈,Rg?3k 4e !ɾ}nTuӼ+'גZ`i O7ZULVdY55jvY0^D"'DۢQ XE oNVa>06mxx-{m-;0QzpW͞,J peftSX%ϛЇd?BQ ;< Q6~j[!G~~D1xt;\7]>)1clG+met 3Fi킲U aN^Vj1rYA/=a "[/I9 ,ڵ k^*)RKsy~eoul)qװz7Te0 mưt-( a.(,/R*WmUЙ5-fAwՍB€yeFQ<؆/fG:erYSayb3p@e;{ Hlwg03EVI*D/owڻ SWRH{'R9}p+ lqž Ki #i NŶZ7=lCic|*ցM~ aþxLS!o=!aHwLb1Y#TO>t/5\)n|t  ?ƻR%4DLވK+KIY$v䘤(7:7v!M*?K?, &j~:MSdNXmv똧f gH/;(Lݖ_v‘0 6.ɃWN+#~^JN0?Ao= kkt+kЌÕ(vj*E}m5՜z)I3O߇k]Oܤ+̌0`xkFoSv7M9A6,@$$_iN7^;ӉwACܿVk_VqfwHpjm0kܞ Hj b#,U3CAx _zdd dԁ_s5쭍ّ=o3a}_Q_p}55\.kk-Ǜ'/4 '1!9k> RCd=r> *! y俖L㞯.9yNK3rNq;ׂ/X h s&lKio:0Fa_mQ&eOpT?wȒ63r"QWM2Dw>DuX#jǻ)$+0WQ*GfnbV]Jxi,7V\LYyզQ~l(p`b!:ſE죁A_߬:e[ I@qA%;GCⓃٺfla, #hłOPWFg HD3N q;:{S2[o2/u#cvtR`Jm@+sEn  HviK<U< ]:?iCEBEo|u,ќ4Ky9r}}qwa<"^?P-On- dտ\amyf X qQ; s#7b"050qQop.|{`UIiFs6E.NǸEW0ֻ/:]̐_N%o]C?/EtZh.SqNy8O5ʐC$} 82; L4g"N#zhaȇ9L, @^"'g %ñJQ&ҽ_U)wRYGW C*>,ZtDo-ĝ3oE6 NVA5ꂵ˕ xܛ:nvMţ< ?Z㫯giZ) I79ֺ@@73f䐇UYGqQ6׎z/0֛QU{G+OG<+Kgrgәc.D}E1ip$[Hg|TʅVck?,oj@Hbm 1Ffc(el#L#U"exiZwPN KTy3˃'cCXiAr w AW񚞇= (4DeE~/J(r$ծ;I6EUrl]0|Bs')}֜2%fnwP9(N+7no1vEXKs9_3q;ݠ斅~ ӸC9N|n;YmUPŁw~ < u>ɆC_#sn1 hKWXɾظ0a=:6Ko8|_~:w*I5Q@BuyC6`DcFG#[zJep2x*s $O'LZ0K$09~4{<kat76ϵu&@WKL$2dj;fەf.=ækB`rאgv"úݽJ * ;Ea!h,<,[p5nD;8[R<1њ=D6v`ԘƦ^>zEP{&:gr4[ ͠v3_˫-ځnWtx WSE`LeDhKe$ zg%$.NN(:DU]rHJs5(>W3fJ7YՔY%g9x +|MTDMF$pfLQNDWtXfy7jsIi' -^Δ.UL>U?KyCcH$.wx֏JfŊ+r 0Yc9kƲxmI%AXψҝc4B+V1Ls8E$'tr;Uy%sJD)תDH$J)G(E Y W:f=v_|:-/Ҧ=)RzUJ@=ӫ]""[pY!U k ]1^7ݑ[15>W;_$$;\fNumK@4u5$?Ӛ髛=%5n<&ӳ)S~WrɋyO'~>i?N+zFCW} cal{c ({b(w}J)y/Q2? KRMYkRQ/9$AiVL"1KeQ׭VDAbeYP1U[Xqk d82=93Z|bwxt# Yu38,|چԫPא H<=wqŔz~tDBGRz-Kll'*Q(,Np]{p@ㆃxĴ ޡM|(C/4]1 u[D7<-kԯSKhWׂk|7ؑ륒|Qǀ[N91xL%vau`M@i Ko:RH0I+.ۜM|=p t.k$`\S+ҾG^^ %5 9rYYf_8oI(i6݌V"f?c<ҬK 7 v2:'HL@GF,TDh$i:#F˥Z糖L^reRq{wiCkN{u s[l9D/]B>FΌzё8>9d?ՏG2< p }4Mؤ.}} |C-Rt7F[aٴnUE:9CK$`:ȮpjLî M-R&ȥV7/)ub]Kde/BYaf;vd qy]; Ak|cTx$ΉqH+A202*p)D3b$Sak3foOSF4AAqΗ6Gol3t;4 ֘Q&aItF3 C, +yEܩdD%DqgYQ8qN@etR+ HxSW jlbCUոT2XEU¶t(=HL+ֺ^Vm; mK/8)Abi9|!dݙTĬ«#Cܖnˤ#*XG+^-gɞ`o#-ȗnD:YZUb[u$ E&_iꈲ4佘 nx $"߆D&e$4ȐlDltQ&dUBH$\D" tTG+2 =J 98 e(D3ʀ>9d$iElQga23LJɚxI){"s㯴J{!{~M{ʧ^a25pJoM ]#L "̞J&dF 4WzA>IO9IX]dV:-KN7]ȁ"패nf4Еgs9/737aJ׊3ndtA\ysAFhd>bI/2[LhIh@͓C\uU4rɷFĸˊ#r&HSn)r^cDafK|@1s6fRG]'Z dbtdxټeAeR9|N^Kyu 񪉵IF{<.`'PC4ysI *<'e[B:hR/xdGVaah`$cQaNlN@4!O,Ni? Xƀz3o3K5Ndgl3Zx` >0!kXghuFdV 3;KY/pTfR /rS(Y75mbϭP?E^DgZU#;s4㿧49%^*f@4`\NҬZM0b9K+ԓďiiarFL0>dڼ샌AGdyNe#EE&$ms,s>")H&S# #7XYG1uHU^3X'|ʁΦz4QvTuŀָ|.̒ fGpC#ntVY; B6*WIP.TlcR?0W||\_ .wE'ult2[5秉MeP ws:*Hql -f@8J&"N=nV}2 g%ah6YAp&*>ŨOg _P +>suVt?pT̯鼛E)amNǿ `'|,}zxLqG_>EFwn |h4֙X[8^ĠI,|†f^ol fCཟIlGpN?d9Lg B C\E4-f^ {s@rI9*9x0řj(pjrƈqLy%ʺ10ŗ>drؘf4\MF0w=Q 1!nEv(roz!&s K5vHE B\xUi7SU]O+Õle-Ofux8wNq Atܶ ӛG+#[&lu'pkہkB#2+V"Wit2sમ%4f'\*fuSj$#GD  N'sȇuu5b ~i?s\z FzI0Bps1h_4229 }e K2/#o36^|TbLă|E.u42bl"quJ$'5:W xw }]4s͎._ ~cVyl#UbfVUƿ_mXEMiH@dیI^YYJr i0[J)^SL}|hE[+7@qDQfp5Wb!`4F8L"`U92s|H Nr"ϡfh3ۥ <+B5 a .ap*+ttR>L *YS7oȖ$-u*"rȈ˗p™,2,Tְ/- 8x >^WZk Qk)A77wzHmğ~%RP;q$q7Mto/AN^cq8~!8_!LE/?$cQF(k@'B6z_ï9/x|H*CA(TS_tL).oǑ.Ļi`X+GUPq!]Q`CFAeNCBh'^ډHbouwi}7ݷ[L׺uc~ڱ<^3Fwxziz̙Wz|3+n턟Q~E9p!Ҿ * x7Uqz؁tkй}z¦y4ϔZ5=Wt^T5 R"0O& uKZټ0zQ'VLK 33%ͽFLϧEo=pe2R/=|䪗Wl{)Fο/ :gc8?2GUwl+̃WүFzɓd뿁WSORw?ͧG(!q;>u lzXI6JDIl oПUIl,|rcY,V*Ab޲0WmBnyb0O֛kcۙwrUz=gc;vjB.Fc(9g Eq8Vɚ&HI󘈵iV"m4H͟tvt,oj _rIZj$|*YL-Қlqwee/wlE\[{NJt ϣR#{}'tyks> Z*Y4ҕW6p|m_P#r,ШO|s#U}<SO#7as qj>wKo~;O< n* Ykdkd́qX^k^UqUy{U=~C_?t/t[ݧpu..90~X0&na&3M7vTͱX$~|k1z{t뼇?<^,~[ytrrfhKm #)j`al2ffW#@Ջ"ȱ`Ʊ JՏH`\=M -Eoo@~.z۲v.p0gsl;rraBCXWEZIUf>f怍7*l1?F% 'Aj.fDH3ɒlYJ; xL^NzH #tw'b#.^]g':l >F+ 5Rzx#|pD*9nZwb#H"z6͔T*3veTJ r:-mp۪ Bv*E͙ pRn_zXguKT!Gx neʈ|Qhuʩc;?ĩ+K-W k35kz[2xC %4:KCMIfZ}7]/њ  $VbWuޓN9P.^I=z@wnB~k<)^(av"v,?o>Ȭ~d-Zz P8n6a{ĞuMo]YW cX*^aW7mp-{gp 4hyKH \T_>~ŁZTnZ$ieG;ᶷdz1tp􅍕"ܺR+Lө<πOLPz岧0j߁əxgkFoxSƨycԤ|CpF~N^M ]Yy~D0g^'y_>7vԩmɕ*m+?3~߀H}#gɼG8/,]2͵ʕJZ >,b4ul䗏x^>T>=l=gɳeRT!U$q]]߁ٞ!/ }wus=wD^"Y841$7`S_KZ,5ȩTSwHʎƇŎP,םg !Kk 4d#QL2OcfiNjKvMp-3ApA xl }L2웢#> B u{F`\ܞj?*R;H?dDt'{aP_Fy{j 颱Dcj61w_>:p>%Δk3Hڪ xjˉ!FFZIԾg (ǧ'Ǟi{B专wv6ަ9#ˑ¡ / YAP+ 0 a{U3s~wtOw=zIUUأ6K:'k с}ߎ[_.5dE7ChɶlN3?Y"b6O'kfBuo9Z=6[{S|2n{T(WBۺr)5x6u8&l C¤rJH;T1Nc:;|hsQAs`t,U R[$xN*^%K=g`Xm騕Qñuoԧ:VdD5O.s# >Aӧ;k1`_2sTNhPJm<)+bnoq,jT'@m1W]O~hШ xGը:Z&N$ uTfǸ:0$##j)ċDC<3 I&銺~R4c z1N#|l*<rYP&a8cjp\0)+g#F"U,[ 0H,mDW,=QqcW#\#YcsY5ӄM1iQv BAlqVꥲR*˲REHz-FCݰnZA[kq%98'TŁDw&`$th{t(G5,1~ 2c@"\Xt4.xx\ 2=U;(`0yQ_NDu KS5;xcpZ]֎FeȎ@y Ep\FFmf$wddb$6S~Cf!(]:24] ԔǠۜcxk۰,{q>oQ쟉5!H:ml`Qf&ƼuuZvԶTw}v t겔a9]"=0XC~hC% 5K|1]VC4|V<~, |_٭k]tOA9GyXCq=ބ>r8/S&z->;3{EO{w=;)?=ݥ:%gfE9/fWe!.@KYl: Ch[-mSd_ExR&Nݟcw U8c}[w9OT]E}0mLc# W!mEkɍ!F: Ny1]&*=pCt֗G~O9"{B=P۫kEh$z}8":t7c"!_zlINe牃e%#p~M|y! ŋ9)#bH8pgV'Yl} T<0)u//SӈރQC!D+&o 4(֚"T|r X^~YU?t nx#q00ځXR3w\wLJo SN+d8Fk>Q) -yϏei0*v=,\e,TGUg"{Í-e:cRG*c,z _d{('8.[_cd%k.-94^<[!/r䛖zB&iԯbs̀};&Z%ڥxu6>m?A}+f}n7Z xp`dN %8 9p22V٨;{]=۱}vuHk48 GKu-z;J,RdeX:pϿ4W" mb#Kv\Çӵ$/֘TWsxS:lAu_?e<gS+a xe2„N=2w҅ rWb\eQdm5H{'-q˸K.OUIv@8nMZ|NGP*jכ7mMU(hp:a<wں,Di0 G/P.8 kX^~>aZT$L}VjSSq8&f {<9aӛIA諭82k4x(z/X6dkⶸN)-SLj4P>5kyԺLscݱX1.T߆pˇRB;irV4rǠ<{Z[# Dצ")eEn'Z`lC!*YIhik"dI0ʜHC媤,VaNZK5J8ʶmEs^#⻂i"[Kb(s%`RtW,l.xtdc`/%&|:LSQMKZ)å;ѯ+|,iDqa|Xgr,1U:67jzN*hPes;$i!\+utड़eGqZYVJ4\G6,LƤy#tΙtKmKЕu EzE]֝Cge s}]Fg,|uxRczy-{>Sݐ(f2Lv`nQMY?b4vb6lgzvށ|ZAζ#2.7ֈ4hY>b5^LZP4o WcS=Zfzn qf4 z#~cninbk?Hk[35LвpgkD_禆YP6PZ`YΓ O㱺 ܄O #fMRXgz f8Qno9zE;|4Fv8cpN k{zug} OY=:8mx>~=an}ȼ<[r!`+8@q^w + .q˛n]M{>g[OsO.WUت |ހ2PO6B!-.&|*(Đxʮ̌I}Ko\ed[S@4K7be^)9ѽY^uF!,^_=^ܽ{8RN .-<q9{׹w52{磈MxenOnx,12D>c]M3_9bpN뀢S?p-:MFb"u~:n1ڏ^P&#n4;Qw#Q4#*pyJGxM/SQP Yk#@+~*P+l8/ Tsc^VΡbΛLh8eib-,-ɽMYQ`up2 .f#av(`U8OdG̟9/Ϲ˺r] 6JV1em'J JUB] ]> {\cv&Өݨզ0K@qښZfV 71MB"J+5Mke"a=f>N 2Ha%l Cy&K`)'-ʧx<$F\`7Û.FV(b$bqx2X|Lm3Ay*ve6@aMFvA | Р`e tRh2(ymPGL)ekRf:P ߋ.DN aB'܀aCy͚XG~ӱ>+(<I2xgM\Lx4۔^>Y8b-Pxq4OHN`{q%Fh^(l,{zi x^伞 ybGg߻\ yY u ZYx.Eut|&^G(ξ ~L\%~?sD+ώ`.wfP͵ۜ_л rODo]rpNE%]spEyXt3i︉]vu u5BY$~ =B^Ȫ.[MmswH,ydc[{wZohOl{|Ə#x{xS> A(ڿ/2>kyczFn纞}+C LjmFP=5VIDIqV%">YXEȂ A bd\KEגr/([My' 0 h"#.KikE]'kNQ<߿PIo!x ? Wxs=_kmϿ_lhQëc֟ڇƩWjT N>j4hfyug;OX]vLꓓ'M۳;F}%aplF4m-HhV> {WihA( xj l7L ~\2T_nOv U7Lá6@>kVD؆Ut"!"* _(u;A*b@vCҰjC~BM{ ܻH*̚bq(15&/$#²' q!~(B>|D-If¼{y g-aYDCUj _##+iPFOIaRixXZ KWE;Jpn >-"O>B%kx6H'J0I'v;/;v+u?tekQk %8kw,x.M'St}&=R4OLUM}5nuds%8KZ,Xa h/E,g ͣzg4J,a-[xf0&@W΍$.x6@$ \vx 7ʻ` 8EWp Nfq—p ~i@CXܩgd~Af4;KgQ,OsJ|1fJ,<Տv{? aOQ?OտlMhtZ7a[4ktεo;C?y=?\&WL ~һ-8WD$>`HVa? nN$R#BHx(I"ȖTAM`_;qK ,Q2tBʜJP˕8qm֑Ke Kߌ%zz$}||%yޔ!"3.-4E æ+nT!-VkPZ8R/>㳁Ųă=ɋWB 6 eS$jF?_#yHب4wJN,gpwg0I'9g!Y:Fk7J 4Iv/6wܢ~uH YPj-)fQFtWy;B{ gׁ?ˢO}1`@QedWEm ێ5sLm|F]A {NJou"ebn>#/ѥJpy?C^WW 4"L3b-q,&8yșd̿3z T`>aPVB(A\h0>jɷhh @-c8w kh?Xqg%=V;pz$7PQ~_l>9ڏ&A,UZQg6ԯJ,)ދRT0hCF%b/ l} QM |hO 6zGgt3;b\D{Aބm\klolz|@l 9qlJ2abuz9""br׉cR:;/?l0P ȹZ/ 2!>'}SV +e&:6$ר}v~GcH^xROX_35z^QCcX-Q]@J[-}E?WC\G뫥ě9n40J PP }@wxz1"?\̰s'3V9$ʃX><>pSk{n9^=dXiSTSaiԚ:zx."UR2"\WؾPMrF}R[%|LW}< HBQ֗ԃ2df&x[(X +BU0ogAJrA=U0^qre#Ԝ7h#lRxhjXpSBdzclgFDq~Jh'㶜*q5Ԡhn1%to?5$X!%V{7wypb#@D V:$|^K;& [Nf(\9syqb{k.7*Hun @LdW~"ޗg? 1oS?LpT>(O+SH2mn¾psG6m˴] f3ܴXBL3}vLMpl Pߜz2; uENYӟAiHݓ'! A3,P|B(ym]Ri[ wUvZvĺw;:9@[I5uq*JT'PzN]rnaslȋwK%} 0Rk}JWGw,V &}&xm}{iNj[Ɯ]P3{ළTB,{ #xR ,@<#E/=guOłon3?l8z-m!-l9sZi NfG0̈́UJNc3h^"vBV\/@TǗָvfebL)wFC;dad9)̳Q&nćVHD$"O-C~X󗊭yƍp%6zJa4ǃ2BS,a!xn}!>5gHRRҚuϓ`U7; ~2|96ܻ1'dX8u>k±N: : [amLeOP,ll$ 688)=0XHFJk?ж.ڶ׮. q}E>v>6:) [uavA1{Du/σEa`gHX8-l:>y)wK,dbx^̦1?MѓcoXJmXq؁-!VAacAWs^^6:q]}achmS'_G9Y򎩞{l]t.=ُ&߆`&aq~}H,Klex~Wv.BϜxnvOO7--@ vi~P-oIoXyU lBIi}!_v2RMIc Ǟ>gi7>[Rf NH=>tA . ;mj%`篬/}^ v|{ i^:*x% ќ@Q5"2JB}WbGޡq6V>38-^#B'k3P^`gѕγV>u|nCpcG0p-Rn=Ӛ6<1ץwSsnV <WJ^@4KPsՋ=-3(snF ,C e)~<!j-S2En x KLAyz6/W{~w%{&OuĔ_X|5E1um1.q$::GxwavXސ1Wy}o_?[i^OpWܶۆF:Ȓ-}#5m'R3Jׅ|ĩFbBRm߳>3ʞ;Gr_d;MZA@?2=BcvӖ@RsQNhr+i(i bۣ^rU}[Ͻt*H_xʕ9o Ui,֕?^н{i_cٛ0A:gx!LmցQȟjg > `X4c\ʙ0H,y\OlpFן9igrEro' emۥ5=cE a3pέqPn<m7qKxڜJr YXPj/[G,Mdz2[y+,hY--\<]Xqr$&ᴌnꌌN'7fto͚>-΍Q-َ8=&!ٙ鷨(Wۦcq7WY'! >'fc;3͹9&iDh!ΖҴt, ș3XnD;z+8f7=R^0A,и3XTF͉{6oy"b\pt&oԯv3M&!NA8M/?P˼+(:^>_,A3%#[ u$.ՍξC^ h:099wߧ+~50.O9dwbO@>6xF" K2S# d1ǃ hfpb]zMUsМ@[㡀,KZsc&U۽no"?bj]xdոE!~ɧT5B;Z^vN`v{i/SuM9Ls NAu$T7i{ϔNHCpn Ge8suN(d0*p$)c&3 6o hqxlxML2-ip\ y&ߩթ\VUxizOu頒AXײ~)(,<%>kDl E#z.j .tTW]?䰑=&`Xcc !rFp*ɯ(Ov\Wi"n1N, 8Z+K6M.MC@-OX8m8\tDjdІp,]Z-Nzֲ-[#n=\:uȭؿ7$8yn l+- N0َtt IeWwL=pb[]shZ/.=塜bְr~@ ] $Qin3'05,YngK%^Q.:]'4 l&4Tg7ZO}RzOeBpEYDԏv!Ov_RtӜ%TKIu,<e[n8pIVd1 Bo˱;7~c)Ǡ5CBxR+J*9 0r>X!(EʆB(B/%p)u)H;S1`wYw(0Rie;>C+eMiHK ":XLV+kwYk$V91[^*Y)5|V {X/e Y kEy(/O;n`|ގSr6^j}:{(q} iP%QF !Rmv%whzmp|/*6X_ f#?ص >\0&W 2XX r'̟!ΪjJ!rgхËGBD$@*r7G|E6z7~on:s . \yߪZ{-"Q1 +?>}s%wf_s˿d>aQYTW|.s5S qp>rh.#dC8Ar B|cL$![d'ș{}INPPo'Q2!֑=7T^}{Q QM.p C;mfd͕%΀s̀@W]RJ}c(DL$Aoces: o)M=REP, !Ͽcb\DM |Tns 'o8|O=J s/ihgdFiEmɇX&AD,SIwh4w`SC [m(hFhLtQ Wn$ǝ(R?.w^qY| g3tϾp^΋yNAlD9n̐zp!roOL`j'ʰst(GTRѐɮ,] %՜P`5sCH(O^m|\E2 `wkʎη- '_?B1lt)v9na"Αxq 8[H@~YxEj,.?_=]ȉN-h|) 7-jĥA7z-PQጥlOm1'e@5&iE<1tjwlhY6[rVGuJ1J aǜty8Rb_*ԗR.o4 u%,WkX)e i||+e1q>^lDꩡIJSLJ5$93ׂ]9ؙ.jTzE{txMͽO4m ~#`C.:E*K UX3hfPj1#鰳FLzN-0mjƣ},<1?IA9#&$D&?qh6% q$L/CN0 NE.grGFMJaQN ID &Q ~#ٌuOic<5m:;CsBe)=V6r@E[1AjLT:E|CoƥaΫ ^!2Dl_@)}< ^9p. $AV*ȳT`&ˆŸ30Wh,?;<{GeNWtLtG{F꓇w˱O']"ޟ|xl m9 fe&]9Ʒ1r+:2` _7u^s;fuE}OP* ̋qS!pH2}!򿸔MW#b&y/)D1QˇNA1W\Ƽ0@xwf;wv͙T(=Lr4*l|{x+&sﭛ$/ɲ`wXJݣ;zDUwD͠ƈg]×\ +!Q-N žn#eWV~}w)8,[)N\_w 1:ۨޥK&+뜒?_@ >݄Ng*b92Q鄙O=g[F `fUz~ wXc݂)Uܹr]B/I-vmV H:+(Ý^<̜szvpyJHDC1)uzCy|0w>2BEifweP@F :kA%"wSIQآxo,;fsi޲b??`! eF/o;rtQ 8@0s> p.S<(&Kr.3:SY ]&!o:%b2!EuE䲯Cx"MO`14[,}BVİ24-Ew]QD߆@a݂T]\RlÝ<2ͷqR@Ly4rj۽q4,(gİK=F'd9%$`u?QFBcǓv@wgHCU9.-Gz\Ll(1w:b@Y W/rzg L'/G{݁c+$֛p\@ņWkm 9J}"𚯜`h3ɸb.ssJBD{}nB JKFL3sb|4=}S0Ň OE1U?8=~u]A/mXy+}rjL_Z| l0  ܺ?3X;)lOMQl^#@>p75^\H'}F-fi^8;:w"2vaVt?(R|z_WHn{|#ʆ٦tRc;);9Q ;xȯG78tfVJ?saGEi*dg")ޒJ2Eտw.@BIH jngrs%P&ŸIfgEU~9}~v6eB|#9Ֆ'Rkf "Ֆ0:> ^s "$ť11b] 礿2} zOUssX&gô9 N>nY-Ap50ng66*.B/J2GA$c^.`|}eg,Ԭg^Yᙰha=*ν[OsnN'df2齇RHH'* *((*6_ue*}{'npvwޏ|^x[$ZȔw'߃BYIU?7<5]pתvZ>Q ^>7Ls_j}ќ|ҫMԦΰ=Vt`򾱎ilʡsƱgXN7/E)*-!(0bMybJEkM\m3܅`iN-ńL-ln;Н/"1m\OɁn )uk?M)[أx-ޮ`F ˿|fC&w~R0^u,YC_YNu'fOy:~8ϡd n^#2ܲRD(UϹ~C3(y=z }}Q5zXMa=} g-AQ0XǿYĵ {wH+iGGܨv}E빌Ea/PHKڍC*[=νT+gNTG]H4;zPė,>\UO,/~V#oG [țӹ!{.ņIbC˩V:sb ck@`_Xba",Oqʅ򎉻.f`6{E#S:5|YY:\Qi\ġaH~rYEҮH/HBШ[}{SF~ꯠ te ;|!/YJ4% wFLKEEH:~:)#[PFenc7O -&Jr3p%R}$XU6]:6PhPߥԲxuQuG{QEpm:yt[%q2vr{N0xLrEgrOR'Yq}l 3t6'TY\u \rԄ־l]jۂ'.-8?\- ,ΡSwj VO 00[A綔?ܵL6ZIDsB~|N mfe"&؅zsXEvq]۫ٸӞSi-w|M}-~^ԙ=ivlyw>v]Mi% Ά[X,XS#SU%^)n*B ;7$~D3$r!2kg5*4r=Wv[.Dw- 9`/|ԕGij'YP+Q*Bov7E==vŝ/d\];BFMckð֩t4q-Va%vߟ۔ugz_Ǿ\o07l;r։ cE]NܥB*{jse|:s:|~^H7}k\D t|?^.llJ3kmG\V0JM|1Su]^S:Nij-u^[95ԷgMRȧV|~#=}aGZ)%cnxxшپ4쩰9h((ӣ+ W(H$=4+Y+*xt{S)KևhMm{Tv۬vN׾%L&{+aOdKYу/^z:27ܿkt59N\q)+13ٟٺ̱l7Ɔt@Wߐ !­xХ;X3`-t!k&$\RNJ6D{nwlvܠe:i2fxUi V|ySuϞآVMo?q'6үbRZ&=G8Glzm/F(b4^~tN(i%2u~'PNɾs|??Mt|fLM1WSuV;\^Wgڷ=s Άk2l롏# om83)CWٶB IwR?'su.my/u9H ;n)9cE~!5k;ZmP R5oeZ)|W<:U. Nyr)g7ꃈ+YX"vnS!.PܦDR.b NMTO9d߮vZSROܵp-$ù[*]lwQr¿!{k4$o|5{vӑM=ZW#gw$[PKwR#M\N3ѻU$5ue`Kٽ:c&'ݐqP7_XZu1Ww|Z3,40o)^zϬ YB_eee;?I0$F6CsG4 _n* -6!zޡ3f"͝ZX<.nw9;Oh)dvq$?+, y`j<53f SauV*7>k>iT;jQ{8={}C!P_5mx 6e/lj %E]%*75гV)6Sej_9GN}c2m+JQ8R^{D,+ U8u6jeo OD茰ZgqbjEDzFi]pw E tJ~Lxck]Tb&]ԚְOEXwL5-o}kN5iN6F>恲MG~_1i;!Yw^|ԶU.t)mBEtTOӆm_<b8pɰF1Hl' 05{ٴ9UV.Uo=׫VXVIDvN11o .I,pGh>P֥.eRB`*,`mzq6q1TBU?@h^'4JCZ V࿌w.=!.뭴\4mԴ1-*'Is+O# fZt%w-:s";'AŐkBGc{ ]zhDb݃? 63L b{ 춺U:<2v+99SޚU. ;:[-aw6xkQuypYA551[59;@cꙁ/)IomWa~[!9Y [;j ',iN\khN;!76ȵ  #$ ;̾\9o {:ݏtxJ:R< h6^c8K)tUoH\*(n!vt\eZ̟BWO#$M!7ګftNT“^jTwdUrOdPU^ڠ3 e4M yꁷ ~G=^Wٲ,GqDIRD9aI4IwL)<"oi?{{ɯ1w!P:E͊m_U?dojrjUiј >ֵ3[WҘ*quFI`LݐfF*znb.Z }bNRVcИ0yʪ2T AE :$LRtL^?8%SȔ i%i5T"J[OYE 8dЏl Vfʦ_Z"R#PtMT,`v=Ƴc6å*̭SE_)Fz%x[w^S|q '´Gc !%^(ċ8(R8yyglq;t }|_ÚgS5Ђ*]TwJ!*Hq^O,Z 4گ #Jy({Dw?RW%d^MŜZ~{ n105#Lpq޵]8WzDAM[lct f(q;j[JQ4q vϐY({}Է=NUCNni LӆhBɚ[>fTӺE5P =2:LvG9'fsZo 9o;' mq]箮sb>v` A]6#g{i@KijTezdɽ變z{<~jL$er!3)S1b|^G0>r} SK;F\D f8;poTh6t3gQv5Jrxz'-Ӧg b~l> $$/G,ANb.ClWx\= [r-mB|mfK4W9C45 l/*&ݙ)޽^+Sf;I϶p։.+jY~1~-:.&ґ}_#w!~k C\6zl q3IxJ1-dJ$L$ T"0 V/1%^[MvɢZ,3qLd ~Gт6DSaL"wَoڏ}+- (e' 5A > ? QeY[+Z,{[!;ټdP'g|*}=Y"/ן%r9zDV߀KmQK7֒2%pݣ$32Kܬ( , [;4X;1H ]x_XC $!j"UTąItMJL~-6hrI|TӮ$r>NZ3vB~7mu;893jסptU (q_g|RK}k69[!wN =is&ͦJ\ |Q/V%yBM_ij$čM7tF%cv[M ,)/;>ϼ9>nh[} Y\~SfTt@*J49c!Ri7C+rIOvwE3H;$q@JN(G;zm*옔Nj[h}2if!_Q#>(؀0P@+!{Z3Rk踻wXQh<. l,F Qa28#nɴG>W>ZŸɪ1+z {6X`j^P-(B7(]-.a 5>_ް˰E)>a7^k8M8:sPf׿a;͝n xq}4ƺ|z+3,tv1 ix) xו=L11GkA7D?COdc[:%Mf:f,{Kv<[s]sѮENspֶP)EZLTSzm5ChuXf/s W)a B)dSCŚ71N\$.H0EtaH$[os:e%Κs4J9-6@gb){Ps2;VKHCJEB;Cq÷ˮmO[yoּO9ҙ1hDW,p]h=3P&4ѧ })?+5| "QtfwEBC6؅7ʦ\\녰Ěcq5{y0cΤИ#U,c$I%=!B1嚽)֘*oFKX$e IƬ]Ҡlcw @vwIL6 >x*C_>p?w)> |HH? ~&#ЇhobrgӁ5& EJ _DF{XIɝ5jLG/}q.έCL' Q{E n`^[s<]ς G+y{%QY)cN:w}md}}F3}=yI1l 2ϥt]msZ4^o Oa(쀈KkqDp <ٯD.R8gkʸKa0*ɋ=NiU,I"WPJESV}vhG!G@¼x5|p]| ~I9N^aex[}!PȪZ4:Ico/1;h2, 2T_4r9yАNql"6jh_PCF}wFh{ZW4'9L-6/SaEt\2*YHZNF$!r`7&IZo0—މ$S}q+NӚ4$46Gsk,5Ԟ\ZĨksߑ|76!B"cpjUds@v; 6j!"֬5WD QPK j|(jt;Nф*OB 7g&nLʜPRcW^ Vh_3^հǿ4j_^.TsEYtLr!KYNA)+/HT$T>4:\= 1踜PҲ/X,2\rRmAjѳW61I<@2p91_,xOΔ32_hw/PWOƶ r4g;=dSwKķoY{oJx# FOzZ!ݺZsGmXvWLt.ܦqFkF,cݪM#F=)g͗kYPL+Zﱴ',āj^0Q=_I]ѿr,߷\[ږ[x<LzyoȎ ˧ZpAX>nk~(M}̦QP]˷lfzcj/ނB 5?"|b>mo뎵>3=2YOp$.lw &g~i;}"a.lE"{ xxPGX}ҾX>;1J ^>3kp,l!}t?ܘw;b?<"z@rT (8qUqURpO_4߫>]َD!J%I#Y z[] SW^Xϒ0I"D@%m肒;G| BXr\ix 3w>,#6O>9qRBA2&Mu(sEb-}n)&7\gsVVV<(Ψ/޹ xi,`wB2 y UJamMS,Ke@JIʐ0c2zjh*-R7ms Ln7/i6dr'};ޢiMwIqZNԀ$CUYO9m`ڭj,^=2&}:x Du":9[V`pfg4zTG .3o \oe1UCT q?=fwcs.`}KcVٍx.dtDU.̽iř^*肧]\o(nurCӾB60 ٤lwk-mX=*JY\lk>A5ҟDҊ-:.3h(aPWTǑQ^mVɧuo_mi(]kyƀ'V֡>sx!/e9>,GihМ2.B~VOy;T +ޏɇP$H!w_֓~n`m:<ۼ$ )/ҵ;t;&׶4RѶoRP6\~aWrpCt w.<|D3R!`dwJЛ7+΢`lsiPΕk4S2궡OEt.=#Ѩ( AJ&{m1wbB複2~7fS|}sPY/K Ѓ呞VO@vt[.'nv,=`b; zZT5滫[{Jy[]g >BJRv @>H0re>&*& 9uZo6KU<x@)=h-8Ux^ŴO3w͗Ktli+۔MX:xVO[BlL?P**\xcU_Ea޷ҙ;Vk2Z'RmT[ZJi3 {{2b-hأFst 5UiI _;DIg>mu~)c&N׼}ũtՏ2\3;GR.޷E3F{h۶&{AAZ }?Q x-HjNMg&IBo۫\|йq%Ob>_暴J'7BY~<=!QXB)_a0Av]Guǿo\| fRNYϘծ[bVӪ gK5ê<2Q(I}BZ.Իvqq-AtsjQF s#Y2˭Mu!. OF!LU@Pa3@,oNże{֞rQGޱml p_GO3LSVSJrAwDS9˖}JlMmK3CρK٠lڐTY #m[bGMi$ kBW5f@"m[6t`G7J:C]Ѫ=V߽Ys\`b`1iSn88n`ݝvLIg3qb=@H Ƅ'isfey{.E{gj;푱vH/! ou%#jP=]rM덱@MA|CߐJ!N][0]m1#nZMmB ^XyL{/:olŏZMYNO&*E iJ7ni*1T&ʩ cEo)xibm |mIakxBk թ7m>v< u8/8=vF{s@Zv)o?tei|)!f=?1ߛYWפp?U]_= gn S};τb=#"@\s][j- 5X97 fMޱi(-vT:f.Gzo,u9,3Z`B{_t0wFCSTcW텡\e[}+mXۆHmCsX1IHWۅm+9Nuގ? g\xba {RS+&GgGH)m[:|pp];;xv {?%lyMf:Z6󫫫ېg@ wx 6D"*q*b[;#,QRcyF+-e~Ewc;bݬ͡a4V %hhĎ[|:';T=osFME+Aljɔ7.&6%<6~5kmipy_KL̦,"]]#O*&L_8bqC>siku:ݯM%W֧vjb]r{žp+=uUQ*mҹsJG%?aF-QDZ4U2.H7 Af܊sdzAk,Yb ֘M9\g'.d.?X) x/yLc#N&;܅t|MIP mPREjJ7>+'ϚMh i#9qY?o*/F d GBSiO QX%1iū՚ŕ%g؍G(y ;2n=VhOvܶۨܐifR+ґvz}n 3+|2IM=^/ɳ{3M.(s[[\y-l(hPM5D$aW5S߀':b(wx*+l̐zrgG=5GޝDYRuFM<+ y,tvfoF*ެۡ<5^+iuj(jϲX,WP~< uX^ kBƚsGݼӰv(̹}Rt6W1*f ꄦ܁GX+C1wݶ ~VXusmߢNj0Rj[3{VWg/\՗ν6%Z%+m*voL4V "E5K BJ`u*[p_N6eumŁ}lk G\s"a.oӸ}F_X 6d0iDi|soapB}2 1V#A 2RyoIGk0wQ_/HJCd+ACCAS7oC8M͢@B6w# Fv\nS+`/w'oCf#1{>DkFv]?(t"nRc̽;oK2pʀ _nV/Jm>I:PT^T2.UOTp+dRBFuflus3Oj8+m[RN֪?+/dlijI>>_'M6藋)ZP95ۻLU"cޮym?3W3ʓ:,8%"bVRGr%Y\g.ה>dO{G3?8f`)7* $L {0NQbbyj?< :ha.vqhc10kL='EvtI!53lFWzwm *O|`12*>rdJ9WòeHLcou/oKaNimN<mO9aK;U#Jcɸgl{̜a3dlA$GZzZduN4ז6}i`FXx#*o#h-+eAَT1&?O&UkBSNASl]i 1xkbD$ F]YszV~ڬcځ BOlrw@`*D,'Îoԯ1 AGױBKn $L W=\t\>9y}-ʤ4p,&Dk?7=T[w'I.>FNv~2d'R]^l0wNex96KPG6+kљ6C:|!_-¾],| yo6]K$=~ 'Te7͍(*_eB#O7jߔ7؅k4nY,m.տς_@vDoǷ]9leGq*B(QG6x\r9l) O,7O)wo>ѯWfp2E"r;zԏ'Iڨe;ܭ/!撍izJcR")#tU̕4~6<1j`d۬RE:<ے1F\m>sVA$>k``SZOFk#IHOWGWȅ @$*$t~7Gh<Z-+\4ܠt>v ?<ۓ.r7;l*֓(ÆM ӻ(=A.\|?+};ǵ2Y,19 \kݢ`9GN4ZX$9W4mj[)Ch5BjӺ%oʛJ>ȏ,jZ2?$ͤjoHbD}e A5^xto{5d?`]VtsY)fR>V{֞\%~!f`1dXEZiJt[ E>↾'^᫃RarY'=ΈA,,76[H!x4L0Ll4R]1[k@2 4€쥸)=%6( U11˽ݗst{px#JKg m23&SH ':ǎO[[Pbрi1)=!6P(#n:A9Dޏ\:R| Jih_k Ǝn%|N{B z!ǿ fCo$I}$䯤*erI\7K`N*фe G򷾦d Hj)79 ZW+Z񄛠+ x꬇Pgę[<\AHڰW(["ݬOq 0ˡ"rũ 8U2&JSf>ßRDZ::hD]c9[:Ro5axnM |~\@n)oG-.1|ξ4x C ' )%! 0/W,f.[/dC3o:Dћ_2bI.13BF3 QJZH"KUI"'oӈ?2)p6{Z,Y5)2%* N ^AbV] ( ԪLµ|@L)E B2UrԬG_2^MCy1@4p.UW/ )C<[yjډOIDv#A0Kir)'Q;pPSz/:cD]:qp뺟:DxVp y,YyLH }U\p0,ؽ3 -|e=_8bK^,H\߰HU W$4TWHpid cTys~XOB,2pNצZ9!йV~$ 2qC 7s-}~_NcʔTrXx!x&T(xj{ AO.έP$g C |Oց) ]0 4npCCQuS ;2]H{ 7>/*̇76H]vu@0.b1 >6;1/WSc4Os<\d֗&UpqkYW $bEj\q˴zTa$\ 䪲ew-S6RIqk(>T<2c4OHAEqI4\ugOIKrN:&$z/2cE}~C ERd;H<>Y@kqV \UJ YIPfVC$tJ">8q50{.fN&пn^3"`XxFiH$Y=2jBq49}gҢ:t9P|$Bm=( `#HY H@MOyR\C DִP\y0[Yk r-h=2`B4C&fXdJ)oSAgPD3g -Y{0G8/A}P*z \#2SPBj=k$*pybRh9'n9oo E<0ՂoƒR)KtHxUaYsB=ɸ!OJ^زݻD(t-|ҦzтheNHM>Ӊ[Õs=4oĬ"_+aC-xIT"^3ATMQ*xB!Sƶg)PD|J mKk F$Z%VIBIy\:^B$HJf°], f.bH#urn)]?Z0k|yx󢜩M\Af4PONiaM9$ۃd5IqpBXK *Cce!%,C"v+ca[(kN@X,A^c9ugDcaf$wt,?$2CF#A\Kä3|GGx ^$MR_[oŷ=RJU),jДE ya/գbTvрkr%uKN=6վ3*Sr58i3Z_'=k^s1IOv9Wu|fRVO۶'w_xr59E( e;nr2" 'L_$% nʹ? %n;c;6}4 R?[g<:JVȯuECjm)dX hu:gct&}4r2h;F%WzHjЇE%kwTM-H]o 3-WId6mC|O~{_/'`IC0Y"H rz$kFO A)B*""+ݘNux_qf~Eͻ7LR#&HĪ(&ei7=lpͶd/*.Pg 2=]Ktsɸ3!Iz\,TUyYݱS+ JEM]:J$CU&.BӉ:*-^RZRT\Vvj-1,^?P2aRk yXu'#S^ /,U2emsOL”*f?{`!6xWV€¿~dZk=#7Yp_awLvT,Q"Rv_8M*AG8jF".g"zS/GbwGlp60 !K2A}g!&ד^OuP56ja"TPplf`sC3v[F-0 _ڕo%ѯGLصo}AuN> sbXՑ`oܭc`gu6TWJ,RLA(|&$>,U3nff%QP4 vgA/"#Gbxa@3&]*%u. #vyʍԐE @9Q1yx"DfBBD$Ƃre66gq"q<52BHFFZ@$N#TiIWMYLj&U/?f`zwzUNe߭ؕ" bE*aqr2Y6Vr{j ]r ŢZoW/HO*/r1-?ٖ,Km JEζ@~[T@X5a",!8%X;cؔɺP4X3l-oؗJt]aj8}8C<}}~5ie1߷ Cx9 ph~uo9$ C[S1qONlG;o!ݻjzO,T$֖Xf_UtɃXRԪ;.wA\^.`(mCQ 68p \F6j:w}Y¤sAx''Fj+=)PdQQ K: *>#V~S6y†:W!X|p rAilM*Q֘\ynv)7:fy nX*TF2п=O2e2(H4,d49*՜ANtfb˕¿cʣJt.'+'8fKȪ)%׭ۓ (J,N7)W{~?+xQ]VW[OQ-PBJw4[,ҫe|"sZ# .`iV# n*03ZFII%Uude|-k #~Mx9jBRtStZj_#bFޅ~o"~K*%<ǔVсHΣ 4IkA'GI=ahBr9;8PshY"(#IdAayW$H!)?w#֫Z2{ [ /zC}~!'W % CKO,RK+'m>&])-OTCQe&Tt$Bl Z)e!\1Dˇr<0/!9v+q?^WX&Fwψ \Lzw&RYlE׹ѪauXI!\3RBJ5-J) {%C݊G55Aζ1'@9Ti$jxK-hLN UE/r!qH1P8hj: x!s&')9DK R`\@H_ȟa`ww^gtKkfef=C&euy՛^pR\c/H+gZ&;D$>ԉV v*:RaM1X&; ,kdW,gͣ+ kS^v0z5<ma]H &ȕ0{x2K R3{xr{r@98R~>I6@/Glh GXՁiߎLo]zheik1U)g (XykE 7xuMXl uwsjngTҥ2)׋++DyFӹϱ6&a[?W}vre*a-|5ZOgP2wa J&Kx~rr:u;Ul-cUn6aG"n!,-qEgUFI]6:HHMO?HC8]!RXl3fC"/cL[UIX0RjvK hBžME'~>aT-Za>)+,nK_+GMTUDakIY[:M-9e Ԛ~BC|K1i'ZDYrc&!ҧ!)bR_!+R'Đ0^pB88Su[}`4 Le}C%<KM]e91(qvӫ&լ9P[eisx ]exb9WVY5$L!DVo Pkc-[ OX1nZWQjCȲnEū Eڔ L m68 vǚz[즯ڴ1@gZeJuU=`E},v}4/]Ee2*+hy#矜0Py!Ƌ _%2Ռ1U[jw|И)zv2)\YEgB^8a(O8`ljgoLШfzx PYS-BQ:a=G--vy3vv ì˸8_,jdRbi4[&'K`Nk[!MՄy ^UYVm$VNd?wXP)naH0I/ZQEQjKFUQwkF3lSGrmk5+fai]-ͤ לbo}Bt̙<2UuHQ@Ukn rXc偫Dt<8ަ1Z\CJvPk=cjJ1+ vcWw+5n[$bj3-ol7GMFvI %3#eVj`iV*9my0`HD~}KNwq?Zr[JP֞Tx>QjdPB.u>Qr[M G<SinnB4T3{)rٳX3aO,CH6֨ ʩ0q $wE&D.hJ.u5 a˲ Q0, كdWgHRwwoL<]/mi9BTT]o taz~) YL |WE.U@ukDh*B Q4 κBʦ -HawSms\ ec03e>L/&'bHn Ko3QΞ K'T-\opdڗ4)F%.Ed;|UT7uueZU RQg5e ӝ*SU#0iv+4q nloJczCn;*TJDjvf]~N-ٞb@t3 >6 3ʈ|c1%c%X`LVe"J]u€LvɏqRJklu 6M%<6^ uaerz_>u"0cFu`(1!Pj0 .i7S zͶ@TEMTԿ|]eӁ\(QSP({6kvy by59]b)YU\eTr _`s eTj*& D=aw(E2cNnݱ.ժ\Cj  Mndecv41CF/Dv SLn;/8"-tFyl{ zhQM6(D"qwkte^lcS|<6LlyFs%8AUNxZ.wb \PqЭowDka3m4|pU]@+\T,K+z ޘ-Q)lO' gW=\ɱ ;o)$ȤNU &LTWLLJBϟY>FLbjX%2B^R$1lA\jrubcIӌHXAjkVp|Hri|#߿ClzNdn2ҍ|D9x8~JDm]Cgn)#+ōn_Sbu˫=_ex"P1F f)t>9vRHPME2Y Ql\gϫ,9S-̶o>9?Gm)7=qh߰rg\${zzSPb?6 Z9umKqɴ+o*d-;R\ a v^1pAә2פ"FfĴʶf`Obs8=v7+z2Jɪ*Y]k0f7ђӭrC+dB}J(V'IOa'UFc?`%0?{ =ӖH Z/VETx#c)#XDlF-b)CW8]Z^SuJA@/'偉@6WeR+:RrRvQ 1T°8}&daJ0 +ǹ20aH4`e* G}eUj6m74j~bKkG#.OVUX岴ɮƹ|\)Ab z1[7]Bz{.GqRvhvyިiq84vkj@$&\Ҝ ZLs<5CFlb0F*Tbqf<:$6=bhη*sSWVL?"9a-m8/QB9b+&ɴr0\[0rH!)#+jI1 $!0iLptb.wһCH#Vh! y/d7@5|L}4r=QƧ[GCo_RpRU[_#Z j"^^IJ+l@]U4q9xWfɞ#%6 ev4%4CBa½b3m}2 69۫PAw*D\@#hK]Ijll])\ RŲ*.ty[T(2J )'aS4lvtFITlv8V+.={3+ AZ3`i<1uo9 xE@'ծkG+։j̤ԚwMsncu +]+eQ4TNҫ:/ӻu=He64]kl J/Ϣ=qa+dSG[\Ho!5X\դԹjMb /`_Q^aٷ|d_ȶ ( WUy5v`w_SֱX}PcH[ zTX|pO Φ6?uhCjݪNsj9\p첚.gi?EI7}6k?N1ohCk4ڨRZtж_6tu]kގJ)Z*ɫ(B)U.ɺ͎ZCtC^:2fny ِ|0U>v4H8Z)M0 sZ[=G|B.Pڭ@3tˣɘI^EMF3rHJ@?MF!t2ZtY_`p1dAɉ-APj iMڬZp!2%[G dj(L-Ӥ2)SIJկlmP{X 8Ȃ0CܭꌣSAC(Bl^9O m\H2@L|-a>t}ڰ71^9?EMAPΗO\/r i4-a^f:h:+_=a|L;ܬ!? 4e=eZ,j ؔrw@,[ebsZ\DEhLaRQtkp0l0qigܒZ>]MS+^VQE|:"^P퉖Fta=|@UW/55qBfP-̹{vS6L'\kƀЄР,WGF*Dƹ*Sez| >øBIĚr@`Tғo>5+\0qIB,-&A*I3eA/IIRPVS&-XIjTy(#{ +C|ǡ6c0  #j](7o_45^Y85cv QD"@UTQz*I}_d}Qr ÙxLM9̺Ғ^Ƨr\Uc<n`-PqryczTb-થj5}R6,%JRfID8"ɸ[ m4mJ̜ۡr9iƞJϰmQ{5K`$媩HMV>jA!hTuqi!86[3:Umt7r"h=j }沐X$2Hss'0'CWpZ4\)t n`$bc(U\L6 æֺ{#iBZѸ-_B 9m } [t݇ ؞&A#KsdD.vZ,kSy};SM˄5H:(b(c7%2v&Fpm}ܧyYY_5=ܢa$)bc@!*A9xa Z>zóbFoL61pFnac_FP6ÏXa@񪒹KϜt50e2U!]׾J?JU=ܻvRŜ8CeG"XA`+{CW9<2cSu?4-f28Cr$cWތ~֋_;+cS* Uw+ixAZBx=t٫U4w)G]qv А?hW>=9P8yO'^#"\yZrP6Ӷft:ڋ[Vn O56MWgc $|99t?/6 \EgQ9, g"[`;&AV+ OL&4op`I I B @ W w~=z#c1< A; Y x@RP`sprq#=#ۺ3{6:b3 @2A&S`Aֹ*cl y%fv:D@. 7v=\}}W_{5_vk<{{|_^bY>?G CtqL@b{g`WT"i9yg 4w&_}W_u򫻛/^f@+;{ͳk{B/ʝhd{dq&*(~at=$xWS?©٘RgcXv*X]V^L;=6Xܲ:‚WB|)|wUX ,dVvс [@WmO쎺hyY;Io{Fq)EȾ{tvƊ'D  d-Ϙ@݌@A@T?a6p6 :(# |Wn~ZڵrǶi^|F^5=0ǰRƟB;i1`/{x|;{9XxB8l8H`̓|k`4џ9J8N< L_yW@.7&SkYQ)`Kaz na>mm$z| 3t'3,nldX['z]D)1P`Sܼ~Llv%W*utAj迺Ajhlz%).OS:\ku ቺ| Lq 2iJDA-t-9|LeemsmqUO9sU=sA<5h^hqJbqF oWLU64UN*Ss['{WU#S[mqtO l>ȑT^5)|>l]&VWBr-_}f  =n)t5ϖr:o2kl}jf5JFmE%:+&:m~$ø] Pu$H{Lζ4Q ]A3ݩb^%1wCh('fI7)E"c#E PM*~tVg)ol(kW]>X_=[7iօ}W+^сvTb$rOIc[>fc炮2*e,8Kл7i=xI?.k#wJ(q)HTUbx; mmWrщ ȿ"D&Si|S?t Lz_U1[\ǯh_ǫY֨R.bsHyB>T5Xb2:ZGj#ޮ zt)e C->7nf%n݉* &ywpJKu^ۺjz˖曛*[LJnLJ!W0`IC$TK~7NMl<>\r mm`w7 9wy%H?Y~L๰QPւ,*{ih3kCduo4CJ2;L !C- 𷷷7]"%8-=r+p(d7_VfrG6qڈ=^6ծزHpsSGWLf߮UyQmW{cSDeV&NѲ4䍏QNQH~*F@|#[+\iWITmGw ]0v3_٤mkb_pgU;~ ƽW#ۯG~{.N?o`ۘ8#i P~^S]}lo C sS>Ϩv2XO)P wa箟c[x XK9wc_ ;bR1suD4= =g{z7kw[}Pb ]@*J|/? s 0Sc6Klm$@+6/ew<՞NOTT*ӒMv"Bp?I *?1o>W{1ЋsLVRwnm1‡1=~c% 9 A 7 98ɍJi+knbL0^k]?O(Gla4@gV_f7nvιk0c3Zװi"Mu㳷4tN瞿ZVAz쮧N[ZOtOSe^'kATtef O20*hOc57Y 0_'nVqbGqegH,1K 6Mv{,ޅtŹy і!3K *S-}W_8hESQn6v9Jrs6Fޠzۧ MN\l0]x1g$k 00)m|tJjKg3tzOX息rX>?>g\8u-`>tOhf.$]t/wЯ@6~+/g `0vn|Q= oCtl]8?ÑfIœ{j{%9JDܖGs+53賹bq|\,M:Ic7((K8|b2Y}@\Gfi,U3chHE4-+ m:јNдq`~ qӢ}W叠^lQnٰk b?tS/64sWk/%03_c[v D#RՉo`a4~8P_7AdqVOX1{PjP.)9f~]_KxsX\^_.Dk5e{8;e1ͧ.b֕p^sMS;AEkYݸupC8,|98VURY>PCm__m0Z4;̥^lp=\gp~>5V=9ce]V$>fy -57ą9RA)s1#ΦKPE yBE l,]v%;8=yN# @%~ kB.*o+L [{VdmEO*<&{HFT~sϧwD!M]= 5,p,;ǹ8"fś.٪T,\WuPCP}K4b%,s6P3~|x#TX*6mY7pdsx? ;cPJ׽}e @Um@6^ lyBH UsPk͐@SBpw3)/Q&:8{Xp~XGS|oa(Aio")۰l0fӓH6FN |LHHJ/k+ A8iJgX9`ߕ{MB/L}H?8#- %h|dÖPb#y}(%=`p:φo±K|bw]nePٮ50Þ|'l-}3s X^h}}3j:scoߍg~pCw _}_q^p.>#KzCRG֯>+GQr{Dń1n.hĔHNc^p79(ڦ)p'4='3gfc=|bGpH1ڥ\.\C R>xv׵4hXs:g8u#j:GA]Ovf cyhm߆=Wﺤrdfd`>>y~7첖㛇Q wg\RȌgvɟn9}̸хk1݊r-~!V er/ٲŚ;]'H/n/^?㣫:X0B://c u*:|WUaGo\v]_2 Wve)d}jδc򇙣@M6 .qܹc?y0vޭl P|7(!Ԝ[wAn`;T0!@N@1@걭p+~Vʣ`'gOg2>{ Z0z7$nWX;8=xÜ2,9dìҰ$2l.ʻ𣘞re^U, t{S5 TYw; V:eG/HdQ >(-du_ yƗنT)cT 5V7͈jM]E yك56.WHӴ)xDnA~GCW^1VS .y]]m Ȼ=v_6_DԂQ ŀ N^:2 8NKssOmaK&ɷAGNm pS ?3U֧ ^hU+5n@i,P, z-X!yXL 4  & z/FH`VV>.Uvdry5$섺 P9>mzm}R0۶V4ʅѢոV%aFekтK,[4C +!Yq=^R"jA FF |bnl )l Fxh5ox2i"o-\XG? ?)e5^CՌxוa0}qI:}I/cCE|/x0f} =ZmkmWD*l^Wvmw}@1hlhFhԱf1`>|OSɋ]#Tܜ!ֶM2R1FM1me)a $Uliy<ѝ+b6]y)ֈ7×}de05Hޟ+. }pn #eVϳGKщU`mtF% <|l&ZJ^jE\!gC{𞬍82,Ovwek0c<AKQQg^zY 2}D!GkYHkQ6&S_/ٚ8? FϖrԞTt$GƉ#Vom"5};b }l}v]mVIZ޻dɶl˖;nwlm6$L 0B ! IHH9:ۏ8϶@~~`;Ocib <Ϝ$mu6 pwZF/VfvtuU+F׍Qo9Zbnu)  ~rG+D s1{`hחВ̓FD7 11Y7pUw1a|||<~w-QWQs#C~;_O"l9ryh_% -ߡ4n;3c]ך}-hI[*_խ;ڇ9W| vp.Mp a]6[5e'9/q 4ݓԍ͵;s?dsAHNl&O@Hs F[SV_t¦=i.lCs|{zlGӓ|.a>}MTS[sAj^?(Ŕm.#8u|&S𐰫~W=ZY(a087 ,5-ɖetԸdŊ )r$N9g$/X+eơ3̆KqяtFʛ/9Y4SU}KDSjmm#Plu5d!bMaW:}\=w|FM(]_4vF)? I,ҳa)k{j,^FA1U>~|ĥgN]Z_Ɗ6ŠD %%;`=9r7^_N.wZOdU)>|;kZ{˗2dp}9:}l\G̺ \s=A]ߴg~X12xQf6;pY,dC`X5"tLwr+OOY+s,{:g:/uMQ2#~O5\um=]#'vtJds!>WfwN."3竕΀%ȒVVxշe,r?}\R[4b7CJ)KU~Vw3oqNk;MWK^{W{kuZ:4mm-Rp liN.h;=ij]Ŧ2Z2 2Oka0Rwz-;(ŷ<*k#IS;_K݄]7F+O-:F'_rjmE d(4.sLʪjX>B?|o.cmȵefJU6G]W%?x~7eϫ yUW{ W;qbpb||^UvT2ol|^O|{) ,C}.C3#%?l.DϹ>gZq~Qa\/]N hfYBJRPMvb1^ .7F\#5 \ҐUyaDJ!jI_<e(r]C%^<^6v%vaX~];r)pU#CC<'s[{C<%l?\l">w?igj dBmX4. /Y婬r4-]` tB.96KTԌyWL8SGZ5"ֵ#צ 8M n:2:+ˉ5d$گ b)AG v&Y]hWUjɝl.Ku]Ip"o(]?a g)iEd[& #EQcQQ8/|6ؐ#mt; ̻LXIrXZ!͝e뎬:BO™7g]%g*_cјD:I^0{Wz-ظ>.4h ?uK[i$};+}rvL# $:Yޭ,Sn'+qx=<Ms~XTR߿ѕDP-*ʲHNP۷6*&դ-kl&^EY[:8~5jsޯ>oz+ j#v6lĸ,7jD2~$ӕ˓[` ɪ#uhH`}݄|- @مyyo+/DZd \-WIk\^}A^y۲[o{sۘpyeL.AcJ) Rya+oc3S$$*)i1}\ Ƃ+jE249e1ġļʘId5,CG-eil]l<2go~8`^]BӗNߏ!Lߢ鱁tKٸ){畃Şn_ \T&E[(?;"{H$@-kiimfhMg:hh;]._(3sLx|nnB'q}A٪{;h͝ ؚ_ʳ{GKrio҃CF Tw ûNI$^j44ir>A0.<@pe=-jin+ci@tdiԧ⯗_?a?֯F(캀zBP.\ͽ{e)!|k {ܵA5UOM4\L(|olrzgiтyB<Fie^QЖqN\z泡e4v 1.]k+B`ҾY A<-[L: W?CwI.\ L/8mkîOIG\.oi;b܋N%չ`Yv&K.&fns:A+>0/ .zV> ]ׁuSSҵiaMi/lMTf-KRںT7q99Hyp"릎ݿwwMړZ[P92|Kg^eNJ+s_;DX_@἖Gq0 q VM7l8|x@%llZ[~r&*Ҹ ܆.p4Bivyh6\g`w}KV5#AGBbuz|x5v&( oz,Y05M&M3]UJ]b`U,o !\lo{M3/ f0M?NT|(@l7v\rx8~DikYeEލzϜ+1V_ļp>9hz-̻HOjNs"9>k濏M#2 O7·]G5laߪm8z5kL &1^%i k6e27ts`u᝟hi0M' i#h `yɿ^-|aI=X|.,x{cFŸ˅Vgx@=O|VF봢u @df-PI#le33D x4!DGg\f&27 7|-ڿI+_urSho]vTۺlo.PEY1й<Ȕirw_;.(۞')7>|`7;W<Jle&x9QnW%#ؾ|K:qn~sZv/5 dq,$|v#gsѵ7ݴ ={G/^^GRk߸` ->tb?P0'9/tŀ[Ȳv\,U׻[v̘|b&Qʜ_ݶ;zObeOܼ1?Ow[yNbpv٫ZEӿS>#F,""IlPt$ ބa)é MBv)҂͈R4}MasO3mm[h5_c" l/% n?mѬ ~ 3߂B* R˴>DVY6Gk3@!Pf8 #ltI+K2x(OZcnBid M)&>\B{p ›GZ氖!gJt4|' OPdwΰ/+ق/Jn>oe/Wc߷ sO~Ft7x[2k;lǔ~rds|jD/ Hü:*|T23G| ݑE9 Rgp#Zu4ݕ^>r:]ڦCg*CO9ՓjeFy"`Am_6O:41~ ۴\+#KbgorJ= yoz|ynp{;^4׍"7 ]ڽgtd/89 ,[NĶZǞէlW+>ω3 Hr#Q|͈ OZT1_ HvWUhJV'hEpv'NHxÓʇJw˖m+cL`nm^oՑmukNFbZ}U3+p`H1&fx[oe71}.|GOWt԰I"øc|Xs5%R xF@3:V1izk8Stns}$}GJ`dגye艙R2JjdnyMCʋ2|LO;p/da Ě!wt:GҪg4 Ux,:Q#[ffp>/iDg{o=/h<΍z ZI\Ķ Fp`Y.4W9mm-i`kp˵Fiv(Pi#,E)&w#x+ƽhvoٽ=>|;"G ~>HN4~~M*hپ)5-R𽗘W^zIcCG VTf02ȾܞZ~_Xn^&v/ߚG,^yc?qf(`[4* k:f56%:M@wٵZOq3ϰOx >xҭF8bثmʀI]7)>\MZ') IL/mOq,)?g~3a@cqPő%1ylKjINgh"ls؏i/4a2i IWNh6Cgfh(Z@fƌ@ ]\7{;Tt#˃|[Ͽ^fwpwÍ)'2.҃#.| n.?駰Q0C&:?t h>Pyڰxϱx5]q2vgt 3"hmfs @EBR/آ;}IwN ܨmu,5+ Hb-r(ߪJj`C"O8{b:.Ȇ`(̄Nx'PhE w"^&oag銱UVjakrX]JJ0ZMLd0,dbNRa_b)|9Zv{iwO{ŝ&o=yDW~&rdX ٨m/|+_1֎=>4;fTj02-aoXlzI[35evzkE,3e5gm־Փ DgcD877 ΀.f/VeJC_~|~}Y0qD9?\]Ep!ub~皞cɟ?6VM5v8ױ>ыnNK]zxy#Ƽû/û2^(NK߇MHϜOr)Mb\koST4º{*rrhv% ~ji:tz-;W+ʹ2x/R܆i4&oٮpL ;j]to?Q*,t;G?H߮P +W,˵]遖$4⍒O3;t4wgkr;^'^c17J!AšЅ|՞BN:Vf"~^JEiʠP‘ŽZCے1@>6yCQ*t"?;@:u bBY|ȇMOlXBI#Ckܪ@1Okާc+W<7Ly6 5<`Of2bgq#Yhc6wEaք:Sn5cʘP&If>ܲJsq:iU5Jp*K=ŝ;uX2 ld0tJ߬BAVfp[z;q*\]5-k5mmk*f(bSǤX ZGXFYV@ڜk)-vs'q[8?jCN)?GjtޜGEP3V4c]=`;|YSz.VFD |iCk fҀ+ÙĜ54oDOңj`^P`8}KKͭe!ZKY-b"?E}s]JA5Ysޘ}1 .\Ees̳μmM: thgG&:>d.2lk,1gaފ\yKvߘ;v+٠juOm 9>U= ggpa{ZȘq" Fv |!%َJ$7=pra7ZpSsʟO任>?K7uTPN07U=P,R;*4]{s֭V(%5#(Z]hYւWpm 9d#]oM%AƳ5O_sgIg/7[Iڛ ':vPVjۛ LgZ6l6hj[i#B#*A"h2Z%L*aU(m*yΤ8Wqޔ@xǯ^s%MS׾~+:w',=U2q1̶pQɬW_f*TN&$q2k& m!L[)MT=n"JCcQe[0ʀJG.ܬ> dljv2J1MKIǎʗ5N9!6\#$s~X5b{g : |́EfOCx(3& f\UT)[҉f]hS%+ՆC I$ƨ;'7Yeb-*b]a}/Aj>R? .+RqP :HjMF;7y45E  ΂m囎_qZ'6aT̥Elϐ#64>VY9$)poP V ^؁ܖ GחbH;ƛ l(Z#b~2sS! ?OM%}&^]K-VTKV[QYlrVVJ'IR7ةٙr,N3Q!JphZ1Kqxz790Ɨ_']0i  ]T٣:;b&S HMS+G3t[z'>w9 {.& ƕXq́w: iSvܘM:D/CB*#Th5f0LX!rgs*{|͕d?)(Dz8KU9'I}J?8n2@bz(U[HOW]1ݮ|Eb󔹮6azi&/@{Ki6>TI9 6r,RYi $M>]=YWAUmu=۳=F76mye^pOP q &eɯA{KB#|lQOi-g RЉv&KDo`|Db!"j !C,}-W{#Ph'_"H H9ѮSCvd/ogw0 MTA#v8e-HO]U,ȅj1)һtZCDc7Fw,۰72ޝ.o6;}h^^z%%<-xNGւc>Βg"Y1BYB%cמY#9}F]+ )P/;'~EW?%x)G~]e5QǫrViX7Fy_R_, crP.V2byIڔO -bXDj4svШ33-½͋7_\{,xSJM1߀._~΄pmw?z^>˙3w9~|R:.h'M8~{[Y}]~bSme슦% lPB,{5::-euϪ*2hxV"9}G'!vϗYxG\*/%9yZcr4rx_od5'JVH_Qqg⒁P-.wnQ@bk61)פ[F=c&ɹ;8׭?W3ϋي {S YVgcbE paB+MשeɶXE+OL*LeH+ HԈپ6nY}gʥ)Z$lW{Z,&ԏ* h_صZMn7~/_wM\DMxF T:/iPҪ\T$SP(F4ww#+z? HSAAae tSqZe[!_.3zb8o1%-NU\mb-Q1U5ڂB~wp3~<ݏ=OQa90Rj\CiyKKA ŬTm6rw@DDh@]@0TI=K,)6Z?׺ ;dg9'h?x7I~%wtl{Ƕ Tj)ўjkK>TIIjz'[Gz9[0m2"P-LuLܿݽڮc>Qc>[i}Y&1X{P.8PL5-qq8)u=9W> sxrXtŝ!A̤L:] Ϲ>rն$mAq jn=[ %.k|x LxdZ%5iKttJ7>]hg^rMʙlbeWLJN8^G9]8fC#ݾV*屖~kТN%C{'5ᆕ#|}@X?hW^ LcwͤxVeXh'foVSodI)L@U$B$TO@"QJ*FJOm%z9~RMj-*/0EX$Ϊr2ÿg.rg@zc'd | ?HKDæҚLT%ry݅_٭˖?li k *F ʱإ؈җm\ߡ9Z} 8E918y~ jfaQJLujtdJٴԐo[޸L{86\X:f܆G}]{f0V{iA߸9~\nWl ߬ZdPK_%B]-Rd#~?>SM'Ϥ۷(w XD\nSB8^vLc(%"1Y#zt\okz y6{!g];װA?,㱩P5 C\(U0ome9{h+#[1d髡J udj!ϰ2,N< )h]h`Dd儺 (D0lrZ ),!wY{> .% LZi4eыF2@ @ vX#i 2G2AFA^٪UrkY"EUԐpXS+AT5\v6(#etrܦp=ӪBl|.4l_FDwOLu"lhR͕Û0sDv>lǫ+e?pod{.wVw I~!Si33_9_*uR#a(&lvG+Ptzs2c4me L)(-o<68ر 074QV_X2 :{J9b1[IZ95n>yke`erU8WTC(t04Y{J{v?%cؼ~NOQT6\uo033 {ibc7`sgl/f?ε1RY֑V" ݀SW&_%ID&(%udj NR\>'>0i1u~!ޣeOpsw0NҥuQ ;.;?& S0?SmՁ6T6>fh66[B"'t߽W X9c\{u=ڷB#XX~ev,>ӸV|cKA]c^Z,"9 {AvjRjNQPH:P2-EI.yU[g>&nbpO=y@&/LQd\0M+l~fۈQC\tb+SEvx֧UhigYGpw iü\{?OaK"KOn9^aX:0 ]39#}s73 |6ti)Co$;ײHO.Ժ(;ݺ)C`x[Sr#[5̉et Q39kF&],qBU*RRuA ZjLEmBI|g"E'L٬ +wp/qNAQLD@Χ֣ Q¢1ojdh{ڣW~m@,jhe3޸i2 r4طmP$VYJ$('7EiP1d.'V}kKq."< i~ ~IlKWWW*2vm;jD&bZtAͰCMMJ1VĪ@E!oIqLgυ&XJ`@2vT Fd[mbEl!-J DNRSAO,O\O. ]#e}WwuFz n 3 N\ACy. '(qp!Y@Si/j;: `tro]ehO/ըv\/SlΉk^@6XDɊQ k9f.bc*#j+^+a@R` THeSf|r;hv"S#ኊSah8hj6[*tܞjb״ Up^J`{R\J"PrlU#2)r@&Uk=AfM[H8PJmU!Ks5OsB::ɏ_#ȟ/72Wt3v لYs*:EknM_PbuuQO[+]X{TP{dU*7fXj󠻶mzعM ir珌qT3qXX5XCi!)"6 t鍽#wz F>^3n\K)KRoT HGGSLUvϓZYga7 :[. `|ٸ$Z U&4mӡNnV #=ݑTPSr)W4 U>?!N/ٍF-1QmZq8㷺IKufoDgq\3}riT!M~.LW,q ObVeHv^]&RhCP$(*A{%lƭ0FwT\߃ ӆu:f*sYXp5V w OORcƉl_^kZ;wo8kŲ?6yW0 t* صDAcgi+a:Қ?[2GsR{)〓FobbD'|Fx9!7;6fEf6YTtA-(* ٻ֐XVBo;ЋԢL\*ͩBa֙+BaE9 K.m rRi5dt~Ie)\uP~-+~Tcniл_DJpY>^h.`"" s0l(1 UBhlCIY1Ff--SXcw`nka«yQO}];<#Աtar |\VJY(w (A:9'Qm23m ν'5+1.?C<42c`Ms$WHb5-弉I.@e2LSoUyw.;!PH qK8B?s*n%Lʭnmay_I)d {XˁԘ ],ZYb K790, ~Aa^0>7S̹^ Mʥ;_һ[`Y4l}<ҲfϑM dD  =ym iT9WƿȭԶFCiV#bni^U^Gj@P "$TFE]sk4򳴟|7/b,V A!N鐪.~?o!\Yoi=BH *oC\v}ra\ʐ6<ؔj7yGSW$X$1osd"A pE+_ܻI!z|\zalU/ 9^rL=Gϛ㩞S"tbGy:V=d6;(S)t[{7ٳI)PHsАm &..v}l 6?D>"H\`Qm9-K6]oP1)F*(h]RwI| 0?kϹ,DI ̼QXDS!I?h-֒.'ԮV6&QFf,ʪa eǺʂ9':Y?OasQp.1kGQ=ׯ@rWnpͱ]*+#_{"e'%/>mtCIܸpwov_1IvCWBΆ{@P9'΁?2m,XV|,%+==č|?aHԅ;TT21z\+V4*] 53Qxq׮R,q.ayar`I٪ضwY }agon62ѧ?|G׬ 64?dGK|J^|1w uk{wysW uZËUmi|OՌ6Sas8Il<%Bkx~xߟNy@gUxSkʴN+=D=VB.io-#WM57 Vt#R_+2{FF皼̤JKQjEYqkKNW}>p[ZuFdsȧSWqf|\2B탭Ŕ-IOgW~ʀQltˌOZj?v"O%5~sԮ+K=P4#Eq\BƑ+;o:8w R?e*S][cUfNypJ }?Sc9}%Vm&+5FV C9Y9"WOþ%V'J_[Jt֬66M!_y6~/B>RfUi&.E\cD>F&]$}$V4f|]G;+5We~*]  q{AVdI۾3P{xpu\=]ș3#\qM 7\]0P.O߼g9϶_XW^ܶ^@bJ;K4dC"*DwwhѹNc|;2?ɇAafCʿFذFXc#ww'g]q!0[$vwYkgq!)-w}lk2#qsωub7X_[h39cNWVaӆ;;\34̜:7{zw߼śV =3gMX;yIV> I\32`cr­d3 Y섭Az7`l# Oz>rX`5"%>-X# ;IL j)f_:;<+ي3;MnYS;ٰe'oV ?Vvڂ^)#ݫm餦FZ׾rBh96c|Ul|Kҿ-~mnD{E%4ԐRVSl05T49:Ҽ-оb+h WU["< {v ;@6G/rq*Ä=Y6m⫅V,it_X&r;鞵m;j.rIYOb%xVbh+N'l?[}U6PFKl[42Qt/[:$mnsO,^aVz|ji٢E^iaHG|azШ;bwW"[&V_Fe &|v(&|*f.GV(EQfjPHX>UtD>_kh]ޫLՃ?3xklqዶpѽ z5/b{=vVkudY<ߓ_Ydukj͋/5n|Wd#wLɹ۱ت-lkY9g=(vu_(ug+$٩Ҍ ڤNM$%³w酆dn2KK.3cL]OcPlUDbItLL=-%-['\IH0-꫌S7oV;5k_2Hs,\%yvg'Y1ٞTƞ)iTjiUi|VBUJDȹ|䭎>WPn0FdHQKŚYY-^\|0/_?s{=_TIϬ&_p*5g)/eG5\e3dINU-˖,>ѡDFh`eNX`ƈ)2V[UiZ#!#L򩥶 {xjMgm]ׄڄԐwy\2R $g|#Z0tG-IQjt9 | Syg+ GeA}U7pR,=[n^^ s7\QQ|Å ֎uq| N,-2Ě_\WcI͗A5|$Yd/ _{ej05T_bl.s{q'6g$I3,>z&썻Y$Mܨ;-#!)!~ [ˌ @CFpMkrhřUTmMsBMD.Lr=%|Y_D&W:9be=ǿFU3 `gO-8*xpʵrac޴`^*Gຊ%;ѳ*;\ظ$SNK^%;]Fמ|*Ϝ,`ZX5},F<g6¦"#* =m1ZZ KKHKSi9K}8/_x@ƾOo6l2~T3+ٚ+ݛZ<5p_Ӿ/ےz/KRhv JZNX2(ŵu 槉l,nDD$Ց׹^.=e '4fal:/3]{Ite*t]褌U7\@4*EQִJ.u lMOAYf{yCyCƶJM#a)M:Mn۞QVltb֩**+{hVj SϛJ:Sꚦ߾q잻e{q}\ c^=6 bkP DrĽq%s]R[;7uO* nMq|v.4lzfCqw0|猢&czْ My{+7e3j+!vԥu/YyN8 /p4ڧKt:ʱ]7eyPWwJnrZf^ vJWuu7,r@{(eNOD?S|>R'[{OrEVSIf;HZyK*lZX|a)rHOWysJ7Zs}.W=_cǜ1aQ6)6_2?p]&9٥Ü/=%zMԳf:6wl%Z^Bѷ}{V1|TwI׌4!oWѲz&L /{rܼR{:̯V)sf3 o-Sڸ}a011Vo,.2tLoN@ڇ4s]mvM{%?m9WrųL)\%yzXpz\(3[!4rdo'ľ1TLBv:u 9nV7ԒD$ύ?宋틜49v+q+h BX3[~ש5a8[07'LGp γ^Z/ ~==Hˇ{Nq'ķ>'6/ *6u/#cQQNԈW2-Z0HwtwRןyvT2= =ٝ [{Z%oPxwpEí^DlqqR|-֧kL[a.h-Z j4uxbm XWqخ$6c{sL~su|iuLPD]x 8#sHGS\qO_k E6n3:gMX+wFA (aEЬM2? KTr8'ܵReD FwY|ؖfnݛsQ[EhRؕb[s6ooeA fp-F\8:{- {*-փzbbž3̌ zꞎ+VHK{"k6%0:8및X=CbvN hp׭h YL:miw#/ҊơZ-^euԉˈb" 5E5E,T9ś#ٵfG& H47r7yl71(5 :FW#qVbf>rjy}Ba(]pxrKWµrY֯ R[mM/Bnqqeyb߯1Yk8&OB!La6h<_-u|9ǵݙ^)զlҦ`'lt-s:mTITzI4Ҳwh%"k=*p,2MR,%^zgJ+cb.KlM')yde5GuCspgyܚ5k!'M")9]lxJx;5; \DFGۆZE!<]ѐ%,ss[?i~b_ QX -SզZ醅^R] %u"O; 'p-i sZRVёeas֔ |YQ_>԰ksCАΉ2>[Y[-SyJd /U9$]pϭaG:YI&ҲEk97N*D~%lczzL ҕM2̤n_E8.i=!t*#iJ:kuA6{Cˊ:>N8veeT]Cyֻ$W3!'dѢ\rXNQ{Ŀܣl }Z֊->}#gv6ퟞٱ!ssn7HHpdH GhD]k:pc :L*֍ɮLGPgSέΛ];z7y095Y7LN]PTA8so=5]sΈH=!*+6;Hb~kk7HE49MfUϢLHִ='2Ɋq}*\Vm_#ʢ^3;J$|lwTZfMiR28+3ˮ7$miMuVϭo1gd#'g-WBv X,ᘫa[|( 0-v5s"0%@s5{==,~Dc)J.]_ʅ]1Z*90ywkX>HMʵ #r{E&|'G2.ZI:˺;G[D.G\Y ͗f3@6#^.5ԕšLqۛtO1N[Sⴝ1 SL*3ŭ[ET=Ӡ}l2QZ5fst9agnzqy.G7ީ5yFP S"/HfF۩^1[%?V8nI;key]͒WiTMl;"uSYfV:Kx ՝ %kZK\m_9əb#c+X V[ZgJ1 U*N_YUԝw>mã?G[oFxW{CKׄ+H VI|uuj- )JƬQ&J]mTt2DF+70=?'%#Ot .Wѓחv7nRy\l1FJ-ی,)QbӥD` XL9>F&pw>~tbYd:bI͘u9?4[6S>?z͚ڲػڙD NUk_.QvLdH"d$[YÞhT$'OBԶ{kOq벚P|Е@[(69FsmΙDzr%>Q`'#LgبqDk;άp/tPjˋ J˛cxÒEn^[l4,Lm YC)+`Uo/7={o]$n fwujFci'fcxz{lMҍ3IWL`CkM*wRHnivEBWNlo>KSߝ-Wi#%[ N_Sn5a)ǮskU2ͦSup k.k`A~yӳBvwcl* ?Ne7Sϳٸ\{{VI|>O-TgkO.0t60oa˂I^X  pe}+Q[X׿t5ՅIQwmkYq^[k&-{r!z u\) -sM[`\OH& 'eh6P-O/Փkxyvy5KKi7U$u}tJF̖G*[̞Ri#{u_vGmU5nYKEE{>w7tmzݗSn}лmkAQܰ?KU>2Qޓu/(sPZܩPBs)Zs}Y*G͑*ͽS3ě>n#% SuXtҩs͹»Mߑ\I3%%UJvɃjC&qҶo#-f/JE56w_/ *s66Uح@[Bzopa2)ٛDMEz Jra}+;d)/,ݕI)7Μ`tf'iA''J,%U"Ζ厔u3gdb٬VwPDSh>;h>%!ڢXVa[ LCAfTƶyҟXǓm@.[w֪5cU2EיxMXBg\ޜԪlh3;V .:V?b Uבctv|{Ē̌[)wln˯z>nZ^leS :9{Y9axmTZ;e.9UNm ,uǏ ޼A%YU'q<<,ai۹B ҳz[LìΑh:k˾DuWwT3MTaxo"uprƽHs^~]RPo̭u5ǫ|-Pveۄ6k:wuwKgsь3&j3@4,tz-tttDS#u֮FܑBKnO7Tݭ/j+.ڏ&>Kj"5T@EQX󤍙\Lgϖvc˜gc ;ff.yj"kldJy:a<չ.1F|}CCg?{UnA[蒠}c=$/qHJȏʢT_佺xǶm&|po! n?]QW25fK(_8T"/F=ñFC3fe~+wO)H0>unTrÉu-Ŧ wલ`lUiN|6ZRc Ļ]Lwۆ͟9,f܅]I5wʌM\ukf[*lXM9g4P|Eϙ!P: 3?K M>$>M1zj"{hFVdPUg&˰}=dh)vu\;}V Yؓk&3-qO5Zk앞ѓOMk+o֕Zo!nyk:✸/,(tFȌh儮 ˏ'~X?T͉Ӌֱ≶+k]u'뇿+lOZ;8=>KHO"sOnicIŎ**hY mm)l%=%-[4flX: ^oXP+J 51?P! EINx赉N4t[.k]JZܼi*ƵW}Khɲ%ݎ[ ; ME"cZz^QWx3_\*̈M sX2恛zzW].4=b.5vz9y Cs%GK&EM+#-M%EhZ;AZ>ۨUA}[ ޲aڲ f!S<%"ū86n 9RM .|yk(E:1I12\gZsѱvC*zh9|v0-7?xᅋy -|[=.\SˡbJc7`o֐3z KE+#ܮ,ض&R^SL"=.zיZJ{=ħv.|EZ8yMdp3$\g3k'pڅL64L9ن*[=u)u@M]04.'V'}(l,V?X8e+k9#gVrM;N-- OF)5s>gi5}k^x:l`ʁj՜d&+i4Be=evf61sh"ҡ5;ה9o<֪V@E/CH  t<^4&Ss=S]NO DYX,oã[g[v<]K"q@dYݼheXxz*}Uz]W, NҐ֩lfgY\-e.sѮ'G<!UL.ϖg6 W }Znv-#b"dz%ӥ4㮨OHr2&kYOopgEfShMOIJE('uY6'k ɂzѺ57Yt˷N`۔~^ұtiǢHxz?ꌄe'&)5&f|iW/IAE5bypQue)N'q Y^yCE$ώ5tW=a%墉WN72N,S8r\S}?~ϸ?3/a}({#c=:cc=>c=9Sc==p]}F$Sg#ԯh(Y3#QaBo7 ;;t<ӧw8s] o"Q7=.oK#K#J5pBDD EEiI]KthJբE=,z9ы߈+:!Z80+rf d{ W7So,{ S5[M{9 [GXXmPL0h5,k4xJ 5R$T*'쉓fs64Dd0/q'wIYdEV!IL-%8uT%$%LZD!i&Zfr:\IKbIҐޞ$Kń%R1*rU \Dɑi I"[&ֈ3jdIK,9UZ/9UU2)5$+Xy\Z e ⭲=b[پn64D + .e UybGN_8=H(UdLAؐ-MUd)rKIZR.-'''tJRSSd}8MM8Iai"?ԙL||IFbr4KҤ$Nj֤7m,IkT.xDBJ"|3dɲR#KTqV*ۤȳ% 'U:MK''HҖ&Hrj$MRl)إ$+-)Cqp~jWge2 'KMzӒIݒXI{qyA=uJ(]"IsHi 2ŠhTPM'{4\FE$H$Qe8El*]o4kX٨dIRvkF- 'ǵ-i">-fݬ4O|Bd^|]B)#ӑz!/+u͍̖ :%VT'Ǯ}<SD_('D?uR4%x[pp,^Ͽ{܍"EC~sg[ᧆ?Xy\ BNS4?!i>D/]D:~6ys__K?'gOO'?x ^?u_$_ /'뿛D|l}>~r?gi_IC^O}v:Fo?.]+8޺:k0愦Xt)_;׿~ ]}U77zm?ɳ(:|ogO?I`~~=o:=-]NǑ07,R<.:.։o(^{b '{j ~όwd c=;sc=?߯{a {i {e ߌ1^~~ow| 7{k {g w{o ߍ~'` h ~1>18c?ci ?~"6)&"'DR(U"rўb8ƌ#wQnBd(DNA/ȃ>C`C`Ka/#`+)fjnG> N{N~p 8NE:! YNpx6xŸ ^^pAJxi ~|| |zIp x.G_A w s K5 ܿGahzi"b$AKY :::::::H' mBö<\|~B"bt: &:I%tt5:_20mvA0UЏB?r*1wCA ;W?;6}/csbqsTPPPPP0t@{b0zF끃|ti^lzFlGlA<Npy7%>p?xxxq[[;满@~|G="\^~5 Mm]=|<~~~~ ~| ~ D3fDb& h%t :Z JbzPm3mBuF)R̴1C@BACХ!\hiN;L-q|YEӀeOX (_6ZfFKմdcQ^l(/6[mѳ -]$a(wvF֙iܝ. zA B,Ft:]2eԎjE20 V dF lFlE6;.c'>>>OOO= x.GCC_~W\M跠߆~] !GC~~~ ߯{Gմ´Z   YQi}t :Z csb`֍LC-Vh"Z7Rku#^>h?tt!tt1t:Rю^DAzګau/ijvAv 0U(4m>jZ<^ӺiqZK^?c:/.Gq;xz0_oo)"~9зq6i  ݠ^hs9h=tXBK0["e`{'piK#6-avnp >:h.\mvp Y//{Kp>p?xxx<^ #W Gׁׂ׃7777[[;@ }x? 0(8I觐g#p9 ,s8yЯ_q @ y<?c//{G8Ak]2dTt LZҔZi%t :Z csqȮ-u6C[6t^(﴾e, " A1D]-srDPi}tt5:_j"elַLC_0B?*4ַ?AOYu,Xѧuк֥tҺ8Ş;2FNNA/ȃ>`C` CBG(Xd#J'C'=!@oCj;.l?<</ !0| ) )y.πGry <@9%A#20 ,~Z- , X0 )J*\c]9QUW;i)`2âSf 6ڻ`ŅZJht ݠ^h]E`1|At K)t `X6#$'Op\CpB 3.̵p?BB rĸ w8s =^b{)^^@ȃ!0v׮oooa(|~\B? >0[;{>xw?3) kQ?@= -@rB[Bv-vP]h](..3*,0AhK>m(;hm]hm]hm]hm]hm]hm]hm]hm]hm]hm]hm]`eLWCf u u - 5 - - wA;Z0;օօƅ֕8ѶжжжжimT6]+7j7ܨ1ܨ+_i bhK#6-E-MK=xO&Cp*| =p' <܍./+kYo77u+mp{r? ~|| )gy<"s Kk{ ܗ?w7-4<2 +nʺQݘu<1+FtcV֍>J ݴT2mB{E`"L%X 7J3n .p' <<//{AJxq^}-xx=xx#x0rcpy| = g#p9 x <@9=ӴEhL0Y AA!+aEzP~pKp/Alׁׂ׃7777#-mH# G8|3QY?>  5C菠?bF/mS;XD*,Pfj| Z@+e刱,`aXIxQ:tPBbÛv Ckⅵ{њxӗ1bXbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,XbyX,a<,X`>Xψ}[ևy3a~G-RF20 >س=0}ԪK\pm"tS%H6v; w#KK}~2 0x5."ׁ׃7Fr 6v }7x\p)i x.GE77w?KhR0Za݇%‡CDP"|(>J䲫<ʅx> f|(>GI߶2߯iڦM%(ť6DɢăF&)O^Ohr#rϘ9q q`b88F qfOA&^KE}ߵ.ba.8;6k>l-0G"w#'%yϤ$LKq9as#L❓ ?j+3Vg$N &>5zO3xy獿em.~_#15M[?5ms]5;fϺ^qjYgYٳΕVg1gZCz6klj3,w:3r3,wZ=z0k5{g11VgP)')?O״gsnrĚk giZӞ=JYٳȳVggg%ƬĘ0k=ajY3:h=lt"弜iS)m6ͦRlJM9;Rμ)gޔ3oSfa)ٔly6Rfa)YXJSMi)-4ДBSZhJ MRfa)YX,,erM9CSΡ)ДYXʙ4Lr&M9ISΤ)gҔYX,,e2 KRfa)YXJM9tє.rM)Дsh94rM9tє.ܔ.ܔ.ܔYX,,s7S:gy3s7S:gy3匙6SΘ)m3匙6Sfa)YX,,e2 K)3Rg91lr6L)gÔΙ2 KiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb4Ŧ)6MiMSlb3G2ZYHu8,eV2XzBFc},e42M#ySƼ)c$cqN3fI m*c1Ge\qNu8d\qNFhP *Ae4Ѡ2TFȘȅ2GQ(c~1?Bu83Ku8.х2PFBd\qNF<'C'C'dm2ZMFh2]%d~1Șqdhdedbd_d\d)2v.2v2v.22v.2v2#c/ud􍌾72FFا"c&1sG#c(I1g7pΝs>g7pn9svuwb 8r[>'C3K>}}s=>|c f‡| §|_%|_-vey  ^5^ wx ooq'8g7pn9sv1W>gpN9W̹jeΕ'scoݜ9sٳg7cissȜݺ9׊ٛJJ,g%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg)?KYR~򳔟Y Y Y Y Y Y Y Y Y Y Y 笄J,=g%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%|Vg%]>6o-wOr[˝wӼuyBօ [w5Լ;ܞr GqIX6 V6njku6>"~ _ &><#(>^$>O3s/I<=O<|U<;_5|+xuo;xx׽;Nw׼C??Ï_ϻbj^wԼ?og!Z3ogϼy?[3ogϼsT󮧚7/J3yk5j:yw[iV9*Yerʹ+*箨rʹ*,s?TP9Cs'T=P9gx6dz9lΕ9@܋s/jνּrz͆qn:%GXU6kv|ְ5 ŦW>G{R;>O'x?~_ï7 >w0>:>9} /K2'W3x-[~|mG._n}xőCGo4 %_k|ߧƿ5ޥ{rVs]Yaιw)g9ޥ{Es͹?4М{r}sf9s9i69תMεj9isZN\69תMNK\A ri9WP紂VsRN+ȹS)g9N;CsTMTYyιS)g9N;r:CN+i98'rr2-g*箥dYi9"Q='_'?|;B~O? ȂN``sssseLsAY0\<{NB~/&\q| 5Ib/Zp{|^c|̸uo#MW7pܑ=6v}x!88 ޏ/Ke ~+_o/'|oa|u1 '}SO3<#;K2IS>i{:rk. ێ\2\n5o;8r5_7 㷽;x~~b|Ʒ~;]2~ƿt`>s/q/~{} ¡ ¡nj{?___'3}lhA[0KZ̕3MlN¡{rhxz%uqՀ w;BɮY&`M` V-xJoz#k z=' -3m Yp̂e\-jEY(eݢhѮE;Ͷu$^O8X߱hcQ:-zBȢtZDEOZ(,JEEk>Ȣ}ExOϧm`"~ _C]#?Ox>>/I<哜3xy"~ۑKy +xuo{;xOoi,zעg|-zעz-U_òho}ˢE;,,9ע9ע9ע9ע9ע9עγ,9΢nx(4+""+""+""+""+""+"HHHHH&D2! LdB$""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""^IHJDzE$%""+""+""+""+""+""! HDzE$C""+""+""+""+""+""+""+""+""+""K^ɥHRWDr)+""+""+""+""+"^^^^^^^^^^^^^^^^^ɷHEzEWDzEWDzEWDzEWDz]ӽ%{Kw}o;=#~?38)Lc0iKYO%d%@.rɎR{'pe`q{3޺# lzq6v}c  E~ 0~‡| |§||_—Ooύ;+|4ٖ$ے%ɶdG~I-ّ_lKv䗬N/s@N/t+B$ے=%K藬N/٣_:q-I%kIZҵ%jIZҩt%KVZ/Y^jdzI-Y^`KlKl[`Kܗ$ؒd}=%+Kzڒ[Ӗْ4[֖%;Kvؗ/a_þd}Ҳ'(.+-'Ir'>ˮYvϲlֳJˮ5]6YeseO3[4eW,gg9I֌>Iwi>?A!|G1|]OS4>sBG(%q9t:>{OI| gY|E| _W$IN<|W_.%^7M| U6q]|?U::::::Nu]u쪳gWWWW*m:T_ꫮ#]U^U^VuU`UX :@A( ^yAHH7iy ^{4~GQ| '')|g猟^0~_—<4x_xgwx 7-W^xӧgg>~gMx][[ʷn}ozO18Nվ/kں4^@5u d]Y@5uW[[.nEn=Q{V5D d]^um>[x5oƺoG)=W:& MU,Z -9RƊW61aOl7O>I‡| $>O3|y_ėe|O)4x|"^5|ķ ^kxoMy o]|?I|TbG%Q}4p򞉆~w5~?q88mGnvԺD{Z7;EMtۣpTg>3ՓzQO:_G(ۣt{n7ݾ8MDwbmh6w|pÝ򆶼hxU_6OcװHӸe|}>#(>~>9}_ėe|O)uY<Ӿj|p/eo[x57O5Sr=򆶼-ohwN=8 mdCF6ooo mdCF6>4Ȇ|HtIt|3 my7t dC>o ~򆶼-o$Ot(?yO$ʟ=E/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")HE/R~_")SW6uMwoRrlz.Ǧrlj)憛IϛIɛ$yMWt6Mt=tMozzƦ6==c36]}8܌M܌MWmznƦ=MMM{(fiMwo~36=%c16N^x 7s dӓ.6=b-6=b6)m6%O3M3M3M3M3M3M3Dio8QڔCӿnicܤMOؤMڤDWJt,o6j6m-vKNnQ˖U- [V*l-;[rr%߲S/c;^s̸'ֽCwo3~+‡| $>O3,> "/+xOyx9U9o|x /ko:;~n$ڶڶڶڶQlYزFebٖճ-g[Rqٖճ-g[V϶mY=ے[RqK*nI-[RqVNlYز_eE[V϶mI-%&Zg8m[(QlYزFe$K^%3\ dW2+dc Jfp%3\Kfp%3~KT]2+JT]2+Jfp%3\ dW2+Jfp%3\ dW2+Jfp%33~_r/Jfp%3\ dW2+Jfp%3\ dW2+ϒ,ϒ\ dW2+Jfp%3\ dW2+Jfp%3\^r~/9K%3\ dW2+Jfp%3\Kfp%3\ dW2+m dW2+t[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖLe-mnt[2ݖbMb5BWT\SϊyVEPi<*t*ҩPiܪVJT4Ҋ抽披t*C\\ܪBPlb+[ V4t*fEìh _qNyBiJPZZ*RswU:yMU:WT\SqNU:WT\S1hUV#TʊVY*+ZeEhg}}}t*ҩT\SnY-+v*v*ݲ[Vtˊt*ҩJ*tR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-UjRKZR*TJ-v]߲mmgۜe9qۜeۜeۜe5vg MVu=;e۳SVS1MEf+f+ۉ^O]ǛG4~GQ| 'I| gY|_ėe|O)s/ "^ˎo^x x Ixttttog%JSj;j8'J'_ =vGmȐȐccǙhǞ+wv{Xޱ>h30wȓ;;IL_Ss6pWSA|GQ| '')|gs$// S4xΧ}{7Eko:;~ֻ>{)82]ٱc}x;CQ;CQ;f;;ILӾzg1s8OfGHܑ0;fJw$̎iܱscz'əO?ږ3;rfGș9sɖcZֱD'\{冯n%cǫl8~ֽ̑sw5-A|GQ| '')|g9E| _W$x9U/%^7M| U|?7e)MN185~vL;ߎoc.w̺ܱD;[;KԘqıD{w%ڛ?6c#V5M&EkR&EkvjvjvjVkRn`7}]kvj}M+Q`M֬ZԬZ\S5)Zj}kR&EkRF5)Z5l5l5l5l5lD/ S4xΧ}9Hͽ5m(F5)Z\\\j֓k֓k֓k֓k֓랐PꞐPƺ}]]]{u4_4_:A u;quۉkDo%٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A lg>٠}6A l}]W)u_ޮLȴL5v]t7%,cWaxױi|}a|q|w=O >3~%|_x9g,W<^.%^7M| U[x{nDS~i3T]S$]]]]ju{wݳ]#8WO'x?~{_o7A!|q|SƧ s]7rmG.'?ƛnm_.v}`[~:v5Cx1ύ?a<}qׇ99o]+rm?aYq8c0<~_/Wku~z§|g~|_—8=9y*鞧29y*s랧29q^CNcIT8t/qti9l7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nsS>7M}nڷ J}`w{rƟÎb Ә9qY4Cp yԧtߎ}w~ߎ};nvq۷׶Jaw O'x?~?{_/+U~A|GQ| g~7>}N<귌/_o;r;]Gc|k~b|Ʒ_W}k;O/?0C?2c5_ow+W};վ}j߮⾿rh;1r0[ Lv7&MwS49weڷgMOh#}$CN۝ܷ;owr䁴9p?6wMw$aO???9ia6c<)Lc猳9\sC`bKO s m\su\ȟs K@ H)t \u9 *q ҁ\: $n$olϿa~c }%2~s~ oE>}§|ֻ=g /K2'3x}}˿Or%_5ooxőCGo}Oo;-2~ӱloJJ{zc3>c3>c3>c32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!32cȌ!3 yp_~YYY]f'ϯc7ҟӟg/울pyys/|#7/|#w/|w/@/@/@/@/@/@/@/@/@/Nh#?}l\eZUZ;+WƟH%}c^ҿs?4~ =......N|^DY~?@;{=PS_]<\bbbfafa_f^\WxGDY=yiuR'\8‰4] q!.3yr'yr'yr'yr'yr'yrqqqqq9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι98gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8gs8g89Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι9Ι2C?'s?'s?'s?'s?'s?'s?'s?'s?'s?'s?'s?'s?'s @f?' D{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{I'ўD{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ )ОB{ _?sϽsi짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~i짱~igОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОA{gОE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўE{YgўEs/OL}av]>wF^v]}[νxi}M/Oܞ_\%Wҏ_o?~.=Y<+A4E4CoyK]eZUkAE_mvhhy'#:{Xҕ+kgjqHD;==//ї=+eWƯƯyyOХM/lzLK^uuiEޫK+v`]ZѼҊ]^ݥuK߫y{u5/ozdKg^:9wiե/t=V޾S3E>SB[B[B[B[B[B[B[B[B[VhVh@ m m m m m m m m m m m m m m m m m m m m m m m m m m m m mQKQHQu^=wJ?k'=߿Iۮ|G9mWu囲W+xW}e;i_IW}^Wl|uxOO;#{- /OuӏП??ks= (_;oc1{'Ώػ*2*kzYuڠMڢ/6}B;K{OtHK }}NgsaIttG?O@@HD_/B_:*pcr~잫s{>vǧqַoF˳~/ȼyc5kcT?>Q}~Y;o?>8GtB_{Olۏg9;|;|;ͷK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.aK.a.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c2.c +H +H +H +H +H +H +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` +` V+X` V|ʇ|*z譢*z譢*z譢*z譢*z譢*z譢ʇb*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b***b*خbkخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخakخa][%>QW')#]?DK'9W~+觿ߜxy/~>+|+0+}l\eZUZom}cOqhyֈ>n3+l~~~~D_ }5_οj5~zx~̉~3} =s~k_Mqv*Sk\<')>C~~N][߻wk|ztk]h?=DwYvF}rGZ뻶wmZߵ֮vkg];k 7 7wqwA oD?o L o7 v 7ȿA o~'8 I7Nqnpn`7vn`7vn`7'Ϗi?~:]ڣ}:Cz睌NS65钮+l~~~~D_ }5_οj5~z&7ȿA o`7 vn`7v 7ȿA o 7ȿA o o~_7ȿq 7ȿA o 7ȿA ܾܾ:s:c:s:ܾ:똯s:ܾ:똯c:똯c:cܾܾܾܾܾܾܾ:s:s:s:똯c:똯cܾܾܾܾܾܾ똯c:cܾ:똯c:똯s:s:c:똯c:똯c:똯c:ܾ:ܾ:c:똯c:똯c:c:똯co`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`o`曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob&曘ob[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oa[oaow߿񅓾C2y{"~~"ާ[{nkӭ;Z"'U?yԭ}PȿJyk*U[ν=ds{niVi^NI[6~vGt@γFtL'w;5Ͻ%]ӍW<"}5_׽~:o["DO[3hڣuk-oXZbyk֊[+Nuݭn\SNby{"tDدu[گuk-okȿEi&{D̉~}۷Ʒk׶Fxm޶mw_6ۨnmw_}mvQm~Fu | | | | | | |mvk׶ƶ}m4~~~ն6vk׶mw_}m䴑FN9mvk׶mw_6r<3<-vkmw_-mҶmw_-mFKOk׶mw_'>yy< 'OpnOmOm_u3 ~oy''?cD˴BFׯm}kwGt@1Ч{X5x-/==//ї^*}{~~~;9^5O|^5O|^5ONxz͓[KF=.~ⓚ'>yⓚ'';OjONwⓚ'>y'>yⓚ'|rvqO}btOgtOgt:\p>;\:(pp렴:\:\:\:\:\: b; pppp :h頥ppppppppppppppp :\:\:\:\:\:\:\.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥.Zh颥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zzh顥Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>Zh飥>ZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZheZhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe!Zhe;kwvY=;s;kwSt;Ys5;D!QwwwwVu;wuw"%* ^37~c6h s .>!#:Իz3K;yE%}kB_yWFpwCP}gΚ5;kwhC~;s;s;s;s;s;s;ߡwhy;s;kww"[wȿCI?M?Cϻw|||G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G!G#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ  'ȟ Nf{}OنOmxz"xӏП3Oy<|ç'UW_8OO̟E?ޮ\yJ{( ^37i6iwGt@1Щ6{tM7;yE%}+B_yӯү?3OiOFiOFMod<}[o=OO"']?^>5{}jSg >uS >=}Vq>T?uST?=Q}]'?=o{MZLZLZLZLZLZLZLZL8j1EO9ԪŔNN8j1j1j1S;j1SSSSSSSSS:?SL3SSn9j1j1j1j1j1j1j1xSSSlS6lS6iSSSSn6j1fSn6fSn6fSSSSSSSSS3n6f3n6f3n6f3n6f3n6f3n6ό3f3n6f3n6f3n6f3n6Ҍ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ8C 34θٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ٌ͸ 3;f3n6f3n6f3n6f3n6f3n6f3n6f3TP=C 3TP=f3n6f3n6f3n6f3n6f3n6f3n6f3n6fȼwMYz{?coN~8 ='{ߞ{ߞ^"{;j}on{ߕ?{~G?v{?N?ʧ?0N$M4,}]uڠMڢ/xm;qDtBҩxV`ҭ+xOK%e }}5}:wuzmxo9}K+w|{ߘw>;Ld{߿1?lw1~>/>ݽ8Ow"'O*8 j5>Wߟ>gzo޾{v۹ognܬmn\Bss;v\f;1`FN ;1`n޳gs;:;1`n67S\=ͥ0\ZK siansUgs?>|nmn67GȜ\Kscns?>|n2X\EU޳v@ہ6mnhs?>mnfgslnv67;c{n>}hs;y9N ۍ6mn܉s'̱=wb܉s'؞c{9^ bS,tN):BX bS,tN):B,tNP bS,tN):BX bS,0):BX bS,tN):BX bS,tN):B-,tN):BX bS,tN)`S,TBX bS,tN):BX bS,tN):BX b.bS,tN):BX bS,tN):BX bS,tN):BX bS,tN):BX b:BXN):BX bS,tN):B5-tN):B5-TB5-TB5-uN):RXKbS,RXK5):RXKbS,uN):RXKbj:RXKbS,uN):RXKbS,uXKbS,uN):RXKbS,uYK5):RXKbS,uN):RXKbS,uNTK):RXKbS,uN):RXKbS,uN):RXKbS,u%:RXKbS,uNDRXKbS,uNRXKbS,Kl/)V:JX+bStN)V:JX+bSt*X+b V:JX+bStN)V:JXa~StN)V:JX+bStN)V:JX+bStZX+bStN)V:JX+bSTJXN)V:JX+bStN)V:JX+bStN)V:J]JX+bStN)V:JX+bStN)V:JX+bStN)V:JX+bStN)V:J5tNR/+bStN)V:JX+bStjZ+bStjZjZjZkbSuN):ZXF?'__2e+c~ƿa|kbS}eSuN):ZXkbSuN):ZXN):ZXkbSuN):ZX>ZX>ZXkbSuN):ZXkbSu: }F____ΝbSuN):ZXkbSuN)E:ZXkbSuﶬuN):ZXkbN):ZX[][]ZXkbSkl g~jszgr'?Do3~;=s0~'}}7}ǿ}?b{8 ?ߜ\o|~4s/_Dgg}\+?ɓ<ӭ=iߥG?KC?J98Mxnhfh^z9{JL+Jkxn6h ^mĸcܥ=ڧ:wtDtBz;Yҕ+kg Cu%2ݻrGWh_2K㗌uB_v_1kW=?nO_3g6~gp_,'W\usՍ6>]Hy"6ƙnFZal|ƺg)b 7 @@@@@@@@@@@@@@@@@c)"")"")"")"")"")"PJ @@@@@@@@@@@@@@@@@@@@@@@@@@@D%.p@@@@@@@@@@@@@@L E&"HHHHHHHHHHHHHHHHHg RD)""^H RD)"HHHHHHHH@@@@xi E5")"")"")"/ xiK^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґ4!/ yiKC^Ґnȶfd[3֌lkF5#ۚm֖kmȶfd[3֌lkF5#ۚmȶfd[3-ښmy֌lkF5#ۚmȶfd[3֌lkF5#ۚmȶfd[3֌lkF5#ۚmȶfd[3֌lkF5#ۚmÖ?lÖ?lȶfd[3֌lkF5#ۚmȶfd[3֌lkF5#ۚmUV]oU֌lkF5#ۚmȶfd[3֌lkF5#ۚmȶfd[3VmUV}mȶ*ki*hkF5#ۚmȶfd[3֌lkFU[3֌l-fd[3֌lkF5#ۚmE[oIIIIIIIIIIIIIIIIIzc$EDRD$EDRD$EDRD$EDRD$EDRD$ED1RIIIIIIIIIIIIIIIIIIIIIIIIIIID%".IIIIIIIIIIIIIIDRDs")""")""")""")""")""")""")""")""")""")""")""")""")""")""")""")""")"lH\$EDRD")"xH_$ED<0"")""")""")""")""")""")""")""")"""IIII/FRD$EDRD$EDRD$ED4/xiKwRNI;)b'E줈"v\kǵvRNI;)b'E줈"vRNI;"vk'E줈"vRNI;)b'E줈"vRNI;)b'E줈"vRNI;)b'E줈"vavavRNI;)b'E줈"vRNI;)b'E줈"v{w*z'E줈"vRNI;)b'E줈"vRNI;)bvlvRNeN5N"vRNI;)b'E줈I;)b'E쐿NI;)b'E줈"v!w?w"OVO^s^s^sǿ/zԱ8)oѷѷ?B?`'gyƋË*;)O{K~>C#O?Nc4N/~i>%ZZ5zM_s+Krem9@/_җ=*;}oG׍7zkg&o<{c 7S^T#/)/O=;,/ЇcxgoFԩS/EA_x>?2AC?6vG+7ҟ?E#ϽA~P, K?`?҃ 9?H*A=;}~.=Y<1ӄ&iifGhWiiVi^<1:#::{\Y? iD?1H%|WƯOd5g6>5 >A?HzOV\m=k}Tr >r~ >r\pr~=Nqo{pYA/~ЋA/~Ћ{ Ͻ{^ec{{s.{s/Ͻ{so^˟{s^˟{s?5w{ k`^{ػގĽ{;v$H6ގĽ#qoGގĽ{;v$U^U^Ͻ?5w{ Hۑ#qoGގĽ{;v$HۑW{W{l˟{lݻ^˟{s/Ͻ?v$Hۑ#q/Ͻ?^^^ϽW#{ձW{*b/KܫlϽ?^˟{sн=c~=?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`?`(UʣTy*RQJG(UʣTy*RQfؘac6fؘac6fؘac6fؘac6fؘac6fؘac6fؘac6fؘacac6fؘac6f| 3l̰Ɋ6fؘac6fؘac6fؘac6fؘac6fؘac6fؘac6fؘac6fؘac6fؘac6ff666fؘac6fؘac6fؘac6fؘac6617f 3l̰1 3l̰1 3l̰1 3l̰1 3l̰1 3l̰1 3l̰1 3l̰1 3l̰|61Ʋ"fXb ˍac612$fX 3l,Ob6fؘac3l̰1 3l̰1 3l̰1 3l̰1&6M,mz cǰ=1lόxa{ cǰ=1la{ c'z c'z cǰ=1la{ cǰ=1la{ cǰ=1lϴLkϴLka{ cǰ=1la{ cǰ=1lϜLhlǰ=1la{ cǰ=1la{ cǰ=1lNKϤǰ=33=sc؞1la{ǰ=1la{ cǰ=1la{z{z{z>a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aӗaM6a؄aM6a|% 0l°J6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a؄aM6a&f61M6a؄aM6a؄aM6a؄aM6a؄aM61 &7a' 0l° & 0l° & 0l° & 0l° & 0l° & 0l° & 0l° & 0l° & 0l°|H6 &"aDb$ ȍaM6 &2$aD$ 0l"OM6a؄aْ0l° & 0l° & 0l° & 0l° &&6IM"m g>ϰ}3lߌxa g>ϰ}3la g>/ g>/ g>ϰ}3la g>ϰ}3la g>ϰ}3lߴMkߴMka g>ϰ}3la g>ϰ}3lߜMhlϰ}3la g>ϰ}3la g>ϰ}3lNKߤϰ}37}sgؾ3laϰ}3la g>ϰ}3lazzz3m^ݳδ96c۝Mݚ2mla;x9^xZrCx~:>gMYSvO:;M+5x7x 걷e ~߰7[m~ew»9%/ol_Zg Ƙ5G8Oqs< PP/+:9J\Y8f&:Ag}u$B]伝vr;gsxκYgu9z'?Uo~d! Yf2C̐e,3d! Yf2C̐e,3d! Yf2C̐e,3d! Yf2C Ќ Ȑeb2C̐e,3d! Yf2C̐e,3d! Yf2C̐e,3d! Yf2C̐efhj,3d! Yf2C̐e,3d! Yf2C̐e,3d! Yf2C̐e,3d! Yf2C̐e,3d! Yf2C32dIм Yfhj,34;C̐e,3d! Yf2C̐e,3d! Yf2C̐e,34kC̐e,3d! Yf2C! Yf2C̈eFfp2#̈eF,3bˌXf2#̈eF,3bˌLʈeF,3bˌLLЈeF,3bïeF,3bˌXf2#̈eF,3bˌXf2#̈eF,3bˌXf2#22/#̈eF,3bˌXf2#̈eF,3bˌXf2#̈eF,3bˌXf2#̈eF,3bˌXf2#̈eF,3bˌXf2#42;#S32/#2bˌXf2#̈eF,3bˌXf2#?bˌXf2#ˌXf2#̘e:|2c̘e,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌŘe,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌMԌYf2c̘e,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌYf2c̘efd2c2fyԌYflv,3f1ˌYf2c̘e,3f1ˌYf2c̘e,3f1ˌYfl,3f1ˌYf2c̘e,36c̘e,3f Le&,3a LXf2̄e&,3a LXf2 LXf2 LXf24a LXf2̄e&,3a LXf2̄e&,3a LXf2̄e&eb^&,3a LXf2̄e&,3a LXf2̄e&,3a LXf2̄e&,3a LXf2̄e&,3a LXf2̄e&&hbv&fb^&&e2̄e&,3a LXf2̄e&:2̄e&,3̄e&,3as>>\;iy͹S~ ?OO?뱟_c F7-[-+ {^lA|GQ|L >9mDߞss>y9ss>a<.d)o1s=osE/N/z} p=Lλy09o=$uyw&9'ϧ]=x3bͯ?O3v»?>>~ħi|mk#X=Q#GqHX:n1ē`Clevu6^WUK9o|v=}q^qwbq7cS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9ՓS=9Փ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓ3=9ӓu ~w}oM0+'Sx5fղܿ]j댠]g]GRwבԮ.u$ks7շSވ7Yr-ܢGQwxދz‡|6S?YP?O >ym%WW5|O6b{[wqs/segv \]:h]wC]ݸwCݵ/k_t׾}]iOfۿJ?1]'wCt_4]߹pu Kwc]Pi{ҽЌ)玞7w4sy;sy;sy;sy;sy;sy;sy;s#m>~\I| gY||_3x k-om|.;9 z{ $;sx={9sx='cd잌ݓ{2vO9sx={9ӓ{=gW9rٕ{ig}{9soݷo/b?Oif8f{u^ľ}ݻo/b^ľ}{igOUѳ_g/Y~=`7MܬE}kc» >#-?~ܫ}B$>O3,>Q x_j_R~kx_m | o;.v}ܱNpsy \پľ}}%KۗO{;rx }}I/c}}}>|߷K}I/i&;cy_ۗO<]b_b߾ľ}}ݾ/{}}p_}cطoc>Ɓ}MYUg"z[D] ߁l܅]܅xȁ={ rDH$>E_:K{%7x͔z_#1?ß % \wxދća|'I| gY|Ϋz_3%Κ7,yS|>w,GzyY5|}:z`؇9adؓ9`w<0q%xG\sG\sG\sG\sG\sNTOsw`?{;r`oe3s`C0>$>O3,>5u}uA_.J+ퟔN|A\9t΅s޼V]SyCT5>tO]#yCH5vxP>C?<7Ϟ])yCWJ:Z9t+%]#yCH5s^E?}_U| g{o[]aw͇zw^{R^b 븁pOb eWvQ6^Wֹ*d{)?UG}=r)]>Kw8#؋cUGӭ],g~?gZig=s|`k,V}z3ވ7Yf۹E}wz%wxދ?>jW?~§|: u/+^ën o['|w=mp^+Ye>INyq<;(exiu<'=M ~:?1;(Y-/?Jy%g0ɋ%2b}x,X^,K/Ύ\ot$os6os6'is6'is6'is6'is6'is6s6os6'is6'is6cs6'is6'is6'is6'is6'is6'is6'is6'is6'is6'is6s6'is6'is6'is6s6'is:s9'is6'is6'is6'is6'is6'is6'is6'is6'is6'is6'is6sz>'is6'is6'is6'is6'is6'is6'is6'is6'is6'is<'is6'is6'is6s6'is6'is:<'i:6/i:6/i6/i6/i6/i:3/i6/i6/i:6/i6/i6/i6o6/i6/i6/i6/i6/i6/i6/i1/i6/i6/i6/i6'6/iz2'636/i6/i6/i6/i6/i6/i6/i6/i.6/i6/i6/i6/i6/i6/i6/i6/i6/i6/i66/i6/i6/i6/i6'6/i0/i6/i6/i6/i6/i i i i i i i i i i i i : i i i i i i i i i i i z i i i i i i i i i i i i i i i i z i i i i i i i i i i i i i i cc(i(i(i3(i(ic(i(i(i(i(i(i(i(i(i(i(i(i(i(iz(i'z(i:(i(i(i(i(i(i(i(i늺(i(i(i(i(i(i(i(i(i(i(i:(i(i(i(i(iz(i(i(i(i(ioKoK$iK$iK$iK$iK$iKKoK$iK$iKcK$iK$iK$iK$iK$iK$iK$iK$iK$iK$iKK$iK$iK$iKK$iKK$iK$iK$iK$iK$iK$iK$iK$iK$iK$iK$iKKz$iK$iK$iK$iK$iK$iK$iK$iK$iK$iK$iK$iK$iKK$iK$iK:$i:,i:,i˒,i˒,i˒,i:,i˒,i˒,i:,i˒,i˒,i˒o˒,i˒,i˒,i˒,i˒,i˒,i˒,i˺,i˒,i˒,i˒,i˒'˒,iz'˒3˒,i˒,i˒,i˒,i˒,i˒,i˒,i˒,i˺ʒ,i˒,i˒,i˒,i˒,i˒,i˒,i˒,i˒,i˒,i˒˒,i˒,i˒,i˒,i˒'˒,i,i˒,i˒,i˒,i˒,ifrK}4[Sc|OvdOvLt^-lc/+GW?W~I+M[y6v2~_oX-6~;wxދWK^Zg ƘuF8OqeSq٧$G}>r'#G}&rԧ!G}qG}qgG'RFeI ;^|~:GOCH7>8}7‘>83>83>8sU))hvEEs}6q4Ѳe§O%.Y>_50'Y_]cj%Q6uǥi2gk~p5oF)K}x4~杶vލxޏzy=KկXU| w<'k{~ *c/I2cx"{F^/K26^W1RsT\C.칲mRQY}:5g)եRp~4ތ#٘n:ƌ)+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+"+:"+"+"++"+"+"+"+"+"+b*fb************{***********************sz[:********k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k&k:&k&k&kk&k&k&k&k&k&kfjffj.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱{벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱.벱sz[:.벱.벱.벱.벱.벱겱.벱.벱.7}iʪ4F,Lۖm^?B>+«Q5wJ7tޕp3'79ᝨ gNndWo[,o*~ QPw{}c?ƟOgskށ_x'ޅw=x/އ>#uS?<~§|_k,V}m~I}x3]C?şwzn~|C0>S?OS4>s=NJyގJ{D:w;eeG?><NE\TLy:j w»}‡| ')|g[{_-?]aw#̎NO OO O>W}w§{'.sISQ禿ϔ77DzyiK/-:j󢖺fM{.6]l{ٚOYj=3|?g {5U:z:7Mx5o[-wkt;~_ů7M~s_=xxk}>ࣶq}B$>O3,>gئM{bS6mzOl3=NIel3=NIkfqJVg{hKt%:aJVh%chefV6dӾ&lڣ, tN¦M{w6YΎ6O_N2>jˏJP?O >ڗle+·|>'}ϲd1Cʋ1E,cӓ|zOOt6dsM4M}y?Cy?Cy?Cy?Cy?CʄP&~!~!~!~!~!~!~!~!~!JC~(BeQD y?CS y?T!ʫC~!~!~(By?Cy?Cy?Pr/{!~!~&7O&7Oߔ?Mo~i~i~MhJ&7yM &7yMo~&7yMo~ߔM ДM h~&7yMo~&7yiƛfiƛ&7yMo~&7yMo~&7yiifiʚjij~5MP&7H&7y&7yM?vJY*Zߑ2KS>~6^yuZK߈7Yrk/p;~_ů׭ &~ ?ּ_S/v7ރZ~~|oG=~Q,yܒ'IK§˟U?Pg[K:.꒺>3|{HU]Sc{7-960&_r)r)r6)rN)rf)uʽNٕmӄ ߲O GK :5Kt%:_ x&N'yJ._K.jҕީ4ҙ-g>:?o6}OO;t3R~ ?gǧx:5n/X~%תK\7xl[Էּ {^<˃>yL>O >Yy|^Kկ_u[x?]aw%G8]Džg\eLQd1< lbvvigvvigvvigvv鴇NOOMj=viڧKv]ƿZ{:t FfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFfěoFe/sMe/s^e]Sކcvlܒ[q{[>rV{I^|Xtk[n*[%Ͷ4˶v%h׫oP߈7͖ojo*~ Q?'Sڳiw{^SߏXA|GQ| 'I| gY|+y_3"{55^|Ò7ow=YkpzwVX2fo˖3ܿey[߲l-oْ[Ιrs&3-Ln9r\~q#W?Uo'y;f[xJwHr_-ugΖJ4]Ӝn-eBL 6&tۄn{jW~?W}j_)O[3ڱm׎mvl;XZuvٶڶ?mʶ-l[6e-=]GmxW޿նm_m{j;C0>z͏'I| gY|Ζ վu~W5|O6b{w=?W_Bv-۶kٶ]˶Zmײmm;U1Ι|[oۋ|[om}mFն}p,i}pʬ÷/m[ommz~6m6l6lmuoqMkZ\״5-iqMkZ\״5-3״5-i״eZ5-i״5-iqMkZ\״5-iqMkZ\״5-iqMkZ\״5-iqMkZ\״5-iqMkZfeZfeZ\״5-iqMkZ\״5-iqMkZ\״5-iqMkZ\״5-iqMkZ\״5-iqMkZ\⚖kqM e[fe[fe[f5-iqMkZ\״5-i״`kZ&5-״L\ĵL\ĵL\k\6״5misM5misMk\6״m\暶jsM۔5mS6״5misMk\6״5misMk\6״5misMk\暶hh6״5misMk\6״5misMk\6״5misMk\6״5misMk\6״5mm暶>o>o>osMk\6״5misM[5m}m6״5misMk:::5pMk:\t5pMk:\tHk:\tc:\ᚎY蘂tc :\t5pMk:\t5pMk:\t5pMk:\t5pMk:\t5阩꘩pMk:\t5pMk:\t5pMk:\t5pMk:\t-8\`{@{栤g9!Tn{=v*IS9xog(B BmI6ٖG؎ԃ۲e ֪^g}W,usM/rM/rM/rM/rM/rM/rM^952W^9+{`/rM/rM/rM/rM/rML^952kzc/rMq2Wʸ5)pMk \S<*pMk \S5)pMA~5U,+pMk 5)pMk \S5)pMk \S5)pMk \S5yQyQ)pMk \S5)pMk \S5)pMk \S5)pMk \S5)pMk "5q^q^q^5)pMk \S/pMk b5)pMk \SD~AD~AD~k\S"5E)rMk\S"5E)ʑ"5E)rMQ.5EPE)rMQ5E)rMk\S"5E)rMk\S"5E)rMk\S"5E)rMk\S"5E)rMk\SSE9USE9U"5E)rMk\S"5E)rMk\S"5E)rMk\S"5E)rMk\S"5E)rMk\S"e_kr5EXE9XE9XE)rMk\S"5E)rMQ&(\SE)"(2(2(J\Sה5%)qMkJ5%)qMkJ\Sה5%UהWkJ5%)ɲה5%)qMkJ\Sה5%)qMkJ\Sה5%)qMkJ\SהEI^EI^5%)qMkJ\Sה5%)qMkJ\Sה5%)qMkJ\Sה5%)qMkJ\Sה5%)8/הyIyIykJ\Sה5%)qMkJ"5%)/ה5%)qMkJ\S%_%_e)sMk\S2ה5e)sMk\S2ה,G\S2ה5eP2הBY5eYP2ה5e)sMk\S2ה5e)sMk\S2ה5e)sMk\S2ה5e)sMk\S2ה5e)sMYNTYNTk\S2ה5e)sMk\S2ה5e)sMk\S2ה5e)sMk\S2ה5e)sMk\S2ה5e)sMk\S}e)2הebY`Y`Y5e)sMk\S2ה5eX暲,sMY&,\S暲+˸+˸>>ρ<>ρ>ρ yx~߼3R=|ǖl\0}\'e}YogR_Ȳە>{>> |秕}3s2pGQ=L4Ž8pN)U_ Yogq}yKyK'qMh}"ʄ>q'y8}\=@qS_pMؿUO}$-}!YogT}VYEa*$U1U̓+,_a WXFx-Y1T\KV\KV\KV̟+~*^1 U(4>b}r W̟+-UD3ފoŌb[1㭘Vx+^f0{EvWdw+f]a W"+^Jbr*UNVr+6y+l^a Wؼ6y%de!<2³s++f3ۊm̶6y+2r'HȚȫ5k+0WaX\1_VQ+<^1Gx++f] Q+s-cVٶʶUXe*Vٶ*l[e*VٶʶUmml[e*VٶʶUmml[e*VٶʶUmml[e*VٶʶUmml[e*VٶʶUmUWٶ*l[e*VٶʶUmml[e*VٶʶUmml[e*VٶʶUcEml[e*VٶʶUGml[e*VٶʶUmml[e*VٶʶUmml[e*VٶʶUmml[e*VٶjDmml[e۪ѩjtmm [e*VʰԂ 6+_)4~ zec|7DB{+DB'q"_ů9~WQa|o›ʷj~?߁b˟Ogs/+5'3v*߇ >#(>$>O >sxx;T>|XrW(x 1fF~.7{vAѬ߳ f]]2܌x~?>Fii{OGѬ:/: X6x7;w7ݼ~3~VRQߨտA=ߨot~V{:A!NHwyѣo^0,~",~",~",opcTf/*g B0 v,\; v0 xqf83`00 g\5 x ʀ_h> >#(>$>O?,> "d˗8fT51 i܍38{q<.!~ \A p1 dրM2h@ Ț2?\?>~uӀ_řƀ_\A ȈO<0 h1b;D x x L2u)SL2u)SL2u)SL2u)SL2u)SL2u)SL2u*RʬTfL2u*RN:A)S2(A J:A J:eꔩSN:eꔩSN:eꔩSN:eꔩSN:eꔩSN:eꔩSN:eꔩSNet*STF2:ѩNet*STF2:eTF2:ѩNet*SN:eꔩSN:eTF2:eT^LSNezԩ|O:eT=eT֧LS#@)SL2u)SL2u)SƊSN:eꔩSN:eꔩSN:eꔩSN:5LORN*)SƖSN3)SFScNԩ'eꔩSN:eꔩSN:eꔩSN:eꔩSN:eꔩSR)SL2u)SL2ujJ:5jLRN`)SL2u)SL2u)SL]cSטf$1uxR3Ԍ'51ukFSט51u8ScqfgjL]3Ԍ351ukL]5y]5y]5y]5y]5y]5y]5y]cꚼ뚼뚼Sט51ukL]5y]5\5[cSdnMlMikL]c1ukL]cSט51uk&jr&j2&wj&_jL]cSט51ukL]cSט5QcSט5_5^51ukL]cSטu3uL]g:Sיu3uL]g:Sיu3uL]g:Sיu˯̪ˬ̪3uruˠ:SeP]eP2.L]g:Sיu3uL]g:Sיu3uL]g:Sיu3uL]g:Sי.2.2.2.2.2.2.2u]u]u]u3uL]g:Sי.2uy]g3u2u^g:S{]י.L]uL]g:Sיu3uL]g꺱u3uL]g:Sיu3uL]g:S׍$uOL]7ԙnl3uƙ:S׍6usL]7ԙu3uL]g:Sיu3uL]g:SיuRL]g:Sיu3uxUgQaL]g:Sיu3uL`S7a$i0ux04' n0uFS7 n0u8`qaigL043 n0uLݐ yݐ yݐ yݐ yݐ yݐ yݐ y`ꆼn놼n놼nS7 n0uLݐ yݐ ܐ `S7dnC6lC6iL`k0uL`S7 n0u!r!2!w!_L`S7 n0uL`S7 `S7   n0uL`S7=MOjzrӺͦw}6-Molzg=~Ϧ{6߳Molzg]d 7T*'h5=iZS7ym6lZٴnifӺͦ7r6鍜Molz#g9FΦ7r6Z/kM5ٳ))))մҲ)ڛieS7+]MlzWfӻ2V5kZ9N̦wb6XMlz'f;1ކ̦7`6魗Mlzeӻ,M5BPӯBM5Y=MozrS7=ݔMnʦR6}Molzeӊ1ioFN6Mϱlzes,5 CCP=$ڇKHHHEE^2#2#2#2#22 !o!oԸ!b!?d4q;'39މ[>K}~|ća|c8>O >:s _W3OiAG>/O-kc80Ӹgpy\pV!|]|_xeuOݤ}m܂6{A|GQ>OoyZyw=,> "d˗8(p'aq7,9Oհb;?^)Ěl<37Xwa'`ڛF^Xsa<+xG~{zƸ{zV k`=y}co\~߳* q]]g({y;/߯؊{bjdў{A|e|em_aOWq covpwn|gk>k&PMpfb/_7*_psb`T Q10*Fb`T Q10*Fb`T Q10*Fb`T Q10*Fb`T Q1jWB{_5y~5:2f!+6{̅j8S9'Cf21aEYU1_(!_ \_ÜA|0\<#O*_q q܉<< W_l$)W>mrz_WլŲ9_C|XcfcfcuL|19fV0&> 3+3+3+3+3+3+3+3+3+3+3+3+cfczy̬`̬`̬`̬`̬`Ll<<<J!ŵべcx_W18_S x"'''''''qq8n.&|qnbr;nvǼ]Lnv1OvO"s.&whmܡ;q6ڸCwhmܡ;q6ڸCwhmܡ;q6ڸCwhmܡ;q6ڸCwhmܡ;q6Ɲt)vʻn)vʻn)vʻn)vʻn)vʻn)vʻn)&¤^ zaR/LI0&¤^ zaR/LI0&¤^ zaR/LI0&¤^ zaR/LI0&¤^ zaR/L)m)m)m)m)m)m)m)m)m)m)m)m)m)m)m)m)m)m)mimimimimimimimimimimimimimimimimimimim]f(vQ2/eaWԏ*by.]+v]+vW {Rլmp;w/۶<|:xxn}[֧n}[֧n}[֧n}[֧n}[֧n}[֧n}[֧n}[֧n}[֧n}>}COЧo>}3eaWp }>}COpЧo7O㞧q7p?ywE\·2)z>l83ƌ1c4l83ƌ1l̘83ƌ1l̘83ƌ1c4l83m9qNfތ33#ggq~fgF΄(] <|9v-gs9|cL qŸ7F7aәG{ڡuo}j&R=-ߖmWmWmsȶ36l;3mWmWmWm1vvvfڮ:ۮ:L9iy]oͶͶ+Ͷ+Ͷsv$svNڮ4I[Ķ]i]i]i]iκulYͺc6kulYwf1ulYwf]Ϻc6٬;fͺc6٬;fͺc6٬;ffMͺuliYwfͣf1ulYwf1ulYwf1ulYwf1ulL#=2}{d=\G{d=2}Le{dG{.#pٽGv{d.e{D9Ȧ="d:f{̈́ {̈́ #{̈́f{e^߸Lx^}Lx^W{̈́ 5 d>ٺO3ǰ>F7Ͻ}c}sod{#s4|ל3f9fc9cœc9fc9fc91q`s>s>s>s>}80gc911~mܯq6ڸ_k~mܯq6ڸ_k~mܯq6ڸ_k~mܯq6ڸ_k~mܯq6x@x@x@Юb怘9 fb怘9xb怘w>}׼]w>ys;9|;9|;9|;9|;w>ysw>ysw>3bfŤQ13*fF̨3JfŤQ13*fF̨y2bfŤQ13*fF̨3bftʌQ13*fF̨3#UfŤQQ13*fF̘;ގvhoG{;ގvhoG{;ގvhoG{;ގvhoG{;ގvhoG{^ bxA /1 ^ bxA /1 ^ bxA /1 ^ bxA /1 ^ bxA /7x 8xv.p0M_£ly\.ƛ!kNݛu|Wmy{3.Cφ6F+oT7afhC:rPhckW[xwxO)ۜ3{pՖ+ǵXzH!uHCzV֊kzV֊Zq8x;q<'bi9{p{V{ЊáV֊áq؊#su9s_1e9a#,seoٕcqe=>py[t*Gm|xOgYt~EgYtfG^p#^0%dIV.uroK~{]r KnoKdɷ/=.uoK~{]?3;EN.rrg#w6rg#9;;#EN.rrg&w<3;3c˝ܙEN"'w~r;?;?ɝ]]]o-ۿel߲[GmT/ GQpT/z^8G^8ꅣz^xv%NM.=uHuʞOSpھ7/UsKlRI&5Lej6٬f\j.Wa5Va5WBj濩jjj>#j>J5WRG|TG|L|LR/5[V|\|\UjRsOOZjVsk\j>j>Sj>3j>3jY?g5UY5Us\sj>sjWsUӫOM>5Wy5W5_P5DM_MX_31/Sެ| Z3OU,^ X}Iܧ6`8-S_/~_ m_뾉ow=qm"&﫿f-ʷ6}b8{?şN܂f_/Wk ?}Og ;xm|‡|ԙy 'I|6O+*?,> "d˗8(ꌽ<Wކ]y'NRVqV^ܧfNy)+.Sa#]<𸿞P^V>|Vb9G|AAʗ(__(!?|򇕯P^1~\*O(_|M ?O)_)Nz^rQ\V]de5c8 ?{pخ w)˂ w+cx0܎# zC7,Rl\+Ook%?_y"ny2Stŵ_ qb6~[^-7=l(߂!Fǧ k~|ća|/a-(*f1~q{^SgqUG7+w~/+7'^W'_Xaְ|!6!ww +ڦKFgU1Z~%Jy u;s/ 3>-w~?g:^X ʉrEFhݝm7*ߦ|-P) w_o;=_xާ|?>C0>O9Wkju5ʻ쳍p? ls`WQ<} e3}\m G܈~Q)a/mQ^Om lPȿ3>-N ܶlvf>(s6) wʅ;s. .l{w1rK|O`n1b>%>'[~6PMow|7If(ߢ|}oS#ەPϱݏ>>O> >/98^QU~18N$NnY܋sxq><~OY߾#>5ܑKpn O]W'_|^,aƈmXFd|UM[~Q3V>\R--byXmaK|Ps'm,x ~*|] فJ 2~>/ ~7;=7*ߤ|=ܢ|+o) w7# {}A|HʏjǕ'<< >9|_PWke _W36w$N4^8 MCʇIJK^%/wg?np3~/Q{3R: X԰q&~VceԿ+v]lxOJx5>q90F t@|_l qz}g=߄Ws@_|^5|GQ?O8*?p_Qy q§&qw ^8 po9댭:c#/c4n[EVѸUn[VQռ{*޶[ͻwo5j޽ռ{k#쭆q5@8?"pܺxp*Q:'SWl[EVUdn[E"Vquw# &;ϱ\5!nc+U#'w57M7->{Gx-p$'3ﳷ|‡|>O9槕g9|_%G=pX͈kp'q qy<\pT>|Xq특pwiC}p3~/Q~OxmlW뱀%&bn1woC\CmCޠu0Fjy=Z"%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["%b["vp|nq~naîY~C|oTʷ 7<f9|‡|Ԟ |Q~|_r/c qcqI8}#x1/)\u$ nܰpð1 k: X>6"-0\هsnfboU۰a6lٰ+aWdîf>6c:wf3?kxO}Nz~1|Y+U|ތ) wOow{ލ|‡|>O3,> "_1|]͸m&qwagq/9܏o8 !<]G3xǵč 7x~?Wx ~ lό0x'nPgA"E]|f߶m"~hu6Uk-"޶+AVV m[Domw~hjFѸm4nFѸ"~hjj-"~hEFѶQm$l F¶"~h-VomE[DomEvMf6϶효효효효효효효+"~hg[D6۶] ] vϪU="~h-"~7B!獐F0BƚOgZ,"c/}d,'X*`j/-~ɞywy no(g5썶I_୶!ކ?xOx'n_+5.܊w㽾>߹zć?>>Oʃ>>/-_㈳ kd _W3|EJ-?ǫx5^cO*JZeh5L4P&_XT.)||[4.w68?e eX7 wl)`X~Ygy/s|p\r >Ѹ|gƽy޼qo{6_pp%:_b^Y_RW.]tr0q%-o>߸]S7)ߖ7mnQsZ0}"o܋>> |秕3s g~g~g~g~g~g~g.3x?wgɻ3x?3y~gɻ3]x?3x?3x?3x?3x?3x?Lg>3d}g~g~g~g~&3YLg3x?3x?3x?3x?3x?3&dƄ̘~g~g~g~g~g~g~g~g~g~fx?3d2όEgF3x?~fx?3Re~fx?3je~g~g2x?3x?3x?̸2^g~gwxO;w?~wx:wxc~;Ɵw?:Fwx#@;wx~;wx~1t#@;Fwx~;wx~;r#;r~;wx~;wx~;#:2#:ȬȦwQGux~Gtx~;#;~;72܌׬m #̢Xt_t}EE.ZDz袻.;?#].T`ڳ_V*~67 Ggߤ}߬[VoS#my3/j~<?;q -a_7[?/x-zD >aGQ{̧W~TA5j/*H^(,u5l3aoەw⤚)i]Y5{q9<|~: ~T>|Xrק1<]'(1^txѺEw_txѺEw_xovѺ 7+Hr+_?cq ?Wo 񝐁242PCKeoarC9Zt{qs{} [Ԉd+:^t7{E7ĵZ"3m܋ƽ0ʅ$7Vz,ZhǢKW%8s6+U×  ~<{oTs՞lsx-A|GQ>OmV~y|_ėl2pG+ʣʯ)8N$NnY܋sxq2x9rSTȂ ^WcK/K!׷%e/-{)7oK/( 5ֹ- Q&W_ jX5͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7sy3͜7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7.ovy˛]f7ٍXk/[{3p5ʟOg_YN甯^,`_Ke>$*`_/lyھ q-owxoVEVmx;'S-o> _-?w˖[?ڽxޏ>SϠK2p_W_SՌ+opmڸm:T>|XrGw'(sʫ+W^v.bTFK/Cam>Sq嫔?|5(w.#ʑh@9rP\(G"H0Wdb8F.{VurSy(?AD# _@8:@}ב)0_bROŻ['8K 7cYzxGK[<  4$!  )Zܝť@Ŋkq9|7_rٙgsB@ ^0Ht¢` $. ]T填Tu^6@R6ʛ %B{k6t{Nh = %8 Hp8=`8p<8N'S8w8gs8.QR.FĖKeh_\[VCעe-в܄p+ڷAoJvܝ.F>Di?pOgr< /A_}\#n@߄}>z>㺞@?~tBͯ %hZ֠uh4U: @tL873-Y0ѸCuq4Px];^W鄥KCWw_V=ȿ*]cpU:(p4Z*2ٯ wq*w8W鄿{=tx\J'\)J'LC ҵxx][!6tm2rC`*b1SB?J5 ?2|`пɽCv5>sy^ȿF',Ke*X'}bOr 5~-܎'YM"z>&,inonv`G?  Ek1\ .W+Ujp \nh7-Vp=h?D!Q8x<ρK:"|ӯf %PuyH8 9sB , % F)aup?T'.~V?]@x՟kw}U%a<4I>|y?ץhf??g}sn`KimlG??v;]9 #(p4%F N3,p!׵\.+X*p5\ 7`Лp+ ܎+w>\~~}<ρK*κ^nހ } ڿGgz{?˧? Ag .;|:'t.<~B~|C'u,ˀ`U:;CqO"k+];< -·_|!T)0s˓YuE2X}j'fl6vFvFKp.8yap)\hNp!:oS0/>*?㊌C haZÐÐ ÐÐÈUVQ_Vkd Exa2}__%1 1 1 1 1 @P!P!P!P!P!P!P!P!P!P!TTTTTTmyP!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!P!d`BBBBBBBBBBBBBBBN~TTTTTTTTTT\B.@P!P!P!P!P!P!P!P!\.r\BBBB@P!P!P!AX>cAX>cAX>cAX>cAX>D~cAX>cAX>cAX>cAX>cAO>DcAX>cAX>cAX>cAX>cAX>cAX>cAX>cA~>cAX>cAX>cAX>c ǂ |,?X ?q0/|>'P '[|`~X, AϢ` X,ˡyX VkX]]a#`o] GہXIGu`G1?'Idp 8Byֹ\.+u w@އYx-O`E2xp G<CsBA~q.yh]@ @k:t&Yk0:tN\m;yA tQbšK@.] 4*AWڐ|] : }M܀P @= wBihSo1}ןa2}_ks]OZةoN ,{^ D-OA?NGp_@_k_{cY>5&^qOcӘ4? ri2Od419ru7sdL_ϱ|/[ܳyxsM;h>=S -| Bk_Αr]d7$kBxv:Xwco~ =\&2_r>`?"__}}'Gu9‹d 7Hf a(/%oA.q%k$J$2a/@?/# W!WH 㨿*Yo7[8z|>O3-/_@?WpWp]A$bWɚUdUdUdUdUdUdUdMbx 1B o!ûCb="?޹y&x -@?~% vH4Xg2v0'XC2,=JJ`ؗd$OJd$NU'#XO2,qHFX}8}x`1}}}yy<.<.<.<.a2a] ӈ*IM)t3*?as[k ZvN8 B\ .W+s5\n7[m JBCau<Ogsxn%zX?P1#T@46`03fGE ̃B`X,+1ZUO5 O6#Zq)@rf~+ ]u<&KH>6B`tslĹp5OOO# -@:E8w1\ .+q\aڍЛp+ ܎v;]nv^Xx#'Sx^c̛m1zSO7 { ?2m.s)r)r)rIX,Ke OOOInO΄d=e]Ч  "&Oc% ~'#dFdH a~ S)p8m 6ٞB=L-M-0Zs[`[i3vNh "\ . p%Z׀kuzpn[mv wcm{g/~q(x< π % xco KDO7 w &h.̊r31Cks=c߀kΊ>K-ٳ}t3:'ڇ@Ƙ{bܰCUAT E$U)IS.7]oŸ?K%jEfG@E?Gb%&bU+.~PLTŋ,X,VYxD݄Vq=D&DEԍ=2):. nV2zDzJ& iNZQ}ȋPXP,Y5E$K/.ݠo ^tn\lRݸQ%TvD"W@A:ST[4'(M$-wmoWPlJi~rZTB"DDQ}Ef-ZtԣRmȗHX;:WIn9+QdeTc|{$듈ѺXɻooS&uJRq\[ȁqE8T =jcWRȟmDmh GDgk Jz1cFPH^SȎ&km׭IK10spe_O42߽}3 J6MH!ВykP5:c-v]nJ"Y\ךEV6ksү9}*=[߲I\?Ή!KLR >~'vC6OPdS-:Q v-y?o,iOBv$ǬQh?h3W~Q@;_G,2ݭ"8F{\Y7\e~\NE]FL}w<[?ߣDkv߫/?9:;ƻTYStfHy,Ϙ][g߮n%sˀtGIH]Qs׸ Is?|GJ1h\ϿF$Lo1}3]Y߽ݻ黽Kʞٺ~z{7ƀw1dXr1 I57ӲV}ҿF/nMjQYˈklݠV5ZF4oӲyVu޴߅D{TRdtL"dɒbGE6[TtHO(&.'.+n~􈈍K*HVV@>. 0O 1oGH,V,F"21>[4"j`J>m!&.Et@n'O~EDJ.F?~b#c{%:6)n;=AĨ$8!!*_LR4 +#Cd RțyZui U*G*DD>PT! QU|LKP FjBԌV-VlC%FۓVNTg !15b*HvRө{Hj5K 5H POxFuzLͣVQ!* Sa p7jO$?RGQvu:I#{LNSgHFNdGOp R NGDSI'`RSQ[Pj5z@=-- R״FA-ڦ]ڣ3Ltf: F=RtIsyt>:?].H E ].NKҥt,].OW+ҕtuJW5t-6]Kף t#1-݄nJ7-t+5݆nKQ/[mݞ@w;ѝ.Gt$ݕFwtOM?ct:;]/@'It??=HӟҟџC0 :@Az=Ecqxz=DOSitz=EϦsy|z^D/Kerz^EkouwzzDo[mvzE{}~}>DH??Gcq}>Egsy}D_W_ku}Eߦw{t2}~@N?я'S:aN_iK~P 0 p H(hX8xL=}&#da2٘Lbr3yL>&?S)b 3EL18S)ɔbJ3eL9Ӏi4b3ML39ӂiɴbZ3mL;=Ӂtb:3]H+ӍD1=L/&|0}X&g2 L"c3 f0)93 c`p&Ȍ`F2̗f,3L`&2Wf*3`f2_3f.3,`2f)Yά`V2f- Yl`62y:|lc3;.f7c3?0%2uF]~e1?2#OQs9d~aN13Ys\d.1+UWsdn1;]g~c03?Gc IaBLy}>bOاl b39ʾ`ؗ+58c8888S88388s8 {\F.e%Uv.rq<\^.+ q"\Q(Jp%R\iRWq \EReTF}5\-6WK\!sM&lεZr\Rs\'3ׅrݸ\׃⢹'\ ׇx/%rI\??7 srqsC0 . n$7}ɍrn"7}MrӸ n&57rn![-r˸ n%[ͭrpon#mrs۸n'r w;~~rǸ $ w;͝r"w]rr׸ &wrd>{=sO\ 39ʽҸ+5xgxxxxWxx7xxwx {|F>g>y||~_/Eb|q_/ŗer|y_WUj|u_uz|}ߐo7Mf|sߒoŷmv|{ߑw|Wߝ{=^|4ߛ|D>A`S3s~?|G/1X~?O')T~?g9\~?_/%R~_W5Z~-o7-V{~w=^~??#OQ?O3Y_/+UWo;]?Gc OC|?S|ſ@ ` ` AxOx_@(d2 YB6!!r B!O/ BPL(.J BPN(/T* BPM.j BPO/4 BLh.Z BNh/t: BC#c!R*t QBKz 1B!VⅾB($ a0H,|*|&|.  Ä/0\ #(a0F+ $a0E*L 3,a0G+ "aDX*, +*aFX+|# &aE*|/l ;.aG+ ?!GpDIY8* '/)pF8+ %pE**\ 7-pG+owHx,< )BH τBBH^ iYyQEQeQUQuMm]3Lbf1U&f#bN1[#bAXX,"bIXZ,#ˉ bEXY"VbMX[#bCXl"6bKZl#ۉbGY"~(~$~,F]nbw1J!{bo1F#ƊqbWL$_ O!PqAq8R%Ljcqxq8Q$NSitq8SZ%sy|qP\$.KerqR\%׈kouwzqQ$n[mvqS%{}~xP<$(??GcqxRE<%ψgsyxQ$^W_kuxS%w{bx_M| .>'S1E a\L_iKZ|#Q-1+q/ (I,)*i.)Y-9+yR=})I,eJ٤RC)rKyR>)T@*( KER1TB*)JKeR9TA(U*KUR5TC)ՒjKuR=@j(5KMR3Bj)ZKmR;A(u:K]HM.EI=R/)Z-}"H}X)NJ R$K i4D* p)(FJҗi4N/M&JWi4M.͐fJ_Ki4O/-JiLZ.VJiNVNZ/m6JiM.vJiO/ J'gtL:.NJHtN:/].JtM.ݐnJtOJKIߥ#Dz*H!),=K )Mz)^KodJeFfeNeAeIeEVeMeC6eKeGveO '/ g3ə,rV9]s9\rn9W' Bra\T.&K%Rri\V.'+Jre\U&Wk5Zrm\W'ח FrcTn&7[-VrkVn';Nrg)w(S%G˽O+r_9AN~ry"$,I|Z># E|Y"_M|[#ߕ}7PC~$?O9$gs9U~!/WkB)()"(")()b(b)()J&%EɪdS+J%KɭQ*JRH)Q*ŔJ RJ)Q*JRITQ*ՔJ RKQ*JHi4Q*͔J JiQ*JItQ>T>R>V"J7Pz*hQb8%^$(JO P*ʧge2LB (Õ2BRF+_*c8e2ALR&+_)S4e2C|Rf+ser@9R~T+G1rB9RN+g9rA\R.+Wʯ5rCRn+w=%Yjƫ}5QMR@u:XTL\U_uTG#QhKu:VW'Id+u:UNWg3կYlu:WW EbuT].WW+UjuVF]~~W7MfuU^ݦnWw;]nuWݧWPCazT=WO'_SizV=W/KeOzCRowJCX}>USԐVTT_7񚠉ɚ隡ٚe>2jZ-MˮEh9Z.-G˫kZ!VD+ӊk%Z)VF+kZ%VEUӪk5Z-VGk Z#Dk5Ӛk-Z+FkkZ'EPHXԺjݴZCҢ'ZGD-IhA`S3sm6T}ZPFi/1Xm6^M&i)Tm6]Ծfi9\m6_[-i%Rm\[Vi5Zm^۠m6i-V{m]ۡvi=^m_A;i?j#OQv\;~Ni3Yv^].i+UWv]ni;]힖~hk?GcTKBZX{=RZR{N..늮ꚮnnꞞAO_@Ϩg3Yz6=sz=Oϯ z^L/Kz^N/W+z^Mkz^O7zLo[zNow;zC#c=RwӻQzK{1z=Vz'}>Hч/>\#(}>F$}>EOӧ3,}>GϣS}!B/6Rb*@FK2j\_W5Z}uPVN_o7j[ߪoӷ;.}ڡA~X?ՏI~Z? E~Y_կM~[}7PC?֟O=gs=U/WkA< ѐ P 0 Ӱ p {FF#bd5ٍ#e6y|F~Q(d6EbFqQ(e6erFyQѨdT6UjFuQӨe6uzF}hd46MfFshe6mvF{dt]HnD=F/#m|b}X#Έ7 Fd3 c1j 30p#h0FƗc1oL0&Wc1͘n0f_c1Ϙo,0cXn0VcXol06cn0vco`0'gq8n0Nq8o\0.q͸n0nqH6ߍ#xj!#l<3 #xi2^oLʤMdMMMɔMTMM4M˴MtM`go~`f43,fV3݌0s9\fn3g7 BfajY,j3%̒f)Y,k3S fEY٬bV5թf Yʬm1fll61ͨ9fsle6ۘmvf{dv6fW݌2{=^fZnƘ}X3Ό7 fd3́ s9j30Ds4GPSiHs9c5Ǚ Ds9ʜbN5Lks9ۜc5Bs\b.5Js\c51יߚߙ Fsbn57Nsc5Ay6O3dgs3|a/WkEYXY%X%YXYeXeYXYV&+je[V+mZVU*lZŬV U*mZVUɪlUZլV U˪mձZVjl5ZͬV jmZVlu>>>"V7ezZhcb8+k%XVo Z֧gk5 Xí5iF[_Zc8k5hM&[_YS4k5Úi}mͲf[sku:h~[G1u:ibN[g9uh].[W֯5uúiݲn[w=+ٺof=~ZX멕bznZ/4zm)9[%[[5[ ۴-۶۵=;dgYlvv;asٹvg};N@{=b_{G#QhK{=g'Id+{=՞fOg3Yl{=מgϷ Eb{^f/W+Uj{^gkg7Mf{fow;]n{gCa}>fO'_Si}>g/Ke}վf_o7[m}׾g'C~b?STf_ٯ7Ȏ⨎ᘎ؎㸎dpsw>p2:N'D89N.'s;N!S)s;%N)S)s;N%SũTs;5N-Sǩs; N#i4s;-N+is;N'؉t:ݜNr'Nljux$:IN?3 r;:9;C0 ' wg3|q:g3ə|Lq:Ӝ g3˙q:gY,q:˜ gYq:8oglq:;ۜgq:s9q~r~v:ǜ s9q:sɹ\q::ל s˹q:dyuSܐvZs_7?c===ɓ=S==3=˳=s=}e2y,^V/݋rx9\^n/ xB^aW+Jx%R^iW+*xJ^eWիUjx5Z^mW׫x F^ck5Zx-V^kk:xN^guyݽ(E{Oy^_/K~^o7 >>>xCa^Ho7y Do7ʛMyӽLko7ۛ|}u`V0,feݜXjvmWQDNıSCd?1$н9t]87p^ .\4pY+W\6p] 7n5p[;w7p_<x4X'O<x6\ /^x5Z7ox7^>|4Y/_|6]?~5[?CAIMjzjfjڨ4j:5 PES RS%R%S RSZ:ԺzԆF&ԦL*H(:.*L͢"fԖ(MP1ʤ,j65KmCͣSR "j;j1ZJ-vvS;Q;SPRQ+)(S 5Da*Mej%rT*P*j55FS{P{R{Q{SPRQSPRQSPRQSGPGRGQGSPRQS'P'R'Q'SPRQSgPgRgQgSPRQSPRQSPRQSWPWRWQWSPRQS7P7R7Q7SPRQSwPwRwQwSPRQSPRQSPRQSOPOROQOSPRQS/P/R/Q/SPRQSoPoRoQoSPRQSPRQSPRQS_P_R_Q_SPRQS?P?R?Q?SPRQSPRQSkkS*k:n&n[6z*=NϠ4E4C4G@D˴BFt;6.>!1 )=!ڠ;Nӳ9%?z+zk:Jw=t6iMϡz!ގ^L/N.n zwڦ{>ڡt?=@'$=H)zNz^Ig (^M^>~A!aQ1q I)iY9yE%eU5u M-m]=}C#cS3s K+k[;{G'gW7wO/o_?̚fjZgFifZVLc33C140,1<#0"#120*1:άŬͬìˬǬlllllldL1b,&llllيٚ2LcLbf3s6-Y,bc3K2f{ffGf93 +ٝ^q8 0 & 2CLfLaV2Y&3ʬbV3c8'7/?ss ss0ss(ss8ss$ss4s s,ssss!ss1s s)ss9ss%ss5s s-ss=ss#ss3s s+ss;ss'ss7ss/ss? 0(8$4 ,<"2 *:&6.>!1 )9%5 -=#3 +;'7&;bcmbmc 6R,2,r, J*jζkk3 b d0;[[cbfl7Xv. ;n.`v)ݞ݁ݑ]Ʈ`wgmc6lMb4aGؕlͱy;ϞȞĞ̞žʞƞΞɞŞ͞Þ˞Ǟ^^^^^^^^^^^^^^^^>>>>>>>>>>>>>>>>ϾȾľ̾¾ʾƾξɾž;þ˾Ǿ~~~~~~~~~~~~~~~~íM᪸jzk䚸fkڸ4n:7 pGs rs'r's rsZ:ܺz܆F&ܦL.ȅ8:.."fܖ(p1,n67msr "n;n1[-vvs;q;sprq+98s 7ĥa.en%r\+p*n57ƍs{p{r{q{sprqsprqsprqsGpGrGqGsprqs'p'r'q'sprqsgpgrgqgsprqsprqsprqsWpWrWqWsprqs7p7r7q7sprqswpwrwqwsprqsprqsprqsOpOrOqOsprqs/p/r/q/sprqsoporoqosprqsprqsprqs_p_r_q_sprqs?p?r?q?sprqsprqskkS*k:o&o[6~*?<<ó<˼«|;6.>!1 )?!;N9%?~+~k>w=|7y~!ߎ_/N.n ~w{>|??'$?)~O~_g (_͏^>~A!aQ1q I)iY9yE%eU5u M-m]=}C#cS3s K+k[;{G'gW7wO/o_?šJjZNFIhZVM*L 3@    .%-#+'/l l(l$l,l"l*BH0S,!"l&l.l!l)OJZ BLf s6 >(>$>,>">*>&>.>!>)>%>->#>+>'>/ ($,"*&.!)%-#+'/~ ~(~$~,~"~*~&~.~!~)~%~-~#~+~'~/ ($,"*&.!)%-#!)MjFzAjfEjڤ4i4C HDKJK$J$KJKZ:Һz҆F&ҦL)($C:.),͒"fҖ-H1ɔ,i4G+m#͓KJ "i;iDZ*-vvK;I;KHJI+%[$GKҀҠ4$a)-eirR^*H*i4&K{H{J{I{KHJIKHJIKHJIKGHGJGIGKHJIK'H'J'I'KHJIKgHgJgIgKHJIKHJIKHJIKWHWJWIWKHJIK7H7J7I7KHJIKwHwJwIwKHJIKHJIKHJIKOHOJOIOKHJIK/H/J/I/KHJIKoHoJoIoKHJIKHJIKHJIK_H_J_I_KHJIK?H?J?I?KHJIKHJIKkkS*Zk:^n&Yn[6yّr< '<()yXNyD^)g圜 J^-^>~A!aQ1q I)iY9yE%eU5u M-m]=}C#cS3s K+k[;{G'gW7wO/o_?ʚJVjZNWFIiVZVMLS+3B)()"(")()ҮllllllTJH1SR,%llllOJZ*JSLRf+s6>>>>>>>>>>>>>>>~~~~~~~~~~~~~~~~MѪjFzAkԚfEkڴ4m6C hFkjk&j&kjkZ:ںzچF&ڦL-4C:.-"fږ֭h1,m6Gmkj "m;mD[-ӶvvԖk;i;khji+5[4GkڀВڠ6a-emrZ^+h*m6k{h{j{i{khjikhjikhjikGhGjGiGkhjik'h'j'i'khjikghgjgigkhjikhjikhjikWhWjWiWkhjik7h7j7i7khjikwhwjwiwkhjikhjikhjikOhOjOiOkhjik/h/j/i/khjikohojoiokhjikhjikhjik_h_j_i_khjik?h?j?i?khjikhjikkkS*Zk:^o&Yo[6}>M:::󺠋˺z>S!;NK􈾙?}+}k=w=zL7uK}HN_/їN.n }w{>z>'>)}XO}D_g J_^>~A!aQ1q I)iY9yE%eU5u M-m]=}C#cS3s K+k[;{G'gW7wO/o_?k>}j3T;δ\;.RܮZ޾V봯۾^3Zbl$O 'd\ΎEmW}ZG6!u@&}ӗSM}eǵhƾ[=Ob};_g0@h Kl 7>5}qBfW85P청^"y~eTP;!WA_OTOW_OG2|6N*3=PO-D3hBBZ& ;[Nم|KR]}X\C҇žY,kiZRэ2_/$S)>v_=Ro(P.2,[S fY6)x[MhYR[!/l١U ~qƝwx ଙAQ%W}Z03Ohth4 5A-Fz혒  #2 #2b,Ld隌E(`; (; (f2Y(cvv7U<3nwp7ݍ~Y7;)x{ރ=~{1s ?c?c?XO]<_ȦN[IƳ|Fr~Ä&0 ?9?@Œ-Y)D^0 &zt -v69]!mEv>0LL'VB3gAChh'hhth4 5A~A~pʵ>W!-]Q1-?QxgAxg!xg!xg!xg!xBτ3!L=Bτ~!7o|FW p0 8`t8:@t@;wjls}H &2> q/fsq&חXe7ޑH.O*ƌIWKe\Mb7 x|fL͐Flw&zY{8Gq8ըwsgR:ZiHn[АrjIԤz|]*'RDͰgw9w;5äi￷g+qw{@Âꌋظ,S3o_H"IĚg56e=>_-eC?#k.qn5,.B5dz&MF#ױ&Wz+Vsy2d耂[P125djFI"Ǽ ˋp㥎 E=UnGֹ413#*x +H<ߗhu;7iRɾ"\ ߟ-YA:iNi )#3th⡚^JX&kθjmGC5%λ=槞NHQBHQBHQBHQBHQBQ~Q6+ijd [;蓬LN%?:ťc|2FHH69쭾MqW27g]e"]!͝oN7y!o^VQqvXO!X]3ۋc:Urj&\gص^Ǟmaʂ”u`ʢdDfIr`خZjMբD[C`QnKQV/6?Yl~08Rk 5{`V4`43V3D"M.LYrڜ׸` !Uyr/?W!W͕}6L*G-S5ߍZf \NPkQXA㾑`"K^KjsŒ˸R3D/G59D}~,7hcH iA{tr0N4KڄmuT>mrب{ wG*qLٰb(1~xflIvQ&UpGiΎqϋlꟌ+b1#Yx֯eJnZWi(]̻K9_&- 5C5IW*TCVRhNe T{%9MRL֤'kHsecj ̱WؽC {iITJɲ7ٹfD]:oÙA;h+;0I1[g'dM#|p_cN' Dᗚ0n3^pӪo_QS&)%& JO8ZNeCv[qb,l$i3-314QJZŹ;55IFL$?^.(#f ٹ(+#VT>/U/.--"ތ+ZjmBZM2߲Ļ_g-Jp4^ TӰTh'kr&99*mKN[T!e*g`fB\0p12ߩ[-nv*VX ׃X bVMR@6 [fs 21Oʧ2?FVʓz<Q{Uͼ})2;q0 E&UdtYRdrEfiɃi+F^ zDT׮$Ecq1gS%6Y=e=e{*jި]54jJ15Al!^IJWJM1暛rxv/7tSz,k|]))/s'W1w1r/5K6ͳSdiۊKM 2J{S*}㞲iQb6,@>^2߼+[Xj^^QyQrU VY=IQ9T.><+#١5/eFw!M]Yp[2Sr{vI򳭕fY[1ʳ\Awvu4+x+/O|y@+P<`iu ÙDy  C}gXy+&Nb⌖쫘8#grder'_9q+Oʉ3R9q**deu;[gb]N ]aYТn> ߘ |։:2['^flxO;O;O;3j5dg853XfP{\]UQ:F켝7t5'4%2>h]\bYxݥ7N w(};#v.Z+,UL["_@zneNQ;)[\jGqxKM 6KXƁCɴh%Bqt[C Eלskδ #pL%|v@[Wf+1[Fߋm+Jf+ 6Wpו$0"۽ɾ\|8Irky}Ħ=<o؆moV(BeUɺrA Ywv$|nj>pWBθCDLJqn'\<^* 9/'"//q%CMn- EvC%L>\jFc:SR3i bKOŁu5eإD|;iF7 LN.<ӽx6?2xVAהOdQϸ>MǾ!\]~|{Zd0T |&[\aMr b5&n^ 0nw- FAA{@c&x;(F #J%ÈaD0dQ2(F #JwQ2(F #J%x;(F #J%ÈaD0dQ2(F #J%Qw3*pv.Fݱd:jTkR$BbɎfT ' 7[vܷKL5e*de2~h]7|.˵}؇R8X,5||s(X2ȣ9(/T.p/BCܺOkSi} L\WZ76ۣ@m=YOyV<59AlKN[ &Tq'h OO'L3d09Rp|e+p R+ArS;uJ(8~K|iIU0T?9w|Ƌȍ]E/^߾:7R2$ND j'}Ck"x)#2"hx/hoMX\.5R#(>R#(>R#(>R#(b-(b-(b(>N⣔(>Jc|EyߜDIߚDIߚDIoEF_oE_oE^oE;qwQiŻqQŻqQŻqQŻqQ*ځx7.e8e8wx7.YTpϮX]kéh-s|2[F˖$铨_`!$%6MdhtR K} Zk^m}'|_?߯;e~{_d_ 2/btEPdUˊe=t:fvfm̪ BZtYgF )ۆpwr:X}*CL/;Rr;qm)mIrbdǭS\Ի@ ,VLR`Aa7-]Qx(`~G&W2$ I*H!/ < $䩞ljV*מfRN{t &S)2+BPPRj3t."EHqMOk X,ץ)\ ;_̀ڰ7QD1PA>+bTgg\}X;1rw9iŃ,*U,\AᑢޢbauY( 抸"W-*/t m#3 Ї08SWPd`PX.@)2vr LCh!UԵ N%C7^|$>O6 %2 |3 v,,5;2/ؘȤ T_";:~f B}.˔gXf c>* |«FOskoskuHs iwM EhgfR~)W]+eͽ^;9wFHf$Ek!(ܟ&Z\zo0)o`C6-]m62)tJm׬ʬv5hnl}sD&!xohBFo rˈΌt:nAJ-v^}]fKœ%e6lTP.P@%&NK%eru}ӈ߿[m)7yn >5s8Mbmp%4QΔجoeY.oH08[IN\/4$vz; uc?5YTZWƍ~I8; 4pY3. @ N.0,h4jZ>~7 nw~7 nw~{?1| c(+11111k |&M7o |&M7o| -K{A- . b . b . b . b˒ , b˒ , b˒ , b˒ , b˒ , b˒ , b˒ , bA~A~A~!~!~!~!7o| 7o| w~;vx^'w~'w~'w~'w~'w~'w~w~w~w~wӅ^UCu? 0? 0? 0? 0ggggpgofo"G`?؏~'E^x"A/C!e2xB !^/qGwqGwqGwC!c1B< !C!a08B !BG !n7C"=.¥C !^/C!PB !^/C!e2xB !^bӋ 6bӋ 6bӋ 6b 6b 6b 6b 6b 6b 6b 6pn@4? O@4? YKgF@ݠ=1P@47 Mq@4' Iq@4' Iq@|4 G@|4 G@|AAAR+⣁h >⣁h >⣁h >⣁h >⣁h >⣁5!]5!]5!]5!]5!]5!]5!]5!]5!]\ |Iw~Aw~Aw~Aw~Aw~Aw~Aw~Aw~Aw~AwR#N⤁8i N⤁xa ^⅁xa ^⅁xa ^-⠝ W⇁a ~ \_'≁xb '≁xb@\1p}e /⋁b7⍁xc 7⍁xcq@1w ;⎁\ |@1 @1 @1 @1 @1 8d Cau4$t!ɬK\ܐ]b"(e)2;Rf{p+2*l&"K^Y$].8#g^rd{#UjXHEEEEEEEEEEEEpD!K"2222222222222ΑKh- s%ޝ-Be >\Y(_;|/[q,4VXe TݹW+ {j?'+ Ɋ̴I ȈJ٫rxYĐ9H$}1$}>I_ IA̴q4q~"spA t:HusmK؆^HNX}} R݅庙o '7<3YprOd&= '2Wx/ɔY%NZ¶mɉѯC:m!"ZKRjXV % 첲k2e岉^&ze ^*;FHc%͏ϔ2Gx"(x"ޏX_,nXQ`F Bh!Cf=}S4B{YW`!=ZH-C 顅Bzh!=+@Z -rB O,pC  7,}> y {;W"YH,$~VV"YH,$~? Bga#rH,~R? Bgၑ{ XH,$}>r(2= LBg!ӳY,dv2;  .-rr8h { .-dj25 7h-p}P A-hR4 )Bf!EYH,hR4 )Bf!EYH,\[p)oR¥Ky )BJf!%YH,d֬"ڋBJf!%YH,dR2 )BJf!%YH,haE /ZXxBJf!%YxpfgYxpfgYxpfgYxpfgYxpffYx`fၙfY=5d6d3>5l8?P%BC4 ,Yߚ񪤓OqzILg҃d:%&{yh]j5_iP۴D kuzSߒ赳-~+8I_ ֍M[,WӒ"Et'HrVeS3.S#X;Le-䗍NB鳳<S9 MI|^;=@ê'>syo7m-RE{ͿY(h7hh h] ~'; Nw~'.wٛ{W l^/ MP[K%)J *y/ǗfJ弡/KqLif\tVn(Aߓ~3wxwrr%Ҳ-q[VCZVHJeEY~&i1@0@ LD00Lװтl:T&4v{Rm´2Lz,dq2FQE1eY7OO'ND̛ASsz̖A4.5K[u䗭{VVsjB#oLPupzE[pQ)9+]<+/* ȭ^UkWUET^lZ=fn6dh4|s[I2s۶g^&;(rm/DB)vՕ[uEC\[jY4$͙G]iIhVM^2Qب_ -#poBW2;:0ޘ ,V2?GȨ~!c0VygwcB=pI},H[8B}L`Ii`IiEM9FEf#$Hԏ),lM%<Mт̤p2)~oL+7/[ } Asq8\='UgI[wER]lsr jJGVdMS @Γ딴8ށ.TB.Tba5k5tf ]YC׬kȻS[ۭJ4K"7l9$CuQ:z}^_GѴu4mM@6д 4mM@6д Կ]4gQXlr@ h嬱q7ZCQɱpK. 'Z%B2ǜ_t{^E*8;3mqyyV5@MhDmA-h n }ma0v[-B[kG=m:05lUݸq\qnqi՟Г"f83|Y*tᴗx*j9PY(၂ׁI@@A{9V# 4 0"(2"(2Ò{O:ӧN:dWGmQ9 q_ܛ{K)mE: U78a4 8{JGFt?p>'E|DNf2?5Fj1YR46y07uV#XDW*!ò(swD9m|@*w 5<5>Ru7QU m呓Hi@B+= qΒ%[HxE`2y5>Er`.k}tN'N976s9 :*~si萍du^䰪K + NvDb[ǩ,W.TwxRJ*^$hnc4 Wo?z:a7-^xReK-^xReK-^xReK-^xReK-^xReK-^xRq.7}Z1;2nPv@ncll&}l5*g իw.޹x璸9ga,I"-q000R O)>;]5u MxԳ BA;-b>%8ξ"ۖo[ mI|mNN%wg$: .9stK^WxP5B˔Ecj&MK86ᷛ5 ݠ,M&s&6qnj:Q0Zj-Mx\낯[6x+}[ ԏlaz0=[-Lg ӳjlaz0=[ /PhmO-L>YiV {NkaYRt_ڗ;ƥK& .m;'@i,A .'h 779:4omTRx6_l7߄MhДt2Р d݄MA(vmwls6|sQvhq& ZhiD['҉k:Mtt 訖UKZVX>-]rKgog 1,GzEm8q4jhѨQG6Fm8BmxB=Hjclclxԏ-ǟ6ӦOx/-%*-JK*-h:ھ]o˧m (b--,haA ZX‚-,],؍*4㨦OXۛ%@0r6 =l[u6"NW].-4EC=H=҃BZ~dW"Щ^QgoS@N+qz.d8ƴqi1bx]T㨥|"S>zcic3H66#mc8ƴqi_n+k2QLG62m}JT:8w0pab~<A@:x*U:ثtW`^J{*U:Pv%J:ؕt+`W]Iv%J:ؕt,]ڋ]I`lJ:ؔtͪ`7nulC==ԃF{.֚.֚%-owk[b=b=b=b=b=b=b=b=b=b=b=ZqłłłłłłłłłBB E............N]:MDX%X%8tvqšCg.]:8tvqš/vI\uఋO5555555G*]g> ޅ‡wû].|x> Gj]|Gj]|Gj]| &.`RI &.`RI &.`RI &.`RI &.`RI &.HR"I$.HR"I$.HR"I$.HR"I$.HR"I$.HR"I$E_ï.>ï.>l~u񀶋]<mhx@|sK.-][3Ig.$]I8twA;(=q&Lřdg%p^[mwm M%lg<(Fy6ʳQc|moqcw:¦;guS8BVkv^҃mg}{I)|'#F|F\ +迾1ـ{z|4zyzzz1G$s]|D$I6l'(~@(ѓߒ lL8@87Ѓ{O&V\2p]~w}ϩo;;lmK~ˮJVߢ]1Mbeb {Fǖ7ܠ| ~j=lz(Qu[eJ]Rpg%+p4`;jcsXU S[i0[Og#R~u.Kgoҳ2 _WƖoY,m YZQ*nVBרų{DxU.L5paap7 $X伉$RTTʽ,OJ$XT;A{ܴe! Sa:<&F Ba$% 3{^B) ΒÑ)ك *j[Clߚ߷&J"-2B6ؙ?vf<9dE`dc{~x0[NfQ)得IFDqaJ:3W(qIBSyYxgi6x n=>wx7P7P7P7P7P7P7P7P@ /P@={ #"{Ja̚煵`nkeeh)1Ro*nBfQƭ6^)YuP޸Ou@dMi5-BkZhM i5vۻ)>ԫ|oyz;pcmKnPТ -6Ƭ-:;6~T`G/,hTc?}akpWD{^8,uN'TO >'W1n7:yx=n#T#TƦMf-j!X6xY}5jFNԁQueF6R{X^0Jx B&e}G_٣g{=}i5kQpc}WYt%͊w_'X)l54$NYqΊuVdߨ)6΀(Ox\}48KS)M!UF:FBr؀"RBR4b)QtTbEUb&,^Y-1%wʬO#d QG(6#a{ʰ=e^Hұ悤.(>@ Wh%YPJ=y'Dr%!Wrr"Yw%b$%%َO#UJ!P@ B6<`%K:CDD-Z $z1Hxג]Kv-|ިb ͊ڋTcD%?QEH.7~ h 6gkgsO꒑>UyP1QQAѬ>"* 3H"oTažm$Ey࡚jI{'-(qk?RBђK`l@HQMvMq8mĉ"6R"yjIƢJ(a(yeq5lG4f6TGXOQBC E_ th].5n]ZAp[ Si_d5yHW.Vl-؟>*ex:"A]zFWi#Ы)x_AA|iG?5=t`dFf7^AOd$ LRNyL(ұQ=Yg.+S<[hݑI$%I6Kl$,I$aG99WOT#nZR5UʑNX+ ?o= oklk/lki!IllfƬa6Lά6mFm4FhugM7KYH ,ႄHFgFyFԞko*WjFYԢCtZ~S,?UDhj/39YGt$3vf.{*m河\jP \% s=#fT!b^,Tn,2|:#)DޱDQ2,LD H(dot73ɰTH''Y;Lv=wRI)FHMG#j82CL3zSeQ{eL97TM3"|eSNҟ*r*jLM({*73O 7ʤq2Of9r&3wTR>4_'G][vPE% xِfȐ"m6r(jbHi&)_e|9džw 6'j+!nFEܡymFTFA_=,ϡLͼDϨ r(v'IG5[W_䙣R%W^40-OioTѤS6%}I£JM ؔIGGlQ'KȀM%6LQGFLD9SzXO CzDt{pyQFdjN9VEW9xwz4L9%cݐsyH'8WCr!rw') qMR Z;x9Ȫ-XV(ÁK쑛.P<),K,w]OeA΢-2 ,`$2P+C u2Z%sɗrȡȡG)LۆH-p (eQyɑ<*? `YcBWOHv<㓄ϳ' Z}!bO <1nSR;}LX( ! 1V 3L<Ŕ#[{\ȱ.c#b<6",O4ʫՎjGF>>>>>jmZ;65oT7jUdE|ciO=cCgL=s~Ϝ{`]R,g3w=\鞡t/W7:ӡCF?M;[[E{h4sh6sh4shvpüCüCɆFfFfFS0jhkoBvDYjÑ2FggDM5sfQf&ry:hy<ߟ*=0$9TfTdc<3&2 ۈ߈m#bb`F1Ir̲pHup{ڙO3\ zo9\iC>$XP^Ӻ?Nv VJy4Zw$|p$8KS##4 .yU2 -ɒ] y`:ٓ,4 #7^9vȫv9Mb?Rkb[ L*O'#7>j+J!xVF[C'M%|ƐS)[ib$ȅ֧l'UŨ;ޔdOfե!S VLt< DΐgR]-W)Ð\.+%|(?:^.;RԕCKn:$\ar8^8)/ĸʉ$sjQYsOɻ\ + kyUꪧX$ ͼpg[EUș~HM HN 2Cg!7ȕY-$7eŹ%N^LuhiA#H>ҳ|N<-xucU]IQ+Ul#SChŰ ~Cw7 @ =0Q n= '^ׁĝWqOXf_6J S:v8$5/9Iܩg3aK|u:td^ uƔ&2J'">wD_bb_GѾZ&־, = 9.? R۳';T3V!<{ވyh}-G$3N`O\; i`>,'x}0\9^+'EO:y+9CXi(5Efrnz-b.BQ&v'.,(̋+]H"ށkU]r7A^@,-)ȶ+@S ݣZd!pyyyje%8ɱHvy]"W :" pq8OU={D -ڪeB-gA^i=Z?PF@k|XD cȸSYsԳGºr]cYS:h^t7&Ou+*Q2`ྒྷ0{fzLKWlnYp$ 4,)c'aГщzI]=?Nݲ;%]/cB:̗X8V഼ڔ4OBg7e}JHU 8vv$☤Y\E4oǔl$?u,9UN/vq8,]ypYݕ N^Sa`*>1g9Hk)u vR;ӲP~v|fSyzjZd[+33㱯 Dv|Ǣrx 9# yf;$:.~&ႆ,ɼ$+3cqR~zJĥ]ddN7N%7`A9ڱ֙)LTMBj 93:\yw$Rvӵ $d0KiN1o"3%B45?۲G_/(vzX{*KcpqL kEh,q8.j |L-y?yn@4 ZG ]~yku&9%K]"HxXbdшv N U/1\}H44Cs9*t$+њSy"9pg8CMSFa#M`FKfQrBPlD'ϚEňyִ^ uƇV+ئE'M9}0,қ9yM ?B;^6A%)CJVJYg hՙU 0,_$_7DqL<&iI:$cc34t\ԘY(O+r(fvUh y$9rdžz>6ҌԁbC`E{xo_[Tp)|Y#gKyX~S^#\/[~Tcm**p]:8Ϧ@zOւbJ&A2Sq UKVMNxZ\J:2Tq(3+#Y?x=,"‰y6T6H'Dee>w4RcY+fhM!PUvV5SH:N*=ϥKz&I ޘV90N3˷k {8YdS4z'֥K4445hi֠AW5 545i`4> OC4> OC4> OC4> OC#>B#>B#>B#>B#>B#>B#>B#>B4>MO9릳Ll3dɋL0\grM&f2;L2&L1LzLL&&C&.=&L<&>I$bI$e2fr1'L&Ll.5m"ڄYE&W\erKL3&[Ln3y&wc L^eC&XLl&=&|4!}&I$d1yI$a239`&&D6_ ~ 6w~U)^7[*.ffu o$jT}5<Of1?*^%kkli p*3/DhW45 ^74- nkw4= ^j@<֠A_GC FiAAAk$58O4hp@b M$w$a"kL^br &7brL2&L,&6>ɀ ?#@edg0 DL^c3ILLw=p<#c<?>?Wlr1\&wz6M.fb6M.fb6M.fb6M.fb6M.fb6M.fb6M.fb6M.fb6M.fb6M.fb6M.fb6M.fCDl? v L1yu&7drm&/3.{L^arɫL0yͤǤa2`2d2b2cc=!O$d1yĪAȘL009fsIo_ԟO'%D* WJE\>1ӛ>p[ۋeq,’opW}͠_gq+#oK -R= ,4MuӜihҦi.QOd¼i-MS_,HРTl,RM)h3E`Gm./Fd]N< .PyQ EenyH%QvP.(pS 7%}V n@-y]P .(킲i!ؖb.( `hP7M;DӐ6MsѴ}4O7͗ $}"MnliT.(8oYS,R- ѲM؅?'M @n/Z5h`M7~-o{I|m+x+73){OfQ_ WҼ<[gl]lgl]˳QKY1./IP^sy/"< OC4> OC4> OC4> OC#>B#>B#>B#>B#>B#>Bu5u]M]WSu5u]M]WSu5u]M]W3Kmo궷>-OK>-OK>-OK>-OK>mO[>mO[>mO[>mO[t>OGt>OGt>OGt>OGt>]OWt>]OWt>]OWt>]OWi}ִ>kZ5ϚgM볦Yi}ִ>kZ5ϚgM볦Yk}ֵ>Zf)J ſkE, *-I6}}(􍅿K#T? mTw.W*~W*?&CTCTO +~W*@g_s_ T¯|W Z#[I__X#\Z3_**ӅRL_(E.׊1?V 3)k?g 33gN3gf:wϼ{f[l{v03[ [o-o+_#R^aJ˯~P?/9/W](VSyOa lުlޮl\LxCU*$ʧ ʧU)T_HJ &=D?H%cUǫ?N՟%s_(X# f ZV&\K}fj}kTWM·j Z?(O 3W,PZx}An.P{޳Ixk: 4[(.0楐pu҇Ϟ->}U9>ku %[:?U(> ٿ O _ʫʃʣo"wWȞW>slxV|/[?Bѕ&#+?Bc+#+?JV~'Wh,V>BcOɕ$"+?Gs+#OW~W>OWWȞW~m+A7W~?_7 ͽ/|[ww"+@^dl~OWWBvJҹs4f؝;7G~< .^=oHsŗ_x4/޿Մ!᯻E-IBȶ/wҵZ ƿSAm'~Eq(-Eo{J93Dšg o~#+Wӊ<+ }ߛ/'5_-U|HI%,T.GAwt\]I_$} ~PR!$}NHJ.IBIZ#r(Ѹ[ >#iY3v%*I,EIC7JڒtQSV$J,[$=+钤sHږiI3J&9IOKK^I&ߒo6%}JҷJvISIO^s_.z bie5/yko?T7](~?WPW//ӲY+-VJϗRTZ+}ttdJiå\x3-RJ[O?,}W3%RIUO|⳿σ6?Ȕ^i(_ޢX ZX]@ ]xM"M*_i9c%U(ןQՊQ\VB h }Dq q][Uj}R ;T֞++o~ + ֐*ۊؗ.]9~%eҵ7_m/m_9U7(kxW꽇#[G ~<_=1fi,zâMv%z-C Z+).//.؅-(|`/٫Tu>>oIɷ?%e)~CW_Jg I圖5$_o"پ•ui!٣‡ɓrw uzVrW?W#ņL}2{+S,Sܒ)nI2śd7I)S|PxL#)wd2#)2Żdwo?Bddw}FiT>C}n0i4[.|­ & J#qŸ~N'$csUD%8NN~C ᵒk?/+]]g _#h-|H/~U?*7ĩV~F$T>]N]9=MqA7933U}vfT g_P_.W3rpQo~mA+|bi7ҿ7ߎrKWƿK.|_ą > yIisC?$I\,ŵFݤfapNZ?:^188}~_S:_񓞅?Duܸx⭋/|ŻlH\؅ 3*0wg ԫ hGtE_ϔ7GA>}a[*TNn^]}i+WfZuVxuWqWo_߷??՟\'-*\{o-Tw$*pis깽z׮ګx`pWi[Vw~~tWlz>Kgz>ze{VzCۀXk]h$ !I%I$IB$I$I$ɶ%[mlIm[eK$$ i䫙~u_Qz{\:s~繾ϵֹA  +Q0`L  L+Y0`n 4  T0`o^7*xh@ zZpTWhQm,DL{L.d4w#`Yrc[|މi=Xo֏ bC6fLg<_eK ߕzOP- z+h?@:tA na:~QpC|^A!Y2DqnXkSgKBmo zE~wmMFH(|B-ݒByPPD9رsxbnx ?żs uHsR](}s.<Љԇ(也/ ?G9|IL'LmNP7ZH kvjY(BsZ;Rd}Y0ݜk>&[~uSUCQV~GX!6WV]Ey jҜ؀5ARcu}к wYWWŚῡ/gYn} k={0;Y% =5ߏ?׏/}ݫ?;I{?6q}~}ų{'Lmu$JFigzlH DÈ?*;G~wuxmcBuEآH{ !4z}sN?^ko. a~;v??ݛt^y.~yٴ֢W[{~w/ߪwK{w?*~Ok_7ia/mRO^>b8{cF52}ߪ}O{oC>-0\\8. ^79vrZx4ˀ3b&{wiiK+E7y<$Vf, ut2)>noL5pF [s7[X*uu0g7'~s^矞 !w6)ˏχ~ow0 w:vp^(生`> S>3Ǽf(ݼl0GҼ2GHg9I,iN6:p~щp6Vi8:9ױl;ˎsǸͫF%]xOޏd>/|Kgphn($\$\kp\+p^Խ,M]!m 2U>:\G)=DWN$,=:1 .wmu '[y?8YuҚ?9qj>JvC{Y6F>%l픰} 0X3 Ǯ[| c$.KF {^>vsHsb\p p8# bQIsb' "}SN!ѱNC됓9Dv℄0ӭAf_ #K0btR>/t}d@xhbeUz9z<̱8Z'O $OY!+rkQS]~0y3<<psݦn3{mqpۺWܫn{սVqnV[E>P6=,6mcAvsB;Mݜl#fʀۛ5 wo}\%ȍZ/_ܬ[p{Ӝ wo}D\~z oԺmѲvv!F駌P&*uT zj;{ՅDKhi멍j۴úT}N?`(FQhet1Í"cm5cfb5G3͍.pH jڇ&慖օvn^>1"nAMWdHdld~dYds`TѾ)yѥMñXQesOlXlrlnlMlk4o__/Kd'$':%z'F&&%$$6$v$eYd˚:kKެPv~vݳf˞${MCUBU4ҩJ*#L*[Rϩ2sNQ9sٚ/ɒ9ɺɶɑI9% C,7'nnrGN]&wG!yV]`[ Fku܎4 [8k'س*{sYSKtKXⳖNt̾ _u%|R6u94ZCJA4nF_h`2XBFH 8H$84&BJ,4fBc @T,ABU)[@gq%t߆dEd#$dʇ@6W[\8@`E@8vm>GıkAJC54.FJ@34N4AahCR d\s{=t߃d]"q+iah|CHJfjn99Q9!gf8\&^qlGGX_*4^Ɉ#$ ٧[fgrv]%T-!@+rʇFB HBj9GBR'v OXuȅ{$2$ i I)@g趃͐t$3$ƨ)Ck!" [IH 7Hȍ@zJHo 7I,#!.!wQQ%rddF{4$HvK @͈=d423< ̓ K,R*,!Y,!K!!LBJB{F)֡d>o $d+$ 2r؁>d9]_Bw$_H|%!_9Pi.8R9 8?9  I$?ArZWi3H3lV$$,-gRloG2үI6$YRjd ]̌-馀KHu 2b!YԬTQʺgשB>4.\gguvS6bI9K$RB"#H*HIWXP+4{8F ?f$7C[J 7Cv6IwC ז]n C3t.fG[@1@Gm6f1)K{rFTHt1oҼi? d\Fzso{' $d!$/@edžc"5 yR YoO^!!wHVK2$!|loʐl#HTOуu0:|`>uԁH>2_2rXހ rH:`uY,#!=itGV{s )88+TW̫:O-@w$Kہ|*!;ȈbsIw//%d?}A샐|-rXB0;KI '2ruNWy]uqU%$ $$!nnߕv.|[Wi]ɧuwݽ-̲n5 w֔rϖ@Γ̼7rvlމCͻ+#pc9+cDqsR52+dŬ,+Dz,תjUβjYZuVCb *j:Guh YY1x )k5ךo-bnicag}`m>>vZ~Ujm6찝slγ v=nfW.v&=þfGۏ')4{=~~^`l/o?N {}>av:a'd;IqRNSӹi4v9-˜6ΕN{jssӹչݹ suF:qg3͙rw^t;/9ל7λCgS|r8_9;s9唻k17q-uSn[-rP~OӚuF++0Jg~Kw!pvd=6&k`{w0Tc1Sh_VE6q=T)c%| ;ue6weRg[f'5y]ޘyWދC(>O|*_K1,mǺFql2[Aj#7> XM nR=pnJ=pS{&܌ppܜpOf&+c%kĘ@Dj16!w_9#c3my[p܆Wm nS;6܇%> qm O8> Y+>E /no}pnugS}gͨ_%PvH}665[vU{Z{mMﮏ*Kޢ1]xR=Nx{%kn<.A"ޫ'91Y˜ҞҞxĝO~&Uio# ~ 7p7&o0J!;n I>1]#]Q.w뾃݈.&jrIqć]ac[ nA3~RmC݅=>HC"lQ;N{#l1W}cx8݁?Cg#R'oLuUwrmE /{ŕGV5"jO."@3p6*/.z?/&EE>Ux"9"?ͩw]ҝtuD睋\j?=Ѯ"/G "Ԡ&jPWG[UØK}Zyȫj/A͐fSԫ ҼmXvEvk(& ymȡ5xV.E.eu55ҵwv(˕(K[1R@YތFN7!^FpOGm{=:IW}-"捼kPΙsx t+rꋴ0ӟv_ǯ/77ݛ>n_{{;нqrw{}H~w\Dҙuux#ޖw}Ln~T[4S:*!Xe@YQ6*۔Aj`EhU㾫Lu5"Z)0Dܠ#ܝ7$ Rð@vO {nDp#JbXipv(Irz 7?3-'鼼AA) R@ޖ@GǀLǁL'L)@@@Ks@fI @Hȟ̓,%@*!n_k*RB6>niwS h!ɞAӤ< d<ddn` $_ [$!Y,!Dݤr,2 oJ@^smF>h2ƒ쓌'ƓCj;}})^OuqgJ>˝rv׻_#y,O3iwv^6ywcxfgU.[-5_~2w(13C3Yss\~ 9WpzZW3;+ .wmuGYd6flb6cIwL7?gQs)q=f__K:_Q=CTO_yRKLT۷淔!;S[ Ic110K %v;ZыlޭĥVk͸G']ze?np_{&o5,OIF6Yv] ud%}߃g~OޭA|{h˦l9;!"ޘ=h=ORP+ 6J72R{O9FS+_h) 2PBnOBYBnSB^BEBr\\r9KBIH5  $KB, ^H)ICI:rDB~R*!"!.!|.!_+!Y/!| !kCBJBVyKB^򊄼u yB O92 ȳ i2ȓ2q@Ĩ{ܗ4Ӟ`,>?Jga6)yHxafJx?tJNehևЬsY^E?;8OWsК HNf#T +\g?GµPލ0k&|6_|-ċSO㩙>cjϕKz玥}hjN=sߥܡԓ>mjϕoR|`q:5 HxۛzL=}X۝z>O],35vR|n{~45S^$5綥S}nk(5綤Iv|@3zv!ydcl Gl\mN< J)V1=aduFݡjZKMkbzZŝ)q'cYj0ôD<;s25rqoyY ɭ͐IoHnʐ䏐ȐI7HːtH:gHQ+5eiɕ͐4HBĩ yqΆ&$52$)H\H IuHBR!IxĆ$ IN$IP^~JD%➻➼qH!)ˈ $ ٟ!Ð|!9ːlCH6gHv@)$/  >HdOd$A.CoH6B ?!Y3$!y!Y2$d1$ɐ,5HdHA$ 2$d$/fHB<$3$A2< SL Hn3tCɐaHJLXp~ɶ = Xx+Xv\ F4seW_y~~ Ρ];t}9 .Jsϕ/ nÞH )›kTQ\pLm'r@h@ڃ=ڃHoЯjm D~E{0;}'$;s-Zk){*ܲ3ו!?]ƫr|Wc Q|Wm`w51] VjD] (w5]F|Wc1B|Ww5}ݱ_q~/j,1ę 8W_uUu5 !7Q-/_D_:t0 ?;n:  :t<$Щ3A1l1a*x6Jy3}AV=Fq(-8X[ K΢❤5#ﲛg/ek& gM(Bgt)THO/6Yl݊i ;K7oc٢| Zy\o3L4\Dz⮄Zx+u}j ?* /TxiK6DJq|ʟWֳUD7_Zvݦt.[@Y9@l2jqr|gH은Fo4b=JE5M\rD|:&:jc ҜPa${e0񥏦CT6~&M /J gLʻDRj~{ױl +^vfVx'x.Z\m%Z3_GA)p?F*D:)=#Jxy ,qvųm~ V?9HX"FJk (tЕB )U|ϥ/ M,s {POU1l<ĦΡkYV8ZO3VfX ;ʎ2QGx69uJV$1u2'w,1Jlx@cBT \.znꗎ}6L}gŒژQ+3&?L| |c@v :Iz5賕)9TkڼoěV-Ȼ}·͂*ŽmDx1AU}3=K B> ЙON X}PDtv]XyuYaazzd'5`'\$/lk5Ԃl͊Z@?WBFQKaQEa.SxVQXKaQAaw)ڵ #5| Uƈ9_Ӝwӻќ;|v@TeJ|5 |G|̧Y|._s-NW|̷|?c$UPb ؊x0P)R(JsNtUz(~ e2B#h۔DoxrJ:O@I @CL'@fKRTRfйa zi XFZ/rȋ.@v)Cs'|hV<[ OAk G *rdGJ}^ZoRj(.ȋխx GE|C1ltظQ6E ⮱6SLWCs>6F@=8A~b2_yZjhv !Z_hWO|-|hE~Oڝ5ܷ 4mn;cՙ8?],2SF K>(ΏS68c ;yygލ}x><| e|%_S^D \ "w@.%Q~РsR 3L}B_X@76n>:Bз@%U,$)XP͢$?ʓ/?.AgI|D Q +qo+4NGȥ rcs~j Va>x\ ]j<_:Q> %=ߢThy >*lT= #[>^?kRTj+Fx椋WR&+sw?7#]h#r8TLWRƫ gmYIG. zHСª_h^U532X>BM D9*#+J2C]vQǾQ sdk%:*b<#+m@yGoђϨE]%EC+գXmQiTT.ᛕjldrV; 9sP JvF{U|_8Df'gΝ#12BBKAW~t<(F,ͯ`4C(bMߠ U#@r|."/ys8[>o#XKHg&tmkP7{WL,}ރOT!:MKAQ)ӈޢ'BNw}+=cJj>'>Uj{UY_⛡3q:E+,\y +(Xyr%w(W<_j̱R>I(J;{vBTBAv"KtTGxғblpq0++!+DŚ8)khf?U"Hw?x?4#ZMrKO4g1\PGԉu:[.T_U+:uE-Vw{ՃaT=)ZHKhZV]hMZYh0m6FMҦj39|mD[hMVm[ۧhGZ=[^[7қzG]C(}>AOgsbu}J_o7~H?4a1#pBȨc7͍F;a6c1ΘhL1yBUcXm36[bc8h6JӦb̄kZf]li1ۛnfOl3Gc$s9Ӝc7KeJsdn5}fy9-3'?282,222&2>2)25232'2?($,2&>)5=;/R99)jH4;jG 5͢m]ݣ}CãcӢs GGWEF7D7GEwDDDEEOẌb917V+ՉՏ55uu MMM͎͋-[[[[+NǕx(u M-m=}#cS3sK?MTqEx=eQEk|!?ԋ):|x}A `0kI1A#}tmwDAPP_Phߍ[Pq#V+hD*0AoЎ"hEەg ? >zf_ owk*ґ7QhoMN@g:,LTBu!r -e+цK5mtw;yc xkZ[|K0t~=tnEK^w _AgXy=;|# ?3|2;og?Ua8[ԑ7W]j&DjZSEUuo2kQ6h%GD.CT,6|/ڕ,-=ws!!".T\-^)ƎG1u"VDc"/…e23?鋳l4;a5rZ`{!*y4S ̟!ٿR\jKu'O!4is+vE%l֢L~@osl? 4vK+wV`D:H|&|y4F`'PyCPV&I;IsAy:XrO[k!Ak6#R hR/n3AQfJ9"w="6h;HY!e;MAHehofP q~5IgA %iЈ |M 3߀+h7%ϒv |1֯crqխ?l?tA {"Ex/RZ)bv%vۈ;Tc`o=*χby,a[1"|OÞ5n?^1N/Q+?}WsoDZaYS>&Ώ xQMfCӡy3 AᳱkbU4' ~9Z"PTNZCƴllwM^8;(aBܓo{EƔz( LU>P>=GF;JKQUfjю2k6b[rzso}q#anPLaR8LA\;-.0RѾӾ[aIZRh@ PhO3nzRC?QɼS)L0L s(̧ (z&V3ѧPwSGQ )Q[Ю'=Џ }^>T[/%lLOEsAǁUA' IOub~ 7H3?ϒqu~2|C|֏ໃ]fH1h(;5 ae{Z>\?B{w5e׮'c[1 x;4smOS~7£eGƏ&j5^D,l#4 VҖ_ -K)R |Ǚޮ5!x4 6oޛ"ೀR|&;h]i+(M\ZXh*LSsK~xbFsx=&f"e>C9GWRW*IZ ;,X&P܈;<S!\NW^\N3JyIyPDhNǣ.锯=}Jk'ׂn/WTu.(I'O4)3%?cjrgr'ӓ_&$~r?Ӓ_'&## u*yOɟK`䪹* LQg3U599ϫ}A}tDEEokr+o[rd1QQ>T]]T$ݓCT'&t_r!$KJ"z8y OM%ccZqBLN&*jȓe2i-r5<;/Zw.'TϨRR^PRF-/[[lߒ* #?9ɳ< Gyp yp |^}R-4wPRJG)tIOY g;1*h=bN},l jRM+.БB )З C( 0X (L0, 451Bpw2oM_)~! (dލwLyaENJk (tЕB )]wzP,h_ @zϠ{\3Nl:@:鴆*th?л@F^;ɓwW<Ư?щ3ѨXUK+DP lx_ Wje#*g*oPLQ+yBUeBYM~FeRR*# Z0j-@mTۨj7GV#1xu:UQ立%2uF]nR>D=W4Mhٚh5Z=Lk:j]Z/6@ Fic dm6K-kk˵UZmYۦhC1tC9EzXozOGqD}>]Kj}QߢA^6#d$\#ߨn2 &FKlt3z}`c1c7&ScXb,3Vk&cm3Jq̈mڦ8;@AӜX?g/vz^ gih=a'$g!O)>4u??:@kw(:߁mR>V~@v{=ٱ^2x3ck_S~^6y/Ӱ;[wJ([ZCڱx,Ӣ~Kw%o>ʼ'oCQ}s\X֑UcƲGمlG0v4>Ϛt\ќ-[FGK5쟬JsJv Yɗu d]yސMg[m e5C6Ov%ǣFIѧ_lZq6;XXm6/v^[8֚-]kV:ĺ5c-Alk+vwl8́ ˢ3j])_)_K(2ɪa5 ,5P-eg)\ZQ"v^j*(ޭ(/ R^:^v!I/s2UASYr|=K/7AJP|- 0;Bt4X o-;iltam v֌?tr\_/4B^a ~u؊ͺ(J]TU uJ].^XuW:PޠtSg=XO/M FFBj0v{!Zb4 5ր<5UժlZRkgꅬNBOD8cMى*ENDAJ& egW?w%) hVjRMfffZQVH ͔^Lܙ!` )0<Qkks=q>ZОotOaёg 2WtHYr!MGзX悶m6B5z|S|X/")"?/q|WZZ8<oyًDT.!rάO?ɕ McÙxxI/~SUj}'4:ҫ'W-04;(('^kv~^=#\ϼ@AiF;w)/(-/)?!ΜR*6흉'#"ї|G^,_K|'8iJ@)t^{2WZwxe*Iﱩhb?MV)ZKo65iyWLj+AKXҧcOBS拉ڥi9{ SAJ*ķ ^=Kt~ R؄KWhv̤K+Dk<_$EqNhQط`i 9|įeڪ}|·#~i-[w6 ^-^ki0vzWpusO{PMa߿J㷦tL}zCgCgaO0h)0htؗtWtt:¢:"1ڑ(# n04L8YLUxIݫ )ū,5"z6?UY_@B~!ц!ы)ysfX?j,%E~A,EgGg33*[[ Ų`UY禎23}{IKc)u4UL%! jG&Qn:5\M Qa=U`=YxZ:!6 aC!P6`C:l(J ͣw/#lj!MLi.b alؖ2ȶ&w-Â)dgo:CeXE as99 96!Gt(?؟S`_e X^6,OUUkժ ؟3`O)?0/ B<~ٙ(0 + 80+ XaV+T`\?al1 [ ðl1[K [*:E {sQWnd7a1$K,d|5B3KߗQ/}x5?OߣcOvR|I5'ʸhvrZ7EZZlj R{5vj[Qt6@mjj} z06j=Jd"cYYUf+5t^+XߕS_{oXΓ" i?'祽UN⯎j[Zq'BIP^ qPބ?G:}߯UhWZ֐ BСtDiڈ舱ttDhwلVڦKȦ]Ms[Б!1:T6=Ad?=MGv3

      A_6&sҞ[^@au^hM^h/b^"ZץG>Oo@oD oB:86_B^b N/Gybi]}4(ӣE# ~}GяHggt'ßG?'?E_GfXXSfI${{:xaC*lȂ ]HvcnT؍InM.F(*5xGc8Gޣ 1Uv]H_yu(~ 11U3\بUa*l46 ̇̇W ,_6S6]xzYJ6ux)x:x x6C6 x!SϩDx?Z=sc[υ\xhυ/\xWW0;@x٘ r0X1#X |oovga),g( >yf 3aH?aQG1(գM,& vN{i^9sh]:1OsXш4_4Lq -h>L8}Fl*ٓl ֩4Vgt6,4Z_d h,l D+Vdf'%dZ)ru%a7 z&xJ=CMhNRjV}Z#jϩeVՅYx7-_ Z[<^H~zE/ %b RC*~΁h>.a;J8wGC?_ q ssq h>A$4*LFuxe/Sح4 6?fwd_њ),t({$Y JYTX Ie9d)UBZl1E 귦lX+}}d=>/wOЮᎲԢTREU>B#eO VMb?]=@$ݍ Z`%* ڈz(*("Vb`g"Xb'yg("y3ɞܡx y;L̼7o'B~\zu3m(fznD˺F6Hl.;X"XP;_;Ore%b"I]_r.q H]cρiv]9ݮ<)njZsNGe0Ao{Li={D7Vȍ<V"X!T56niuES1n:$Z$%3ca"G^=ؼI cYWqm-eS h; 5uX;8ۿLO_,<6k"v١8磒J=;0(6pӊrrGb0ӡrZȄ3e%dn#V1j9cץ< VQynR|vXWSWD*ʑrKq=b18_s}6rZ esf"P#Fgj9$V~5%X %3hX 3eXf'yp2G6f<AEISOgc1by^OoPaO&Zf䲹1Ldӛ@w3ap]_"J/HszЭ@7Jt @:>_8~Ӂ}+OԟBe8W|Yz%=>=H<7@vTm^p6=w *G;Bǽ*?WGӇrj7Collabtive-2.0/include/font/freeserifb.ctg.z000066400000000000000000000130161237252063700211230ustar00rootroot00000000000000xs-I0\m۶m۶m۶m۶mofޛxM̷~RUvԩ?> &b432< Ƃ,$ B0,, ³,""(,*Ƣ,&b8,.,!K$,)Kƒ,%KR4,-Kҳ ,#2,,+Ʋ,'r<,/ + "(+Ɗ$+J2,+ʳ "***ƪ&j_O>kƬ kʚkZ֬ kڱ:ά ʺzެllʆlFl Ʊl&l ʦlfll[l [ʖl[Vl [ֱl6l ʶlvl;;ʎ;N ;α. ʮn{ {ʞ{^ {ޱ_{}dg}ewp Ax!P@X!DH@T!ĄX@\!$D@RH!T@ZH!dL@V!\@^BP@Q(šRP@Y(TJP@UաԄZP@]4F@Sh͡V@[htN@Wݡ^@_a A0PaQ0XaLI0TāY0\a,ERXaUZXalMVa]^CpQ8SpY8\KpU܄[p]OD<1O“d<9OST<5Ot<=3L<3³l<;s\<7|oF1o›f9o[V5ov=;N3»n;{^7~?A|0‡a|8GQ|4q|<'I|2§i|:gY|6y|>_E|1_—e|9_WU|5_u|=7M|3·m|;w]|7}|??C0?c8?OS4?sG1Ÿg9_W5w'_7LB)@V8E0\!E(ZaE8^DE$YDQE4]1E,[qןx"v_넿O$$"H&~@I%R4"H'ҋ "$2,"&"%r<"o`|"( B("b(!JR(#ʊr *J"j!jZ#zh Fh"fh!Z2EVEQtEUtESEW1P 1T 1R1V1QL1UL 1S1WP,T, RVQlUlSWqPqT qRqVqQ\qU\ qSqWP<T< RV(>*d$BJ$J-I/2 )C2 +2(#2*2)c2+2L(2L*2L)S2L+2(32*2)s2+,( ²,*Ⲅ,)KҲ,+򲂬(+ʲ*겆)kڲ+l(Ʋl*沅l)[ֲl+(;β*){޲+r(r*r)Gr+r('FNS49͐3,9[ΑsGyr\ Er\"er\!WUr\#ur 7Mr"mr!w]r#}r< CpP#<&<蟖gYyNEyI^WUyM^7MyKޖw]yOޗCH>OSL>/KJo[N"|*b WBI*)* B* ©*"**b**J*J*JRSUVSUQeRUUeSUSRUWSUUPRUU7SU UR#wB!B!YTiUFUTyUAUTTeUEUUTuUCTTmUGUT}@5TTcD5UTsBTTkFUT{AuTTgEuUTwCTToGUT5@ T`5籇ajFQjƪqj&IjijfYjyjZWBB-RT-S RRVSQmRUmSSRWSuPRuTSn:N3:Ϋ ꢺ.+ꪺꦺn;ꮺz'zz^7z~QQ}RWB/@ 5c0 !0$b8 0"Fb410&b< 0!&Ęb2L)0%Ԙb:L0#f̘b6̎90'ܘb>̏ Xb1,%}!B!B!lX Kc,6clͰ9 [cl=v ;cݰ; {c?8p88 Gp.\p9 W\p=n 7܊p; w܋p?x<8x O<<^x /:x o>>|9 _||#~7?4ӠZjQkmN{L!tHJatXNtDIGQtTMG1tLKqt\O tBH'ItRL')tJJitZNtFIgYtVMg9tNKyt^OtA]HEtQ]L%tI]JetY]NtE]IWUtU]MW5t͠kںAn&nn[6n;.{>z!zhPazGQztPz'Ɂ)25Pt=CԳl=G|@/ԋbD/rBԫjFzAoԛfEo ʿMo;NK{^OA}HGQ}L'I}JgY}NE}I_WU}M_7M}Kw]}OCH?OSL?/K*p~_{AԟgEw1 nF4c33V„4LhƄ ™&h"&j&ib&k&藎&Id$&If&IeR4&Io2&l&nr&m&o )l)nJ)mʘ)o*lnjm꘺oilinZimژio:lnzmoflfnFfmƘfo&f&߻)fffef9fgfYd%fYffYeV5fYo`6Mfjfivfk9h9j9?|6͙ܯ悹h.抹ص@nnMs6w]so@yd'yfAs/+ڼ1o;K|0f>ρ|5w`y +hikZg}f6dʆWeJXg?`#H6bh6acX6cx6M`D6Mbd6MaST6Mct6`3L6bl6as\6?>6k-h ¶-jⶄ-iKҶ-k򶂭h+ʶj궆ikmUֳm6m6m Ҷmֶmvmvmm;mзlip;=vmرvo'F&I8N jvigze էg.. Ү8k_[zn ԛfv[v j{푟Z@}Ҟ{֞{^{^ {޲{޳>> Ҿ־A?؏lدn8q'd)N;sλ`.v!% ]}]xEt\dE .b..K.K꒹.E`6KR4.Kһ .2,.wvt\nu~w_twWw(Wܕ=G&9}ߔ+J2+ʻ **檻j:k&k暻kZ6kڻ:.溻z>n!n憻nF1nƻ n&)nMs 7r7s-r-s ҭr֭smmq[6p;.q{>p!wqG1wܝp')wڝqg9w]p%w]W]o?nAw=w?~GAǿN~7#O?r {^{޹[{>쾸gq?{ B!퟽ ħW@!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!o>3L>l>g9}.yB!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B +*?nU5}-_7cu|]_moo[ov;Nv@b7={oΚB!G~_cCollabtive-2.0/include/font/freeserifb.php000066400000000000000000000702021237252063700206650ustar00rootroot0000000000000032,'FontBBox'=>'[-796 -306 1830 932]','ItalicAngle'=>0,'Ascent'=>900,'Descent'=>-300,'Leading'=>90,'CapHeight'=>676,'XHeight'=>461,'StemV'=>123,'StemH'=>53,'AvgWidth'=>426,'MaxWidth'=>1850,'MissingWidth'=>700); $cw=array(0=>700,32=>250,33=>333,34=>555,35=>500,36=>500,37=>1000,38=>833,39=>278,40=>333,41=>333,42=>507,43=>676,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>676,61=>676,62=>676,63=>500,64=>930,65=>722,66=>667,67=>722,68=>724,69=>667,70=>611,71=>778,72=>774,73=>386,74=>500,75=>764,76=>664,77=>943,78=>722,79=>778,80=>611,81=>778,82=>712,83=>556,84=>667,85=>722,86=>722,87=>1000,88=>722,89=>722,90=>667,91=>333,92=>278,93=>333,94=>581,95=>500,96=>333,97=>500,98=>546,99=>444,100=>556,101=>444,102=>333,103=>500,104=>556,105=>278,106=>333,107=>556,108=>278,109=>833,110=>556,111=>500,112=>549,113=>547,114=>444,115=>389,116=>333,117=>556,118=>500,119=>722,120=>500,121=>500,122=>444,123=>394,124=>220,125=>394,126=>520,160=>250,161=>333,162=>500,163=>500,164=>500,165=>500,166=>220,167=>500,168=>333,169=>747,170=>300,171=>500,172=>680,173=>333,174=>747,175=>333,176=>400,177=>676,178=>300,179=>300,180=>333,181=>556,182=>540,183=>250,184=>333,185=>270,186=>330,187=>500,188=>750,189=>750,190=>750,191=>500,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>389,205=>389,206=>389,207=>389,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>676,216=>778,217=>722,218=>722,219=>722,220=>722,221=>722,222=>632,223=>556,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>703,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>556,242=>500,243=>500,244=>500,245=>500,246=>500,247=>676,248=>500,249=>556,250=>556,251=>556,252=>556,253=>500,254=>556,255=>500,256=>722,257=>500,258=>722,259=>500,260=>722,261=>500,262=>722,263=>444,264=>722,265=>444,266=>722,267=>444,268=>722,269=>444,270=>722,271=>692,272=>722,273=>556,274=>667,275=>444,276=>667,277=>444,278=>667,279=>444,280=>667,281=>444,282=>667,283=>444,284=>778,285=>500,286=>778,287=>500,288=>778,289=>500,290=>778,291=>500,292=>778,293=>556,294=>778,295=>556,296=>389,297=>278,298=>389,299=>278,300=>389,301=>278,302=>389,303=>278,304=>389,305=>278,306=>882,307=>533,308=>500,309=>338,310=>778,311=>556,312=>534,313=>667,314=>278,315=>667,316=>278,317=>667,318=>433,319=>667,320=>528,321=>667,322=>278,323=>722,324=>556,325=>722,326=>556,327=>722,328=>556,329=>666,330=>829,331=>556,332=>778,333=>500,334=>778,335=>500,336=>778,337=>500,338=>1000,339=>717,340=>722,341=>444,342=>722,343=>444,344=>722,345=>444,346=>556,347=>389,348=>556,349=>389,350=>556,351=>389,352=>556,353=>389,354=>667,355=>333,356=>667,357=>488,358=>667,359=>333,360=>722,361=>556,362=>722,363=>556,364=>722,365=>556,366=>722,367=>556,368=>722,369=>556,370=>722,371=>556,372=>1000,373=>722,374=>722,375=>500,376=>722,377=>667,378=>444,379=>667,380=>444,381=>667,382=>444,383=>333,384=>556,385=>805,386=>659,387=>556,388=>667,389=>556,390=>722,391=>915,392=>605,393=>722,394=>862,395=>667,396=>556,397=>550,398=>667,399=>818,400=>631,401=>611,402=>333,403=>903,404=>776,405=>807,406=>327,407=>389,408=>887,409=>556,410=>278,411=>495,412=>1000,413=>864,414=>556,415=>828,416=>793,417=>584,418=>1192,419=>795,420=>749,421=>556,422=>748,423=>556,424=>389,425=>650,426=>465,427=>333,428=>667,429=>333,430=>667,431=>768,432=>620,433=>811,434=>685,435=>853,436=>705,437=>667,438=>444,439=>593,440=>654,441=>508,442=>500,443=>500,444=>654,445=>520,446=>444,447=>611,448=>220,449=>418,450=>570,451=>333,452=>1331,453=>1158,454=>990,455=>1134,456=>977,457=>611,458=>1200,459=>1015,460=>879,461=>722,462=>500,463=>386,464=>278,465=>778,466=>500,467=>722,468=>556,469=>722,470=>556,471=>722,472=>556,473=>722,474=>556,475=>722,476=>556,477=>444,478=>722,479=>500,480=>722,481=>500,482=>1000,483=>703,484=>778,485=>500,486=>778,487=>500,488=>764,489=>556,490=>778,491=>500,492=>778,493=>500,494=>593,495=>502,496=>338,497=>1331,498=>1158,499=>990,500=>778,501=>500,502=>995,503=>603,504=>722,505=>556,506=>722,507=>500,508=>1000,509=>703,510=>778,511=>500,512=>722,513=>500,514=>722,515=>500,516=>667,517=>444,518=>667,519=>444,520=>386,521=>278,522=>386,523=>278,524=>778,525=>500,526=>778,527=>500,528=>712,529=>444,530=>712,531=>444,532=>722,533=>556,534=>722,535=>556,536=>556,537=>389,538=>667,539=>333,540=>464,541=>455,542=>774,543=>556,544=>731,545=>649,546=>568,547=>494,548=>667,549=>444,550=>722,551=>500,552=>667,553=>444,554=>778,555=>500,556=>778,557=>500,558=>778,559=>500,560=>778,561=>500,562=>722,563=>500,564=>437,565=>636,566=>415,567=>338,568=>776,569=>760,570=>722,571=>722,572=>444,573=>664,574=>667,575=>389,576=>451,577=>505,578=>479,579=>686,580=>750,581=>722,582=>667,583=>478,584=>500,585=>333,586=>808,587=>608,588=>712,589=>444,590=>722,591=>500,592=>500,593=>523,594=>523,595=>556,596=>444,597=>468,598=>658,599=>659,600=>444,601=>444,602=>611,603=>440,604=>440,605=>611,606=>459,607=>333,608=>665,609=>500,610=>556,611=>550,612=>582,613=>556,614=>556,615=>556,616=>293,617=>333,618=>278,619=>369,620=>397,621=>389,622=>667,623=>833,624=>833,625=>833,626=>556,627=>673,628=>589,629=>500,630=>744,631=>715,632=>667,633=>444,634=>444,635=>564,636=>444,637=>444,638=>394,639=>394,640=>556,641=>556,642=>389,643=>503,644=>507,645=>507,646=>560,647=>333,648=>394,649=>500,650=>557,651=>529,652=>500,653=>722,654=>500,655=>500,656=>672,657=>492,658=>502,659=>502,660=>500,661=>500,662=>500,663=>444,664=>778,665=>545,666=>460,667=>722,668=>556,669=>438,670=>556,671=>444,672=>666,673=>500,674=>500,675=>872,676=>878,677=>926,678=>645,679=>634,680=>724,681=>825,682=>636,683=>604,684=>490,685=>500,686=>611,687=>722,688=>378,689=>378,690=>226,691=>301,692=>301,693=>301,694=>378,695=>490,696=>340,697=>250,698=>408,699=>250,700=>250,701=>250,702=>300,703=>300,704=>340,705=>340,706=>333,707=>333,708=>333,709=>333,710=>333,711=>333,712=>333,713=>333,714=>333,715=>333,716=>300,717=>333,718=>333,719=>333,720=>278,721=>278,722=>300,723=>300,724=>333,725=>333,726=>333,727=>333,728=>333,729=>333,730=>333,731=>333,732=>333,733=>400,734=>333,735=>352,736=>374,737=>189,738=>264,739=>340,740=>340,741=>526,742=>526,743=>526,744=>526,745=>526,746=>519,747=>519,748=>333,749=>333,750=>480,751=>333,752=>333,753=>333,754=>333,755=>327,756=>261,757=>437,758=>437,759=>400,760=>278,761=>175,762=>175,763=>175,764=>175,765=>333,766=>337,767=>432,768=>0,769=>0,770=>0,771=>0,772=>0,773=>0,774=>0,775=>0,776=>0,777=>0,778=>0,779=>0,780=>0,781=>0,782=>0,783=>0,784=>0,785=>0,786=>0,787=>0,788=>0,789=>0,790=>0,791=>0,792=>0,793=>0,794=>0,795=>0,796=>0,797=>0,798=>0,799=>0,800=>0,801=>0,802=>0,803=>0,804=>0,805=>0,806=>0,807=>0,808=>0,809=>0,810=>0,811=>0,812=>0,813=>0,814=>0,815=>0,816=>0,817=>0,818=>0,819=>0,820=>0,821=>0,822=>0,823=>0,824=>0,825=>0,826=>0,827=>0,828=>0,829=>0,830=>0,831=>0,832=>0,833=>0,834=>0,835=>0,836=>0,837=>0,838=>0,839=>0,840=>0,841=>0,842=>0,843=>0,844=>0,845=>0,846=>0,847=>0,848=>0,849=>0,850=>0,851=>0,852=>0,853=>0,854=>0,855=>0,856=>0,857=>0,858=>0,859=>0,860=>0,861=>0,862=>0,863=>0,864=>0,865=>0,884=>199,885=>199,890=>0,894=>333,900=>330,901=>415,902=>722,903=>250,904=>811,905=>938,906=>556,908=>840,910=>886,911=>879,912=>330,913=>722,914=>667,915=>611,916=>759,917=>667,918=>667,919=>774,920=>778,921=>386,922=>777,923=>722,924=>943,925=>722,926=>650,927=>778,928=>812,929=>611,931=>650,932=>667,933=>738,934=>868,935=>722,936=>924,937=>811,938=>386,939=>738,940=>605,941=>440,942=>605,943=>330,944=>550,945=>605,946=>550,947=>550,948=>550,949=>440,950=>495,951=>605,952=>550,953=>330,954=>608,955=>495,956=>605,957=>495,958=>495,959=>550,960=>605,961=>550,962=>440,963=>550,964=>440,965=>550,966=>660,967=>495,968=>715,969=>715,970=>330,971=>550,972=>550,973=>550,974=>715,976=>550,977=>605,978=>722,979=>871,980=>722,981=>660,982=>715,983=>550,984=>611,985=>550,986=>650,987=>514,988=>611,989=>513,990=>715,991=>439,992=>722,993=>605,994=>1022,995=>715,996=>626,997=>576,998=>616,999=>544,1000=>539,1001=>441,1002=>932,1003=>653,1004=>593,1005=>513,1006=>654,1007=>517,1008=>550,1009=>550,1010=>477,1011=>333,1012=>828,1013=>424,1014=>424,1015=>632,1016=>575,1017=>722,1018=>943,1019=>809,1020=>550,1021=>722,1022=>722,1023=>722,1024=>666,1025=>666,1026=>852,1027=>617,1028=>733,1029=>568,1030=>400,1031=>400,1032=>513,1033=>1062,1034=>1057,1035=>899,1036=>769,1037=>788,1038=>731,1039=>788,1040=>704,1041=>659,1042=>678,1043=>617,1044=>718,1045=>666,1046=>1104,1047=>654,1048=>788,1049=>788,1050=>769,1051=>793,1052=>957,1053=>788,1054=>828,1055=>814,1056=>659,1057=>733,1058=>649,1059=>731,1060=>864,1061=>715,1062=>788,1063=>768,1064=>1129,1065=>1129,1066=>794,1067=>984,1068=>659,1069=>747,1070=>1136,1071=>734,1072=>528,1073=>567,1074=>545,1075=>439,1076=>565,1077=>511,1078=>805,1079=>495,1080=>572,1081=>572,1082=>566,1083=>551,1084=>682,1085=>572,1086=>571,1087=>572,1088=>591,1089=>495,1090=>501,1091=>496,1092=>879,1093=>502,1094=>566,1095=>564,1096=>833,1097=>827,1098=>647,1099=>764,1100=>545,1101=>539,1102=>800,1103=>563,1104=>511,1105=>511,1106=>592,1107=>439,1108=>539,1109=>436,1110=>291,1111=>291,1112=>333,1113=>812,1114=>824,1115=>570,1116=>566,1117=>572,1118=>496,1119=>572,1120=>1066,1121=>769,1122=>796,1123=>648,1124=>1033,1125=>778,1126=>977,1127=>685,1128=>1363,1129=>971,1130=>1086,1131=>778,1132=>1466,1133=>1062,1134=>650,1135=>462,1136=>974,1137=>771,1138=>828,1139=>661,1140=>808,1141=>578,1142=>808,1143=>590,1144=>1318,1145=>1014,1146=>992,1147=>744,1148=>1066,1149=>769,1150=>1066,1151=>769,1152=>694,1153=>483,1154=>258,1155=>0,1156=>0,1157=>0,1158=>0,1159=>0,1160=>0,1161=>0,1162=>788,1163=>569,1164=>659,1165=>548,1166=>659,1167=>594,1168=>618,1169=>459,1170=>618,1171=>439,1172=>666,1173=>585,1174=>1155,1175=>843,1176=>670,1177=>495,1178=>833,1179=>610,1180=>815,1181=>597,1182=>901,1183=>676,1184=>874,1185=>636,1186=>788,1187=>572,1188=>986,1189=>693,1190=>1086,1191=>864,1192=>913,1193=>666,1194=>733,1195=>495,1196=>649,1197=>501,1198=>712,1199=>609,1200=>712,1201=>609,1202=>790,1203=>567,1204=>1043,1205=>785,1206=>768,1207=>562,1208=>824,1209=>598,1210=>768,1211=>570,1212=>960,1213=>637,1214=>960,1215=>637,1216=>400,1217=>1104,1218=>805,1219=>742,1220=>557,1221=>793,1222=>551,1223=>788,1224=>570,1225=>788,1226=>572,1227=>768,1228=>564,1229=>957,1230=>682,1231=>400,1232=>704,1233=>528,1234=>704,1235=>528,1236=>989,1237=>725,1238=>667,1239=>511,1240=>818,1241=>511,1242=>818,1243=>511,1244=>1104,1245=>805,1246=>654,1247=>495,1248=>644,1249=>472,1250=>788,1251=>572,1252=>788,1253=>572,1254=>828,1255=>571,1256=>828,1257=>571,1258=>828,1259=>571,1260=>747,1261=>539,1262=>731,1263=>496,1264=>731,1265=>496,1266=>731,1267=>500,1268=>768,1269=>564,1270=>627,1271=>435,1272=>984,1273=>764,1296=>660,1297=>495,1298=>793,1299=>551,1306=>818,1307=>588,1308=>994,1309=>716,1310=>769,1311=>566,1329=>889,1330=>787,1331=>858,1332=>941,1333=>775,1334=>765,1335=>805,1336=>762,1337=>938,1338=>869,1339=>765,1340=>756,1341=>966,1342=>992,1343=>748,1344=>469,1345=>731,1346=>941,1347=>745,1348=>966,1349=>641,1350=>929,1351=>774,1352=>779,1353=>784,1354=>841,1355=>775,1356=>955,1357=>779,1358=>927,1359=>555,1360=>763,1361=>641,1362=>656,1363=>824,1364=>869,1365=>768,1366=>754,1369=>300,1370=>300,1371=>270,1372=>307,1373=>270,1374=>324,1375=>322,1377=>818,1378=>548,1379=>601,1380=>608,1381=>551,1382=>547,1383=>496,1384=>548,1385=>586,1386=>585,1387=>548,1388=>269,1389=>798,1390=>594,1391=>544,1392=>548,1393=>513,1394=>583,1395=>560,1396=>551,1397=>397,1398=>567,1399=>447,1400=>548,1401=>411,1402=>810,1403=>464,1404=>548,1405=>551,1406=>595,1407=>821,1408=>548,1409=>557,1410=>312,1411=>821,1412=>550,1413=>511,1414=>668,1415=>602,1417=>333,1418=>349,1425=>0,1426=>0,1427=>0,1428=>0,1429=>0,1430=>0,1431=>0,1432=>0,1433=>0,1434=>0,1435=>0,1436=>0,1437=>0,1438=>0,1439=>0,1440=>0,1441=>0,1442=>0,1443=>0,1444=>0,1445=>0,1446=>0,1447=>0,1448=>0,1449=>0,1450=>0,1451=>0,1452=>0,1453=>0,1454=>0,1455=>0,1456=>0,1457=>0,1458=>0,1459=>0,1460=>0,1461=>0,1462=>0,1463=>0,1464=>0,1465=>0,1466=>0,1467=>0,1468=>0,1469=>0,1470=>433,1471=>0,1472=>155,1473=>0,1474=>0,1475=>400,1476=>0,1477=>0,1478=>347,1479=>0,1488=>593,1489=>498,1490=>339,1491=>523,1492=>561,1493=>266,1494=>291,1495=>559,1496=>576,1497=>266,1498=>496,1499=>501,1500=>510,1501=>542,1502=>581,1503=>273,1504=>347,1505=>512,1506=>552,1507=>493,1508=>491,1509=>537,1510=>561,1511=>544,1512=>502,1513=>716,1514=>571,1520=>532,1521=>532,1522=>532,1523=>396,1524=>432,3585=>590,3586=>578,3587=>661,3588=>592,3589=>592,3590=>699,3591=>447,3592=>534,3593=>692,3594=>578,3595=>659,3596=>899,3597=>804,3598=>633,3599=>637,3600=>484,3601=>730,3602=>876,3603=>915,3604=>592,3605=>592,3606=>578,3607=>670,3608=>542,3609=>671,3610=>621,3611=>618,3612=>621,3613=>617,3614=>708,3615=>708,3616=>637,3617=>589,3618=>552,3619=>484,3620=>590,3621=>569,3622=>637,3623=>526,3624=>599,3625=>802,3626=>579,3627=>668,3628=>778,3629=>560,3630=>514,3631=>510,3632=>412,3633=>0,3634=>423,3635=>452,3636=>0,3637=>0,3638=>0,3639=>0,3640=>0,3641=>0,3642=>0,3647=>665,3648=>357,3649=>624,3650=>529,3651=>486,3652=>475,3653=>423,3654=>500,3655=>0,3656=>0,3657=>0,3658=>0,3659=>0,3660=>0,3661=>0,3662=>0,3663=>657,3664=>548,3665=>548,3666=>592,3667=>614,3668=>631,3669=>643,3670=>508,3671=>744,3672=>622,3673=>585,3674=>721,3675=>1381,4256=>540,4257=>544,4258=>639,4259=>718,4260=>553,4261=>545,4262=>541,4263=>810,4264=>540,4265=>541,4266=>921,4267=>540,4268=>529,4269=>810,4270=>540,4271=>540,4272=>810,4273=>545,4274=>642,4275=>643,4276=>659,4277=>538,4278=>718,4279=>541,4280=>592,4281=>535,4282=>586,4283=>540,4284=>628,4285=>521,4286=>548,4287=>630,4288=>541,4289=>541,4290=>660,4291=>544,4292=>542,4293=>498,4304=>522,4305=>518,4306=>621,4307=>716,4308=>517,4309=>519,4310=>518,4311=>796,4312=>518,4313=>518,4314=>934,4315=>517,4316=>519,4317=>787,4318=>515,4319=>514,4320=>788,4321=>573,4322=>620,4323=>593,4324=>639,4325=>516,4326=>714,4327=>518,4328=>572,4329=>518,4330=>555,4331=>518,4332=>559,4333=>509,4334=>572,4335=>677,4336=>523,4337=>517,4338=>595,4339=>480,4340=>519,4341=>484,4342=>838,4343=>517,4344=>516,4345=>621,4346=>522,4347=>450,4348=>389,5024=>718,5025=>768,5026=>633,5027=>878,5028=>1001,5029=>371,5030=>576,5031=>754,5032=>531,5033=>774,5034=>692,5035=>499,5036=>668,5037=>829,5038=>575,5039=>681,5040=>485,5041=>607,5042=>885,5043=>974,5044=>588,5045=>583,5046=>726,5047=>947,5048=>558,5049=>832,5050=>1096,5051=>780,5052=>595,5053=>869,5054=>752,5055=>710,5056=>761,5057=>802,5058=>760,5059=>656,5060=>655,5061=>982,5062=>684,5063=>801,5064=>805,5065=>1042,5066=>755,5067=>612,5068=>707,5069=>889,5070=>584,5071=>623,5072=>536,5073=>763,5074=>763,5075=>581,5076=>1052,5077=>600,5078=>730,5079=>714,5080=>714,5081=>697,5082=>543,5083=>943,5084=>718,5085=>630,5086=>660,5087=>692,5088=>841,5089=>861,5090=>617,5091=>733,5092=>898,5093=>896,5094=>781,5095=>612,5096=>830,5097=>948,5098=>886,5099=>757,5100=>796,5101=>578,5102=>601,5103=>797,5104=>623,5105=>886,5106=>730,5107=>827,5108=>648,7680=>722,7681=>500,7682=>667,7683=>546,7684=>667,7685=>546,7686=>667,7687=>546,7688=>722,7689=>444,7690=>724,7691=>556,7692=>724,7693=>556,7694=>724,7695=>556,7696=>724,7697=>556,7698=>724,7699=>556,7700=>667,7701=>444,7702=>667,7703=>444,7704=>667,7705=>444,7706=>667,7707=>444,7708=>667,7709=>444,7710=>611,7711=>333,7712=>778,7713=>500,7714=>774,7715=>556,7716=>774,7717=>556,7718=>774,7719=>556,7720=>774,7721=>556,7722=>774,7723=>556,7724=>386,7725=>278,7726=>389,7727=>278,7728=>764,7729=>556,7730=>764,7731=>556,7732=>764,7733=>556,7734=>664,7735=>278,7736=>664,7737=>278,7738=>664,7739=>278,7740=>664,7741=>278,7742=>943,7743=>833,7744=>943,7745=>833,7746=>943,7747=>833,7748=>722,7749=>556,7750=>722,7751=>556,7752=>722,7753=>556,7754=>722,7755=>556,7756=>778,7757=>500,7758=>778,7759=>500,7760=>778,7761=>500,7762=>778,7763=>500,7764=>611,7765=>549,7766=>611,7767=>549,7768=>712,7769=>444,7770=>712,7771=>444,7772=>712,7773=>444,7774=>712,7775=>444,7776=>556,7777=>389,7778=>556,7779=>389,7780=>556,7781=>389,7782=>556,7783=>389,7784=>556,7785=>389,7786=>667,7787=>333,7788=>667,7789=>333,7790=>667,7791=>333,7792=>667,7793=>333,7794=>722,7795=>556,7796=>722,7797=>556,7798=>722,7799=>556,7800=>722,7801=>556,7802=>722,7803=>556,7804=>722,7805=>500,7806=>722,7807=>500,7808=>1000,7809=>722,7810=>1000,7811=>722,7812=>1000,7813=>722,7814=>1000,7815=>722,7816=>1000,7817=>722,7818=>722,7819=>500,7820=>722,7821=>500,7822=>722,7823=>500,7824=>667,7825=>444,7826=>667,7827=>444,7828=>667,7829=>444,7830=>556,7831=>333,7832=>722,7833=>500,7834=>507,7835=>333,7836=>333,7837=>333,7838=>792,7839=>534,7840=>722,7841=>500,7842=>722,7843=>500,7844=>722,7845=>500,7846=>722,7847=>500,7848=>722,7849=>500,7850=>722,7851=>500,7852=>722,7853=>500,7854=>722,7855=>500,7856=>722,7857=>500,7858=>722,7859=>603,7860=>722,7861=>500,7862=>722,7863=>500,7864=>667,7865=>444,7866=>667,7867=>444,7868=>667,7869=>444,7870=>667,7871=>444,7872=>667,7873=>444,7874=>667,7875=>444,7876=>667,7877=>444,7878=>667,7879=>444,7880=>386,7881=>278,7882=>386,7883=>278,7884=>778,7885=>500,7886=>778,7887=>500,7888=>778,7889=>500,7890=>778,7891=>500,7892=>778,7893=>500,7894=>778,7895=>500,7896=>778,7897=>500,7898=>774,7899=>584,7900=>774,7901=>584,7902=>774,7903=>549,7904=>793,7905=>584,7906=>793,7907=>584,7908=>722,7909=>556,7910=>722,7911=>556,7912=>838,7913=>672,7914=>838,7915=>672,7916=>825,7917=>659,7918=>768,7919=>620,7920=>768,7921=>620,7922=>722,7923=>500,7924=>722,7925=>500,7926=>722,7927=>500,7928=>722,7929=>500,7936=>605,7937=>605,7938=>605,7939=>605,7940=>605,7941=>605,7942=>605,7943=>605,7944=>722,7945=>722,7946=>830,7947=>833,7948=>761,7949=>798,7950=>721,7951=>722,7952=>440,7953=>440,7954=>440,7955=>440,7956=>440,7957=>440,7960=>817,7961=>826,7962=>944,7963=>970,7964=>964,7965=>1009,7968=>605,7969=>605,7970=>605,7971=>605,7972=>605,7973=>605,7974=>605,7975=>605,7976=>926,7977=>921,7978=>1038,7979=>1064,7980=>1092,7981=>1102,7982=>1005,7983=>991,7984=>330,7985=>330,7986=>330,7987=>330,7988=>330,7989=>330,7990=>330,7991=>330,7992=>534,7993=>541,7994=>653,7995=>659,7996=>705,7997=>714,7998=>612,7999=>614,8000=>550,8001=>550,8002=>550,8003=>550,8004=>550,8005=>550,8008=>885,8009=>886,8010=>1038,8011=>1052,8012=>997,8013=>1021,8016=>550,8017=>550,8018=>550,8019=>550,8020=>550,8021=>550,8022=>550,8023=>550,8025=>870,8027=>1014,8029=>1043,8031=>944,8032=>715,8033=>715,8034=>715,8035=>715,8036=>715,8037=>715,8038=>715,8039=>715,8040=>905,8041=>913,8042=>1066,8043=>1085,8044=>1034,8045=>1044,8046=>980,8047=>961,8048=>605,8049=>605,8050=>440,8051=>440,8052=>605,8053=>605,8054=>330,8055=>330,8056=>550,8057=>550,8058=>550,8059=>550,8060=>715,8061=>715,8064=>605,8065=>605,8066=>605,8067=>605,8068=>605,8069=>605,8070=>605,8071=>605,8072=>886,8073=>887,8074=>985,8075=>993,8076=>937,8077=>956,8078=>874,8079=>878,8080=>605,8081=>605,8082=>605,8083=>605,8084=>605,8085=>605,8086=>605,8087=>605,8088=>1096,8089=>1092,8090=>1223,8091=>1250,8092=>1270,8093=>1283,8094=>1174,8095=>1162,8096=>715,8097=>715,8098=>715,8099=>715,8100=>715,8101=>715,8102=>715,8103=>715,8104=>1057,8105=>1073,8106=>1228,8107=>1251,8108=>1202,8109=>1210,8110=>1151,8111=>1131,8112=>605,8113=>605,8114=>605,8115=>605,8116=>605,8118=>605,8119=>605,8120=>722,8121=>722,8122=>722,8123=>722,8124=>883,8125=>500,8126=>0,8127=>500,8128=>500,8129=>550,8130=>605,8131=>605,8132=>605,8134=>605,8135=>605,8136=>790,8137=>830,8138=>909,8139=>931,8140=>950,8141=>500,8142=>500,8143=>500,8144=>330,8145=>330,8146=>330,8147=>330,8150=>330,8151=>330,8152=>386,8153=>386,8154=>506,8155=>550,8157=>500,8158=>500,8159=>500,8160=>550,8161=>550,8162=>550,8163=>550,8164=>550,8165=>550,8166=>550,8167=>550,8168=>738,8169=>738,8170=>858,8171=>880,8172=>764,8173=>550,8174=>550,8175=>500,8178=>715,8179=>715,8180=>715,8182=>715,8183=>715,8184=>884,8185=>857,8186=>927,8187=>892,8188=>988,8189=>500,8190=>500,8192=>500,8193=>1000,8194=>500,8195=>1000,8196=>333,8197=>250,8198=>167,8199=>500,8200=>250,8201=>200,8202=>100,8203=>0,8204=>0,8205=>0,8206=>0,8207=>0,8208=>333,8209=>333,8210=>500,8211=>500,8212=>1000,8213=>1000,8214=>333,8215=>478,8216=>250,8217=>250,8218=>250,8219=>250,8220=>500,8221=>500,8222=>500,8223=>500,8224=>500,8225=>500,8226=>524,8227=>560,8228=>250,8229=>500,8230=>1000,8231=>250,8232=>0,8233=>0,8234=>0,8235=>0,8236=>0,8237=>0,8238=>0,8239=>250,8240=>1000,8241=>1588,8242=>270,8243=>492,8244=>714,8245=>270,8246=>484,8247=>693,8248=>469,8249=>333,8250=>333,8251=>727,8252=>666,8253=>695,8254=>500,8255=>953,8256=>953,8257=>338,8258=>931,8259=>333,8260=>167,8261=>332,8262=>332,8263=>1000,8264=>833,8265=>833,8266=>500,8267=>540,8268=>528,8269=>523,8270=>500,8271=>333,8272=>953,8273=>500,8274=>497,8275=>576,8276=>953,8277=>785,8278=>450,8279=>881,8280=>620,8281=>620,8282=>179,8283=>621,8284=>569,8285=>179,8286=>179,8287=>111,8288=>0,8289=>0,8290=>0,8291=>0,8292=>0,8304=>300,8305=>185,8308=>300,8309=>300,8310=>300,8311=>300,8312=>300,8313=>300,8314=>300,8315=>300,8316=>300,8317=>216,8318=>216,8319=>325,8320=>300,8321=>274,8322=>300,8323=>300,8324=>300,8325=>300,8326=>300,8327=>300,8328=>300,8329=>300,8330=>300,8331=>300,8332=>300,8333=>216,8334=>216,8336=>344,8337=>304,8338=>340,8339=>337,8340=>308,8352=>710,8353=>722,8354=>783,8355=>611,8356=>500,8357=>833,8358=>722,8359=>960,8360=>1101,8361=>1000,8362=>889,8363=>532,8364=>761,8365=>742,8366=>631,8367=>1435,8368=>579,8369=>609,8370=>639,8371=>660,8372=>556,8373=>500,8376=>524,8400=>0,8401=>0,8406=>0,8407=>0,8411=>0,8412=>0,8413=>0,8414=>0,8415=>0,8416=>0,8417=>0,8421=>0,8423=>0,8424=>0,8426=>0,8427=>0,8428=>0,8429=>0,8430=>0,8431=>0,8448=>624,8449=>625,8451=>1009,8453=>623,8454=>737,8455=>631,8456=>709,8457=>923,8458=>500,8459=>1035,8462=>556,8463=>556,8464=>792,8465=>737,8466=>800,8467=>427,8468=>835,8470=>896,8471=>855,8472=>666,8475=>747,8476=>955,8478=>722,8479=>722,8480=>991,8481=>1186,8482=>1086,8483=>722,8486=>811,8487=>811,8489=>333,8490=>764,8491=>722,8492=>806,8494=>551,8495=>444,8497=>723,8498=>611,8499=>1203,8501=>593,8502=>498,8503=>339,8504=>523,8506=>906,8507=>1181,8523=>778,8525=>1028,8526=>408,8531=>750,8532=>750,8533=>750,8534=>750,8535=>750,8536=>750,8537=>750,8538=>750,8539=>750,8540=>750,8541=>750,8542=>750,8543=>750,8544=>386,8545=>760,8546=>1138,8547=>1098,8548=>722,8549=>1098,8550=>1474,8551=>1850,8552=>1096,8553=>722,8554=>1095,8555=>1472,8556=>664,8557=>722,8558=>724,8559=>943,8560=>278,8561=>545,8562=>812,8563=>758,8564=>500,8565=>769,8566=>1036,8567=>1298,8568=>768,8569=>500,8570=>768,8571=>1034,8572=>278,8573=>444,8574=>556,8575=>833,8592=>964,8593=>523,8594=>964,8595=>523,8596=>964,8597=>964,8598=>964,8599=>964,8600=>964,8601=>964,8602=>964,8603=>964,8604=>1152,8605=>1152,8606=>964,8607=>964,8608=>964,8609=>964,8610=>1078,8611=>1078,8612=>964,8613=>964,8614=>964,8615=>964,8616=>964,8617=>964,8618=>964,8619=>964,8620=>964,8621=>1168,8622=>964,8624=>622,8625=>622,8630=>1069,8631=>1069,8632=>964,8633=>964,8634=>980,8635=>980,8636=>964,8637=>964,8638=>557,8639=>556,8640=>964,8641=>964,8642=>557,8643=>556,8644=>964,8645=>964,8646=>964,8647=>964,8648=>964,8649=>964,8650=>964,8651=>964,8652=>964,8653=>964,8654=>964,8655=>964,8656=>964,8657=>630,8658=>964,8659=>630,8660=>964,8661=>630,8662=>1063,8663=>1063,8664=>1063,8665=>1063,8666=>964,8667=>964,8668=>1100,8669=>1100,8672=>964,8674=>964,8676=>964,8677=>964,8704=>627,8705=>716,8706=>558,8707=>627,8708=>627,8709=>746,8710=>612,8711=>719,8713=>576,8714=>576,8716=>576,8717=>576,8720=>733,8721=>713,8722=>676,8723=>676,8724=>676,8725=>750,8727=>570,8729=>570,8730=>549,8733=>676,8734=>752,8736=>555,8737=>555,8738=>555,8739=>240,8740=>531,8741=>478,8742=>705,8743=>694,8744=>694,8745=>694,8746=>694,8747=>323,8756=>629,8757=>629,8761=>947,8764=>676,8765=>676,8766=>763,8768=>305,8769=>676,8770=>676,8771=>676,8773=>676,8776=>676,8777=>676,8778=>676,8781=>676,8782=>676,8783=>676,8784=>676,8785=>676,8786=>676,8787=>676,8788=>947,8789=>947,8790=>676,8791=>676,8796=>676,8800=>570,8801=>676,8802=>676,8804=>570,8805=>570,8806=>676,8807=>676,8808=>676,8809=>676,8810=>1047,8811=>1047,8812=>450,8813=>676,8814=>676,8815=>676,8816=>676,8817=>676,8818=>676,8819=>676,8820=>676,8821=>676,8822=>676,8823=>676,8824=>676,8825=>676,8826=>676,8827=>676,8828=>676,8829=>676,8830=>676,8831=>676,8832=>676,8833=>676,8834=>676,8835=>676,8836=>676,8837=>676,8838=>676,8839=>676,8840=>676,8841=>676,8842=>676,8843=>676,8846=>694,8847=>676,8848=>676,8849=>676,8850=>676,8851=>694,8852=>694,8853=>738,8854=>738,8855=>738,8856=>738,8857=>738,8858=>738,8859=>738,8861=>738,8862=>678,8863=>678,8864=>678,8865=>678,8866=>487,8867=>487,8868=>752,8869=>752,8871=>487,8873=>659,8874=>831,8876=>487,8877=>487,8878=>659,8879=>659,8882=>676,8883=>676,8884=>676,8885=>676,8886=>1380,8887=>1380,8888=>1027,8890=>626,8891=>694,8892=>694,8893=>694,8900=>512,8903=>676,8904=>759,8905=>632,8906=>632,8907=>1000,8908=>1000,8909=>676,8910=>694,8911=>694,8912=>676,8913=>676,8914=>694,8915=>694,8916=>694,8918=>676,8919=>676,8920=>1441,8921=>1441,8922=>676,8923=>676,8924=>676,8925=>676,8926=>676,8927=>676,8928=>676,8929=>676,8930=>676,8931=>676,8934=>676,8935=>676,8936=>676,8937=>676,8938=>676,8939=>676,8940=>676,8941=>676,8960=>737,8968=>411,8969=>411,8970=>411,8971=>411,8976=>680,8994=>951,8995=>951,9001=>398,9002=>398,9251=>500,9472=>1000,9473=>1000,9474=>1000,9475=>1000,9476=>1000,9477=>1000,9478=>1000,9479=>1000,9480=>1000,9481=>1000,9482=>1000,9483=>1000,9484=>1000,9485=>1000,9486=>1000,9487=>1000,9488=>1000,9489=>1000,9490=>1000,9491=>1000,9492=>1000,9493=>1000,9494=>1000,9495=>1000,9496=>1000,9497=>1000,9498=>1000,9499=>1000,9500=>1000,9501=>1000,9502=>1000,9503=>1000,9504=>1000,9505=>1000,9506=>1000,9507=>1000,9508=>1000,9509=>1000,9510=>1000,9511=>1000,9512=>1000,9513=>1000,9514=>1000,9515=>1000,9516=>1000,9517=>1000,9518=>1000,9519=>1000,9520=>1000,9521=>1000,9522=>1000,9523=>1000,9524=>1000,9525=>1000,9526=>1000,9527=>1000,9528=>1000,9529=>1000,9530=>1000,9531=>1000,9532=>1000,9533=>1000,9534=>1000,9535=>1000,9536=>1000,9537=>1000,9538=>1000,9539=>1000,9540=>1000,9541=>1000,9542=>1000,9543=>1000,9544=>1000,9545=>1000,9546=>1000,9547=>1000,9552=>1000,9553=>1000,9554=>1000,9555=>1000,9556=>1000,9557=>1000,9558=>1000,9559=>1000,9560=>1000,9561=>1000,9562=>1000,9563=>1000,9564=>1000,9565=>1000,9566=>1000,9567=>1000,9568=>1000,9569=>1000,9570=>1000,9571=>1000,9572=>1000,9573=>1000,9574=>1000,9575=>1000,9576=>1000,9577=>1000,9578=>1000,9579=>1000,9580=>1000,9600=>1000,9601=>1000,9602=>1000,9603=>1000,9604=>1000,9605=>1000,9606=>1000,9607=>1000,9608=>1000,9609=>1000,9610=>1000,9611=>1000,9612=>1000,9613=>1000,9614=>1000,9615=>1000,9616=>1000,9617=>1000,9618=>1000,9619=>1000,9620=>1000,9621=>1000,9622=>1000,9623=>1000,9624=>1000,9625=>1000,9626=>1000,9627=>1000,9628=>1000,9629=>1000,9630=>1000,9631=>1000,9632=>678,9633=>678,9642=>309,9650=>681,9651=>681,9654=>681,9655=>681,9660=>681,9661=>681,9664=>681,9665=>681,9670=>580,9671=>580,9674=>494,9675=>738,9676=>732,9679=>738,9702=>524,9711=>855,9733=>1003,9734=>1003,9824=>618,9825=>645,9826=>587,9827=>582,9828=>582,9829=>645,9830=>587,9831=>618,9833=>333,9834=>556,9835=>778,9836=>778,9837=>556,9838=>556,9839=>556,10214=>561,10215=>561,11392=>760,11393=>568,11394=>545,11395=>444,11396=>598,11397=>433,11398=>1039,11399=>760,11400=>681,11401=>502,11402=>572,11403=>405,11404=>583,11405=>463,11406=>698,11407=>529,11408=>754,11409=>555,11410=>338,11411=>258,11412=>688,11413=>524,11414=>700,11415=>521,11416=>799,11417=>609,11418=>708,11419=>537,11420=>546,11421=>411,11422=>778,11423=>541,11424=>724,11425=>524,11426=>545,11427=>446,11428=>676,11429=>498,11430=>615,11431=>433,11432=>759,11433=>589,11434=>800,11435=>670,11436=>669,11437=>512,11438=>801,11439=>609,11440=>1003,11441=>743,11517=>266,11518=>617,11519=>307,11799=>333,42790=>774,42791=>551,42792=>964,42793=>754,42794=>652,42795=>452,42796=>478,42797=>422,42798=>662,42799=>612,42888=>333,42889=>278,42890=>282,42891=>349,42892=>278,64256=>613,64257=>559,64258=>559,64259=>846,64260=>836,64261=>603,64262=>723,64275=>1105,64276=>1105,64277=>1099,64278=>1105,64279=>1361,64285=>266,64286=>0,64287=>532,64288=>552,64297=>570,64298=>716,64299=>716,64300=>716,64301=>716,64302=>593,64303=>593,64304=>593,64305=>498,64306=>339,64307=>523,64308=>561,64309=>266,64310=>291,64312=>576,64313=>266,64314=>496,64315=>501,64316=>510,64318=>581,64320=>347,64321=>512,64323=>493,64324=>491,64326=>561,64327=>544,64328=>502,64329=>716,64330=>571,64331=>266,64332=>498,64333=>501,64334=>491,64335=>593,65533=>900,65535=>700); // --- EOF --- Collabtive-2.0/include/font/freeserifb.z000066400000000000000000011143361237252063700203570ustar00rootroot00000000000000xwxUE=knIH'BKhI;ҥ(((;* ((h ;s|̚rfJ@!hZXصC Z#{g*Y5s.p*DE]D1O:uIJ Vw8؊`h+D9'M0:u~[7}T'=tԄ)׎EMG ?ҡ>N3@AS6S36aԠ9 me!*ǎwBOуBL~Ac~Rx;yиUjhWP_8_knrl\n95~sXTTyVECRW_EX K[_KLUu\U勩65E4-SZW({_^,K?AMDpx8]9J(/+"[]'rswCڥXuὈп#w#~d,l_'oeKߝp薶cZ6sK_u^|ѹg) ??w)t6y59A`}̟ ?2/>9rZ2;\֠#;/rd]ʵJ֮RF8l,s_g]-9֬Kt[tNdI%_{{c UcDk"Y̘YOjWEzl"~P~^չZ(룭uz5Kz}/ӹOɠի#DdSvx,ŏE"EW;QoZf |8_uFS~b߇_c׈'پρirznwwIߔ;m17۹|-{TԯWe|٦8|1Oܚ1~|G6)Gy0wv]}LHu͇#ߕv:>~~](}=Y Oo%\ߙ%28yz&{Zm?}PӁxі>8'69i1SwWrӧfFB*'Te!{|C-W0m@^6Kɝt.kpPRxrIߟP[pM5!YL=akC?<4p=9vNdž>輨̞s@=jA&<$7ϕzLc}ȱ]r9G?DB=8+<L蠯;luv99s~NLC\u92/+mQU'ev[To+e+Jۋ錌txq6ö2逗,메n.BmN<6#u۟m)?u6~o6ٷ GYlvR7{$Xgݾ'H0 xOꚀdPMuU8<[*%:Ǻ}`C/Q0L;?w=s&cd:16^zq^--;NhpaoڂI` vkgXyek]_yϩg/ c+YLJw/9 XF}yWn2Ds$q!~ښQxh4ܜf0_[c{ Vl$A,+̑e'}\+.l>T;-LkAa΂7(CL4#%KB&³EoIMEs mKu3raj-ky=G;2pDp[O'$norZN9]i-Pr!L{WcrDI扌?pOepG5)3k;?(e\~˘Ɛ2Wtmv2'aG/sQjgh" er}yKkCϹSS$G.ekEϡ;Ky^wبx#rNg0$[%#=ra!>enjS¦)]&u+3{67yJ}\ŧE~GIz?ֵ 2<s1{+ym1 U}L1OIL#6I3Yܕo_|I'c+(c9@1}ԕȎ⹌g_^DٔmYyޯdNc#v.9'+8V^L+yr;-{8 Njh|8 EP 2x ACk_ xS)hSm +W~#g7g&CW23V )%9[RMkJo!p; .#ϔpc꾔7gA31np>OD %,>&lHш5ј~{idYc}׷Gc/9xX,6)yS#O"hwy$GRX#s<0 p6ޥ>Y;}ͤj@@p1 pvMe|txO.'& ;$>#ip~)Dr&gU]vUb/ BS[2mػ6Qhۮ{Ek md$}S[^b^̼;E3ӷ;cÙ&5wx?: c+y/>hao Z\-9E w9@]m`ΛșRmbȾ<CImhƟWIn9nW#ϞғRwu&}No}?7KY῕/[o%w;#Q]/r7bs:/|/w|7~%'(ew*{]*=ۏ^g1]ILs(r8na{Wj\/o5m(;lS{vA}mg?ؿw:ܰ_~PH9jf(9ߖ}{?e9kZgwWZ$8hlg,Z[7m3¾=kA{vSW6Nm%iKNJ;[ K5i.\~dU}p|c d .k7f~~]rBASc9%T=P)tWopTΊU7 yzHPDgE\ Z#^?t].U[r,SKߺaK POrV]!J-"Km@)JZ0Xo+Wڋ y?K?kF1㞨ϗ60y~aHΊ#mb#(ͅ M-9;ogS>IY$mcӿZ؟-JLuUEm;㎭@~O7sf[,j$A{.uȒ2p{~w`9LY,,j5sx%zT .`_ywS*q eJgξYD/د>9 ]{FdiD sIvhA1TʙI^: -ĉ(=s.p?o!ǭogBlC!yrL)\x[w9 \8M_RBkCowr[;FW%fj4m6_[>vݹ:_tCW~7" ކM݆cӆ W uJ8"R[ƭO'_/k?f4BL&)oJ22M-L%Y7LLgL_1]0= ́`s9Ĝfnn16ۙ{54`^o~V;sKaZ,kuuF;{Zq3&:~C-1x}.ڜڼ6l7mgmFZ3~ikG}Ü9tG/{+ޭ|W_% b0:;gmlc8a8cQ'W i6^4 q6yL(S)̔fʂ.Ŧ*ffav7{}'i6S'ۜ ?m\i^d~~^6f~Ӽ ~O71[vΆ7;;{8T 6~vMY?VF6ֵ̈́9*kmlV Z_ݮһsM55mjkjrkZd״ɪɬɨIIIքՄ(7V[WgOW^Y'V կWZJՏU/^XhG~zf}STOX}o#UR=zP}{UQ]PSUݨ: /B /]`u!B7W_t~ೳΦŷo;ߖپ-||fz>z&ncB?7)j(ץ Ls t AX@Xր@~AG /\dVPg)Q.燩B@u^P"Cep\ARV7Gy}_d O[+ج6t2 -e=ZA )ۂ eO;\ו}p]Eԟ 6QAɩ@\ TNԽ)πPߍ~uCmBI /$Fbm`)(H鶍rnd n Fnd?`Հӟ6Q&17ƙ4;kjɍ9 nd ԉ ,ԉ5;rMfw); )@&uV1NnJpoHIww(L>cAJր=Ýӓ2aJrʌ(i Bx[z;Sz&$_ֳå'yzr֓%&j]zٿjɽZbIam:uZV-yScTJ6:ZtJbS ߞcl7'5(wR_OQ>S,\8 wNꞼoO4"@ ,BD"}«b\7DM'%TgH%cҬcSL*ѹ|n2 ?ٟBu&$zx\)7,ˍ"R3E [u)*'rxZ1'C6>'Eʮb,/nRzǡb|q~|K9>E U2 O: + r`,,W鉜w2v.IO@F+%[}IIrprrS(|-+5z`Q2 Q+0Vx_ V`PTu.ߠ(zn(Ѩ%ʨ k}Ef,Қr36\ypKw< Y6xvxpwǃQxx2@4SBl P#n!$0c0Aq=7u*1r |vŵz$ko:v0p6PʳVpNptƙ3y3w S.\8sC;r\!{p]I'^рwhzӛӇ҇w|_ӏy~!63ϟ3Bgޙ AĹ!k?wy0/! _h GV8\cgwYK"=) 3f̶MNs~<l`w4DޏhΔVV01c8"/)_1m15 1}MфH|ǿx쌇'k1hKB)MӔsDS6žf<7fiƘd$Ӗ̘d$3&YЗB_ })ЗB_ rNTNTJ{$It|H' d0&1dL&c2+79ioN{s8jYؔMYؔMYE,ZZ`[ lkmٌoI޶$ZbcK8ny%n -SKxi /-=9an~y9ЊiG.6bS.6j.D9=y9|#|#7mm= 6iÜ6Agr r(,8+D~!Y!>VD[mEas6as6o-fl1c[\h?~O;)l,PBJC{|X;{u$;; ?;։Nu—N _:aK'#DglL[)bK)vbw)vu)\uW2)Cg.ꊍ]Ӎ1ݰ~t'?#;+ǖrӓĦ^ME}lCbO_= D dV ?쏜4{su%mc,iėBp9a0s8NG`~-#i|m4cGhxGc} cj/GEXޱ>;2n,6eXq18q5{xb}/݋Mis'0w|L6N&+i3&N'N'Sʩp;S;T8 7Sr*? !>x܇̛μ̛μ̛μ̛μ̛3u< 3X3X3w=3y2gc&:fc&>$&3=gbL쟉ݳ{g16<f軟<=sX`ņ0]2Aby!!>܇axFMșe[N,'e[7+l%yȽg rg򟃗ؼykm sZZdE{Ѷq//`~j=z^§K2}/WW *_#ί1u伎7x~ߠxj1*]*Bۀob݈ ܈M ?7&r-8{mFf،-BҶ۱y;yx{ͻxY;ѹxDNޝNra'>NtGG{>c wa.t]]m9fnލwcntHCrCb! {2{=p.пK,^K^>}yл1~#o?ُqѻѻ  r{Atw |b!l;ms9w:>"GGp<}ccɯq0#06&ca;#=GAr>O }O'?(~%.GQr(z2(sa19F1d8c~98>dž98Sx>ŏOyr^OsNXI<'i?Ibw'w'yp\Sg >#ޟ96}4cO# t}3tAp2,EY;Kߗ%1 ·5C~|Cns<]`8լj~ Aw"}?c=:~@%D%.#dO&2ϗg_hB|`Ur*J\~#5]:\ǖw?ٿE2 wn7Md$|KacmPPP\P]rPlU(NA&h n%87<;W)v/Z &ō~w7|w{cGi.΅B,b/XDc^3q>' |zO-A_/K/ػX.{'I} =OSp:8+ː yh[F2 ˈ2|_q9{r?̧4\< O3gkjv+s| n+Ȼ_IJ{W*d¿Up 1{۟ΝAyVSy ^Cxޅ-9Cb^#7ӷpz`AACzYU#y#31:ct3 y ǣ$Lj1>F'DZSs=x>E|Oci418 G_W ]_{_c7;ǜs39JVg(3cEl͜#s~dO}gB/x\EUJ~ŗߐvWcc NȺm7R:c-T1[JArQBu[ եP]u6Bu~rpD;ڠ-!zwDž3/2ڃBmRp] `~ O 5B \a!plqNQ#!STHFYft)-Ml841}+4&_ 5L}BM)$IM,|!dIƷ8Mal*sSyNCV:s2vdO&65pE-#ʆޒx-rv.cwAWbՕ9݈A7xF8s߇PdEPdEPdEPdEPdEPdC0dC0da9 ;a0}80|N>pW}80|N> 'F#ȇa0|zzA`dd$G#42222O? ? ? ? ? 911111q玣C8C8sQǡǣ<ǣ<ǣ<ǣ<ǣ<3^y/qXO@dO@dO@dO@6&uN$&2g"90܉Dr`"90HpR'ȁI$l a6pR'a$dNp0&d8 `22ɕ)5ySO%oSY3SY3SY3SY3S۩2JNe4/iQF|>t߇Oi:>Mǧ4;fLg>$63?sǿcOl~r~A6sk\=Z{6ͥ}.ǃ]S}>C"ㇱa|}8<蛇y?y}>>|z>c1?O`8XJ,iէ[eYNr<͸c%rW{3ԟ,k9x:Cs|\]5XX_kн{ c >aZ|ZOkyb~ ^枪Kert; TarƼ7M$6oFtoįض܄oE[xYg 1Bl-ln+[JV"k+2mƼ woی{qomƽܙշyOm#a6nc6Flm߆ ^3v;6nGvm'};Nܷ';y2;Cޅw.]Ƽz={sÆ > >{mu wѶw#c7ww7!>d!Clۋ{}>rxv'3v?d?| 2 c<Gc} ?qgGʣ}wێQtC1r#7!q8>%>e}~'ț{OS}-s? ϧN/X_ 3aY%g,9%q;$_+‡Կ5<| `79dzyl@nߢ[W3|FW 6Q "r.2".[~s<\"{ [$V?zȼm3q+]!Gگ *yz< WWx[~_+q<| .װqkpp ;u|;qc?SoZb[~o &ބqS:߶Ih"R!4 t넦Q׆U`qNs@>` @ez8u`+\zChn! t#cV*8SBs.wc;6c|h l dx ]D'<.Oy"s'\Wh ^sx7mLhptxÓ7\xÅ7\x7z 40ׇy>r}}_|||? ?d! o ynȳ?g?2Ο;lG?csvKs,ZkB *|HR$c#d\Bg:*vFag>bWc e@8 ͈-&x6Cft7-ȳ"J{ 9XK[qÇ8ꍨ7"15&mBnO<=hKD%M)hkJ?)O?Rɩ4.]'egf0>Lߜɝ,r& -:ldnK|AWz[1&82&[/yɹ|ƴiúkC`w [d`K|A!_"/2+&nڑw/!nȡH ;aKgd ].Z.nF̺M7u#3;QA~n1u2>RÔ)}txÜ>ɊвS^bV}VֆFGgeX=oQG;]>byR ?=9˚?֧z+>k톍HTs58G:K3bo%Co]ԼᆜM#!WC܄ú5<*hXv^o ?7:ڧi#c5$By>D o={yz8$ءhhjj[댤QA>t~ېƫX %QaY?E(K!}=>7EةM+f}%D9G@o9Q;YLOl"RQGmeu/N`"Clhxlv3 /yQNuqMa%jNisujn}Nic˟k^q_.'[qQ!]k(=E)@W0ֱYʭxT홽zeԨ(4EOjp4KTc##}"qAQ!nHogz_s##zvK O!&k6E|…s|uŗ_2.^|)V !.SqƋWbg;Ob&Lǡ{QJ; &Y3cm5KJ"_IƛYٯ Bn#[*zG*A!s*?s&m0*]Բ{^5˜.mo״@S/)/Uצv j6,Xs EoA>jR\u)(WCťCǯ]!>($ձit=rEHͯkE9F,5Q"CIЭy2e!eRQ،%[N{cFAHSvFxBڊ&"}[4KʌIz87>=2Q˚5 55k]\rFw"{RR4?MYժK_oOmfӡHu@]WNpclKccbM&WR:=8uJ~ACz?;ug˂Y;6tWz*uqMz#i=N&aDv-B yplʉQG&tޮ^^~.{VQLXIwhG~Fuuhi-w݂H,+-;"Ծ\=Jo%R_T"Ęצw߼J̨Ou|f^u"2fcK̰FN`La޵rgv?;)5o^?[2j$+1?Ǥ*]S2,JGU9ot u9|8&NQֺk+VDX++hTlrOF\L󺵙 b'QuԜ# ͶZL3\/;" 0GŵT*2M8"2on(QT1/ڏ6;Iyqq+n!HZjqrP]LxBʻaRfvݺ,JYpO{(@ Mu.t&e:YN|>><2%Glt %Em6yDB]Jfʬ+AD~~FwHp"yG2/bɜqs߾M&Բƙ2"2huq)4 acG_ѕX;ԳӾUdlQg:ǞiQuQ5""ܨF"5yP* Z+ʕ&wb.Fs),ۻ~wouでWۻr>+k^bw[_8Br>:^Kd7TK1UɟH^msmnɚlK8U͜ݻbgum;nbbw[G0r\ĥق- =?r=5ѽwB,c:Js:ߙMZm/w{۴ZiJ+zUlKV+ ƀ$@@B/ԀHx P/!Լ$h[vU>?ax]]̦JH}#־hLG}x&u1-;kT0rGV-ߌ%c\#pYٳp'*:OkPL8މ%g#Q H`TaxhOE]F791# S_|`ҍ[A<D˼ϊ_= 炁Gb)O6N-gϊ 3ӠGmR|'/;v!8ZmF3@ʣsFLO~J{7R40;A;+;ۄy۝_U ŨAN*XU!0@-%8'yt[Q5c bM 5_1(e1]V2 L_(}sͨ^i9\gBE[e\9+hZ@gքT`ш^5G[?J5, t'p!MݩM]q0T*Y[Z1x⑬ RW:З T&񇏶Ld:hE zDwLj XO=%>V/fm /i&cOn56q'#EюO7EktBQ&?+e04Կ?K?&pȍƪdǢtR[1xq9 & K ,z`.@[ ޚ\ |'AX84jD_X?37]V;⅖ugf]Z4ZZ(tO\:g^(Wy_޿DP;K"Zq6mW݁Ƙ+ ǯq/rA;@kû WPVr*tІ=k:ZUeKk9porQf.>[/sy}n5肩eM袆g_mϝJ[UE_r+kޞp~Q-"vMC$irYkL"0FbBm,<ʈeXw\nU6aF/6Om\W~n>87} db}$ ,c U["wi7-ݾcٝʕ|id}V_Օx闾r{#Fuk_S?.Fg sUfC:V &<:L?2cyna`2(ω;,FL?m.\ԎA2B%q,9hV4 2AEyPf0>tBasXlpAH8 [qEX6.;.Ǹtҡsm8han<Ҥz]}wjMv?tE>M~r)rH{W6 sL-&ZEK;f.:Du٠LY h텚sM!7F'^3RS/FЅx?Dd/&@4W6OA8%K ~yak73Zb1tZV(CRmxm􋹨< ! (-cetѦ X'UUZįն>P}6/'uu5C EPP[\b>1HЉʁbFl..kQ܋V4KOIxt<+k}O6S7`d<]R@[#9Fݚ7Z?,;tRow4T[oF{ͮϢA|>&D_mN)z"3 z s '/%h~~na>&KwR_uƿWݻrދVļ̘ ^|/ߴr׊}.ޱ{IXƲ[7iӤp 4ϿJCm^ܱ'>hwƜ/vFm DRtȿ_QUS"O&Ic{$]z ڠO;w?Pq߹|iz Ovٓ?, @拾,ؑ9S')|,A3&gM2~&ƀ#iN`]UG@x69dڄ.^at!F|>W,!{I5RbwoVǻ&5gx,|ko4y _> Xp5TK,I#/6=fw,h-hJV=Ǭ׉{!YkPV[Nh!XֹQ) )[m_LRs' l|m{h+P1Ȑ- ڂ h,rۿ4ףE34x;AHߙR)/kuJh&s;As 9@yLq@.dS$BCtJsTq p~ǦҪ1ŭ S%ؕZuN}\yA4l^2,WEHGl] NuDズEk>'~,R(+UOW6jMIK syW)C[ۼdDdPT\rYbJ;)q:d/4o"j `O*+]˨J֧ԝL@9~COڛt m-٭*kil[(RlYe`p}Jkq [}qc8?1V][6,x0]Ԧ\UL):|g} 6WAN&mc͠yw53uic0p47"^1krN7)GNE_/5j'={.Ithyɞ"BM=w;k;lA,i m -_ab7]%߽ߛ s:!b] ҙ-`5:›@pΨĂ( _ KK]v/Z\3@C>(hJֶCu-F|HvY^-M)OkGcLjWu:Bz,uxn6X}QTHcD ^l0Kgxd,(E&tʺ_հ"/ao 8wn:U Y[oL"9[75]fF#P\Ob? H|B*]}ԸV[rg݋1[Oў'MƄh2.ZBx_5k*?etGd-Mccp?+ GE%SAǔe9y3Ĩey7 M<oycBK^_,lm YL菭3[0Oo]XC+tݴS7gr9%7Bb2Jtnјܜ|y,r\"q1Oz_>ڬ<}A\Bd+|Z~H {e-Y\2ƂkCz|KK>`k𪝻{=qW=H?rx#Mk{-cY8>Wc޴x^^;/?ݻ}$6!]P-7:TzAhBcdg9cWyV) "I2mkotnpVAV9E.ԥs܃yQ,<;4qOs< TN9ۈ L-pYCCՑ&xPc|cmXss4B)L U(DqQ$&ᄏ0: ZKD _h~l . Eb8)ٶa/K{C$*pmk"hBܓ,QRFcbM 8S(EA4>295XlV#+U1e#[ۺaFt$~0+>rb7Y5+f٠5P_d^>-/s1 惈6rV*0:IQ˴85Ϊ!zD:UQ"?n&_(Ý{`vu[@ ,@Q91ҩC U &U{[I9Sb2}E3V>Y]Wsƅ幱mt} xQy)^uo4Y؄g*mSӯt}3 (ʯ}TB_?"`N>K-\2c00c7 5zbg/?/[Xd'q"{X^Gm$ڧb}農v_t}PhE>}0Fѽc3LJ7x}ak,bb`>1-PeEBe N픫5sնU ]5{Q)]=ˬ5j[P-s&vH~*jVY|65MX(_'l:q $\14>e$)1a'^dKl& G7u3G6`&PF[ArNDG;O x Bw&3}הvud $z@h(q w$f](B7x%g׿X~{D q'{ڲN\zc͉'ašc݉^zo[kGSc.;ZwDF{uMU P\R>rh Y˿k־KlhȞ >,'kډOoyY)ޅMd3_HC)ƪǿU2h'a/лt|eƬi/3[<"ľ8/Wc`r;p9ABKy'ϸ G jUeec}f΀zAܮcf ̀׏ma*ĪJ6dsY&>`xO޴D,o?η ۏLiXge%iǜ3x7x]T/j͙1o=,TsZ.Y`6~tO7JzL1ԙ1FuV64f|atۙ |G6't'e@=-ʦ3+rx~o(u>?lcsr90ӌGFm{WSE!LuFt$'r}vKs|^h5gG|;aYB>>?gKĿ-[־m|אs9;~Y{-EMtg\$:u.z"G"BM^2@kug6wz㓞ڨy:@a e_y9WFiǜ9ۖ.ݽsr{ύ9ZZ7wθG=GY>.k?_g{\>7dQ v2 =t֚B4ZwWLȽ;1$FR02rAV ^3we.\7|L*ZϡupmyglܲxgnKGhߦ`Ϡf۸33}ת|;ܿ|ƕqI'2veGYG _3L?`vg!xNtHNf=-l\$c 2v3q7/,fA I*@JJ$`df 0; ?*Mf`ҷbưYĔ=12[c)Iʪ;?'wzZ0/9I6 Ddy<95lU17N:e*{|MjIړ<'N$Έ.dH0l{pO .Pe/@<#J`dRB r遇љ Q N~9y}ѵ{ҤEvUZ]"n߆\T*Kp4ǔHqd`c.\d&a4\\ǚE2J\#Ě9Y]wˮ{vI {\.e'?􊗅 .=l8/±ɢFwiれ?#4Eoxwr[̈́D@O8<^k),VO .ex؝ ,xlOW_Jw.l#P(s.kXyWf"MSrzg9iLܣ[TpzXZ+9LE9,zɓ/x=yo rԀ`K.s0.,-GbE;?!a@wl,)?r.;iB1=0=cHcnr8МL(ZhA(1vh:@f/Jk+e" 5,!F߁.>=bSHd"{T45c}_ڱH/5} ߣ_ fS;rWj&)>݄]l;i {c!x [}j 0` 0r S8,|l3ЦJ5q J EOH _L?]ȇ3s8[k9Rv"vtu7>MH򭽤}v5"NuץhݗOTlɹy\{Nj€BnZ< }-d*.k6kneҹKܯ'M_g5 ɐ`#[Jq܄xFhQɕlL;=d?O8S[z ^/V:c?I7ꑨ^'jϐwΎ@tF al }0/m>ef2{-,h3IM#55]lbDi=Օū \##,T;:[}7nY$ :In9".N/ >"9"y̜,X .55 Ib84{dk,ln]G}{oo_ʍl, ?)/~ B v儇&Mޅ8^%EXi2#5!aJ #pq0PNOU~`F;MŷzL&fx+ћ ?aryE-993/d|ĺV6"X٢hN &i"ʲ3vC|yN87W@mW"L0·lW"c$>Ԍdy$y~IAElJsGYT4> KRjJ(4e {)pL=r=5=8@eps0pºQjL}[ϙ|=rGc}UlfY.yk?[ 9aRֿ7 i7 _4e"g;6 "YV(aSB)8k0@:@KRhvn璃2i^Z:BRzeXW/ttKH@ ٵ~xX%"5r.|\c ,= 9Ǐsc8gs,a߄AvF$`{ɕ%4qo }]:mdo#v2 ʖGGhc [+S^) Btٜ <[)4h]Znxҥ |<gILcQ 6Fl'̣#?(N$cd,dF' hF9cGc@ޥ=p)~@tL2H-h.j.+_Ts[EƑ(S /i e8s׍N{c)* DÚJKr;Jv<DsH> Ooϫʢҝ㫮C禽* t9ӫ5˶,_'frN1(gJ]GeM(53 іE3j}uF{41 .(E2'qY}e ų˃9l.A98E&QW]TN{691`@r8 bM  ytRnQ Nskfe..qXU!.($IA'U:9؜rJfS>Odo7'`Wڡ%v-)wB9E{&vۚcv}Krْ3nN!7TfdSUUc s.eU=>M` ҋ0 _9l,9MgTiؙȅ:NY`-u`wժ'Y֔ϝx8Ecfg`pav}n)VG}%\cNq*/+ىG`oҬu xSwF ؜肋4oNw4\ܼcsٌ]W2͋6aҥ qaH)zfoIS [[[VL0ٚҦm=a2M8p*{9S|хIwl>gNuH^SZ_RLGRp97N6ӝ + ?E(zF LA,KN$ # ba?H__j ɗ+z.ϋ5 k& /FBS.x-m@]je-gxFf[589kAm ⃋ֈ qQx+cR[yYm[S>*)!j_sks E/SdE  3 !\ 9#}_|]Rb4mmϤ'.LC& xO  bVJqh;hpFQT*FG7Xf9U Kg@J^}ANVBv 1*4/HuKu#"x wA(%`蹩A\-7)\k^^UQ=^ۊ]Fиɦc Ua+E^讷sl,NƒXVYb8B״8+,Wx^ d$ĞwOQ"ٖLOF&kN@-<9xï=۰0c?(g}oX42In/ovY4V;N&=Yk8f=Q'w'̭2 >jY.l-I;k:Ξ4=%ϓh|>6,mn6qq&DÿgD4z(7ϫ~9G)-wʞHqXM|TS5v=1=Qћ""~WJB@2P-KAB'9a52S/ϢI8KZ 6o%^+]2byM.1ࠃ=uBK ^AumVS Is~>J4we9[JS&[YD>SbtH|$⨜?@ƂjD( Ӹ_z:x!?8zc|ݍJws/L+6σs:^Q\mmW&O ‘pN0i.A`Z .% Ɯv{ɭt1=BYl=yPf`s.{@m]{׭*U[h.6p۱sY}9>~[;=䚷L$=]up`w_.=|(͈˔n"P岓4gf1A(JG/'z}ʦN3oG RaqhqbU^P./\>2B| bKMjrޥP yfLG$ð{o8\K4DK4wE 沫 NA**ɾZ2M&-+9UU[ {7z8+V`uq;wټ []"Nb:a_o&X!UT Yהhg$fyNeS~/]MrAc譭?n$o~dB ԗ_=!j` )~D JVr+HPRe;YNI6okt@󰼓NaWAJ2)KiVI#(^1{&wĨɱw<;N^Q'PYxucse$mN+0豮Uwt7ūU~յX0qK⫵ſ5}YN0l\ Z;JEjl=m"K!+ZÇ-j2MT~;9N~/P64w{c=g,`2C i^'C t[4Ri5P@`uKp6*l6-j?Vݝ{$M*FsgI͜Db!ny$ Mft/ssP; nZg*-`wgvqŔJ[nzd|Ԥ2y6p|^x3\z͌j+*vt-t껿;+b0読 f掏\?UΒ~@ D@zjX:py[kZ:{6nl\ W5>7gmuPo\=w+A'*cƚQn?*r)  |tp{`mF ,GnZvl*kimգP \dɧ)3Z: m7l 9}5㬌j2 'ߡ%yL%IIgFO<}ܳ=?wTUa)g'{!& ,1|Yl 7/uBCkRR}S/Fw; M~&:HEEwD?'shAo#_^~g_~ylC'ڧa@3v8jo,kG0%\|a1eD5^RQ?7:vA yDžqƹ݈ګveyUjx@tLjު>v:ͤ/ױ?b>E'H ?>`'senF3w!R ATʐqdG`nz cGJʦ){X1/N4ŋ_dO\c){&1Ξ[(bhh'| ?%$y*0̃> C(gOv~4˷ROm1$;%moLfw٣63yĞ˿wy\?L??O_v^hEoC~ޏ!%WqwXuBC,qP')TXcK H!Vn}==__c4RźӢh(Qm/[{#?y l*! <}}*TLVN`yn|'Hݟ$YNG>ˇB?OyC?n:_W6ܾGꞺڵUJFc@*$vU<т'["Za- cŔ0Dl]/0VCX+Z#I*xPE4{s@ڬ&ql!oM!`4pĜ[2nh_ZG%k#RXXa^Дv-2+%K̩W-:m[56ڀv!F 眑bsKo{3py/Ľ9;ɛ3ٖ3VwO!.:/UfU)jPe7?B/E 7=ԫih4 )g SjR$-_wx5㦯4r+X7/ h[`d\'o7~?~]"Hlֻ%::=lҮBk~,AI~r&3pl%Y6MZ},^.k9-zJqWL8Dguߴ?׺6`]rVU~q.r>)|HNS$ץā[SJY1\Rpπ6m[uT1hѻڋZݾ*YF{iUWLY+\upXƟwaӠ\%e; s 3~'̉r=t"pNrXo-/X~k|~e=wpP!x&zzcYZz3n*^\a xMs^#)ce9oYwro|}7:Fpj?? ޤ|6Ǹſ |"Q+(i~H9x!a;S)7B6gN?S|+;M%N㫏AXFY/SƯ9| 7?XDC>S_8OG2"7><_f_,П͗axJ:?Dce(r]B?۟)}Eew{b i?9 \~eIR@t!l;eARf<#Bq5`M13Iy*zNK=oRW J)vRbi;7x')I^Bh^2[ePsHo6@!SH%+ck.ty'x`qt!HZF _2,IR\e+sJ50lkαNMUqDڰm^Bi2\D%|,H1iu }EG1֜ y-&SVʁge7M\fN'w2#>Qÿq"c'1֏W|n(Zz ^}cBg;F3ѻ(C4*6,A% $YJ`X 2̻V!eFS`76υg{4f2M^EMڭ2)2SqqPd:4[(ΰ:x_UPơ)21ϛ %ZQH65oUY|glgoME{M&7%6G; i?2{+}TfSQ1yrN5zV_f ڇ4hfMO,3ϯilpf^iw"|MŶ6=2|1GT"O{lCI1=77 nZK8kW* ,B9'Snmmi/i[m<}sT3˻bJ5x1gdǰ3=oxiJd$̾\sSyq2{ 0AX=)>}ͥy4B݃d DDN{G"IТy#C$&iJ7?)ρK :Jhgd-; o |V1V3J(S>U`PbVc%8qK*/\[ҚYJ$(E.15ӬYkpX`&)eA`% Cy;~ۯ.w pĶmt+zbtѳ- r1wuȪ4+#!ǑPmWLt~\&-r9zŖ}kNRk5XYlٙZ{uOOA~Ot H}ټ.bA4r# Eq6э29/ZN}I6!Uh32XLe.[&ŕR*O=:z <~U6kC?qʅj[wCwǴJTd9сqCOC9z vOmZa)*4ZbIouTTӴ WMs<6_IcZ 7.$V LObFbKPi4s^tBoBXNS-k-v)*uN6[5.#N'ЙIh.PJ/PiTbt `wD {A.eչj[*Z])~2[1b}Ԫo'F_w;[QSec; 686 )2nJ̃ hH+6ӊT_fǡR朣:B;THn5@H{O:#Jߤ7MLŚTHfpδ/x:J塋/kƹk/ߐˏMl}Ėza?Uaͼ]7Vkyt{]Pu]&wb=eXB`j wl⁼t]@*m됁Zԅ+@oPC47ą'Ǩ@*~t|j7D]InjcR. _t'KfM[3)^N}%1Ga9)6/TƀNeʥ9TBAXjz^ lبעجPr +mbRej Yӭ@?$9i3)I@ĚJ[jž*ؐPXbvt@13XbhjZI`+K]=!Xf|0i=Eonw^xӣ95 f`A`^S;d8!c,őiq% "<#6 eke)>5|=')AR̮A<Ռ_ f,ja54DCccRI&5< U/nc1,шvs%&XuS $&02>%/!{%cxfvW勵>[Ґڢ9w%J)$IVspOCi?]뜎a-FF)x}@)1UQe;/m)#bQK^]~-/߽-gT~՗Sw$p |*|$Y "nw`VI+tu)R'?]t8; ldHTKe>' сV${^`[RC6@v{Ɋ xO +3Q8#R,(b599llǽ xtuOG3QSŠ5{<ߍ=Nvo,ݭ28rW'^33Aɞ{Q7{w{twNX-EnrŸB1݆8tl @HBO @% $0`gfN'Nx$j癙g6|SilxTT iUzJ=*W7m0Ir$ LZ =%7@,`+gZhg<ʸ%Z8>2љ(f41>"šHwa([:2iO) '~".<<'(mpq_З֢@ߩEڮFmiQMH= "kMiUwrM\֠|[hV?ɬL9`|yy6qE">5̘*Q/[fO"4"3aL`p$!!48!AR\&" ,~r> d Jѯ7wO^\9kfs6^ 6D؆f-.h DdsX4 EBb=_waOZg>A)snNfU ׈Q8_D/U`{M^lKF,l?2dc.=wecfPMǦ<%*'4?VA@>36inmmΌ [b} $4+A@sF#&DńK=inۗ!6|uxe1oڙs.aZo"76s'Eoz"]x/qK#mA1[xN^XfѤ`B4PlX޹fWBy5)(@,G 9Tkon/p=V܅{R{l0ǝTN_>Nbj6%]qzRXNWr*}#H2dKjS'ڃ[F~^)"^E5BF9WPbzx?^~.Ciw]qA`pz,ob?^,hȾG6 ^gMjɲ7%۲߯?PXcFa󵳼N)"Y~M4_1p-p ɪ a'kVp_-fԣ{i6l,iu=5aC.ύf%J΃=\}jҕ2l_訣yrJZF7 ۃmͩO{uI^|TXw-Ma |õ_9+/srOKMSt2>,\Ω[ Ngv|9 Tvj*Ƿ:"6Ok6 `c-ӑr;C9/I24j01^bK+D!Js)ʴ[7sƨwLo+۽LĆbkk%weΧHp~g_ 4yG̹b? N;e$ba<&2 ?b0s|FFz, @<%8LC.؈ xY3fU>ky Tjx(E݋w/UE{_պ{/[,EP(: /=1B br2(ߑ낝$["_h~^ bqݯHb؆}w>6> H5gg6ai !EaT:occEluoEnFgG-2eN`J-jB4'JWebn*l>QMɐI7D e4\׃?iLK2qlUȖ!WZ:B:M٦Pxsiq|*kh:{a٪XfTiM!vs=O;o_ZiB!i- }D2A3R =SpzSK3B훑N{g[>o:mLʑZֱZ-Ckb )Ԃ`4=DL:Ch< pWY'aFdx}. MG _&× _)1(~$^atҩ@^tPo0i)˜xΆ͆f{OP)p8P,xdǙb !3H TH K&S7M]96CC275\U{m$G\ka* Z#[|HʹDgP *@ ǜZ5霆VoavʭX)Kk#Q].86+3Kl,x\Ēz6`XPm""\CwG /TuZcDɍxPЅdIr';z,L =$B`gzOg=jp v ?L!CWɿ.K$α`4u2s(oi9]L:g\&_uuWsm~[9N. SnTg736j[9p5]n ~%`{!h0`מH ]E#"q6de/˅y"T0F>4E.aI"x( |ˬĸSVa;Z2An010aB ǛⓕI;%eȳbı5Idtq _OA#cW< !#I8hD'/LžJO]d8cƮY*X= 4{0[f |h.pax_8n$c\PMX:gBdD<NBC :C{oVbX-&x9'hDm_T)fL@>V\i0,Є5%OI"L̑oKS:W9U3.5+>`ζ8\@U:niK&OsS4EJ$/m!{W_h{%Zm%&.J Gar$y)bCMyRO*SVU``kjf= J*ǡ};G+{‰sr6\e4+__9:rw Hk8=cf6**]T"ʶ|,~$k+;;?Ù('m6xIr(WO KCs B<|,H- -' 6G*b`1[%)-kJ/ uz7EQFKK׍C;+@u-b+zz,N'lgUπ3D%W·8v:P) 'q6V(G#Z8,V@SP+Yna&LÏM\3NG$S_')H42zfi^KCmM.fZC&8`0`JM 㰘=$s^)h[O>}uwG4sq2n@>RlTݖ_ gjMxy`)w<`>N/r4oܴu|4ZuS1FD+Xz7gaFĻy:CpQ.?y >>J>+QM>o~/y"o OCcF~Ǒ.Җ]uK"G4-ہ #r622`XwH^&w8ĒS /J_G!>L>\ɿv6_r;$ \i\!j F`64>.MjyX*e W܎^InɧX|xαFWFUaPRbu2WnFx,Ch] >jm %CbsXM@39ސ Klfم[wvdtvM}2efK@*щBKCwA,7acܾw= ި'B_ہx-܀`O Ed9JZkǴT`p|_=J)h. ZUD/8;~qxrߊ+O&XOd|VH$fF>YP)n$rIjᘘІ)$pnw?.|c{E{ 0F *os`Q+Ly>}L9 7<iS h@\~b/y} pD{_CB$;Lʃ! XH%kVzP9[ 1߆Ķ0j ouAv g@(Er+G$wx+jӠIÈgo]x]dr]3 <}M3=dm)zbgO;A}GpA#;ڻHs sǫPۿH۩}Bw'>j!1«pj>KsXUN~&N <cKa Nc WջTN×n˰T'dQJ[UcF v:}p D$6SYT4'JT}֦g!wٯNJEOzk# /foH?/K4GCh()F +9 &3/y?G=t}4 җWyѻn^Z$ Ãwq_ s$H>^yW?B6+sfDmgqhjӁ?Pܻr'>xL[w-4ՖE4Gc#󏼏G= w7?馁>| [ܭ:? 1p'[ÿmOy2y5q.N"m7Znyv[M~h]ƹWhPv w}+>#1 !ғ*=]Sž}9r.mOF]e3Stuz}T_OmW4iO5%}c|?r<܆`Al{DF_]r= g-^GD+K%As3 fܯH&sj)-Q? IoG,1bkIk+VtX5a  zBO +`c|IA1DDͮ;Z_k ӿC:^,—2@ro#gV~"s:jîv̋fj1ukLb"["[Ȗ#V>Ŀw$wmOis4ҙDq_6|.3 &oGh+ XV)n~>18-ߟiE9O!iL$?Bw?&6wHnVp腰aπ|zU.)Yο w,NGwV~' )s>EdZ u-a㾏+R`܏z˿C)PD1Pp_~-93;"I! (rC0*^UKـIB#. (JFmr*9 |*lƓ}Q.,) cuhBeOPdufv541Gn J4wлţʪ*7Rj'E{8`50PFܑol:^0" PsWKHF|_*yi҇W"?DCWmHwgGGkyڛױNj!ٱ92\!;wpn7IMXV2XEqk|Xƌ `l✿8~vJ|\Xo~=.+iC};{ ~_\ؖ.=";w Yes{ o"e? 'p[ /]+NdABzDm#6udʝ}k"f?8?bH@X#01fvrCK8C#hlZ-SP;KI.Dlo}BdF!gPbѯx/CUݍ9,1CP3 ;(Zg!S;־w5C{44,A^0 ܴP y{Ѫqt,aM=r*#TiIh0ŚlsdE>'eO#N| \ oV,L!j/R9! tns/wYR n\CUqhJkJB>ub$w<8%i; nfs:Y'[m$MY0tp+%G}]C$lz(Qq.* 3bYqǜ%& s3`YPqt9z͑P, Lo\3vJr[$CjUT.=sUGVI$wB(+wk狏'ݾg?iȃXM<&_k,? UW65\oZt|v8=~Qݧ';7 iJ-Oh:)~akX9sΆᗹsggܻ&$ wJ(>鼲ZR(PT˧UҠmn_G29t>6@\k贑pدstJk,1I^`x:LbѸ  i(B*,|mϞ!(եĚMhDr&ǗyP #\""Pzu9EM6}G]d}mkO<}mܾzItqd~zI~dرoC۶aBa~6ʑjD>qݐ/0۩Xr1\A 4bӤ=_&-㹨sc}GkH, !WQc2Æ޲ v^e뢦z[Y{FOqr3B绳PZF ʋN5 jۄὫӋi9!G!A՚65ߩFIm}\ƤU g.X:HiF /Y+ S7Ra w<2SJ|ɇ'pbo *;>q]gP-F?9s{\2vJ}FShh^g3C8R^pӥyRV{9\I3Uq05 Y={h`hl;Ne^17$+,cz^1 xe`dm*>Dv2kUU;'s> uNϟ2z#-Mޔ;Mݦi&cq96I'>|5O@&3ť*N(-М]NP݆yx/VCY6죍f˕Rrh\ZaQ;N 7 ;K3:Hdњ||fP TM8 fń||Ȏ$@J#YV h/m@)?b)V.\;v8;S;;/`۰RZ=djng`PCv^!x MZ#'!uz [NyNxvro}g?0;.34{d2/z8\PثZDx&X A%:R"ḿ䆰\ J)j *_-1&)&'㹌ƀ$):TƤgƖUȹK4ù | \id䒑rR'Z32E f_j2Al͊BѴJ #3|dW\${ s#yf6̇#"6GdϡI3 \d2RH=78z4zM~ru Zr}weOo9Q?u|xW&!8+%5Q M5 2OF[o0= f-SK kkW!=ڕ::O4u; M;dԜƕ`HJ ̣[Zl.ě̌FJD=ќas]Hf y]wR{npwᅂ pC6V\ Q`mFAfxM"pTAJJqeR RQvH}.Fꖷ>EC#4u<913ˑ"QQ3a46`-uW4je8kuyֆ=kw] +0-]k5^(_8gho npCXGT 7,[TLVw m1ϛ3=nCrլXuĚmnsrVN)lh=q#|46+H0*:̺z*iieV3S3.B+t5x'ݣVi]&KKr$О |!Pf  ;UC 42.%(B{9?!YgZ՗lLX S:F|a*Pm࠭aiBik g*3(hl۰e苩]5Dm:7eFO$򣂖 f0+R9(v!gdy &kTG=^kHZvO6V;=7ֵ&V,,gtn~g9Oԥ)`{ se3- l/)]Pz[c7NɳrZ#ux;CVջf.Z`A!'m$}w;CDQ>O`FK$~ VQ섃ㅴ%gp^.lQt%p<ͥTiO)f/[NZ;{)j:jGg_댅CYP>ut T"`Zd ܥM\@ۧUl0X[Al:ك[IBmR37$셠dvfB.8#|?& O.ߜƒrw.u$ATkSxFZ!`oAj_#A1hᛨ}%::7uRs&/JCDsx(>Y/Bflj1yꘅg0Ӳmr~ yBF_O.xH"hl>6n%YDNqو..U]6Ph@-l<-%_iQPXl_ؙbѿZZ ϣ+40ݶ@k۝ ۾/F:6.o`^S &}RU!$H6cUb '#!S%ciӛbu-H5g4tzlY@oP.ظL5Vڱ[3*-+<(L# yxSp=$qJXUQr4THȞS+} 林װ|7iR]SSk6>tjo=5)r "+qcKf)ӺxML]':uƶ!-rGELoL"+<|8R)j\ؼ⌤VHM2uzv±.WerKκ+`AIL2I勻ffdҙLz&C0 юf4l[o}/i9̙юh$BҊEHnT!)hMF(̇RXd&N-\\zߩy|,ww炒@=M.O,|U+}[(9g>,x ' PSL6iSe~ut* Y4&̄tZ]z y_sE=s;BdkOdnW/KH?Z&Ā2Jd`m_I iSNv71!WfOgjM^nPQBJk@V9Kj$gIv⿅s%Yým2:7zZk?9df20Pj2P 0~n|9yisl"pܬ&9-@DY%7DkC#KkStBCɤ W›Q{ee*Jf4ݴJcjQmVT Aw=T ~gsKdMyΩyMކ$drA )PтFbUCo JࢠKǚ]5&Wj5֥ +f~&H+{\ew9%]Ok#dTǏקokt5ǹfް"z 9Txl^HOzfHoխ l*7|QSihlLiJT&\e}RP;l;W>aPfN]#4mˬїK/]vYcvbDr"Ec`7{^qJqqOa{ `!܍;KwX?t~(%kȞ)1ދ"[%9 cP+IM^lo.+J-TpnXh<4Y;ѷk&u ygh>Pf.I ՑD9W CI)#o3%/hϿy nSؙ^ciԛX_iXȆ@7wx$&3p'!^I-) R&)QůGySx?+{bӷ&g{`q!&SZ,d1Hu>IԵ b%+ʟ6n<)7_ELfwnŮj9yP?:sUNoSj&_bi+:FN1X^#w:'8@[!HXLk4qЌe/uӠjwYKvobl*Ӷ;?#!FaU~~IA#T*&N*gczz: :պo* `O5U71 ~TZnT->ӏ_6X4Ks]WM҂#}' 17t)2嵻nFd vt/ꈵ[R}ϻ~~/Y0xN#5z:$O<~s_{<#g@Ks(2b/`nz!Ϲmg=$Cj((}f9C|VJ?18sL"KArQL(4J̠@ʟy'I31FfQUF[.@ 0e^6C (L$SH\=ۘMk#"Ƥ3ԝwT"*R  -B CX6<2hHA.޲|D x}| %-}V@yaMGYSnh-74/r})e1(B-kS]d׺.fXǂ49oޅo$CSU>g={sޓFFct'mͫVl^yQOcKMv o?:k;)YTLܯ pgͤ?'Tuk)<>Bf$Ch= hRU%=WA0d*!V@@gZ4\H=7wg k@{ܵY^vWu 99ٛ2:.}j5/z`st`aH6YU7%20&p멪~N@c.Ƚs)Kh֩qqޣl'%br$kѼ|&@vS;蓣K;,l*y v^{Ȗ^ϖ#p'⶜΍XZc q {d JerFJGdGVH|Jc:Qm\`MH2 \/'Q9[,G>BJ-L$oFrQ}By饈G ʦ<Z'V'B 0;\ٕ""t#wr'?<+4P{C>$tkY_8<9(7$5˩PAq_E?_4F4= zWA1|燑)$HtJ,"Z4.!ss`#WdWs!9dqHx]Hiiy+A"HZ.+`$ȌF{* s2R JJR4ZgHsw幗p+=(^T\~h=pVHuWG>r)YgYRj91'a _,SBZ@BIj )jG-"4yw'4rw79w3 FKQP_'qcbt.C# xk:pNs+Uln\8&<2z:3*M-=]=bSzZ\ZfS$b|8t>$[Ȋ\,e-LPרּF]\wu\ 7dK}ۣgGgR)Wřc%Xk(vE ,k:5!1NbJv"a}jBL| A$= MqU,+{\m:;nSU~rq9  uT>$U'ҲnbqL]6xO8%rg&z)I+ ޏz(ڇ[vz{23>$h*I#Lqdf܃GSj'~Q$2Ƨ{FdJP(dzۑ,9Jf5[Y#{-Lk6eJ[Yv8|ˬѨSFI~7eS7 ٤ꆆ>q'RxwHΡ(LpZֶkU݉5v 9O85sRp+/8Q*8X=],544뽌]iT3U]b/7bp+MsKE*Ut;_BX 7[2~P z>!Lڧ{:&gB0F5=<7*{FoހS9UL ( 5=zUjf `|&J&i=[iv{b)ImMԇDjS9TՐ#Kik+()5ԡ9Ce$X*>zo@ ՕK6N?Vhmg2&3Uc!]Xe&lV"ܓ8 ug¦`'~V{^O$'= R):ɫŽܵkQa >GoYA%<%sZZe`W$*nt:B砅?WQЃ2CDP@*䀷$/t*s U Ds]z8S|#QJaMA5!J)vP9,-tN<#OCPC`ަsFc0.x.F!`OZ+P|쁶/QRQF}Hh_B |B͢ {FE)lQfSGD\0Sý,.R|Uw*x@tU~u0)eюmٕ+[fJ(Ȧ7U8ekB/W\8_!.n:ƸQS )PA("!ᯏ1{H>4Q!ffȚP1D[DRzD u*eGiYa }Ho2ܟٓF8YF[p>WEr)*–V"e < 8fOaӝ@Vr&曬JX: -^05%]d4UѮKͦZ'؆=g;ҁA'V-NQGENa~h|HJƻSd&4e~JT*حoAѩ] &BI;8*UE[be뿿wyqC"F67;{ujgl8ePf7CV}6dtUaIh|Z+pUk9 Sc/HF/N9V<?AIgG=sQDl vi;st[lթwmyzy0FWt-=x&azïl5:t3 |UW3]5vd}Ę$BŤ̓TYr*, LdykG]sSW)ᣃ6 K֠LLcRl~B0tj[x$Ę/"bUY=O #=N3A9zMqgbEqj\%B[?ߧe-H5ć zC4"`cLNqʇs oɆ|>J xGA,)B̄tuw{2Ղۚon ?}C$ g itjl%VBRkN5&?~]W^)mZ/ESƂzɼ}=+Ϙ)v+T;vJwFN0.Nj2͌,^yӼmyEŠØTDnvb^SEWbyJ'ɝevJ RsI4$u1XT9-a+UN GXwW7'ͽqRlEZ\fiViW8[k!DE2"r#PiMm$҂{֩o爇5*4,+9 [rhņ`:Fdl5XQi_V#osP Fqe4k-nZFƸmLBYJUm *(%>LVV,mJltVY+Ŕ^ʡd6W|ia2>L6D6x -T{A/`!Y&7xd>_kO~>l3 Q_Dt=`>%]!aI/.Lg{PSVǺQd8Y3Ng‰Tv3ŕHl˼UOݯdlT8 ,MI%˒|5H J QXH8Xd|{*К'C)fu[LuGG*S VKR2gS$z$ 6 igx' 3Y;̾Eh~:u_ڏF_!ڎ^g@X, /Ƃ{֠gSpzgH~yr\Hپ#Ffp-KGaLw>HH3 6%Ba< 7S"O<)+cBj3u3>q:+?Nmilk۶uj.qk4-ԞK߼>{gM2˭mJy"gdbvAdWpڧ)ӝ-Jʼg m >H6} qXr6N.ѓ~ RPt눟ÓiaV\lZ2'3iԫ:ZNvddҞTTJfWd23.22E0kRTaȮ߽$n38*r?uӕFJ/UQvT;S%MGnNQO`YvN-(<";AFUFM%N錇a$e3$l P > (N%<2Ruh͕W+M/(߉ِmRNp}2Y vwgafs*/Ve/~3&m0J&8_ɍ6H_1*ZNA`3ro3&s-elRNMIw+qco-F8e{?[p-sB4ѕ]. nt?fЇu#Ǐ8+quvމv9;n~t˦(t4y|ď2Hof)q!|TMCן vx|W3V./spM̊8 R>cz?%3& n%toP_[ia]F6?K[厐rhnzSfAC~V%4ȥf3~/5>'uVwXơ5OI$4̞,iKx@J B7hg`zEx:\]&>_Vo(o/c6km,7fRi#_W&=F%kv x4c8[0PHmt#|ty3x}>LFiuAM5q7iZVdk4zn?xQSoD1{`mdy8읓[Lb\kqei(SHw$=8nx 3缰M$ιd&]=9HjC5b96+ވ}p0q.EVgr-ɇER_{Hד~q˚ε.,2+){FftggOf/&j!Fq08{1=jy9S"yo{@|-/Q}2ݡS\r"-䦖C9:+viBqQӍ>k9# -8sKOR ZB-y6_$Rǀ\Gi- JڽI]u4ckaf[3B >tX'c:g9oSs^`-7Z"J困5 ׬Hbd>kc1M wC)ёr6FFb8&[rb fcT*T1<=lnLo|onKWYIZ:dtڵ_|SU//w$ã7#$!tlB7[s))6[I; ÐyYۧN\&'I03\傑ɻ[% Gtn8]?$? l4F3$6Аc`r aQ`øT-ړ ؼMߏVjӭl~>Uv)HCT1 mZ?ˇu6ȞoKIJbsV,HkƢA[}w~'gH[?ۼ%?h4?kRFd+QBi>,ʳf@c˯j=`)@;σil~.0SMvBwAxVM|IxM>g ]^?d+C &^ ѦLzedžMnD !~̄l&;C-dlJq*-9pe| hu*Ÿ-6|Qgگ4dw.Ma;ET5ri,.|6/_/DGfXu!liKƝ8]FӪ;}{^}G:{#UpnVȸIՅ*Z5M\xo;_SKKjrU]FbqJgXs8㙗8Yi~b:2S%dRh:jy NΎϰ;YҀT!O[|.`ud&51n,Z$Oc~;l}QvNz3-84rٙgΠש6(y5*ZF*䰷MJW";6f:K_I7zNYӕ0 : U³tC ^ĵp5z mc*ϕESdr ou^<,t^إh%e}@ ml6ID_ׅW^]޺Ѷ}S) ^b1u-'uk &W7\JD4w̤k8A%Ɇ;஠1}I]oF;z+"}aZ6C%. z5?fN T 8ԃSS-5ݡ4ߵePagp"~HE<gwkgHfCb`k\CmxZ^;&30Za9u_  zYa?M ˍ:^=< VS1>7xF,_>N{3qިm)rK?A:57 ~W`y7ݲ Yy\COj7MD} vTq>!BNR9EޣIDb!zJS'X$9M +}1S2啇5K, 6n 2%m}QЅ\획xב?5F1OAzbrWku{G=Y6[{!sc#'(ǹhy@g{^nӌsRnQEǎ-cяD^R$:Pע=KO<ј.=0 1\=\  %-zv'`[2 *ꟕ/;DR6@~Y`b1:_FA ",i;&+_{cI $_,!iD2Ȥ? =勯=LMth)d̠}eG?ӳ"%߰hoFݴ^OhXLf{  =diqSY.}s?;@.,`إa%eviUOrUE8d[HdXe 0EKyw4A=YI,mry ~ 6xvXRzk.5HFMY<Ns,◾r>N=:" O8Mfp5u΍]JřOU\LŘvU6<O>Vd*=LVY\-* ZeBXI|S l,\}v;􅙀RZSͬkVQt:^_\ t j[HKoKfٟ1|tkԭȯP)->^VYS .lAIk$sϯܮI Y/]ᑧW6~md)R<Y^Z#^̾ /$*2yƔBkaBx@%\ނۚp6Gb4uV~^E3!GCu*80U>ς0y0n0"/͡JEc|N?64Q|>ų (4D]Ehũ8`AlnsHsiP^!)$l {ߥeEr#Y&Rï>/M?fd7HSB7G-DŽ谙nYyIih-NʎйGώ;]sLKxRQF\x&?,[$^uTσ`̨o\͜5be9Uzy{bDXϬe=m4,Ą7~&oxFv9p&]w$FTlN5.E5/Sܦ::'mL`ΜVUśS2?Q T9iW]R%PܛDh^"kBYiw]0&Ro>E .B@}݋0Iu( u45Zk">֤RK~S,M>b ĉ3qִUy~ M%y iYUg'揅@ q>89o0D109~Y/2 v"!Yf18Q0=_t:q~dVhoFV|s#b_x3yg?.i!uz4#{ "TfWlAhE>45{On{>+}'_0}vfNsach8K/q>K5i!4OڽF'M'?埿_$]2UO.p0NAFhNbxf@%#g]f=40ڍ&8IGWk¿DQV;Z{cx֎b-x* LW-X4:GngYoHl荥bzqz>|},? i뿷~s-!pI7¯_&i{RILd .|҂jjq" N5=XT{f+W^=4@3lFjK '&0!$:$??kmA{\p=Oۭ߿x?ߑ@~x_C??/<X;w A|皱-[1Ѫͺߜ`V7zˠ)>{bGszS,s7?MGfljIp<&gMxmAU s|ޟw*?g!5 C7BN>MJjm\MA%t]}WBWl/o#`?g F]>6ׅ򦮍G*@Q@otx7ZSTvCz H[ !([˙L{V-v׿u2 ݡh%;X=H@aJ;jP9DL|VO=ƥչ4qn?zKu \tvK":ۆJn.\R E~OhB_0G_&b;N߂_"gGySm[Z^<{9׶XEw|=Wt޻ƻBWkh\`!5hr7@6 spyZ a9˖mDz;C! Ym|ѼWOKxdTPnO{ۖ\{Pzg.(0.ӓf'8ܐM$[f2Jq68fZH,L*`T{}`{'jBtHM&[>+ Û !P靐d/Sy ±:*B&dT'9~+f^F.Iuem}]lju׌un;CDf5x!rEuSѧgGF՟uv+ <\e'g-6<uZGf:kN^wClx_C\{胗W`u"}PoC]vLWwuv|u|I^X(y𣸗GhZ^~<07#[ BI=xV?/ NI " y[z^LhS[=P_~_uZy:x6h]\ u@o.)J?x9A' *?A)MAU&x\O[B~j`Y+l{sS2_;k[n;7Oܲ厐@$k2I>\wY5?Ŭ*6O\R߭z>}x_$\ sK4{z.Ś^v/#Iq,b^UD.p$:@z?Tԧ՝͸)S?xmAG{u,BcBVhϱM9Gy6mJi;E{ |rQT\8L/G%ҽxt9#`/,etS 7'K NmPh4o-7vޑ*w<ݴk!׶ζ Ms]L^O,8>p1caYۺ>d2}%r-њ\5؇k , Δ'uh!R]mHN䶴'篸 G+NuVikl$c+ v#VvӕIjis5mN'l2@spɩ1{-c>]Zb:GbPS`UbDŽiy>I[C1S[sZl{ *.4n3tu9ɛtMdlhI6*O6pٶˮ#`OHjC}zo7dW䓽+Wll?2vɲKGr1 C'͘N{ux/Hn%pv籇pA>d@7cO|lr(^ D@%ϳ@̍E wjo 0)ܪrѿ!^3YWO(yoMue" WybKxD;? t{xxŞZϹ`yOʺy8?ɶ}*- M0_00w>S3^Y]w?[ڹcawGe850TB#d&orpqqXK+6}/Dn a)elQ//p,/Nh5 NPWvn>|Ղquu=|MĀO{oPmxR-|{d4Vzk9q? wݕ)zyU`{l;rpG.ZhxO{yZd`rif^M3'q3re/$>"xe8_sn<(Q~z$BSrMT{f.8h 씆C{ݝپche/fC40!j[hC.- tc\Ӆ=V_qoRk}Ns7\m&wv(9ZB};<& ,h L{IbvGғt! ѐ18f32-3ʺ9wڼZinگ]k,T&a$2mmWi:gYhN/^Hke[SC{9#K/aݠɈv&%R_d_PH{sG?-,KcpY޹[NG,BH{{/|g>=] ^į?BkA^WyIIPʄ~h5vL$<{_ܕ>ؠ9;F` |Wr Wlm-ܛՔ'xNwt;b1x<0)ĘU]_@q[nVLXF%ULT4NhXOz}6H@T%Ug?NVJhGcYyf9>Tte>jn;|HV7Fr%Y$CaK6O0Bpz⫮ah{Nn}2 3IZ)k,R_Ȃqc}(Js񃐳? RRnɨk_u_T?77h[3޻^,.YJ;*p9z2 #KrgSdȽiC?󲭡JdB@֭&_+\? 4 ? `Vߏ,I1I̷-8f&+`{dW[2s=+w u(Sx-I\;U)ۡ:68,Zے eF֨VֽLv3e}m$QoLs¾z G?o/7I:"͑8wEO7ibj"Gھ&gޗ)5ɱ3GjԙJc99S4Ip~Z,0h}?. 9%:|mO:nx R͊.K0>8 (9H߼$T_kZ0ހB2gA]Ds;Cvl>vя wס;]ln ofoX~(uHCO_=?[>-~oyfTV)[h K:H~0Zrm{"V_sxiz'msshYAr߸&B ZD[w{mVA&߆>a;esO wH'c2qc.l(iv[].zٗ^}b2tڸ:dە?s'MǾ)i@3S`Mł4C`&g-$Z|^n{\4xx yd%R?灨-6[B"\D ++^Q>_|*/yId ៿'k _t"R/uF;r] |3^7:=j'o.cl2Lv%>肹K˖z6?޴|RQ&Ng,,x zd&d Eg9/wYoXOϱYKV- TmThܣz r+nZH)igg?8ZwNxd 3z"qd$_{;::㹸>&gFsw4T(N9cN  ٞ86<LnGpW0 `,Dnk󚷯ۖS-}kָڤx-$K#O:wd_Bzכz y,i1 #:NhKaSjrltzwӆ O2w2ݨMNBsœevX е\EGBdƟ:oOo0|?f![}_ػi^VOi")I rئn-7Ie2DqCrAMKbRa}|=Z"ŽЛ +,5@S֦y@GTn\ʟ=-qv<{K{R+Lht2tpGkfc6є\u&5^ ;c٬!L;3T@8aK;4uyI/;g#NXCb..9b ܜ tokLV2;+}[.A%>` a>62n0$wL=5SZopig8%?˂fGbOd⨢xSX%m֨ή9P+ǥ q>CD旼+l|'#xo!ӌ',\]zcW޴Ԩҩ-݇o0> )JӦ2+J22gUfYFajM>DE[w;<6"a硽*ot,2;VnfpS #z8%ejOV E+eQeX9R8~:RRtpjG+~蹏PMa!38LHa׶t +0 t2NJ%M=H`4&7՛,#*ݛyG떧Y{<̾(-;.Gg@PWB)V;G¯T5tRJFh02G~etD~ jo!aUmvF15dg VZ&]L?8ȼqp::WA'6uHH,VAXG-³X!xC$&gvh)-EK)C&zjjY@O8^H$c<*JeI !,IQImb!! ~*Mۉ~kPtt0̣'N25zD'GXrv㟷6S=Nסbd2#Bkӄt[ן.D󷸺z,`^{Ve?6? 60 40 >| %GqYhjH\Wd" W; NXmvD@;pRRb䶎qѰ_kQRiR@9KZklJp }ϗ%HgfH$۽nF>߻ܻJbyE|@Z yQm~y\owB>I2& /z9dw21X=7ơp?2\D8ވq='~Cx| w370_*<~!᯿F#ŅS~$F<^diⳂ`CT)|=^o%4!90#(d]N,s3Tc,5)<А= xdXǕ# 8I .\u֝qe6nRʎq2>r)Ų]mx cPfͮK_ 2s vQ2WS^yAEq-G, bZb>~RQ29%nwR)EN2ZbR@밦EvD jG$i8/\ʺLr]]YoRZj얼[h eJMH6=%%,?I= YODGG6S*z_$锬˶04^fd"V ㄤ4eu4\Գ#lC&ئ@J&=b/y8tغgEV*; iZ_)yPkI!8Vu5;5-!6z==^sӸȗ`9*jd!%wdWJnʥEEUB߾@PeU:H;Wxy}'bDQ?oϹ٥h* `>)~PY$30ƕXx%=4TG/Lunp./߅J Mjz ńH ĿD^\!eJQW^&첨L_pnbPhZ^FP) -F nGK[:Y뛸U>z5C̾+5Z` #u*~EU ;Uz#MgcK˩ ZP2Z=ޘ+DUlCn6Z`9tݜ$š!8JɜW.xX.9h^x-\O,P,悊KZiQ=2&33d 3xmf&9ewCaCƄU;m[),(k!a)Ɠ_<:*:P`dhZP'}JW,231r ]D)+!p[1:ʮI9i$StA[sOQ6zϠÀR tGrTQJEW:K*02R?#:-.f*+wBE;tYJ&3q:wŴZI!X=&zbɂpv #Da|[Ȫ7EQɮ7^ gᣢ,􎄨 qZ`7*N!WwspЬUu͵*Tp`%_^F2v#QfqX^-h0m+)%?5/X GN 9r#XE|0"xhmf T\+v<(56*i޴P^)B*g -l[:R,}DGᄼ],8N}8nB&[N:p zؼ4"'EVFQSu{UJD͔*`h T׉QZ 4꒳h_tjf4жƗ.߳*O4} Y%.YV ̐}ϳJ^C2M.\CWZlV^#Y߳rJgn\X1m `evd -Q{K5`Б &WVw@BV#J4HY`3YH?kĶrB% e=TU(8>Ȳ+űvZ [C5+L:z''/n+M0H%0- ,!H ZbʬʮS+,..վci;YBʅBN v L:p>I4EGY|yG5Cо#mA54[_X = }@$xj1"r,麴:g<g2 y3 XMs/A?|71|n_{.X1'!r_!_1ƃ'z7 AŁD).\b0RΣBmTzr&jUEn\ifj60jXXMw@hıJ H&(77M |. Q[΢+ Z&W(tG=ҝh}1-?h L^:J%G\zdZc $4_>5FL_4U&ɅE%z~%VeLD0ߗ֎u:ws=p?z{ib`ۿtڄ">[^#)T$Āք&78i1kqK,^c}9?QA+ձz%j/ֽSJB0N zgw{ - K':Y;ev[ Qݗ͞C'#(IzMx)Z~L+΂+#%e [y&W20uy6.I8"Eѣyjry&TلąaYWwwu*<ap7:wтؐ:qA& x+/ 1PtfL5.湖u."Se Q;Rq`s0xsX0^3@O BEBY,20zΖʶێ.U\d:0Tڃ0UzL 2PȆ~ ,~ G%m8+Dfb\vU?hzY.V3˷갤K~Q= Tt 'J$}E خSwrmifcT CG '``+RE0!9"P\="*&ԤRя鼅ɤbHI P{k y&%U ( IO$ sW -Und+7CjAf!q5#W4#ӛLn7- NF)  4o|fG$Xq^[_r3$r8DkyH 7ڜ7Q}ksOv]qV_QEwEޕ4\!%lbgff/_ 7e{脮 _|}#3oź^sȲ4*G'ՙxfYZfYI|rz): =J J$T0h໌4¹a}ЫtWΠbz^Lo y:$~|![5n[N}wI~%i}(m7ަeMʜ-,gz[Jk:ɗ 4hGٚL jK{+k/,/x)}T%(Ba3cE氫Yn".2'c;ǧ}"=qs҆V)璪$U$TRr98=&$όgyq&$m0 MX $]XX׻le߽UZ3~>Cꮛ===NN Y42F~!gMr0KaO dse_BZ`g.K&`1[|3(m)4A\xdL$1ς\zgJ&-6lo_ؽ˟_.~SA끼u4A"Õ}+jmڍKkHViyBzW@/6^C9qY!oD3@ L 7+Ic?a?~o[F\YM8| 7#^淈/3lx%O WK~^rK^YA!hԇ¹pخgA'{pI!gQ >[dc4Geiҥ82'-hP!vN_"RǖA;^e6fFWʭId<1lߝĘG8)놻?GKso#׺:I?[cl tQblͥ [$J+HgLO1鞫7zbdm |6ed?h7r䷶oOilmh>;x: mS%,:[h('ߑdճ.xȷ  Wh 5Yބ | &C~*v+6-n>q @ؘj^)z<-읟sNs:Ŋ(2pJ#> دd[;5-|!Tx>m[ Nk9xRSHx?l-\M*_wvss>:y8PeGi(<*Ԣ-X=>y_8uB >Z c3NU5Q]#-ig=97YJ%$Iv~ἮJ2-kˑD A5T)jI⍎ G= $`~ `h~ϧB^{ޫy8Mlu"%GZ7CHjϢw@(V*5#D:e?lSU{aomm .D?̮h$߿ByFLhG F4 5_wSƢv=`=|b=S{a'I(s#$Av"|O:hLn?hώ+܁6j?翨ҀLN$ͯ{ysQI>+5G-|H[/ =D\rY: 4αkb-z?thhiJ6)IW{熮*i&K :XYpB3X 8?c|!뫯9xmaW/ڟ3%26,Udt/CjfSA|N т)U6?)vRfRɌ`ٌd)$YRko`˛AwSp Sʡn0'R2=r`U7LX{;XE ˅/>rb}m^ZjYЉmj9By[3<ܶUc%zS*e3™K̝:1ܳ2ʓ%`X[ }P7TC 9ˋZXV-d6Uh:{;﹃ ͶIQ{=NO#{n_N`F^N=#o?4o/nZp;~,ׯ>p'kWk_5ݶb!/wO.t'2hՃ`uuL{YjgF1%ujH{^^kvƝt|b?\ Cs{m2QšL8p<@}mװeבsbݧ," n /6 Jk6XlWzLj՚!],ywGhVkMxJ3 QA)V[r04  1k;UI |NA #W7m`.8 2 E? K^8lk8qawI*kP/k6vtW[ {0p kFH46]5- 42pcC^q YO?QPf' fmrabKY9 $TFjJA& w]^u! ?뎅T쮐W<\=9]̕u]rcB)}m+r/dRWx)חe 3WwuΒ5aN.LIbLWR eoFyᫀ:{ڨq.qV32" |nHƗN XXMyWGkc[Z[C`@#!?TߢzD*WJ=+h1&haQ5 I 2m2(lw`3¸w!'mlEgx P&K1Rn5xJ}n R0m|Biwe@:OkjRThpDnevr9$Ls6o6zIM`8XճH 5(Ԛ a©A15|p 9Wodxn3ɌIfpUL3ћQbnn V uA0fWΩYgdQP^֎|53GvGᢪ)'o.#\;($덳lґ)h]GRNԚk[Wz6:X ;s!lREgZӣ&# |FI)TU Ng)Hv#T5 UGFEa2qѴW_F1L-vPB JX(T{1Ka/iM@~_޽G{==5ڝr,Icywn/JƑ[ô-\O @Ï*GLbvC &; :Z ֠y^l7쳱96T$MbP'j/cZ.8m VKkyIbP;LNJN`qblRT9XŢwx ʩrѓhQ7|lLƍ1AYk6NN' o}S>;=x[(ΈD=i1:2̊c {:KpO i+ hTUjW(1I fNw#kW59(Ji5E!9ztD½pC!lvpx'HsvϑطۢȷX݌RA2GE*Rr<8/!Iw`+wnL;*Jٝ<zD 1fn]ŨОۿ;{6ztZV+fr;qL+LF-g8y>>NWuy [ŞRə%[Ut3Ucj2yܶ?}98tݍ}ɕrbcw//`#åm}~{f"seHj/vuaR'Ϸ->eB% |%DV6֍As/r+|T (_s-/Xʝ\cA# z37`nyFZ;ټǯw&8b<ɏXRM)WhGʟF'.PL6Fn&R)+1vjp"83%c>DZrm~zRn? #>hLxEA ]rs[jCFU۝~7_8}pW:F\b 5-c#O/!6!ldu1 J1a ť:2$A:-:4K2BG{ijgC=rB_G`=dBx'T]<$;7+#I6bs{>Sϸ8pNdy˕jbrZI> ynmߙs]\13;k#!Gh*Pw&ݼj->D$ =-tkW[AƓ@c_}D7@6*‰)7 S@M3bbOXM90Y)k%$wh=^:Z n_Ǡ67)kD\IYEL-j-AKX؝FWb {}C$QNj^u=-7QPRZh}Պ{i[>e2ka# wzby6߉=ɕZ5rӨXx.eS| IPP s溏d43g-bѕ@?{:zob* WP dQOwh=3q`|*Qs RJ_L\wǃ4Y}g-Q[>rr-J ƞ@3H{՗m^/7ٓWc6|NDY>Bʫ-ňP&Y͞Y1?!$|#j^GG!+AU*AmDU]ĭf&@)qJ7B7vۣC$ P `O܉$ ?!UX.;R:³`}]\ ~ݔaRftP򛅸eSbvl)E&K G]=X/VԷWNP=矷FLmLbà 3twD'CT݊7 [VJm$%(]vbMr.KvfZOyx{pW~Li濹㨅 a#I'w=ΪlP&*iQu>>e^Z tJ-IkԚZ{WJDz"/R'rs:l!_.0gLT[FEA]aϣ<4?R+ټ+%@l J\/[9峾`p1$BBHt K/N؞zjcy!]\[y8c=m_OTCcqt7s<r xZ/Qʲ:/eD"e0G>\'N24_0܆*RY*.FLd*0DYEϥ2\k}b7+-%lNh:Н!M#MtyXvy:Na2;D`3D>7?jNtCsw(0>_z&ܩسsA› Ndp.]U>lK3<DZ!nys6%aD5MRhEK0t?ҨLA+TuGk1\ p,9t#&k6۝Fk3guʭ[X%4#eR {6t]%ELo_(4<9 GGW׫t^3I]hRGt^$%).W/HdKzb NPɝ=t)ƺOX? 7RE ݞL{l!s4mM-%(3L•,$H= shXs( *7h+3?uMy#,7nrpJ٣o&79Ѹj SL~ɲs632dҭt&IBd>@IOї~x]3*x/Z7[Еjȷvܳ*dQ(@5ٷ6׷`2dQ{pcװB왵7ߛj@, b Ym|)k'j }~U')rqkgae51mƽNQf`zw:qHW1*BN:N_;bcջN팀r4%9%̏}2K)XH&iV3.8=S8"3e|W]0vdr wՙn9diX+bLZ;̟Ii5TVsahm*/#6\"nojwͥ|׳R(Vq{I kj?k}ܟ´zܶ{ b}|# -)ѩ|L-يHb(5иaU^/>~ny[OXe{bgf ~VmbYnh~Fs)aT;R/ʶt {J2*qP7AV%RVķ~fsN5&JmAKZVUhmж ʔ0l :e ސ YI})znϨh Ra{0[ kn jБpNMI[1+|![ߺpbP#`vQ|((;e4;X2B~@gc4;dvz!3|0#"z(_-Jj4mtmZr⎢t2[5 %uRjzYمftaQcm7<g)m?s`1sm#$Z}^CӐ?!3V2+rYb,X߆LFgLBa`Cɐ-o2L'춵5ٜ~'vZ2Njw{e. ^UYv>a. -N-cL\fwrJ1R!I[xK>vt&'uz_62{;(IdY8U?r[_5=shvv\l'v0ɸkztG:#Paۃ;%9.\eqPO\L%nqd8Jx"n= d&d){⡈o,nwAqߴnf- <2Eov띫˷qBeܪB(#b8T'gN(T8>HH6xїJqo!A5l\b/Q%{ɽK$򄃁Bo,^.ph5ccj0=PߺsZ[db½.t|^>MmJG X ۮbG9 ݑMT<:%44b7fwi/u# ]Q;^hjGl)=40;TQEaf%{nMNW-7V"i𮤓|};6补BdS,X;5.wkL|u=bXQ0;V ^jb5%Gu;.\u=x#=`)۫X~.J{]ëW]39=1@~ oA4oj>

      dX|g>싩ٰ(nώu,O{<6N3n]`Юrŧ[=73KVQgIs[ >kr`|iY3AOD_ F+py}2Hf_ |*yak>[ygmBH3p5C]ebWKTer t#}E#9HPDg X8<9OwE+2 өL&3DǼvt2>au{7j"l!wA ==FQq ]޼ /2zx*O{u9П*H:Q ~weSPJgaұDWb("Y 7kI_OgbFmf͋7ZpZ!v?[ ADϜ:53{xK&ۏ,>| pL]Kxd-Qn`ǕVN̖b :SDGb,:cԛŢ8<;sd J҉tl('a,L{`3]zi[sנ5up\"/#3#PU:%ޛFc+ SǺ0^7wXCl;\k^ΝLϱ HX2^sͳV;g=\v/愈B"{{%cs%෨^755wVΐg!}撎oeR6>&q#(B΍|OaS(QHr3 '1f~ܥzBwIyVґ>5=BB6oVB5e͋CgP@EB-۱[sبb+DC١G?3U|萧sp_2sle׋ i'q? n3H;+Wb1[J҆$ |>0{yȕd2(BKv04_8`5#HdvLa}ݔaTD"k>O,^_T1kg&\vi18Mqt bv@Lr͎(Ӵ|TҮ>ixxi^ס=j@";qQ*uk25ߺkvtEh*k'ٹO'j?nFtqhdXA3bFn=h` pxnIuلP6QmV8GQ B B|JȡT|Egs{on79C^KjؾYK;0Advk"<./>&,72M0,BKj!xARz]F`fNײ+V ;}:n3٬m.IpOBDQ3Űq`uF@$TCe ӏB|jpB,NYsr.:9/b[OJqӊՂbm 83,3˘ߺKz!/:w՞O o"ÖB5:G|5ޓNm;oa>ܜjIbF: ]vny'm>ADy$^,Jp/$v*b{sp`Zk5*Z~s.$jsjP6Qؼ ÕZ .CYk3yW^W1d#)9,iґi堚T0q!۸Ob™r,'p:56[o/W;~G٢vܩ/pTF`XQn`kV@n^XEK}w_(ADߝ9}S֏Xm#D#EddN$l#N)@=,R{F ^<.6]xy~śoά}Ŕ,.%x> }mPuh'pkhf9h:K'q_H5{vP-N|{mmug+ۖ{/`YHpw* b8)?"MEkXck9Μ3)O63XbU`T &Ť^ئ@itM:+ {;f.Ɠzzլq.]}٤SQXr,jFeh5F|y#/,״j0 7_=y}n+|8R(#9 jOu' L*^{[I@ $zPw PKF3cBãR CK=G๮١//ޮV-4=䟧vɷ߶34 43ZJũLtha8|[tžlB1I(D]J&o+6`Q#NMDn PݮuVWI_mtHg̯Dcz =};$N1t5A.Wfl7Z ]Y,MtREb1c,<~X4=x WzSrb;HH !`M&s={ e&JBHK6|R;D %i*dR,7595dwd֐!fn_/b$ Xr&dqE[7B7=蹍_d>`-ER1RD2׫Y.n5659ƙSG a7װnIE@GHY3ӆKɋأ?aU};2 ~XlZyHH^7U5vhj g! zt"iGOwN ~SZsj`J~.;<u ߚ$ <[,i ~FQ`W>tL)[pa-oy͂ vuK>f=k~/B!+JvC+ eMH51sbQK Mލv}:Ud{Cnbkup4DV $K]C#I>ԛk?q-p<q|h77|m8xŬ.v5"?|$VO#U q)J;(`KBQi#t?G}͌Fȥ}eA ;ؒO'k = x*'j 8`Y_ٶ?bAYA5D"+ JoT&hhw:3`v?uX5ѶY>L+O+ʠPb\p ;V01On MP  z,8}9JX9P64QEǖ0qqS{w3۟{n~ՒGIJ|^2>Cg ֆ(#PTS)tQR5MbS 4Ο]GAVB ch ϥ"cicۧOΉu֝/QçM]q IjbH|`j;#Jo's2O/?z~<8_[ƳϽ#1--<>jsS?C_X69}C}]K+/Z[p͵t㽱AܣEVr/c!yZ] eT̋;{Cgxbr.5}UApC9w$zW ?ݡ,{2x0=^}/| '(/ٗS5< J)]ۓu,t\kxn_i+ܻ΅@-LCw[vg>gPqz\ ,'N\]g)COj(:揔rɫkHq9ƶ'X/V0ҙbiyv7\#~A'}+G__z΋4EUHA+2n aP0 Cr63$99uX ؐHXp@Yg\s1B*xkTkV$n4ݿF2{!(G.)j![ȉZFK![empY{JJb ?f5iǫ1fiZ^[~wm`ssؽ7D9bHI'vl؊יx-hZ/n?||㐑~>_qt7/K ܋R"H#WХϵsCv^+2~=hfy*F<{|8 _MAQEVD6%QY' J76|%'''n]|_ *)zpNwj]]wMEcA4s.?%v`S%0ὣUJ Xo2X޽ILoKP(@vIwxBB4RrWa&E+ޚ !}sT`~]m(V)^rJy*  rPPhibu6Ѩ3jMJkށ"oc+zC0/g3sDzƝ \9jl'S^7pݍ4rSJ15dC>ۑ\`K6GdF,j78 `Z<]n}$}~='+apXokPYqF*P\BⱤHb16lDʠPݶcv2p:,v621Slbwףc'_޺ȫ8`^Qqko h\@Vz*VVg3>Ag%ЮRUZY_j<CvNA]0U=ڰzKU8oRhlm߫˨%PNAII}f.q7MVKt*ea$|nh CF>?.#5 Cޯ ,rR?agp^lFW&6T vTܮ$m-*z 'g;:xd6`T ies$%:a!iMJN+b(I,4}>\D\{V־9j{.o|wh'[~_ é{]ڷ@]lDț#YL4=gןC*K_>OvZ]Shd4Z }'?[fҕRr&)vVۈe㟋Ȟэ#;B |0& 1 +xQwu?R vJ`vzJ@!t^>MmRdZH$~@noC*)+ݧ NPtڡ8,Dߟ9I΄H Ffd8-!P쀉KDG''V&<\={ήS &Ct4>#AjeE ʝ_e4[o!W`?Lgjݦg}_G/YD"` VP/~FVVWbO"@[7>$:|cp(~k<=XsTa_vvC!'?ϰkMF +|qq})^Zb?cX7:j: *7O{c-e obH˸kg2hD"H :khMYG n_c#צ1@{s 2Hؙ{=3f+\uTp@q=wUP C*mBh%3SVPAE{=)?}d?nl@) o;)s$AeBsE@`T݌pKam<ӛ,hZc6yhmZA=C,~EZ[@tJ9<cӡ4kwrepT%{{g׮llcpmQ-.yu l s~*YoeAN5ȝXWPnќvcC@gXDG-xtu.=k-v (G{x6 #ܗ1Pۉ#q΁.D5ZgU+fɬ:6C ;y_Α]|J%<==|DjCX;>?ZfY= dW nEUA99Q^t|H:olW갛O..Ov)6mD=Oš;ݲpī<}Bǹ\w[6? #Hiy:}?|!=xOO0=] zk9![PdzLJY "M L5k 3mPb⃢: SdBBS7;-^5{RLNJNoc9ޫv=~z2 e~_F tAJ:ܐ|I!jFMW_L21}hT_\1'm*o˱=^=#wekvҘRbX]X5;go$| Vo߾MHi$[|m{95UZv6 +?Jyjt?}ipbv+}=S=wL|JU8O:tjl7аB2YIq3fa^n_:v&=ZH#F2:/mIk Ond{WS ;?n}m9zqKb$[oH? RdޔpĖjpAQkJ2C|Gz=ӟyA %nB66n"^y\[*w__RÔ ʪq*dŝ(L6wi]σL S*0D\hŚTDs儊Mi9e"֙kX+޻QclP{V@kB^Ī&5\#.ig׍k zs70-]AY"R-f 32$b+ݢ >H7Ҏza΃_`8zqY7VA]t/[I7iľ3ZAL؂}տ!"ّ,:r9>e#/ʗs9']с@PAB0dƮ8FnFuׯ' 7LFe3Z[ז.ԮǥCbju횝 q> Bwԙ,3L)y;K{Qd;V^V7K.Y&vIJGo_Krt8pwrਖ~3+y f߼yM{o(քI%ZzMnɄb+8yjʳkH=󉼡gZ:hǽE%B~.GoQ@yD&eh( L2&**dV,8 *6VvuwѼN=1!qEjcÌJe:t[Bgm9Q$[S7Wnuˎ슻\5O.:EN:%8ŪpGmɠ(z#94-h h sUʥʽc%٥M'0XuGkdGs)ts0p.MpO/ ^AW̚%kN9?[fmK7 Fͯ>cQKVh7jZ?V:Dƕwd{k_@lf<(H<%8;w 5@b|%cε]Yw;"c,MAr]%| J[ }ORhY@68 CEbX> ۼ917HFkՈ`;w.7Sez-67zj&Oy-z^4NV<_O+*3qKѫ3i%? p]Nn?rk\CΎ]QqkDJA+WnYT}jE-E0{0rktku6mPJW3@\*&.;S55Vj+u S8IfT`z[ h6D&|!"?g^H#>L z8itw`kuwDQu4 ѷg vo/ͽi/=`xNȌl0C Rôa<1̡S{;xkG e<Ѻ*{ ϯάnL[v6>>& 6;m C3zz]{\a.Urg?YMy:<9&>fddе&ᤓHC=lk̵cŒ-i˨˃ %v}sq'f: ~5z[BޚYSڂ1ehcisg{Μ,X;+r/XX6qg...R|#';qcd S S"@}XؘlWdwlTv`mzj kÂ!6x֎ s}Ş]?{ǑFVmXVy׮Y~+Gӡ\K>{?ٗz`Y5= Q l+\t9^K y#vғ'AWgw~嚃 ꗮȌ:~dKrn<c+ΟY؜6`S9rE%+kYds%/K܆F aU֡ͳCsGGqظClqo" xrApEryXnWkhXy&ni^=J`U,pohZ>kz%bsKؓL[/D[jTՊVc:+ -#ZDy$m٩d!>5&0e7ҋϺg?lsW>t.|E37пӖ.#|-mKc*jL#?_=I]-MLYsē?b kI&GFpE){OFk.ci]̋pn|֓}<;jfyr6n~mIƻ'huq}%S殚y7<'k `w p']@HJ| ^8xW!^3Tx)u!u}W#?FwnʌN kQ9A))Dߍ ^!xlB6SM,O1jbF>^[J]CF<~ggj7QT]<<^h7R%z.Dߍ9#xw]<%'B&chv#[o+'W£uuQ2Tx,RS]M}2UjH.Z["c8n%z$Os<쌄IOa.˥ VrZp ӜxnOԚKJUMsw7eъ9JխX9l'*x9Ӥݏ,36wVK09+ppȝl&xgOĊz .u"n[2>.ח֪;,Z=GNŨ/s iݩ&2 F\/m/ujr$3Hks|msW @6mzxy<>%@~=*>PWSUA9Oo;E_Rv9|=sH>||ٰ֢F~w_Ӟړ-[>&̚n 6a ςӔj]K =g7[u?h6,2RּZj#cpC =3Z~pXH{k+ YM"c3$inX^'zZj\B'8n_}gY]d3 >L<=|Kz'ߜho!?tqJGH9%*|pW>/9b7?B'乤- ŏ>XYG6&r=<q-Dn2E~ E Qb CIb7>L䳒!VƣD۸Hq=Z < MG,t_~#•M򼏗}Dn% =8z$'$ G-DHy>A} 熍lPۏ" S)`<:haeK(cՎșp-jmj m ;n~MֳO;SO~eSSߤ& fΏ= >;_j%i>.cPFarU %,zqc0џ FcJO_l]7MQZY9gGfQ!/A9 C 0rEӳכK?iMüt>o3W$Uܜ a1 }s??Dwnr s}!/Im|$=&}a:d3wLujۃЛB^*R>&:|ѣ12ey `zWLTUعzd9Mo!|~K 9zo V)w zGH#cU^5qs_wjR.w ZY)ӏT'6J枨m~rȋ]0OǍ%n|?|MLƱvpg?C|}跂-o~ħIo'g鑏~?zG~%nez#\}aGnގOʯ'xrW ݼO?h\;^_ |$xz+?>k: Ug)XJ^Gz5Z}/'"@B?iJ=SĮ-\S^=H0O ;Y$eߊoNʙeco ǃHnUhx,<9?ʟ^xPIghKM^Jlܸў*|fs:Foir[M#꿎$FmhG#&?X_}6x!s~Ϟ7{v]7ԇψ..="f6lNGg+dOkʽ]<O)E7OxTO2ES@ݯO=K6b{P!Z2oOl[I |z $6Z?>¶}1<=Or[p1.ҿ"`<$~;!0|5| eӦcG~4m2/p(T*Z gwpm= a'*2RM!oHdrh#׸? d QI7r1'hk"!rFEDE/ULsY_N] |S ƏF~lz(#xK{&NV땙l26ϥNko[mQQ5 >“Z4ΊL'UkFZ>Y3o4ӽN.c}54*JnbnEO2m};_;#eߨ\~OĵkOr{)^h'y8G0{,)8M2?;a!=ՄO!=I_J/ӿˉ>l~[}|$}w5 o?$v\>n2e@~kk=623U9l'-ܾٷeyMds1ɶ#|Ʃ"|qJoJ働ID"5;>H<mOyŇ>n }9CK{.^CtLO{ +u+D":6)ӭN'|n=At.?s4-d`1=J5eRB_#:rj~WlЏl>1`eWZ&7!c]mDgm3ZݗFUp@Y)$XÿB08w?zL~!5%z ?#u~ii_K3Y:$%֔Ω9Εq?zॵ/;>N]b yyHeadZ߇ wCwɝ'0 _0'0>@i "777V"N}*-'ře\!L~7 9_Y<:Ɗ d쏼T>F]}gW>pTK6 k9 _B|WsW 9ήx&&rɩSޟ%\?1-؄e\gϔqqp+D9\Fq;"/P".T+ }>ȼ:k//`": jr+*Udn&܋pm4c7q5v7Fx3kjrՓ^o9$~'\MNǟGk~׀ ~7ʵÙz.MI>!<='9ݢo+TSN k9)1n &6.?(ַe\M>R)uziѯl^Se*AeܰAO䀸E:(s:.IzWr"8*r5~^nM+yѹ>/+/Qq58a$ *4cO\ bNpSQ N-v٧F( _ c+e<Esc߾WQk'xɯm/2{-xl ֯e<~fYA v[௕*NP<7L=%7L?wy<8_1 &f4#$}fû%,oJ,ql228*4|Ih>m+3ǯ$8^ľ,3ǯ'8eK/ˌF'2x8#_^}Yf> }%ؗex1+z}X18}.Mx?F^y7.;xP#{.<Ȟ6;h s7'svNn\ 5%{Nm> @3^%qO ו?;pk>S3J|וpj3u7;幫⽂e<e;6NQK(j3tZ= /|<A;$DRGrQ5iJfF&Y͕~QX wyoLHdzGBR!gD/#|6^?>qxp8Bf=7orid|'qR]Tj h k=umYo5 EKbϴ|'A~锆 NvĿ.*ma ֖pjؗ# ɭ5\̀_w?}UXmA9ה|?NO ǹM%eTIוp$막z:BdEBrYדykuEYd~D&vb~.ׁOt 9@x֐}Rl{ްg'\w&pBzݠ;@p6;HiwX;Ԏ::; Z,7z$yup7xȡ_{85j{ԫ+[,= P@9/Q7|g;1^8qG@c!HQ&??sksٟ#\O'8G, ^X[jɗx8KJ:q{ɝJxFuښtF!4`|X"3P?|K?K>g|Y*cB? >y-p, t8#\fڬYR.RF9yhRb4C^LJ&:#֔? J#eFB6޳>e]BΉvc: ӘVͬl&VS< Jź& FgYU2*D&+3fvX5:'G" ɪD>5|%p^qzuڍʥ A ڮd=<+n&jx|GUb+p=dx>ppdʪ/Q;WeICjbg/.CvX3!g=KdW,u'_dT PL0e,󴈴,9<8Hv@ۓ(%&aOC-~탧}?V苁ټE0 +jɦ£}92ȝ7Q1I@nDŽL|B]Qb ɤy3H[d?WP/N*}.x@_ZRbrDieFsF#=T7/WSrW{=s㜕Ũ?z%ı`ݱ.sΫ,y.IyAY|s&J1Hw+}Ur٧RTiu*%{Zr3*G9 fϕ+/hޭn%߾I]BIx+BvOO9]HXpYa8n?[K= =s? _ƻ[{_xɄYkYw) <;)9  HdE}:b 5`^E~# ȝMLE=KŷkxJ{:Qh EnT&p#ɼ$ِO 8 ]0Nt~5J7Zm iΛ*+\rW]J4߶}rK#=/kȳOqj˄B l4] o2|FZcҝZ aؒnS%7J,L;Nӫů7 *k(du~Y i=RgTjvMzEJxE8wK@`R\ԇ5ASK|bGq[Q)qRoA| ?aG4 #]S(&xOz\ "=Tmx mW|{Ž.=z>UgT%tмŕV| |?77Mܓ ۸W(%|,”Edm Rs9 }%O=bw}&u ]z[2T.h]X9d=cYRBage9M z#Ӂ3#V;te봶s+ RP#yUIndj'S8 ^|U㙩E[k˭~"F ?8 21$a d ١h_Rt)8ф_"yͨҥ »UK_$'J{Xcچ:MlwdT]JxJ^ٚmZ<3 j7SgyP}ƥEMǟdTVxSa-0ND(,)B|p9Td VRbSBCT쎦[Uv л6G䖴6_T@-b}zCPcwW fU2PC n؈|9d7ΊdCCPss~>c>E}*14 gBzz DY>|bxz֡q})›4U+FSzMEK/B}(M|#.ct1CX1&^Dإ "&.+a R"2~U]!n= {&Q#u%sk!aW +aW1IH-];BK3ԈjH17z`]Ƥn}-IJ]hPgQ:p'a= M=S'YGqn1U=68Vh4xϳjͅYRq < h\,֨RG'V@ub{Rwqu;+ xǩ*()HWMf3d,R]cTˤ8xϗ(t2n22"0 2QLgEZVToNT#:gJat$f''H?5;,%FVF4qH~TEZQ!j0kGg5mb+L"BEcNג_.ӚRL&ZCE>YUKbT#3PW)Co[_ʼpf' jrd'x,HWNxE>qXWcrUqDV1EfgvtLn1JёhњU?]-ciw:Z4}5ukf>̚M=hv6 ZvYaquCۢ2oښ:D1-eu-\X=\Lw)BoHGJ N,Yc':GC_j-_)UjF+65ctVMCr6{X&41۠ipu".|gF#-B޿_VG?gVo4F:qzJ@zEwc&6ѻphO?ă_lD`gC3gZ?}% A-/ /-[# kra%H}[Y#FJYVge 면AΊQUJyWB>TU{75f< yU Ovk|*dO k bR`R PjUeXmJ&5`C{˺ [zѵpI(jiG"r=j< C ,o]6,;gc /ê«7L| ER i7e]z/0݊XӳdI ۢaR0bC=|0PTUKz{FF?un`u/[oרf^pK]ؗ?`zdh |@-J̤YKb\S3.'Sn74ւc. 6PYcӌSM*T1|#sFZtFsη֑Uj)ƻɔx%G5GdŒ…:e FdS6N/@5@'N&ὧ:>q!mw5«m[N B[3)l6)veP֯TݓFSuNiM_*_CcXtq@=z)W#. 쑸L$j7:NCUR[MHk(IlB?SvqhtJD1ňx;U7x+D zxW Ss8$'l)OV;&i162FVFY\`DFrNNV5yzmVpFfv?iv xqzt^ UgeìT,np&f|$<1${]uFE ݛ,P5IzRd`6oBjGhvXn;haCd6%x3|n[m0^ b=d^Ebw6II4hnIANFœIxzJ"}Ek٫O woh5nb]cPҪȕ hOCc5]= M.YD.g9_\=0#Hf(Dq1~ːu_,'PD<:G)4'3$6 .KZԉ1}k ݍٽzq5qF>:QSYz~֚%NUzmv36*6YRS(4<>8Gv"qI6P|b^FK@Mr9 i V0n}3?n˹**"+cU/ ׉F>Caxd_cރ{:hV%v^mkDjMῃ#.R1c@=^lc{kEIZ5$eT0FxXgYe-Úb:u~^_ňlM -ڢSk4荾yL$A$zY=g.!&|q񫳥y pq6,7 zP*Gøϡ# кHEB6{N͙۽d =!kno[r6CyH2uzIY;֬>SehP1-}/_[# /^ GQ:2~YҺTjDͩ>鉃FYұdbX ErHV Y6'\>4^|/` cKTިRL&bv>V#l¾'؟'!mbl7Q "R;g`Ox ^EïC+^M$݄k族8i)7E {bBꚠSNWPs _^9{8'+~{ wgg|G}S|䱉fi1 t (K.5H˶E_~Fxhed`Ga04/#M< O"j(d'NZrT>%.Ar7Zps{M >'׎B/8j +8d '{^86?TE3$Jŕ( ډw*b/#!ϹEYN[r&[o$E+t䅉F#~bgĻZR/!|KJz.x3{fݥǭ5O|(k&G˙< 35gRi3qnn,ԧ}%eYE [ ]VrKgXvMQbnxOB30VG8bĢrǫc^_9nw6. Tz.:nޢSUCsIL!Y|,k&U@H%R+jcˇ!RQjI%~6*Ų0Щ`O)^@-&%9wU|VTLi^IdXaNA8_8Mhmց$QVSf WUo6f|Iu^hi6F,u/| Kv|?d"eq,^CZA=딖#J%IU0VhP춀m(~O-'FCզxo(a: @ JϷp] XG9 )>1Av\D#Qd1 1Ah^t]eTp?~1 *#s0Te2Uu ҦW:陋/D2UT"0в>HQl#1A+l'ٛ/+YGSJ̹4mY&ƮW6]RjlJ(.Ϩ5y5*70X"8ooQ0te\6n#s\jR`EM 뫨Ih(k=* [o߃p7n\N $SEAʤ3)h~Chn?uxyJQ쒉*rY~Z!]v $>vW+g;%LrT [ì]a||_֐"UKqͲJgΆ`X9`MIK+׮lx1 ;g.w;N&'.H{fXcYӔ[DdsힰgRm$k綦\RǶ9]ff]A6Ga}|Q͠;#1_Uq;1>,GoiMb>;7joB4ka᪅.XUoVd|UQLfrgYS xW{quUG/\UPUf{UiTHfp~ W CsZf!N¯,J Av84Zgu1H LWHyVX;{[jb饍aMĜxGµjK3C7P\]$KҗBZ"์&pxŃ^ s0* d Ow]0=?XuNc2):vjcT&5FOmo4PBMcKѬqЮ ~%l~Ҡ{ ZJ%lTlXM]>WT8Bſ}GgQcj}DRtnPԌ}"$7a!g D>6_iIT@yrT69$WgW6VGY b n])79XX%rc +jO; R`kZ0r5vfk,:+w,UXqkx*$bD!\/j8]Rhn9pn+:'ki`dfyq*R1'a ,:027VUjҡZN NV95 !ϛ1Vb uPTP+*$ ρDR'5Xsc*STzţYk zu54y ^j#[lՏcg$\n%m ^:w>{﨨ujJR͑>VAPPc$_"o§HB/]y\ `3&zQŕ-a21VڌhKYrkjhD x4gcf:|4F_SSVHh\wߩ2A=E5):OE,`,Í Z4䏷0!,w|)Jx z 5_G{Rn}fg:j Mp5ˏLm+k#\9 hM0˘-ZJm*|]ړ/;LlK=E?oE%*(J*࿸3!۳Q#UT2b=DJTV IEDlӽއg=ZZӥEYaz5Kؽ`(`v[6?rr $&AIbЛXT$vLݝñ}]T2@Ge쉪XU% )9PKJ1!ggi9z?dOF3^ F^b0XFc1g 1At*J{J#k7fmuUfL4bkʈu!:<D :cv_Ok:iS2E. FOC:Ht^(t8">+5J.w  .lXQ -j4tsE3czA5JMyOK?:j{)IeZLILꤐ4&!tP,A|yk< 6DӧD}sL ofSg}٧Ǎ4P? E3v-˟Kgp>{w0-؅69x_G?L%'XGNPi -вpyvvQ-iejñB6TUX3}3Z6=+@&7Al IBm)bt ky밣2s`l|=ÚkxYIG"d HiM}՜ʢeyA&oUo誠 3A=[]>3P8<3[ֺ/zM=ֽY"~BP[K5vݣ_Y30f6c;TϋJڴ;銨ϮZX1T\p=8udw0 SswJdTzXMug^cST~Oy~G0?'ģx?$1{3 x';OҦCǘ8iF8?IM:W'Tlo!!7PaO|kXy_8={ΧW9NkpOBdJ'. sɻQ_=N >4dG7V|F(H;Ϝ||IKQ =_F`y|qz{eÌ|O+6lH?%/Arh_qvZiإrhY6a603goCDG~ސζDMǁhnBx]Pz.yX\yx,(7ۙ^l^W_͖iǎ1?pu%Z~cW؁yBԢ/[6,Ph|z1RhV ,Yl{UBj*g⋗fGQywȲt _b>L/늰>Ƹ/.}l0dq<0aˬ9lZYYB _)aK.$Ȑd,.nN/mDnX=8'X?Qy!m""Bx_ /*}`E*{7oHϴ(M+46xݶm,`Rq`=N( +r= '4ƍz/@ϟTldb0\HB$NQ &53̟R?K7٣T'+7ވ֗0~=;p;.~ym.{fJ>z/'zמOҫ>)PhF${GOc2^*]ѻ[)~ mYgz ٹa|- F=י? εN䮸7޸s}m뀃J'p硽>[_3Ԋֻ?zX\;kguw߽zNNy =*KO#6x)d 2MH|: am Ԭ6=eGX %@F z6VtqtZt6} AaEx6"8=`F[<UP|R*[ m?CvkQգNl!?jD;Qc@kFkr@8x*YyֳT QuxJ,Y;@0׭#MI_fB_iIA8VhLR-o޵Ӱl:g}3r2TgSbM@?18=Wzݬ{$5w`HlbS757Li2:KGZ N2h>.ʇ;2`k[GC Zʈl HG ҏjKaav<赕w3?a\0"4ZucbJ$Qłg^.j{mîsHPYyeB`.鱴“ F6WV͝---^NԾQۑ'&IR|GblQ`ll Q{G86.;opy"q VP ++{lyB G'ňq9pyy !~ookk[Lp$@}U XcUwW?ɢ?`1(I`T7O:M u&:%S`||dt)&)u| 辑}| N%0/ |#cöaׅ.ƶu.1mCl𪑕0U6 U,\ݑ=$6MbĮp gRb3b ~+[RRYK*Om\4ɲRYJ-Vb~fVwU׼=.b7>#@ɇ3x;v$;oſk7یMM~7\G"z F=Nōg0ϚXk#`2|'܍;fmڥZIJm^Cd>j9;\>-FZ_TGipl᫯^I6Z1{vEMkeaxo /sn5cƠ;݋‡(?Y痲i4d/j}hr[ Em- '*F1b(ѿ1\cy+]9kٚ~ԏsSgႽ&QH%ovFTi՝9:Hw/&} }Ƒ6400WCUsaVɵ6 MQbuԅ =ޭWNdwPro4cJܩ7vmw[w|ͼ3Ƒxw>p_ |]iILk~ 7&Z_K-;ًT&]pfۿ9֒ᥳq}W?PTD<Zjasp}#}nC cfśࡑnxhJQT ^ofr1=K>+]:=:n7U]:_}Rޭ]۳q-+VtmPKikq;S5Е"퀠ػwW,٣-y5떷oBmcha*&/:x ֣`8Z",P]" NWچ2G3 7jN|ɧ'> / A>zE#Zf5kX,KPSjFV[\'V`l-ȓGWؚ4Wr?<:k |;Fyb|w'^7Mǂ'‘&Chh pN2b[+ <)H7@E?x-g_].ĿG}^AQ<68QHwUFW)aH~|jmd.$M@O;]oS0PY2pUYb<En ;ƟG@N- c^0jSvZ4}HQjf1Jb0OBT4>IljjmYNR@tmL* z-3ư[Ѧߢ<$ 4̖@ i:*x^_ښ{=nOK-9y% j eBUД}MbYy[ްboWfӗ+tz-Av>.}rEf1t1v^MCηTNqVȥ}bff"}K"c #$X %@Kv}HEc$߽K 9w;_   E}!Kcdu;]i%Kb}PȃX*CvoD 8`7#&#>`wNUwWU0ȇWW=Ƭ@}vL`Mpeb{^0@3a$$ =wG`hqTm.U!ty͊Q;СSf"X"X3Y;.ygjq'^3ҷ%U !B/0WgU@R*d4 Qdh!liZ_ Ї j#Պ?\g0Dfgm׸"[S^Zm؞KרMUN{݊R@fng:kp 8y)e]GiZpQ)O5W]rW`~/+ mCghݕ`y]c~̙4h7,!#&'k-Ɖ 7 CfQN2CM>{aZn la_+Gw:Ȁ[-qkvm&!/ozYeQªZrչE M.S7!Yd_r;SjvgBBxK~OOə_|Wٴ%Н(Mpܶ Ee 6tOw8~z/f}z^gQCDUHq%CE9P"K`CGav(`@.ȆEw߰.D$Ηn;(A9j)` ddQ)XbtwikuȲhǛgעWK9B} GsC0W<|3! jcc_ FϜύ(d#đ5+``U̴>%xF"/yO?r?[^*IԆ"5A翴)yBcZ+i~RÔrPX'9ٛVl|&{+q.[El!5ګjf+<Jt4#;{FJUQwj\,LD.GCtX.ʠq 5nk/֭ڙk+)tz84zz }Hd="9C<-ւaVSiث{μ.e')2er+?_SRv|glET.{2!38\d u_[jMm[fk r<6.c뷻v*}cIpЄc7/ f irrPZ5Q>y~ip,BM"0[:0hZ/20KH^Z@P@pd%pv)+p4qd`r̤2sሏp8Ҋ+PHFsA %>Q|½e&%G8~D˳]Hf쑐x%:8%2 q A?~m0\F\ ;:lEnw 爝V="J9E1p|)qv{/V\p΁)tYS`H?̱=@Ã{| fE[#Z$< KN2螲@@| |3ߣJ`:RuwGGJLsO'nF`Y.<~0zަ&<:/B8B@ԣ-&)fz;xe.5!OYh?B:[pFl_`y^IaHF Y1ws AdF   c '#G)bu}t/{wSNhcA<3SV306Oi`N=JȆ4ɏ ǫvȖ EZ0o"0P;@i=#Ј[$=QϲEbjء*ݴ1H5n 7.B@z"5G"D2}b+_DɳdwU PO L!9Vk|} *5ECSkpSA І5g*~kSL螩 HzB(oRLڀt ꥄ8/AZ{zԈ[8u$0'3|[ tt^DX!*8Z|Qa11Ѓqç<'o;j14*5bѦw9g}章/do˿t5vt0| 4?l``Gs^KV(0#'o~ 1K;n:pwG@FF[yʸ$ 62Q5#+:Ӓ * jN).fh N3aZ#^H9Cz3Ҹ& uH_[kQ^qӹNBkKX2b7 eTnM흙 ]`='6,#HHNBnèsll=:1?`3< exoޣ#z" e%-X?zT_j8n*sRw?A|Q9~rm״.k}W7v\v̟0t6? pIMgs_C/x5 Q7b|[sonp޵w_7gQ ABZ! ]-C@M9s{6n*7ݾ@ŀѴYk>F' (He{-7߼ovžʳ"V(4VM>|QU$E6`s;@et!]݆zr-N+AV3 8'̕gҏ Oi,h Q.VKnC/.`«,훾Í=g~neyN%<}`vcitt,;hQ^gU[M[[۲Ҿ ~`~~rjb˜;AKůᭂrr8vW1d1/4 5Y[԰VSLxMo)@ I;@F+w`_p+AiEܹ,1{Ҧ,xi+x¯#fU)CՕQ0ĭ.Qݷ`\!Ό]-pӰ;Y##^]3@a~$7P+$S Za.vht3aぱZU w >cGhU\eQ*p(Ev2fW#ջ d".DuȉǏ&s?bvp qyzvNʷ|\O:/fDZȮ4ΕԬI 5Kܵ؆} ,'pVIOVVWM ͬ\tVAX+A;SB1JbQ*YkH4s:U3/;#sh-PMJQ\b뺲%1}|y5OZ'z*sX3/,D0qsf nD:8J-pxuq` .F䋛CJp>/,av91EeQ˧EM{d5^~ի߯[z^ըI;k0WCvG`bPu~_w@ǡu"Zd8 v;ITHcnOy@/VDG2p۫æCyW{$g(N|2;;!쿖J? i9fp6P˼ aj=\\x Fsޕy!@rG#.W w|/\o?a~9PS'0|jb:R#dҒbsV64\s>2;,R$mjF%0߹q?|8D6U`5Q6HcO1Zp ^UWŏK>Fݿi7b^g .s_Erp ;X|<;]1$@Ehx3#Leh &4GB_;9w(90л5ѯy[ٟh]L<)O/Ҷᖲwqk~pAM NTvpj939#"!azJ ؏Q$poCPI{Bэ=0=Gvq8=xI`OO磉WCZK@p=A|b|QyG9dOݵG&x-C>N? 4 Ǯb\ 8J/^yn~]$wpgڿ-$-R8 i B@zh̓ST\q*ѣYz8+p/ÛٱCv];Ak9ɮt;̜֝G`.Yb$oqH*Ö]zR5um84hrt %PkmQ~엓Sذ=M02uuTTwt_:3x)(K,V2 bh Ffծ]}Kt}UxM5+?Ԋ5/Oɏˡ̹jƮFqkR#s>ɬ#OK'fс \gjp='`<*_^WOc5cwF:VDDŽP8:n÷Mb׏_&"}&*&,B.ˤLX^f t%<;jiNdN\U ƭw %bchA ?|t%^ůU_O-xX/NeN9*}x:ǮƓږ1#6<EG/{׍]WstcWkx)W1'k2odfvک217WGssw7$bmQ(nbމUvoY^\ѳ%7=MTw.`lꩥuKO37W<7+~_Rkw4'O"` r$p XxYA&R >oׂ+ɩ^q&tk,v\[nF_eJ-Ui` CTznewl_0(za:B 8[Kl`[цFsT>§G3R/bZf)' :'A{#J<:Y?O60&n78,fڮ*mɒt_/ #q3Q4;@/ɾH gHc8]%GJ/:N#ly_rb6w7^z|Ep 砹)No_IS+uL@dq~ :m=s}6n4=M7|8gaqضGp^_?ֱYu^^[zܼ6Dut{OӇ$z~4Fnk.-Q..cD"a󠴐K{D;(6$Q#eHmjC'<#ez;e ĺ /z\*DRQ$> j65Pbj9:ZK]H]D]L.nn~KHzzj.n#c'Q~_oOBWK?RwHɞ_q611@Å8^;!6ϨMm֦D_fښl i-A5a-k=$?oƎ_=x?Sjڸ,6Lzn83_0^+Kɲ;c50]GE;2KqiPA-&?"p@0?'bcՙKpW4L0PeЪ!};2oZP;L8gLC kDŽ a(L a9{-/ O?vG./&)Ldڶ̺W^y 9*Ԩ>??]g,ւ̥۾3 =q7z2d!a/¨FVYVS^Du)ҥf'O{O(qGFqQ8 ~3^3sdҨM-jQwѤF`τұדoåa^ca|XP3$Fl&jNnL+f\=GOlf$$h=j)U9Z!{q=6fYWpYkt:8-n!6Ylݍ{3+t߼/>ޯ~/wy/ #??~kn]2G&T{ f>Z||.[n;<䓠/yh>uzN=R/}as[Ymįd,Cz.X9IŊOw;~6ֲJXA-W䔵TƵ2ܲy66^yd^JT5i%ųYBh6iݰ;jq}kEb_l@)k{S] vmRnό)6y,*2[e^[ {j^U.Ytf*%KP6$9% E׬.SLu;J!A@ jC2Qu NPlZ۴RYd_"Hp{va*̭[\dWHnnE՞%&IR&~zCa^^PCp4E'픑* =q ޢ^g%nBͯ"?e|;ٮPi?dO+vDlhUcr7昧6fӞHߜ7YyݵxcaGYWV7;PK.#)yN*-:=+(4K¤-SYq]s84b ui2J,RY_Z)ՠj.jڥⲎTmvB*,xK&ɢ \0xQ(U>qhvaɷ-Jd;{QU\EnR"|wf盇z}u:Kd͙譕W#RbRYTRViaޔ5n&eْ7s(8*HX n{慬t2N֟y$1 %tM. x{VeKTs*fhUJ:هr18EPCɥM|tB˕DFS\j|_97gqW#4QU7H^ͨ*v3ʣ)3tkK.Eɪ30gMSZ ⥡E usѻ.go4 "4^"UOFEtУvTZ7\P!x;O-7O]|#-Pks l^OWkT.ent,-Vfnw%#!Txk/K+:cDA7TE H7 |%Z{ZƳ u坁9HUv$GՐ3 *uU%[T\ɞo,h.0?h CLDQk $m߃?nr(m PWrΜ.-&P}r, dΦHNJGnh*nͧt׸,RzU󼆰]+k(P(`Gv3LM(ZfCOD $zo4=n|^d 2[̪Ãbr#Ӆ5cn.uHJK n/0IEYf_P%%uV~_aC`V>I|\@:]d#\ ƀI)Kd:@צ#:SvߎY*ި1k@\ 9/X ÇM16cL؂PB]a{𼼭-Wx5[sBM߭jOM^˼)G9^ -f)%p[5T(w<m@#iʥ\xڠ۠D@2 5!u"$.CdU\ҿ|ͩ rJPUm$jr-]*@,!{iѴ#ԚL5y@5zVgUIuwWictt,[z01{.(o=gYPx.=p ⃏e&_b0/hؚ¶x2TK9JEeuׅ>sQɭϫ疳%Wv r~@f(v yFe ^ޒ).iV1QNƌ D(V%SyY<4V4][iDZ f@I//kiw(hd3SH3XL?=QG֦}6\e+*W@Ү?﵋OT?Xޟ-\_o"Q) i%pgX(tb.prnW"__1MH'wL} |1i5'Zځe8XqSO^q/H/hE̵`h)<ŝ#'nh -K޻+d^-'n@! 磌J@ :y:RK'Ϡ ]uyK]FWYka:\$:T&uZU-Vf#%FhE8~4q$W_)qLW_A! o@={I1-Rʶ)ZWPç8˩lSv  8Cgq(kIiΒAngx, fUnOŮ{G%:t-vR$ɽrt{g$ ԑ{ l;ΧO2dΏ}?! Lj .z 6.,mP(UF]GU\+hr,"nVݐ JaC .1?>c8JJ=j,V=TkT\FIʦ3%@1ҩT|-=ӏv>Y0H8yڧJkbvm^5-fpTXT:6Rggu׼\,\$eCn.hm(1I.X/1FߐF(m>|iJ5BMe(eF^0[') v!u A^nMQl.^01̰št8jO2Va|;8A'DU4(-*5A0Kbkډn\=SQr% 9)/;cA:ș@,5+! JA ZnX5RԹ ~X6h+)jEC]+VtMusՠʑN󭸸w ℐsk^-ukP,]Y!K]j1;wRNT*+i^ 7~LCWeTD!&1 &O]U/̣E̒"!ȖPb6y^A$S+9\Dאz-l1#݈5 }"ҎɏYل4NF`1#w-ΔŋYTįqޫ39vR\/c^­#aci}ѹV @c1 ໐TE19цvQPjN2KYGfȥpQ6*3)fc?rET-"xU,(ʦ`xeҍ oR"2gYEc~=qǓBV gL:as%X Lo?Kn+ȫ!A=ߨ-:-!jWJ24R^:jn^?(6E-29\?7Ql߯"U.a\#e IH2w_t-5\ZsJcOx'h|FW-x\ZMކVL&QG5s-KxFZ<24@K1pPLBDZῑa9NU"\{Tn>YļYy -@Of-'Ƕ n8d Bnn賉 }Rri0:׾pNm&}{.^mfmV8l*R+/n`6 ȢL{lAxe3"fdgKaúE3r] %2Ջsvl苙`S;* 47. oh1.vQl G+JF-n`<$Ze}iW;\Si!Tou#"iь˷DCZo^^#AЪMfWDZa*Uf5ww[mSO둌δĞգ8e:U V)ؒ ~e^Z.oƲ+n@u#*GJkO%SseqiyuㆳH3۴!)Ne.0ۼ"iAV/xNFk1KnzRgt6,F~WJ< \Qdm$_ glQX^{gn-[ 1Ts\x:Ę䊲y&@e+ϻn0t)-[kOYi0X2.\й:㎹ Co[5]PT7;'rsvO#Y 1Y?{:Kz%Wd:HOhkVn;w}_"r* B)ַY7-g\ mgTZvM2ɝKۚab9)\jN}q~s$łW:^EӒU.q"Ω9mKvF&p?ãGL}?.L7Ȯ't^=(cEؙ YҌֹ;O_̽WQ[ :"[3[&i Ez,BA`"@OVKW5UX!%gyڢ#D֑ z+E_DŶIf,U(*6i_;jaNwUk߅vKuյ5-uuwuZ-!L{ƞI2I|s1!1`Db:B!ĵX.\I{Χ/3y/u9~N?邖~pu+_&x=>sW+MZtjp㎯^8uW.x6ִn-S5L6և>ן֠k/\v/X; egl޺hżk/µXر+/<3E9dnUpM&8g{G*|L#>-ZմlSb:Y\ms#?)=+lnj^t۹O4s٘ʼLØ_Z21L#*M|ſ[ȷ[ܕad6mZlеd`b9u-(~s[?iFq [J;6GZ[:::}2Eo }cAj'?e9a݆&On6oe9vA|s&mݱx?Xos)OFo]?R`_imM-lJU/:i'gog/}X뽑ݙ]#7D?ꮇ7d|ş}1:>3pvE>e!4h==5Ժlơ|C?\:?ǠPP|^BCCP΍L<77@x^i֌/Ylm ,?cƬIJcOϝ;c;FG;͙(h;{C?Ѹl_:Ή`ᇏXX=-jU;:X 7??pqn#J)8'SYl{#Ѧ%KWoX sXΠ BCi)4ƢiM^o.,qZ"ڸEK,]fduwr wkx3<?zM?筋4a^c0_DktqC_ tIΡͯ N69ѕV;>Ȃtt"+/Fbk/?M'+6m=/‹ut;:K6X]Om㽫;"ȢUUKL_8=7 l5f4=<^:C=f_3@W7.k]_n\8~v#4.r} ]A:̒BB_7uO>\}B?hM+\坩OڥKOk]<ֹ/}ê|"MyNsduXOw殏lZ7gҜ5DxA^7BƳ? v{hIćfYeA9S:sV-]{'{74XݶxK,;}DqޢM+M`WW잶%絮]tU ̚;10{#2Sp݂Yg#G΍ _?=V 40|i87;m| /Mx /Kمxbu|^{#ƯjsuCAN|t}|_wWdژD7&Ʒn̟Ya#5Hl}%?LA=dwkl̅kUWEZ' !3;:u3?T^ԕ~g%Jnߞۦ,lzsݒ\.Ϗ$[>޵mnyޔ5V/OUYzҢ|ONmxla,| [^N՗go޸r /'Ƿ^8kFW4M\D_oWzަkW\yl$:6w3 t?|K'[sͦvx]3 }<`ъC3fΎX?oҿ^3]grelDdt̩+&%`ևN7;Q )=Y3N ;PiPjk_=<|f}J_ٛ&Oٲq|Mre}mWdz/uU1]Bʼn 2\pD}`vE%7};ݛmA=_/xٜ ;mJlْ޷t9XZ}}C; %?M*tgpA.h->5VZQG{ڰjY?<'ڻg}.ܳ;SLv~pAsn׿"!\Hz4?/꒵ד7_:oecm,XزOs 9; |uc~ǚ }fYd/j^17V/t浱ȵOlZ۴etKiq9ٰyŚƿ7E@\LM{7K(8.qIoQ}6`S^~ػ'7<_~_zg|H9LWF޷GI%:S}V>H߫Sѿ)LW2wO9PܢPi_.z8wSO'JIK 95Ӎ).8R>"dz'!*72?O.[[_U_Y:o] /D;꿯iz?BSǭlo5og(dޔߊ^y:B7"atAptڏ@ƁIӣV$OvIΛ7uѤ '"5gDN1iѫ [ŧ%wG" tF7oVIuq=s[Fz ϛ2uWE7yR4fO΋&.\jWm9c鳧Y # gmZ|gϞ>eΌE"n1%6m]qٴ'>yIbYkV7,lm;+i5gNz&m\պlYlͬY/_]f~ij6<]@#Hs[[\;5v[Ƀ ;7MgmzFۢWy/|_Z.:׾=x% N76O?{6Zlps}w"g&ўrsiC9Nr<s3ۑD{siKڧi85/B%}Z8~|/o٠}]w}3Hp[ϩCS{Ϲ^j8+Lh[ ;1]xuDԞp]ɦ_ѝsuY[FUj#ݝ6W([.[XO5N8i)YXmM.4]lޚ'Z>i'a1pFzuc8' k{m};&͛2kꌙSxwO6wYՂ+X9 N7qj]$8iM.YY5dItx ̚6o]MK>z'O|dKljN9KeAmZ:ۿ~wCD7?4/ N鹦9aۼpzjrC[74DZц٫gRCN:X? 5l877-6a b;ưÖ8&0]؍O}s"?pQCX9ZajaWؑKRq^ī%WZ*~ {o1rq}C>8GŏZZul/K#1rO|] aid"S3ijijMEVZ:z1=G6ś! qRwn1%Gr> .:6J/@|/ѐSFmNgZ>'\/'~S~`ϚB!S)d+9caԏttt̼w1sc>ǘ1s 6pC|-؊m18&0)[vnq$'9`V籈8I-%ǁpm3exGl9۴1K_2+*"~ /;k_k5:^7-7w&Gx3~bn܃{q|xމw~|⃮!|GQqrrT:)񸖧ψE#~?_m]{q00? 8g"sc}>On>On|2Pd8dMS'IqJ%NRp E{vo/uȨ{mnJ7L)vgU 1?owD!C?7 pC q-G6p \nCr]dO܁΀l7F-qn 0[۴c8 Lb]ⴸ[͊s<7{ז? K؏^IJmb[XM G.o͘/v ;/ ջ/j-U~Mހ;x-omvn܃{q\x-ߋmy‡+qWWZcx\g ?"'*4s\-~G=lāqXOn \4gggh_ ŋ˽gZ:zP-q]~|5=0Niqr₸(vw/8p׀k_Waw ƽxlva1 N|* 6tk8mi7N{00VO_n?{3G!wln`ʳa8YI܂ئ]{1ILپKw3s籈7װY9۰8VVp+ck8]uxxgrxi6{2J _«xc ^_ů:o m79Λ=1ߊn܃{qۼvĻmo~|x‡QyL8Zާ?Z?#~{_r_GW?~^S_T|F:o:o+~O<.ݵYo6S3ijijsc58]x<B"rḿ:z[6c=}j8&0)4f!~WEj_ PW_ Zj|3_m|5؆6fڬGW\/}_m|5z5ícV6f3yf3xKxf5ꦆ^݄-؊8&0]؍g9q؋:ex9^خī%U~xߌ-^%ލ{p/O?,>Oh9*~~^Gc|X|rT$>?ħY|_'*4s|K6{8NblEl1"{i=[Ȟ-A 9ÅW`T%xxxxGxȏ-F[#-cňw"? RDxNbv#-F[lty87`W0j f >/x_—G O){>gu?_8+~O<.u[Xn mughC|%Cgh mܠMn zhIn !׊׉׋wbڂ55|hSɷ6|hSշ6}[$k9q2~ M&m*6-5O<ަo&y<܆R<Ɲw #4;6吘 -A?7ǧ c16=6=6=6=6=v=vzfdͿF8@ݨ]Qvv<]=n,(\;idL|xW/w _Mހ;1=~͖x'ޅ<:C>x1<Q|R1| i|_2''*r_T|Fۍ,o7nܾRqv#K}=xxx=< $va~</Ŀ Ni7<':P큆Wh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4Mh2F1d&c4A4AF;(2;vPfevy2`_@!q^W#Gۂ+١ԡgԡgAal`c; vs=ws=ws=ws@=~ގwxxޏA|q#'1[>%!x_W$Ė){~M|ZSqX#u0.aDXDmwI<B"qS=02١a|C?z;z;1vPoG`oz:F: tQ0ء1d=====N: t~0|qXeu 4NٝF:fw4iܯӸ_'g̝jNc:v՝WwtZ]?N~YMހ;x}ތ-˧=~͖x'ޅ<:C>x^=Oǵ<-~F"ed>Eo)#)KO^J8HQ`J%R)5@JO)?%ק)JOS*?O]~eN˜`9.s] vjNq.a9u2œu] r^8ī%U~x Yq}oxމw~|}'q|EG(>hy)񸖧ψ_2''|OiyM|ZS񛾯b8m,8g8g8g8g8gwk;p0^'^/`HLt36fm̤ۘI1nc&Lt3VwV{w6}F;-4<06ѭ>{n{ncOFQdd22BFF!##dd22BFF!̘_ȸ+3ʌ2cuqƽqofr3㗛X qfܡsmwhqfA%PוֹGl3]q^Hv%/˵WJWUE^xWZ*~ o~v܋p?Lo;N v^ >h!|qlcs?#cvg|Q |I_X|R|J|ssca3"#f"S#f"3ijij/+3~SkʌQfߧgd:0#GgT:&y ?X1o&*c$cMTƼIƚy5Q&~'3`3V5gfj=c 6#gxQF~eFX3<*#g\^y?3e8jF QfxWLMwedT`AFmQdԴia2*ceTʨQ+z~y8%zzzzT=z=z=VJCzzT#=}=c'{i)a?xT6cZw8Njq|/~2YpWUE^_5_ïux=~x#~o]n܃{qxމwߋ]C>c+pا'?鳎Sq-O?j/j9/iyY#+Ob?)-O*>#~ݻ~7-|ðڣ8[}؞xxxxx#Q5D////&\eW׈׊׉׋݃RJGԣ:`=fz"Eu7/{{)hsHS_M~߷468UѿN=״Br,r*k69k8vʚΚdUA%i)a?xuЫC`Gqm_LgU8Y.YNz '%j&ɪmj&k7k&7k&7k&7k&7k&7k&7 Ny7m;.gGY뚲5ekZה)ʹrlsyN69<'dlsyN69<'dlsyN69<'dlsdlsyN6ϹCsyN69i}syN6ϹOsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsy'dlsyN69<'dlsyN69<'dlsyN6qlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'dlsyN69<'PN6sBAPG(#.X]f`v1̂1̂˂GPpܿ=GP#( z=;-,C F2 Ђ̂5k l. wVA_* Y}^@cA/`챠P0X0WXpO.{,X]0Xf``vc킱ǂĂ5}5H`A_0X0'Xp )3Eٹ(;e\\sTsQv.Eٹ(;e(;}Eٹ(;e\sQv.Eٹ(;e\sQv.EZQv.Eٹ(;e\sQv.Eٹ(;e\te\sQv.Eٹ(;e碻..Eٹ(;e\sQv.Eٹ(;e\sQv.Eٹ(;e\sQv.Eٹ(;e\s](;Eٹ(;e\sQv.Eٹ(;e{/E~Qv.sQv.Eٹ(;e\sQv.Eٹ(;e\se")ER<(;e\sQv.Eٹ(;9IQv.Eٹ(;e\sQv.Eٹ(;e\sQv.Eٹ(;e\sQv.Eٹ(;9Oe\soC8ka8\mzr^nmzr^ngzL/3{LQ^>Lr},+ {"뵊*^z,-lS^(v{N @ކk[^WUE^_k+x-~_z~7Fnrq}oxމw{>ku‡W1|ܖ}|BQc >/x_—G OOU<劽&>-u|K^U?~zVJ^zgZ;k< ^㙽^σUzTJzU2*^ӫ \(. $va6Ӥ{s5k8gq^.k r^zPφ{EׯTzyQ_zSZzBj^ԫK|WE5;3ݹ3/.,6{f=́cp8\kZZl6[9#Vmx;`Gqmg 6AlVlḰ^8o]s7mu;ށw]x{^ >!|q:ć}/ mB߾5=~s y=nt姸~9Ccm͞Tٓ7{RfOg[} %o _~-wyn܃{qǻA‡a|Ğ?&>l#xOi cW&PHHWBP ٢oEp27($wY g_ SGQ}A[‡a|īb<8>"<47|+|P}G}G}ܧSi1T}WWZ\;0InOX9T }ѰԧZD>uByTQ{Q{W~knaQ{Q{ K2~I/%$J^KK^26XK2~I/%dueI/ɒ%>Y%ddKV dOdOdOd_K2~I/%$d_K2~I/Y-PZd@jу_2P%~[%$d_K2~I/%$T%wI]K2~I/Qx```I/%$d_K2~*Ē_K2~(YPd @V[/u@J~PK~ PK2~I/QxI/%$yK^($d_K2~/y?'~:~Nޯ~N鼟s~NOs~N9y?'@a|oվq}oYx'ޅn[#<>#QW1aG( >x_W$x7W6s~N9y?'~:~:7B9y?'s~N9y p~N鼟s~:t9y?':OtO~N9y?'qƠ-AO\~IJW+U<p'P x8Zw=`h@};2P LT&*ɀd@e22P LT&|{@e22P LT&*u:y@m.4`zWȀjd@52Po^=T*J{@=.=0:d`š?<允iC6hfZÑA;HwX~ k@? X͐J;mA5ƠQA2mQ6ӲwŸ/KmryҲ^܇6;.p8!>8GŏQ}ݍ{p/xގwxxޏA|1‡a|u䏉#xq|E}‡a|<*~L|X|1{8s<'e|O){8gM6]ƻծjau8d@!"\]kq=n}|rOa>9' vX;*a4`:vX;'0|rXM;Viմja5vXM[UɪWU*We_WUUp~~sVJUU[ުWUUU|UUY*We*Ve,_嫲|UURoz[U_UWUUY*We,_嫲|UUWUUWUUp4\᪌_2~UƯ*_*VJURoz_URoz|z_UYJUmVjUJUZjVZ*ViJ5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5ZjVkZhF5Z1#T:bm̈ӈyc#fGF͎FFFFFT#*9s#ƌF164B#T:B#T:B#T:O4QC!GԐ#1#uPu15bjX>ˈc#<"/ŌŌŌŌ譌#,<" GT#*pDe8" X3bm̈1#ƌX32bsDeDeDyGdwDQ GT#FPFPFPFPFPR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:)N!u SHBR:d̨:]f!GBQQc2 UjjU{ G p; yK2oղK^܇6[ގwx<!|GQcڏ3>/ |_·]w9|ը\53j~gΨyQ%GK[GeQpT/xTGQypTG5>jn}Qs룞75jvr3F8F GeQ=Q=QFjtԪQkHF='jsF='jsF='jm|mͯ*qmf3f6s'Fx6z9WGqi8Im 2'j]ٍ{p/x-o;N =x/އxx1g9|_2'3}! Cfq9mVmmͳ9fdm9F-<)qg$n15Zc1c#cj15uAc9fćSO|iϿ-~W0|Lvd1m'ncۘ6&10xO c'G6STcc،ncۘ6&ncX>e1mLvP yL+__%|ſU?oM+ni_};v}M?GYRf)/)QR2HUN9n:JY]cS)ؔyl<6e2%HIIIIIIXR<ⱔUzRV)ؔyl<6**********Ł)Lq`z)eJ^JY Rf)YAʬ eV2+H,K,K,K,KYRK)71ō)nLqcSܘO9r$+HVg_ʑC|\q+e/ ez2=HY/R<ɔIB$!e^JWʕRĕr%+q[As˷or-r$#Yɺuv.f]7[>bGQOWoݸ%2c{cNl9+{/Lˑˉʙz.sy%r)WYˍ^ϓ|Z>#/˯ E|Y"_x7o{rŹ[8wn-Gn9 vQ[˷o-e/[{{oq-t_-GnH޽fW r|wom߲e=hҘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc24&ӘLc2@G3`2 &3g*3g`/{ePq?c3#G3g8[oe[oG3x- 2x- 2x-uG3g8^{e^{e^{G3g8q?#\epUWDeATQDeAT֌֌ 2[3* 28⟱___q?~Y˲_H"-,Ҳe,e/~Y˲_̲_Y˲_Yf/~Y˲_e,e/~Y˲_Y4fјEcY4f/,h̢1,h̢1,8̲_E`YfE`YfE`Y˲_e,e/~Y˲_e,eQEiYf/~Y˲_YfjYfe,e/,eQEie,e/,Vc/g(ɜYqά8gVsŒ!g(g–s2s&9㜉q8gb&sr5ka2hiαCLs9S)qΔ8gJ3%ΙLs9S)qΔ8g?(g?(g?(g?(hi9GKsrrr9S)qΔ8gJ3%ΙLs9SC2ǐ9A9s;&g9s㜹q8gn37Ι̍s9ͱhEs9rs#Gαq>s&9WȹA8gbcPCiα\C#9ȹF54'=|p%|ۮ~|wȇ;<{{#=xG}wMnmۺ.mp67|oXmbnȬy^C CX&P= $?!?)?%?-c۔-ٖw|uveOP VFn='ԟO-O}U~M~]~CU&kGMO?Ul_W~P?Mn?ϫA_R7Կ_ν_mo?g|{G~!N[ޥ~a{UO<3^wYa9aܛiÖVK>n?8Pkۮv=nz85Bun6?m~rm;p {|;a^>|D~{K,R|TvH#>|:t>p7|:\>|WpWWpŁW;pUW;pUW;pUGyuAeI~B~R~J~Zޑe[UYuِ^aSd[ueOPsk$r"r&/\^Ʌ\ʕFn=yzBҖgmyZ9gl Y[~N%U|A~M(._ߐ/ozoWo_UG=}:~~kMO?U"/? kT>*\#Voȏʿ)yKeF d(cCy $?!?)?%?-ȲȪɺlc)[-<]ٓ}9gB^˵ȭ/?㙟T?%?k///ɯʯɯoooW;5]=}ߐ?oʟȟʽr?;dCrѡ3c unPuPsOsOsOsI=,Cs}syr9ls̓C9t!:KsvPsPsJbmw٥o:&69tɡMXUnX;Yk(!{GW@OzT>*Gr䮵GZ{䮵G$pdu3G[;-#9b#9b#w=#=rэ[)[n^cޱ@2n]:9,;?=r&Wg׏1KWyUw}]O;ix_tgy]exoK_l+rϦ;PqlO;Owy˖ʜ>5RY5Y y5teOPsɱȩK9Wr!r%ȭO'ŧs?#?/ _ E|Y~S~KUwԯ#wvm1oo"Uu[WwvQmޝ||D~<!?,uٱ{N#v_{5+`̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z2̥e.-#̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z2̥e.-siK\Z22QW2\Z2\Z2̥e.-siK\Z2̥e.-siK+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං n+ං nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nⶊ*nkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆnkᶆn븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:n븭㶎:no 7xwƍ_F 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@q 7P@+ [cG~9c8ǎ8os Ǧ_Ǧ_Ǧ_ǎ;ؕ&]i<&MŎ{cGiƎƎؽ9ޑ^m CD#UY5Y yOɾ3y#993y!/\^Ʌ\ʕr#|B~ƿI)Y[VclWA>kϩ/KeM|3[;e]{U']oؕ&]96u;vؑcSc[Mݎz}?xkwԿ~!||XW>"?$L>PXʱc)ǎcGQM39vcWg?ԙBv;rHȱ#!ǎ4WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WS5WSWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKWKW[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[W[_w]uwwwe_(! u]u]߯z>o˟w_l+oyG=?1?c>nMWw]}z,3t[W[ e,y(<2y (KS,݊ʚˆ<ލɾ3yXNTgT\ȥ\kZnVޓOxןig<_Es/y7*5[^T]<ߒm_So}O~_.$,"uݝ1v ;o_PԿr7;뷪E_S7o߲TwoSAߡۓw}ooL]ɻ]ݴɾw0ܽ?_wY{w,;wwzRc̝y^]W|"Bwc:Sʎ)eǧyǔcJ1RvL);Sʎ)eǔcJ1RvL);Sʎ)eǔcJ1RvL);1Rv|vw|vw|vw|vw|vw|vwL);Sʎ)eǔcJ1RvL);Sʎ)eǔcJ1RvL);Sʎ)eǧmǔcJi1RvL);Sʎ)eǔcJ1RvL);Sʎ)eǔcJ1RvL);Sʎ)eǔcJ1RvL);Sʎ)eǔcJ1RvL);Sʎ)e'cǔcJ1RvL);Sʎ)eǔcJ1RvL);Sʎ)eǔcJyrc'7*g?'5w]nN~'}'}➺'}➺'lvħɍN\]NvS'yw'r(䅼ȭ﫟P?Oɧ+U|]P_z_U>qO>qO>q>qO>q;q?;q?;q?W9qצwm:qצk:q_zi>>qO>qO>q=qM `'??+?7eJޒ]:sNyS8uS>uS:e9̧;rn|̧}̧~h{>xl(:ugS38QS+{/Lˉʙr.B.J^˵ȭjP??%x9e|A(_/W<5_?o73ӟ;;33;33;s;so@>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>DC>D)ܙ)v.k_oʿَ}QQ:3;qS䭟˴xLVߕ=ٗCy&ˉʙK\^Ʌ\ʕȵȭ=~|N~Y~E>/_/ʗ|M@.(ߐo̜̜̜̜̜ g8?C93?<3?<3?+__%|E*_?w_?o7sh?G埻Rk䟻:O[|}||XW>"? ?y?s~sh?G9ϝops~s#VG8G>G8|G8|p>bp>#p>bp>bX}#VG>bX}#V#VG>bp>#X}X}#VG>bX}#VG>bp>#p>#p>#VG>bG8|G8|G8#p>bG8#p>#p>G8|p>#p>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>cq>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>Op>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq>SOq> 3Ϝ4C 3>P=C̹O3TP=C 3>͐<3?Μ4s̹O3ÙsfH9igH!yg(f~3s̹O3sg!pf(hf}hf(hf}eZfft33̌nfF73f}9iܧsf}!dܧBf!d\nf.7C !32C !32Cȅ)ō8 > >0ؑߩGGm{c=&%oiy7+ʞˡ<?c9S9R\ȥ\km-7r+ymKP??%xgs+y|Q$_xWk.(J.p     w} w} wxr텩]*_]*_'_'_'_'_8bwQ͐/̐/̐/̐/̐/.QzflvflvflvflvflvflvflvflvflvflvflvK^(D%]%]%]%]%.uK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6dK6#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9B#d9Br+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+\! !WBBr+,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@! ,@!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D!K,D !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+B !+r}ck \xܟ'p~1%ZWȹk{ȹ~m>n|Sțz?~my(k \yv'p<^oXNTgT\ȥ\kϹ'OOg<ó9e|A(_/W<^o7~ھ}kͯ_wϼ7_駿wGM%=׾}y{׾qys3}_׻W$Fk{֯_h~mڞ]ڕ ]ڕ ]`5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_}5h_} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} 7hߠ} ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhߢ}-ڷhKk.s{h}_k7ow={;_#|T?ݻqKe<浝rjKWd_<#993y\J.R׳'=)|F>+__%|E*_?:_?oxTt;y{Uu?Oks{su~g={@gގB~x;̨e]+ksŞ{sϵzV=wyopߴi}ӆ M3}ӆ i}ӆ M}ӆzuM67mϮMُ#} YM2 V[j-G8Uխŭ^Ź+B+tknmk2 N{"2]HpP&C~n`1YU~fwػ m8nñwp݆c6c3slf1*{p݆c6{ػ m8nñwplm8nñwp݆c6{p݆c6#رc_>}`m8nñwp݆c6ֱwp݆c61jֱwp݆c6{ػ m8nñwD&j5QZMjVD&j5QZMjVD&j5QZMj&j5QZMjVD&j5QZMjVD&j5QZMjVD&j5M`6M`6QZMjVD&j5QZMjVD&j5QZMjVD&j5QZMjVD&j5QZMjV&i&i&iD&j5QZMjVD&j5QZMj։i<{POܱ^[|S6yCQo~[*Y|^ }<ҖG:cHbݷ<9#9939g^'羪za[/&M_zc>NĝOO\;|.?trf]nXYe }#ȏnχ}S3򳾶////˯ȯʯدoooo:+'/k||L>.?Q????Oʧϭ!)%-gsycӴ>h2HuFֱy$[ƿةxd(G[O3I3unwa}zm}iZkta}պ`].Y+UkP uݺa}dRY>I3/~+_噯 +N&f6p}Ͻ-\g}J$?rxxևSaW~iz8u_xq5{f?˞ār$?k?}|L>.'>{˺-CtuNHNL{B.o=;{yCFw! $+^mCB㯑my||#y^tzE^xq}:C[{?xiȋ_4/T>ESMWY5?oN&fֽ}N5SMT>ՄO5</_ɿ:ﳾ[#/?(AQ!1q I)iY9yE%eU5u M-m{a|T>&Oȧ3Y|^ܲn#2Loɉ3sɅRVN^^߼a}Sȭ<;-O;-O;-O;-O<-O5ِ/ 58wt[֯w8OݯT{4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4Cs>4#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đkjji#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ}%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKHKaHK!HKi#i#-q%đ8GZHKi#-q%đ8GZHKi#-q%đ8GZHKic=9f1{s̞c=9f1{s̞c=9f1{s̞c9vsj=9f1{s̞c=9f1{s̞c=9f1{s̞c=9f1{s̞c=9f1{s̞c=9f1{s̞c=9f1{s̞c=9f1{s̞c=9f1{]cWص0fϱ`̞c=9f1{s̞c=9f1{s̞c='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {N\SWӄ='9a {Nsž='9a {Nsž='9a {Nsž='9a {N\='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {Nsž='9a {NPbž1&9a nLsž='9a {Nsž='9a {Nsž='9a {NsʞS=9e){NsʞS=9e){NsʞS=9e){NsʞSW=){N]MS=9e){NsʞS=9e){NsʞS=9e){NsʞS=9e){NsʞS=9e){NsʞS=9e){NsʞS=9e){NsʞS=9e){NsʞS=9eϩbꊘ9uLsʞS=9e){NsʞS=9e){NsʞS=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9cϙkjj=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9cϙ}ƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sƞ3=g9cJs3!ƌ=g9Í{sƞ3=g9c{sƞ3=g9c{sƞ3=g9c{sΞs=9g9{sΞs=9g9{sΞs=9g9{sJ>gϹiΞs=9g9{sΞs=9g9{sΞs=9g9{sΞs=9g9{sΞs=9g9{sΞs=9g9{sΞs=9g9{sΞs=9g9{sΞs=9w]]sœ=箂9{sΞs=9g9{sΞs=9g9{sΞss.loCyƛgyƛgyƘgyƘgyƘgyƕg,yd?oۭ!Éֳv3F;yscS9yE%eU]=}C_þG1|BGXDTL>)j?|Z># ؿv5e葎usz/#O@HDNLW^ȥ'// y׹Xo>Ç3>s3>s73>sO3>sg3Μ;s3>rY⳽[֮;:v9;tgN1sDg|4#9St7n>]֮2'Μ,:s茗xɢ3^>z0/9ewgNR;|xzI맬?sZ.>ۛzzgExny<~3QϜG=sy3QSdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-ERdK-Es{sd;C9¹s#;ws#ܻ v(-w}[#/?9?x{=ay_> Z?}#Gcq|R>?|Z>zlݴnYeGv=ޓ}o@XN\^ȥ_xMKyx78???;s#;v]箾sݹ+ܵv*;w}]S~Gj:]!ιv9C?;ܮ~Nܵp*87&|?2xvgxvgxvf3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3WV\Ykgvڙ++seevkgvkgvkgvkgvkg茵3X;c팵3X;c팵3X;c팵3X;c팵3X;sEg3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c팵3X;c̵vkgvkgvkgvkgvkgvkgvkg葱v!kgHv'kgv-kgvkgMd!OkgvkgvkgvkgvTkgxvZkgؕvkgvevkg`-X{ ^`k/X{ ^`k/X{ ^`[ز`k/X{ lY`5`k/X{ ^`k/X{ ^`k/X{_k| ^`k/X{ ^`k/X{ ^k/X{ ^`k/X{ ^o[lZk/X{:Zk/\5 ^`k/\ W/Lf{ ^vnsY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sWV]Y9k笝vڹ++we嬝v9k笝v9k笝v9k笝v9k笝v9k蜵sY;g휵sY;g휵sY;g휵sY;g휵sY;wEsY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;g휵sY;gܵv9k笝v9k笝v9k笝v9k笝v9k笝v9k爑v9k葳v!9kHv'9k稒v-9kv9k笝M9䬝#O9kv9k笝v9k笝v9k笝vT9kxvZ9kؕv9k笝v9嬝v9k笽d%-Y{K^d%k/Y{K^d%k/Y{K^b[زd%k/Y{KlYb5d%k/Y{K^d%k/Y{K^d%k/Y{_Ɨk|K^d%k/Y{K^d%k/Y{K^%k/Y{K^d%k/Y{K^o[▮lZ%k/Y{:Z%k/]5K^d%k/] KW/Mf{K^}w_gY>|w/|w/|l_ U.E<_pW^W^I0xezWBx+^! y^^^^^BBxeWfxeWfxeWfxeWfxeWfx|ɨ3Q W>Ƈ+/VN_Xە]ە]鋕+/V~ wX oWx2+] X+/VN_X9}V~wXꕩ^ꕩ^9}rb鋕7]Y>tSY>7s7;{pgvn؍pӿw{=ay~|@>77ww>#Q|\>!????Oʟ____˧3gsyy쳴d[vuu,{I9c9sy晩~ˬPo/~+_ejX+ ַYn}~ͤ;SXn7X~ n 冻^n W W WӍ-7]/7o9妝M3s?}[yi?g?d}W#??>"G>'gI//_ó9|Aʛ--;z/Mȡ˩s yOCeYVὠWHL9io~GMsw;zns=]O}=kws?{G>w=)|V>'/xuD򺏍d,?#93y9<::^Z'//ݰ)RnV=@c]ھunTk׵{Ra·_;v>|UkwZ*[vmݽj ]{7i} ַY+wX+wZ+o6Ϛʟ˻yv&v}[}}ǮjwխjnWkwZtkZ#jmv5kkkv/zO`w{X Ե.yr;[y)_}\}\j\[__Qacyz##Q|\>!,"*&Oy͟[BRJZ>-_ϱuӺeݖ =ٗ&]PTWXȥ5ߔ^z?~~~~romu#2G>՞q\q\q\q\q\q\KKKt]uv͗luK;K{K{K;K;K;K;Kydw{=KKKKK mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6+eJٸR6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6 m\e^۸6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^چ6 mxmk^۸7 mxmk^چ6 mxmk^چ6 mxmk^چ6 mpck^چ׶-mymk[^ږ׶-mymk[^ږ׶-mymjݺZ֭uk[^ږ׶-mymk[^ږ׶-mymk[^ږ׶-mymk[Wܖ׶-mymk[^ږ׶-mymk[^ږ׶-mymk[^ږ׶-mymk[^ږ׶-mymk[^ږ׶5[^ږ׶-mymk[^ږ׶-mymk>-mymk[^ږ׶xmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^Εs\);Wʎvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^ڎv㵝lk;Wَvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;^ڎvxmk;vxmk;^ڎvxmk;^ڎvxmk;^ڎvnxmk;^v?Ȱ>dk<"_+㯳~|Gn]!(o~[jg>;]<ޓao>yk_~P+{GCG>.?!?)?%?-?㙟Q________ߐߔߒߖY+'/ 9Og9|3'2}l$cxɉ3Iɬֹ;{yMr#rwy2h].[WפI>a/9hGɗWWJ >M |m&@}idاybd]<Ȱn.a} Õ| >?(S'id~_'i9a@}CȰϻ=@?%{ oo_}GF<\/9kG&.!)%-5<"GcS3|Z>+V>'/Ӧlmّ=ޕeO&/r(r*Lܿpfέ}d]6||Wy9_n WZ_)]QI!%0?/_y;bkޗ>LK"X+r|-շ^rՄ^=Y^=_W{n{G/? ?(?$>Az֫=>þG1|B,"*&Oɟ____˧3gsyߴi۲#^'ˁʱʹ< !߳㇝>˲*ouy$_&G\RNA.($"w'_wpag't'W0WMUx;}~X'ؕY-iд4-iM hZ@д4-д`J hZ@gM hZ@д4-iM hZ@д4-iM hZ@д4-iM hZ@д4--iM hZ@д4-iM hZ@д4-iM hZ@д` hZ@д4-iM hZ04-LuM hZ@д` hZ@д4-iд` fp镢,gL񳈟E,g?YϢ+g?Y"~񳈟EY"~񳈟EY"~񳈟E,g?Y"~񳈟E,g?Y"~񳈟E,g?YϢ+g񳈟E,g?Y"~񳈟E,g?Y"~hƊY"~񳈟E,g?Y"~hhҊY"~񳈟E,"~񳈟E,g?Y"~hfhY"~񳈟E,g?Y2%,~𳄟%,g ?KY~𳄟%3\~Li ?KYϒ,g ?KY~𳄟%,g ?KY~𳄟%,g ?KY~𳄟%,g ?KY~𳄟%3\2%,g ?KY~𳄟%,g ?KY~𳄟%,g ?KY~v ?KY~𳄟%,g ?K&%\ϒ.g ?KY~s ?KY~𳄟%,~p l&Y6e,g?Y2~lY2~񳌟e,gd񳌟e,g|񳌟e,g?Y2~񳌟e,g?Y2~񳌟e,g?Y2~lY6e,g?Y2~񳌟e,g?Y2~񳌟e,2~񳌟e,g?Y2~񳌟e,y+2~񳌟e,g?歌e,g?Y2~񳌟e,+2~񳌟e,g?Y2~Vj?+fg?+Y ~V𳂟g W𳂟SZ ~Vb>+Y ~V𳂟g?+Y ~V𳂟g?+Y ~V𳂟g?+Y ~V𳂟g WLo?+Y ~V𳂟g?+Y ~V𳂟g?+Y ~V𳂟] ~V𳂟g?+YϊIg5'v M.oooof6[C%)ҟ[>(?*}\~B~R~J~Z~|N~^~A~Q~I~Y~E~U~W~O~_>l|T>&OeݖG:ֿ:r$'r&=g!!r#[ |?$\=kKpw 5v }F#;m.?Bk绬~5kk=kݿ}kѿvɀ}s{?p>û~Bwuy{}{<ևzٗ}{?x{?l}> _#>ۭz}D>*'SV>'/xcu۲#B. 7M/<UYeYz8'ϗWW{u vF&yЭ9':~y[?e:|mڧِ}_ɹ jn5q{SVO/g jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![ jVCՐl5d![TLuTאlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud#[VG:Ցlud:Ցlud#[@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [@5l dk [alGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGvlGf #d;B#d;B#d;Bz䥇Ϻ_mOk7Fy||||m>ۭ!)J|||y~AyO/ʏɏɏOOOO////˯ȯʯɯoooo,ߕߓߗ??G1|B>%Xxu[X_?G,KY{\1^Nr3{=szZ==P^X9^Ѩ2Z^J199'gpYf\;""1 rӄ`"?zwzfoOmG'nS3z?}>HG18}O?g賹#!?ϧ//)} =;5OEq(.RQ:,?S^ȟϔg3Ly!?HIX'Ӿx NswXWV!sW֡^2N_ Tlꓩ5_9W}:ܔO<5YÝ5YS]S]S]S]C5$Z4'ZG`Mf }IFNS/ӷз6th EtD/Ket.^I2jz ^^/vF7ћ-p+Aw{>#ȩз97?[M |Bzы%>Rzݦc:tNtIWJz^C F{ū Gzķw{>zyPa#'=%~{twZwZwPa5q3š$k>jMFߣ}n=Fߣ}n=Fߣ}n=Qǽ={dzE@ЧiL OW]3=9EZ[*!&~sbwU#+h*weZ[pǶRPQ)TT **JAERPQ)TT **JA-(ȺY \_ނ[pRpRpRw2uz@hXz\FBv뛼'swLO&oo5m46J_3,%2=KBJFϣߠ?ҿC |Bzы%6)9ڮxNtIWJzc^M| 7z&}#7oq[GzFT|gGcq/Si +T,(SZUεP"q~UpUpUpUP*d5n\Ը e *]2(;EeZ!8W4W4W4W4W4W4W4W4(EuM[uMY\uM\Ae2VpFWP+`MA}쮠JV3#zYᐑ8\ n T8¦!VZ UpfXpfXpfXp|WLOSiםغu[WXׅ eݵϺuYeݵzU79I|b$Yweoo74s#":ә_ez-Α ѻn7?DO=ȿ?%~ZLrͯ5]kXwb5źkupn[nlefD7Ⱥnu @]MYw:buĺuppjɎi[-V:ޭ Y'd]OȺ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 6@ 4 0@ 4 0@ k8@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 81ĀN 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ Y%@@n 0a4 &@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 0@ 4 @~ 4 0@ 4 аE4,a hXD"ѰEYE4,a hXD"Ѱ(ѰE4,a hXD"ѰE4,a hX"yȃE4,a hXD"ѰE4,a hXD"ѰE4,a hXD"ѰE4,ZE+hҢYD"ѰE4,a hXD"ѰE4,a hXZVKj)a hXD"0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0Dк 0D C4 0D C4 0D0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D CN 91ĐC4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0DPV 0[B4 e Cy&DP 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C4 0D C-B-D C4 0D C4,a KhXBа%4,aIV)a KhXBа%4,$%4,a KhXBа%4,a KhXBxă%,` KhXBа%4,a KhXBа%4,a KhXBа%4,a KmɊ-Y%d}а%4,a KhXBа%4,a KhXBRZJhXBа%4ܛ3Sbٿ4^ثCc@աWތ˴*:mЦ-q[go46g百ȑ(:z3x&o >ќ,}W^C{ݥ݋q{4O{ۿ@Og3Yl38_sWWy|&kmtH/8@/^_J/tLth9]%]+U&Wk:z>&}#7nq#m? ]n#*W3}#?,~Dw=FOy^={3gG7y_(~Ӽa;k{z%CŇ{pZ0@\⒘Y^wHN{ܒlj/ݱ`~ݱW_ތqVo#؛e<+!Ų::, ez^~&!>9w3}:ڗCy>1اb}9,n_2p&s-} m0sh?W=so3}Zʎ\j;/ X8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T.T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ2NqSe*T8UƩ#\=oWOG=3Gx&_q_v/;WSگy~jG*ץ_~UYV;9EzqƏoo'9)"l_Vٯ³?L.>ͷoz:=IϢg{[ҡ#_;ҋ^L/1Rzݦc:3KtAtEW5Zz~׿F~?0G?[&]|'C}?$~X8wٻ2|"߽'?Xkztp<ǡ$> m I*U?ٯ~_d~ y^U/ݯw:~c+XQ5fTkUkUkUQ_ᝊ}*:+:+vc؍b7nQ* OUTM+x9\Q4JEݲnYQ[V-+]^]^]^]^]^]^3TzUzUzUzUzUzU.pAS-5Z**ˊZeE?XE?XE?XE?XE?XE?XE?XE?XE?XE?XERQo链oOѧic_]_KC. 4TP9V9V9V9VLE]XQKT튵]+vڮT<)SDUųTOQUtUIMhRG:Ѥ&u4IMhRG:Ѥ&u4IMhRG:Ѥ&u4IMhRG:Ѥ&u4IMhRG:Ѥ&u4IMhRG:Ѥqus\WG:Ѥ&u4IMhRG:&u4IMhRG:Ѥ_uW@4Ф& 4iIMh4Ф; 4iIMh@4Ф& 4iIM<@4x& 4iIMh@4Ф& 4iIMh@4Ф& 4iIMh@4 .hpAMh@4Ф& 4iIMh@4Ф& 4iIMh@4Ф& 4iIMh@4Ф& 4iIMh@4Ф& 4iX kam7통@4Ф& 4iIMh@U@4Ф& 4iIMh@4Ф& a7ްڛhD&4Ѥ&M4iIMhD&4Ѥ&M4iI/h&4Ѥ&M4iIMhҴhDD&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M>jQ|D&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M4iIMhD&4Ѥ&M4iI&59&M4iIMhD&4Ѥ&M4i]MhD&4Ѥ&M4iI&5&-4iI MZhBФ5-4iIwZhBФ&-4iI MZhBx&-4iT MZhBФ&-4iI MZhBФ&-4iI MZhBФ&-4iqA Z\Ф&-4iI MZhBФ&-4iI MZhBФ&-4iI MZhBФ&-4iI MZhBФ&-4iI MZhҲ[vnY-k&-4iI MZhBФ&-&-4iI MZhBФ&-4iI MZV{joY-eѤ&m4iIMhF6Ѥ&m4iIMhF6_Ѥm4iIMhF6ѤmѤ&m+&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIM|6&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIMhF6Ѥ&m4iIMhF6ǵ9qmks\MhF6Ѥ&m4iIMh6Ѥ&m4iIMhF6_mjWM:hAtФ&4Ik:hAtФ&4IM:hAtФ&4TM:htФ&4IM:hAtФ&4IM:hAtФ&4IM:ht4IM:hAtФ&4IM:hAtФ&4IM:hAtФ&4IM:hAtФ&4IM:hAtФcmw펵ݱ;vM:hAtФ&4IM:VuM:hAtФ&4IM:hAtޱ;V{j$BM"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BOEz"=BHPG(£HPG(#RJHPG(BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPHPG(#Ez"=BHPG(#Ez"=BHPG(#p3#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHPG(#Ez"=BHP f/l6E7u#~Id~9yFF2}cGo2':IysNoo5vsN݆F.0r^H/#z1^J/tLttAtEW>WkzFsn7[vczE!}|>8isO!7Cn8pqP+A/5 }:߰7 c7n?v-{kF\/!o$ 7nXVUan.uw]]xŻ.uw]]xŻ.uw]]xŻ.uw]]x׵v]x׵xŻ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.w1]]q]b\Ÿ.u1q]b\Ÿ.u1q]b\Ÿ.u1q]yq]٣+{te.u1n9|΋Nʦ̦)l*j5ʦ)l'ɦ|)ll'vݴ?7LigM՞MOlfy&Gѣ<)MOlڡwy}3=DOx쯴γ MO@of&/Lz=~~Cϥ___o7_oӿ[ ҋ^L/1Rzݦc:3KtAtEW[]Mn5F~?B#Fo??wһSz/OA{Pa#Gŏ链O@)lxSٴ𦜳iM9g>*Q Sbz(==4xu7]ox5=7M;of'2O5ڠ-PmPmPmPmPmPm<*T2Ϧ̳y[#?Ϧ7M;ox7]om~Sڴ\)my~3Hٷ󦧞7_Wh7_p2JߒƷu[/IG{W7쮰\e[vWrf%l'[ɖ|%l'[ɖJז|%l9or޲e,":K2MtJgt.^IWk:z 7ћ-Vz;1I{}|>B0$-}4??r~k[\_[S[ܴG[5[)[<[߲좿| -lY[վeoY[ne9߷-+yJ޲cQ8FcQ8FcQ8FcQ8FcQ8FcQ8FcQ8Fᘛbn)榘b&暘kb&暘kb&cQ8FcQ8FcQ8FcQ8FcQ8FcQ8FcQ8FcQ8Fc8☋c.8☋c.8☋c.8FcQ8FcQ8FcQ8c;FcQ8c9=Fc>Fc FXQ8 bQ8FcQ8Fcec!FXQ8+becy#FXQ8CbQ8Obec%FXQ8FcQ8FcQ8FcQ8FcQ8FXQ8bQ8becy)FXvQ8becQ8Fc+b+b=p{(ܓ7zFO=y=p{(ܓOzIO>'=' 䓞|C P=p{(C ǿ=o{ǿ=o{(C P=p{(Cǡ=pC{Wǃ=]{(C P=ZzOG=qM_z P=p{(C P=p z{V~ϚY=g Pg%䞕ܳ{Vr '(p '(p '(p '(p '(p '(p '(pSM 7%ܔpS $\pM5 $\pM $\p '(p '(p '(p '(p '(p '(p '(p '(p '\pq '\pq '\pq '(p '(p '(p 'p w'(x ''}/哾|G|җO(G> Q}p(G>Ͽ}o>Ͽ}o(G> Q}p(>9}shC>?y}}p(G> Q}^sY>7A}KS Q}p(G> Q}sAp[}oG> 侕ܷVrJ}́~sKp`΁;vرs`΁;vرs`΁;vرs`>y;@ށ>Eyi`}2's`́}2's`́}2~s1~s188 8hAp@zX]|z`_ʁ})؅r`ɁvYh`Ɂ'vsr`Ɂ}&v[r`WɁ$v+r`ȁ!v|1~s1~s12ct% >@oct( t 8Ч4;8^88ny`罁vس(l1ljݦS獩yc1uƘf6WU\uڠ-ڡn.ݢa*ϧ|*ϧRy;S;}[?ͫ=@Og3YKez=~~~GA^ EtD/y)n1]: +z%o{cDof-Jo??wһSz/>}>j18/{MΦRQ3ԹS*r{*r{(S>SoϾsK%Sg/yK%Sy;k}_K~/F;鉃No'o'z=ګwXz={,>A|ⳏR>r2=}翲[y?4r":K|ʥ2MtJgftAtEWy5^KݮA|GNLwһ=^z}')4}&|/Lϣϧ/9#r]|7ԃoʵD#hhhnrwp{OY=e#SQΨ!| X3/f_-dY֜#Q웜Hgz9743}cqx&s,>A|ddz =O={Bzы%{)n1ҙ9]%]+Uf^MzNzKk?DOґ+~J4}&׼G:C{3=|흐LD#hhhn8ΖG=ҙLJX yt?1<09_|_ăO{Owdz =G2ī<{w?`Wӥ)^ej5Zz@KoYm@| !A)g]mSz/ONA>9FR+>j]?.~>ICO?g<~s= 9$牟/~%P׌i+mww_)~ϼ׈_+>R|h1 Fzoxx h|=]E3gIe9sWS&>Ou7w}S-6hC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e 02PC`( e2 p@8e3TMt^2B<3:K)^Wf p@8e|FL@o?x y|Io?.zW?>zw\ }Ca#x/Q3M.gqy>i73lgy ׃YYG'~◘5#//3ǫrZ4 s4w +9«ůV|(zC7cqxz"=콧OC;Ȼ+~PՇ|X_?*7 #'şwNy3OQ|={-s:Wkw}Km7w<w^JtJgtN ,qJWk\'`|_|[mGe|?ȝ,{O}~.}ȃ}#_+>jď_ww'#i9\dϣϧ//1P//3G\/E6oЮ-ڣWI2hu }7zXq'ODOS;s;34#I?y_?*'g SO?C?K?G?_/3z%>[%ϥ_񮯊&>Ou7oo6F?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?x#G?mmL/o1+ۼۼۙt%N*GZ| 6;ٖe,#u|߫7 Fd}?.sCJ&]?>`AyīǶmy`[`[ؖmy`;>8O'FO3le/el:l-lYjN~;i+M# -lY?1}J*}5} }-=峎Y7x>8'ғe<>UGsNrwy7}}/}#N3A!Q1?'şڜ ={-s:W|:牿.|-m{c\?1׏qcǼ?1ycs\?1qcs\?1׏~csǸ?1~cs>1}cǸ?1}c>1qc~ǜ>19}cǸ?1~cǸ?1qcs\?1׏qc\?1׏~cǸ?1qcǸ?1~csǜ>1qcNsǸ?1qcǸ?1qcǼ?1qcǸ?1qcǸ?1ycQQQQQQQQɼw^!e wTvTvTvTvTvTvpGoGowdQWfcAj^ɼM?3}~#=s6#Ҝ_EQM5w>qy>i7⧼;#O?g|y;Y#N#, /1P׌i+iȧlxkdy`wQ@>׈_+>R|=gCǚs<=1O4~;;~;~;~;~;s}w+~u?(KVDW⏊?fşށO??ks{. z%>[%ϥ_7>[oӿOğ '?A Oğ '?A Oğ '?A Oğp'?A Oğ '?A Oğ '?A O~ '?A Oğ '?A Oğ '? Oğ '?A ONp'?A Oğ '?A Oğ '?A Oğ '? O~ğp'\?A Oğ '? Oğ '?A Oğ '?A Oğ '?A Oğ '?A O} '?A Oe,\:rw/z[7̕9ˢg{,{Nz/Ӈ_9£mƟ䚭lu~yγJG5F_J_Fx@_N˭]^h}+Gc1Wg19N|z9' <[y|8|yQqWO?%oY3?'>ëgz,/,>G|w}w] aN+2<~h^"#Bo1W #S:s++Uyzm"B_Oo0]z^@| !̟s%ק/~>hC#JW-8}>ylf՛$~Y_(~9Ki+hFtv홟>}%}W_M_K2~# P{ P{BN"sA'lw?7Nq^{";]FCgŧҿ4!aG%cf~~@Iğ63)>K|K/+W_'}7ߢtkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^ڔצ6)MymkS^lT6f*3Lec1S٘hho7f3+L}c1Sߘo7f:f3̕L}c1Sߘoјhhhhhot4t4t4t4t4t4t4t4t4t4t4\\t47f:f:f:f:fwf:f:f:f:f:f:f:f:f:f:f:f:f:fzf:f:f:fzf3M3LGLGUULGLGLGLGLGL}c1s34Sߘo\\4f:fj3M35+++kkkLec1S٘hlt4T6f:fwf:f*3M3;3M35f:fnT6f:f:f:f:f:f*3;3M3;3LGLGLGLGLGLGLGLGLGLGLGLGLGLc1ѴֱֱֱֱֱֱֱֱʱʱʱʱsFƮƮƮn_eznz)oſy1EQsM5w>A4O?мvv8Żjs9/{i+oKhbUFI2h?z=IܡCT;74i^yUsUmUmܗOO?#^z:"=ëgzY_Y|\BFNϧ%6ͫ smh;Wmmh;?0mh;G9=A0G9v^1G9nss]scs̝cs;9=A0s9͹o}sOyp΃sOyp΃sOG;{` 9?ΝqΏs8ǹ*ʜΖ {`ΕsO=A09oys,zΡs{`>g sssssO9wιsΝ{`s{`>39=A0wa s̝ss\<9Ϲx '#u̝]u̝]=A0wOa 'ή;y*sOU 8;9=A0'>Fs]sgs]sgs]sgsO̝iqvs` ]gmh@.d.v ]]mhpU.I\`s$.0p?q D ] yȻp@ޅ<:::BX y`h!,䁅<:BX Z Z UӅ<BX y`!,t-t-t-䁅<BX :H@{ D _B=ą{ :@/P{ u/i@/| _=ą/x _B-w D ܅Z:ȾpeA@/P~ D /x g _ Z{Apphhz W _pphBÅ _/xhb@/xTZk-յTZk-յZKuR]kTZKuR]k),յZKuR]kTZk-յZKuR]kTZk-յZKuR]kTZk-xTZR]kDꥺR]kTZrR]kTZk-յZKuR]k%?.յZKuR]kTZR]kTZk-յZKuR]kTZk-յZKu%-յܷTZk-յȻTZ"R]kTZrR]kTZk-vTZk-յZKuR]kTZk-յZKu֒ZK[k-յZKuR]kTZk-յZK[k-9n严mZKuήpv+]! aWr=r~+] gWjW8ήv+g+]!VmWήWRZ! aWBؕk®v+W*ܻ_! aWBu [Wغrr:wrr [Wݯu+׼+l]a [Wغr~]ܻ\ UWRZ=͕ܻ_aʽ®]\bTVx]]]\! aWWB®8zx++]! aWB®]-][rrRZR^hx|yr~r~+WBPu+{+T] UWݯ\Aܻ_^wr5ٕ{++^WαWܻ_^5 gW8ήcܙ]9^3rrgv{+++ZJ-kr~+]l)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~)識~){m. IFaYWt$Fgޜ3 ! r(R2(\ ,vb'jVb;bmm837q~޼c*@*@`~p?~u@T:P 0̯:P@T@T:P P:0T@T@̯u P@ԁ:0:P@ԁ:Pu Pu 0̯@̯@5T@5 0̯@5ԁ@̯x>0̯:0̯ P@T@̯:0T@T@T@̯:0̯#:0̯:0̯@̯ 0̯ P  P :P  P :0_ׁu`~_ׁ~?~:0̯:0_Fu`_Fu`~p?~SOq?SO>SOq?~)Xb}JO>S~JO>Xb})֧SO>b})֧X{)}?S~JO)}?S|O={)S|O)bzJO1=bzJO=XS~JO)}?SO>Xb})}?b})֧Xb})}?S~JO)}?S~)}?SLO1=SLO1=S~JO)}?S~JO)}?笠SOq?S~JO)}?~JO)}?S~)~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~i~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g~g5WQs5WQsu>߿9NS:;j;j檿ϽꎚꎚYxZYq]&n?ԮWQs՞Uw\uGUw\uGU7tu^%^on;Ғߔw~x+mȁ'&'~ ?őxX>L9/ę.Uu,Ž4W`17obBLo&]\MU{iϹnGw{}? !Cb*߯ڿsq?O?#~w#/ȿ(<"_U5أC'oOO{Y8]?P#y Oş^Ls//'oĹ{ ^G_;~VY?gVY?gY?gyY?gVYgyV>,ﳼ2>e|Y?gyY?,YgٟeY?gٟ>,ﳼ>gVYg,YgٟeVY?gٟVY?gJ*AVϪY gAVϪY?gVY?gUU VY gVY?gUU VY gJ*AV%Y gUU *AVϪY?dJVY]_u}ywzu]_]iyFYx͑/e"VźWnʷWg}^q+* yX[x{^;u`w}מ-v9>]&'Łx{H"'|'?%sOI_۽x_Iȿ*wxuco+~ˑ'ߖ?%k39#ߗ@C_}H??u%3忐,JGͻkksߵc~}]c5v_۽x|]HN̋EKbYU.ꕛ-xClb+oo;m+ĶĮx(_G:ʇx&ʼn8 q&^.;_c5]c5]c݋WQ&[ĸ&ĤV&]|N_ _#W|~}C?"'a?#~Vw/_$>,Uk>G}ߐ?.W>!~ˑ'ߖ?%ZߕO|V^G? EKLs//)ȯa7ؽ vo{cnw~+{q1zߘ]v_Mw??iyF\ؽ vo{}`7ؽ vo^obknoz޽a־woл7 vo{л7ؽwoz޽aܾwo^CGFcD> q櫋޽ vo{cn{cn"c^F7o㾚[v;ſR|^@A!G>$.F02`7ؽ vo{ݵޘ=7ؽwo{C`7ؽwo{cny|]'o'ߖ?%o3wz?P|ΑɟX'?$__R|wJqѻsα;s<syf^9^xuΚ\9^x79^xs'N9^܉37Ϲ's:s̼g<3/y9g<3/y9yf^3r̼g<3/y9؝̼)yf^=89yf^=89yf^3r̼g<3/y9yf^3r̼ssN3r1=y9<3/qrcz9˹'~qrcz9s91=z893qr*@3r*@3r*@3ryf^3rɩ9sɩ9ԁ{pr@_ԁ,yf^Nyf^Nyf^Nȹ'<3/<3/y9yf^3rSrsWN3ryf^_<3/g.<3/<3/箜gܕ̼rrsWN3r*@9XsN9<3/<ϳ>o=><[ϛ繟~y繟~y繟~޺\yU W*@^[[[[[yy=o].o].o].uչչΞ~^g[[[[[[[y+ry+ry=uΞ...g}޺\޺\^g=oV{ެ<Ξ{y=oE.oE.oE.{y=<[so=>o=>o=>o=>o7O[so=><[[ϳ>Uyz:|:|:|*\ | | | |]+++3uu^___ -X+wu[0O/n - |/ |/ -wu[`} :~_~]wu[~]_~w_ -k]ۂn -붠t._pm:|:|]u[ -`T._pm]]`ۂn -wtn :~:|A5(X/T5jP&_P -kՠ`Mۂn -X/붠u[ -p -X/p`^pmA/붠u[ /X+`ۂ5n -++_~EY_d}E"달/{EY_{E"ߋ{ќ^"ӋL/2"ӋL/21EO)".1E^y]䘢]'\"\.Y+r'\䘢'Y\"-ܢ]䘢ݴ"s-2_=91E=G'Zdk1EZ_VSVdhEZdhE=1EO))+ċŊS䘢'=9"+Ⱦ"S"+h=h%h Ⱦ'uޢ'uޢ'ͯS4.Ȼ"+EO)EO)EO)EO)_ͬEO)zrLeEYVbYe%XVbYe%XV]Zk%VZk%VZk%VZk%J+1d6]b\q%ƕWb\q%ƕW^U^[K+ľJ+*ľJ%;\%k%&qXbb%&XUKL,QssXUc%>K,d+KK,.1В}uɈd[Kl-*[Kzk%̠K-A[bn%斘[bn%[bnߒ1vltwld5K.1Kf%{%F]btw%{%vq8^x.X%`%삕^aKL/1KL/1d]KvJL/%K|/]X_2.Sq_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~e_~W_~W_a}WX_a}WX_a}WX_a}W^{ +| +|bt]1p +pbt]x +F^W+ +]Wx]1]W]10 +\pbt]rW[obt]lV+pيuVZiVxZiVxZ1]WxZiVV+Fu>VXc>V+F>VXcVWa_¾u} *FUxW]wUxW1bt]]»uwUV1]WXVaYeUUYVeYeUUYVeYeUʵ*ת\rʵ*ת\rʵ*ת\rʵ*ת:lqUUWa2ʸ*㪌2ʸ*:lUUʾ*쫲ʾ[e_}Uʾ[a:lU*L2Ī[ebUUǪ[cU>Vu*+UVVYYaܬUVZa:lUUVZekU*[:lUVu*g:lUV[enUV[enUUV[aU[a:lUrV]etUFW]a:lUFW]aUvWu*ǫUWu*ǫ:lU2V^ezUW^ezU2V^aLUWu*߫:lUVu*ܯrfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪfǪXXԁ:PcUcUcUcUcUcUcUcUSj@͎U͎U vM5uԬ`TjPcUS jA͎UMٱY5;V5uT PSj*@Mٱٱ5;V55uԁ:PSj@͎U͎U͎U͎U͎U͎UMٱ5fǪT PcUcUcUcUSjvjvjvjvjvjٱfǪkvjvjvj|ٱfǪfǪfǪfǪfǪfǪffǪfǪffǪkvjvjvjٱٱٱٱٱٱٱٱٱfǪUkvjvjٱkvjٱkvjٱfǪfǪfǪfǪ:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯:묯: q~8a0o7 q~8a0o7 q~ q~ q~ q~8a0o7 70o7Lo0opax q~ q~ Lo7{ 70o70o0Lo0q~8a0o7 7|oa{ 7 q~ q~8a0o7o70opq~8a0o 0o7 q~8a0o70opa0o70o7 q~8a0opa~8a0opa0opa~  7opa~8q~ q~8ayuh7iێ?չ;#wŻ^'oGx=qqsw}X<{bOOšgSx!\s_q^^}ȟ*;? EW>L\5_Ӹ8y#E}L|\|B|R|J|+#?%ŗW_MlKST976UMbST97UMsiST?7MsST?7MlsŦ~n~nq6MsST?76UMUtStoϦ*rn*朄?T3ߥmIX+]G>!a?&~B|Xy~EwxL|\|B|R|J|;<^|@|k__|ŗWZT-t˘y [xؚcS[&k [x֜<ޑw=-v}y=k#}X<{b0z|$cqⷚ q&[xh&*PM6y>m6Yil4YmbۺضOs|-.ҹZo\-.B -ŅZA -.TOsԇB˧B -p -.BKj*-UňҹZh1ňbDi?-ň#Zh1sbD-ױň#ZV5m-״嚶tbD-׺ňҹZ:WKkr-UsbD-FԽRZh\-sFq7]Vn7]ӛ\Įx(f(cq>>OrMMO7q~7q~Yt7M+B7Mg}әt7Mgzs~xyr^-uyr^-uyr^-uyr^-uyr^-uyr^-uyr^-uyr^-uyr^-v`;*؎ ûlGvTlGQvT`;*؎ l;hAwP vTlGQvTlGQvTlGQv{'pەveo]ۮmW+{ەveo]ۮmW+{ەveo;veo]ۮmW+{ەveo]ۮuyq^wuyq^wuyq^wuyq^wuyq^wuyq^wuyq^wuyq^wuyq^w׮u^ky:]v׮u^ky:]v׮u^ky:]v׮u^ky:]v׮u^kyݵ&pך]w ]ʻVz.]w \qw=re]ʻOi4]G=_^3z8'ԑsBgt5JU%;ȟ*[޵:twIGJ|}C򏉟]?5/8'I)iǟ^|@|k__>]Q|{8p=|{8p=|{8p=|{8p=|{8ymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqylc61Aț;xࡃD c1At :xAt :xc6C3QM cC cW :$ț;sClcAB $t:sC v:$t:$tABhc4ABlc1weu:ft $tABw:$tABGMw̦;fCa_G¾U}W߈tߪ׾+j[wB.ȾU}^>}mߪ׾귯~>}O`hshs;}ookߪ׾U3u@;P#s`|@;PԽu@;P7zxX>ʩ#8󞋺w`p?{ށw){ށw`p{ځÁ~`|{Խ333>p̔Խu@;P\W?Pt]@;@wu.x⡫vUx⡋.`]CW⡫vCW⡋.x責.x⡫vC]}C]C]}>`]x.ȡ!}>CY>C6Ml:d͡x6>CϡPmCơxh&~h&~h&~Ȏ{Fxusu9{z=c{ƺu9{ƺu=c{3zx3⽧3ֽg{O;rGFGY9#5Y9#gq,őy,ős9rGFGˑrG~###gq,ő8rGyjבuvw];3.}3;rwF}3w].]}uyw^}gtwF}gtj1ˎj{[j1c5Ǟq<ȡxk^^"}GS#|ⷚ:r.^3?}Qc=7|?Vcc5X=~j챧^j*qǞYq쎋cw\g?6A CO|<'x>a COCx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=Cx=*F}<7oTC}<7㡏>x㡏QeߨQe}>xUC}F}<*x㡏>xoTC}<*x㡏QeߨoT7U*xoTCߨoT7㡏>F}Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>Cq>#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0#<0gޙ3c3 Yc9zg֖\3*g˙r溜"g?Ϭ-|gVW|ng!35L < |gOά93{|ϬY[>|fmyl>vvc{(c{(c{(cg:FXCCC}c{(c{(cc{(cc{(cQc{(c{(cu=sCTc{(c{(c{(c{(c{(c}cc]ilele==5c`c`cPPPV-V-V-ƮUcuN722vǮuzc{(c{(c{(cfc{(c{(37Q&h``b&8Q&*Dśx LT7Dśx L'f L'*LpMTDśxoM5A o &*Dśx371 a7Q&*Dś NT7Q&foM01 N'f3 &*Dś NTLpb&8A $L'*Dśxo &Hx3Lpb&8Q&* S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$L0E S$LpY8wusu<{nguCΌ3Ϙ>c̞ Q3D͘>̘jgLgLnfL1}ggL1}>gL1}VgXauՙ=噱܌30C 3$)Ϙ>c3ϰ= 3\?ϫgL%/q~K_%/q~K_ҧ}K_8%/q~K_8%/q~K_ҙ^:řuc}ys+{/O<#"oA ĔiyF*fuq?9?+HQ,y"Vź鼶 mGZ[xϽ#z垼-v9#x"ľ8'~#8Ey# x>[Ǯ#=yM~$/{'O~(3jȹx!E-c1<⟉_r=y G?-~n-ƐEǿ"T{Y9_}^|A|k^Zb8/}| 㢖>Z>0#W/xMܘj8Ry|;ljSl9rW/w@_ǎ~HEױ+O/^?T#otMŷq_MI/ ,<7rC_ԟgq#V||i,<~ROr^[GqQc[?ߕWɟX'}O/93忐,w-a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,a KxX𰄇%<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e<,axX2񰌇e8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8㬏>8O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O>$듬O~\kZs7ך֬Ak\kZs7ך͵n5wsYZs7ך֬Vk\kV͵n5kVkZs7ך͵n5wsk֚͊5+ZkZn5wsk\kZs7ך֬_YZs7ך͵n5wsk\kZs7ך͵f%j\kZfei\kZs7ך֬ k\kZs7ך55Ckօ͵n5wsk\kւ֬YYs7ך͵n5+"'|'?%sOI27k/ȿ(_U5ߐ?.W>7#Oʿ-J|ǑgwsYG/y/"Kg!YK7?̏< dsi+{Av?H1=xu{>ő'/6'D3q.E|w]U9OSfzNYZ㹌_4U_G=#UŞ2:efuJѩ˸)=sN29e|ju2k>~'T\S(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.9r)K\ R(BʥP.r)K\ R(BʥP.r)K\ Rj&r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.r)K\ R(BʥP.E)Kx RtK\ R(B(wNi;rQ4ʝF4ʝF(wNi;rUi;rQ4ʝF(wNi;rQ4ʝF(wNi;p_{ڹs/i^ν{I;v%KN]ڹs/i^ν{I;v%Kڹs/i^νν{I[{I۩K[{I۩K;v%Kڹ}s/is/iSiSi^ν{I[s{I[a{I;zJ;v%Kڹs/i^νν{I;J[Cj#Kڹs/iks/i^ν{I;v%Kڹs/i+JK;v%m,KYڹs/i^Vi{hiks/i^ν{I;v%KھYz*Kڹs/i5v%νڹ4ҴJSDڹs/i+s/i^νzJSM)M;iS.Yڹ]s/idi^vVOi^ν?vN;g$Yp?)_'Qg$|N[ /_$~Y|H'_'CMA+yX}~$>Vg(x"%)V>zj2nω[⮸/^{o_ٞ[{f܌e]~b]ݮjO`XWO_|5'ꭅ89\/=d*ŷ+o!S|U]vn={?s?`?,Gſ?&j,7<Ϫ2~Ji3gϋ_/ɿ,>d+>ko_ϪҳYUzV]V*~W|>">j$jN%ט]{543?5g +Wigguq+Ĭsb n_%\ywj^7R~g4^ ,QE|xo.VŕFY9dj;.=+D~AW]C}~~,NęAE[ŕ Pwͬ`mL`L` -r ָ_k| ^3[ë5޺QkQkEknǭq5xٚݚZSkjn+5N98383xh6hn7~mfmfnmfm1gs֗2O~FPG)WĿv)k'O>e;\igϊ^K/U}$:.Һ:.ҺYǥ{>Q#ߗO_j}I_fIMHTH$gf5\7\_Rk5<_}J/WiׯwQkݽKvWY_='JUbϺw}j?1/(KwuizOI|:},QE|O'fv*'6Ħo#{<%5CW cq{C}~gNSL>w]S*跁~跁~Ա~跁~}6o6Tmm @ P?跁~跁~跁~跁~跁~跁~o~跁~o᯴/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2!~ˠ_2A e/~5A e/~ˠ_2A eTW2A e/~ˠ_2A e/~ˠ_2A͠_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2A e/~ˠ_2藡 e/~ˠ_2A e/~Pt2tA ug/Cˠ_2AMDMۤMDMT跉~跩7o6oS}n&mߦDMDMDMDMDMDMDMMDMDMMMMMˢ_E,eq/{Yk,eq/{YZcfq/{Y"^֘Y"^3kb]3uYb]֘Yb]֘Yk,e-oYd"[3lYdZcf1֘Y4Zcf,fYk,e,kE5f3cYk,e,`YZcf1֘YbW֘Yk̬5f3kZcf*WYk̬5fxZcf1*QYbTZcf1֘Yk̬5f3kZcf1Ţ,d'?YZcf1ş,d1֘Yk,d1֘Yk̬5f3kZcf'.8W|>_|xWi񌯞Y[+W9u|[3jy^yIu׊_/AY|x&Vpv*}պ!?7+[bdNy,K~x1ޕ'/+,@''|&">hNm>M|pnA˶S@t6v6f8|pnlo{Ӷ9϶Bpۮ67YEWo!oM39yO{{'/> 8|׊;8;8;KhW{p9sYr~W\q~wp~w}βW7['OfU;u;9qю{vvs㞣qю{vp~wp~G%hws㞣hǼn=G;Kί~ۇ<">j(>&H|WWΒYr~?CLW>Kl9sWxψgu1+]|KJ9j#jlw,9{vp~=G;8;8㞣Yr~ )]#{<%ou#vDʾX>52'Y|s"ȧ|.(htwiaw`twzWm5'E]]+]5NvQqttttvmvvLwlvl_ca_`׿}kkvav-kv;wWk=C=ڳZ{GZ{Gjjj7['Ojmo\y//ɿ,>d+u_sf> ~(܇}#ƿ/c'Vޒ`u'ploɱ-9ʟ!gy\#/4B\%3zȺ:SN->o_)<'^gmծyXKFV=ӝC=o{(gmoU|7oI~M~wߪ.oȏMyʖOyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>OyS}T<>O|AG#_Б/t V(|AG#_6)t :|sAG#_\*)m.t :|AG``U.Xet :+낕uʺ`M]. 5uAG`];+XG utAG`]Б/ :+t `\\Б/XGt :=䂎|AG`߸`߸`߸#_Б// :|AG`]Б/Xwt V}}ゎ|AG`U^(Xk :]|A#_Б/ :+|Aϫ#_/t :| #_( :+}|>pAG`#_\Б/XA V NVAG#_P"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV"HeE*+RYʊTV}ν_we߹}^{wes/ν;˾s/ν۱we߹}^{ٷӸoqNs/ν;oqs/ν;o_%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJP%(D %J(QBJPe(ز-زM>^ٞvCʪz˪GSVe5\WVe5\WVe=ݿz.єsY=sY=sll z4eU]VeU]֣)z.Q,Q,єhz4e=Mz4e=*-ϲ,ۍ,+єhz4e5VV]e=*#g9YYYY\2~LYjjjGS֣)єhz4epTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%pTJ8P *@%C{y9!=伇rw%C{!=俇:‡\ :‡\ rC.|UJ>tг8ԡ8Tɇ*P%C5|詀jP z*>uـcC5|>TÇjPP :u x=!P C5|hP rCrݓ|'S?$ A *gUUyg8kkYs@8kygռ 5Tyg8k^]u4A hPG:Ѡu4:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡu4A hPG:Ѡ 4hA h@4Р 4hA h@4Р 4hA h@4Р 4hA h@4Р 4hA h@4Р 4hA h@4Р 4hA h@4Р 4hA h@4THC4TH h@4Р 4hA h@4Р 4hA hpdܑqGN9wGN9wdܑ=+v#)K#?-+>??g}Ha#ˊ=rJ)#䎜;.8.8rrHpȺȺȺ>.݀#GzGއsdupYYߑSG:G:GVGGvY#Y#-iWGN-k;ZV3g\#/4BUbYq]̈~_!@%Uj{W ȋ7RZ-9ʯ&kɯ`fn]xU^3^x5Ny,K~+ww/?ʇ#7'~D>s[_]oW&7IAM j5u:EM&5)IAM jRP:EM jRPSi}47h5uԴnRPM jRPSIAMNQv:EMiNv4hNӚS)j5u:EMNQSS)jZ7vSU7uVMkئkӺSTMTuMӦJk&/hNQSS)j5u~:EMNQSi>4h4:EM !/yA B^ !/yA B^ !/yA B^ !/yA B^*9T!/yA B^P%*9TɡJUr B !/yAC^P% TɡJyAC^9zsCP= !/yA B^ !/yA B^ !/yA B^ !/yAH/!/&!/yA B^ !/yA B^ !/yA BJ yAH!/2!/yAH!/yA B^ !/yA B^  !/yA B^ !/yA B^-^ТxAxA(EA- jQPZ- jQPxAxA( ZԢ/hQPZEA-^-ihE;-ixAxAxAxAxAxAvKUxAxAxAT`KT]TZxAxAxAxATQKxAxAxAxAxAK%D /xA ./xA " 'D /xA侙D 'D /xA "^yKd_"/<%/xA "UyK#UyKdF|!RՑTucHUGֹTudYFV^a#Ops#D*95m#kH=Gֶ.a# 7R/q\".yK".Y GAN߈ D\ r".W&@ .'DQGD!ut>LGه"Op<%\"Op>>HO0B".\"h0B\"z<%\"ڌ?r?~?t #D?&r#7>?J?#;?Ud'Dv"Op<%#>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>c>cl@ـmgh;!vBmv6l@ـm=mg j;!vB\P mںm+sAm'h;!vB@۹kv.\Pަ6Mmzo{۹6\Pmv.MmowMm6iMmo;v.\PiMmo~MmN h;!v.\Pۊmv.\P۹sAmNh몴@ KۊҶk;!Fmh;!FsAmV|m+_ۊ Ӷk;օi;օi;!FmhvZmhv.kvZm j;v6\P۹sAmiӦNـ6 h~۹sAm j;v.Mm+_ۊm׶k[ j h;Цs5.١t)cϤ\MNJC5PMǛ:Tӡ=tcϤ.7eutPMNJC5鸓C5XuMY{&{&3xSVj:Tӡ7eu^=u_ǺcױxSVǺcױk;jc;:}뾎S+oXu[lj(P:v::v:Μt:}QE;{뾎7eu)MY뾎u_G=t-]o)zKat-]o)v=ï-]o)zKa[ -]o)zKa#t-]o)zKa[ Rufk®vR®vI6]󽮽JzJ_D׎DW}vQkGkGk7*kkϡkϡky{]dzKa[ *-]OzKaR®].>w-]o)zKa[ v*R.>wUi[ Ru-]'-]o)zKa[ .RU].wʺhu^λf]o]svxt]OzKa[ c]{n]o)zKa3 'u=c@]o)!zKa>I[ vKvKhܥ.w-]o)9zKaI[ vQRإWf_]}ukյ®=ao{{ޞao{{=ao{{j=ao{{T{{{S=ao{{=ao{{ۣ=ao{{S=aoO =؞ao{{=ao{{==aoO=ao{{؛'yxb'fxnnb'yxnb'xbXq'fxbŝmnbŝ'&fxb'91Os'I'9QωzNTrgľqbŝ8_D%'*9QɉJN'*9QɉwyyD%'N%%j8QÉN5Xq'N+%;qF71Ogĺ;q)NY <1OM3 1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1i}LcZǴ>1iǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘviǘvi].@dK2% tI$k.@dK2% tI$].@dK2%@dK2.yo]5@dK2% tI |yK27 mo@dr mK2=.6@ mld tI6%)6 mK2% tI$] tI6@.6@.@dK2% @dK2% tIh6%@df4 tIXplK2 $] tI$] tIh6* tIh6% tI$].@dK2%@df]=tIh6% lK2@ tIh6%@df4Xl`>@u].@dfCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCRT?!~HCQGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QGT?Տ~D#QT?1Տ=/|LcS>1}LczǞ>1ND]SخŘǔ>1=/|yc {^Ǟ>煏=/|yc {^Ǟ>煏=/|ycg!>煏=/|,Ǟ>vbyc {^Ǟ>煏=/|yc {^Ǟ>煏{^Y1=/|Lc ع煏iLc ;1v.b\Ǵ?1=/|Lc;11v.bc 80sc {^ع1`lb,خY]c{^ƞ>1=/|c ; 1Ɓ煏q`yc {^Ǟ>1=/|tNG=/|yc{^801=/|tNG=/|tNG=/|cS~Y1Տ~y'NěN[mOtOěNěNěNDěNDD?lj^;wo'vw-p'w~o;Yf>s5}\C#?ǝ>,~ל}\|&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`&\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`f\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`\`.r\".r\".?pYKyE^p\f .򂋼"/ .K/2O~F>()~T+c_rUU?.ⲪW?%~W?#~V˿ ~w}Ie!#_*~}7\M[+RUGG_Wc}|N\^yϐ?2l#ky|_蚫Ĵxf񂋼3-fJY}B ߒR*yNo'Z̋ŒxN~P~ \\o5#7[o*M~*0R7GH~|q*ĹAuQVr3-"x%K /a% /n\r%|ϗ2_R^S-o|%$}Kގ{ .%ܻd%K.;sY';عe>uى:;عe'v.;s\vb;عe'v.P\/_tٿ;عe]N\vb;عe'v.e< ^[[-{ ^L~ ^Bo ^-{ ].Bo./tx ].BoP ].Bo[-tx ].B.tx ].Bo[.Bo[-tx ].BoA ].Bo ]b/t[-{ ].Bo[ f [ x ]b/t[ Bo[-tX[`Bo[-tXV/tx ^-z[-z.Bo[-tX[-tx ]=.h0c_`Bo ].Bo[-tx tZ-0j@.x ]V/zk~lħD,cHH5F1r}#F\kZ#uF3r\o#7ȍFn4r_6F~HHHȯ#bȁ#FMFn2Z#5Z#jWyyy7y7Fn6F#o4F#-Fn5r[nv#F0R7R7R7000rdȑHh$4222DF4r;Fb#e.#m#m#m#wF1r{tttV#WO|hJ?eZ7 H ⋟2%/ĔO˯Toŗ޴.nz'e|kv]'wkĂF^ﻦdZ:z >Ųxx+ b_C>W|ıx"ToK[[w5ߋ ?5![ooGO&+g!ӕE.$nO]⟉_?Wa#Q_ڧ}BO6g埓^}ΗŇį_&~]@$\*VL~3TBgB?mS?S,.y_Yϗʯ+vU-O9_$'XNO~ޟ|J_%O35o_.S'Wx˫uE]p \15j?]ݫx*=rUTfW#O=ʟĻb^m럎OGӯoXk2<2.gx%.|wyq'ʯsWԺYRx_woKmm+>~t_*~]|D|TK?KuBU~3b%)RqU,q7Y*|Uz[^g.j-+j,heD\_xY'WrO-+doXeϺaY'|7/.૿!M&~!~Gs>!~Zy!|U-OT_'>iKϋ`_SUb5kG˺]*.+y92v./ w6_2pU U}Ò~߾'bQ?S;*f/ACBBPC d0{׺4ܡqEtWDt-겺|s>o_Μ{ιwG C08:%|,zz-cNSox'g=Gcq81̧p!\Sp1\Bp\W@im%z\ 6f:HKlFL-* _vn>|ދOjH9s9R)sQGɣaK m`[x5y9krY3ʙA̠rfP93\G `8WF5B[ĉ/r3SY.g=\z\qW#2ǖ!IEr %z %8=E|:Rل2 2O ?*7AOM ᥞ.c$(O.).K2>LJ*ka=lf3p\77R p| p'w=p/x$*PFlM "6A& 2dY=AVONNNNNN|.ُ@"KdJ_LXh 3A&O"{g3h(߿* / D5UU"3- {~X Cpڔ e %Z.8[0FI! ic(| >3p!\Sp1\Bͥp\W@j0|nMp3|-* _vn>ދ-c] GÖl $9ZbBdQۡOCGw+V+{G `8W[!bUSI|V) "&_dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&$1$&dLIb2IL&jKwjxG&?e5xt ]{Y ]{Y qXF;ph(|ư.` .K. 4\ Wp \ a `\Fz7-no7vn}koF"߼jxk<ͫ7޼jx!j"b k֊5kX+UC\Ո-\KULqmܹw!jbwޡjxwgYV}ӳn=.ZxV9φa'ؙn;{>0 a0z 88N~8oxg 0 k8pLp 5ep9\}F_d3z umuwwN.߃^~F+J& `K'a;vgp*`9})SOϟ (>]A)?Oϟb?>wY7EMuSdY7EMϟ]&ŻLw2)SO-Sd2>})SOϟb?>})SOb?>};K)DRxI&M$śH})SOϟb?>})SMJb?nRݤI)SOϟb?>-LXK&%ֲ_>-ײ_>-ײ_>-ײ_>ȇυQG jYԲ*ZvnkEJH8(-g[1;==:8k",1FR'Qg2(7qnxg 0 k $| > y\|ư.` .Kҥp\W@im%z\ 6f3p\؞ \F>_d3z mN%;wCFAg Oߡ?GߛԊ iBKC@j动Q-+ZVD|Rˎt-߹ |R;K-Q+% Bb0 }276>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n>n|O~qC7qC7qC7q4n Ӹa7Li0q4n&q4n Ӹa7Li0$i0q4n Ӹa7Li0q4n Ӹa9fi`7Li0q4n Ӹa7Li0q4n Ӹa7Li0q4n Ӹa7Li"6M4 Ӹa7Li0q4n Ӹa7Li0q4n&ZDKhIi0q4n Eɖ'|W|gzs(o#ԳcVώY=;f+}5)xp`Jp8Ȧc(O LDyQϮE=|[ՋȔgqrM\x]s7 $‡8a|>|.).aK2>LJ*ka=l0p|;7(ٌ~+WVJ^CoCx nd|wѻwߧJ>DEއ_;=z-X/2.C7C7Gr^= }Od>BCnft=\o>;8]p:Y2DnBt z!5 F % HZ/ٓYHZj֡1zv)qzrJ?jإl`oA $.ekV b 8JbU'|:Q2 Bb.rp%\W5p- 0g<ϣ777p 7p;w]p7ÕהУm`U\Vq Dd;,bR=<3 ̡f?x/w= "fU%Ѿ">H|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*b8|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*|*Oe >2TS|*Oe >2TS|*Oe|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >2TS|*Oe >>e7%x[;OGτg9#;.+l` A<08^G(tp, ` Ip x䬻x/>G18|^O3|:· Bb 0>_M%J6_Wku| ߃! ?g =?ŸAI{A& B6a x4lIr r'P0 }=d(\{(\{(}G 1/w/DGE?')wfkpx^#q(}G8#H hbF 1csoq߃"&̩sJ=@~-X Χb+x&,x6܍p!\Sp1\ep9\}Up5\z= `w`#o/Q2}mWЯ­ކ~N%;wCFO;=|ދg}w#iyi\ h=t3tst xK~[[[۠ۢOI̧YvA ́Q2WBt\9CH4 ih\ + +WϢSZj֡1_AYB Wbkmo D\ܗz Ë~"8B'ûGQd4̇c?==''jY0 $ʧPͣd>% Bb.r0xVWp \ a `37-p+߀op wp ~ |FOЂ`sxlGְ-1GyDx'WԂaW`?_K$OW1,u7S4lItãd}a[x"OOA~w,}= v`6 8Q \ٯ"5uGM`]$ZN0Op\ !ꌐ}#(v7%>+(VSCP8vd |8:cDZ.,d88o[mvxG18s] Bb/r0Mk+ѫj+ `ײ7(ٌ~+WVJ^CoC߄ZΑ2W :Ѓa xlM`Kt+tktt[d 0wFȿl> }:LQ%v=`/ `(>Lkd/2 :̠/y"Kl;=Hp"$#İ|rF_+W2R|υ \GQ0 'G2/FeK>O3@f:<'I-A#u#3g;i'w~]RwEwCwGg{{{֤ VzJd"/IZdZ'FEQ<4F(CxhQ<4FKQ<4F(Cxh%D9Q<4F(CxhQ<4F(CxhQ<4F(CxhQ<4F(CxhQI|CxhQ<4F(CxhQ<4F("JxhQ<4F(Cxhxh<C(CxhQ<4F(y J(y JQ<4F( FQ<4F(y Lg3|fz>3=Lg3|fz>3=Lg3|fz>3=Lg3|fz>3=Lg3|fz>3=Lg3|fz>3=Lg39́~I ."` )1LN颵2Lx<v`gjvAw`wix.χ5X wL#Hqe<2{k2HeXɝjI!')&p3 o;]Կa$| > |ƹ.` .ij6zy M%J6_glow=Q ow|}#'A;e2F;hO@>I^[BCn&囬3a'J:==ѽDC_16"YdH/DGE?'Ȗ(gwU. J*ЕhbU,:=gAF˾,"Dn;)f(VgUƺuW2LQpr`8ȃ_ BG 1.@OBOFOACG/ ". 4Dj0ynz#7p 7p;w]p7}p?|OO_Y/=%ϕ*'v=Hygv=`/Q_R++`K2 816(A@QN>CX8x8Z1B8.|S.` .K. 4cX^W5p-  \3ћfm &wp ^~ 3o˚(>m [öDx2ut;ʖeN ̑K4N$'5Z&'ʼ*8IȿDנS,oV >Qmdj( Ke$DW0  _ H. D$ 8D/Dr\ w{G3pX8Lsc['Q2=:e/ "_ pa6WWp \ am0yF&np| p'w=w'I{&2K ȥâ5Òa[x2gԗ[@Do[@o/%E_D D]`%)(- z @DkQ8rwD,c99F$Lj99FNc#c99F<1rr#'1rrx19FNcsxc99FTLjQ#cDuc99FNc99FNc99FNcDu1:FTLjQ#cDuc99FNc99FNcQ#cDu#'1"LJ*ka=lf:<ހވ7-no7vn}p?cɜ\HN.$' ɅBrr!9\HN.$z B-$z B-$z B\HN.$' ɅDo!9\H ɅDo![HDo!9\HN.$' ɅBrrɊ ׯSĒjUqC)PJGub (uAMDP[Js}ErBQ:jٔPP:-&juU6mr6c Ж(9#Ԇr1]ж(wږPNi{%UH*?ZW LPZjS魦Cm)'hvҺ:LusqmC[(C[vD{ thu:" mt3Pkn!ʏn3ԆrFe;mjC-i"5J WOoC-BmZ 1Կ.Ԣ~gtgql}1xjY(iB-i8[MgvNZu*}l巡hv6_P:md;-_ hec tjqZ>v. hM3ϝB-s9>|<>\L <%R*J\T)YJMt:{4ѽMta]/KTB=Ȗ(EJRL%UJ\(yYsKӫu$}adnY+񬱉Us*YӊJ墙C=OExEDoge@tP B`%8\Ftߙ|epjpbF<+Ksd~EI9(C/UDj*tPƈCe"Ɠ-%NWT;aL|vTb]{du龱!(e8)\JcW_xE.⎖G%]E /3+E*Uyn׮EˋfvQ^Eͮ*ŋ*Nc.;NI٬Ѭr#*6bظaF ;6kptLVn1;&k1cg36ntkUE%RcU!E!Kf5&gpa&ezVySVY? ^̙sMʮV.+gŋKD+x"*!*eqsfϔ_de˦ 8\(_uyQxƢxVB6Fߡ*%U .P|8-!W"#2^:]Ļ*եU%hJCqb6awKv731GJҒi \ܐJysfȳJf̬?ƻ&ҢbtUR&ӡ)FKr4W](sH6-!2~O1IDii*>+D\Do-mtrޅ˄R~%^ý3fvYUV- 8k7ڿs4Tom?4Ѣm-lѱ-ԑ[mt8ΠToelL\NY38Zm.5~;^X̨jr),_xDHok5'8tUЧUjRøи8Ls~ZadvhZCkrJ+䮽؊e:4S+-J+Fi*kW:(+g(g*g)g+(bH]=^JoWFrx?__gK&O 3D̽apG(#y7NMP&*JL)T&))%ʥ:+ [[W6>n)ePՔw({U]C57?EWV([D+Iq$+6Uexjӕ7ו7?Rl17DDr_G%/;Y~&^.jZe2O^NAQBRW-VU=56S-ԣT[ZmUQUSWOPOTOROVOQSWOUvij{zzzzzzQvV(Vv]njw5[T{>j_5G=W=O|U/P/T5ORCԡ0uz:BUԑ(5V1Xu:^P>R5bRHԸ:]TKRA-SՄ:KXDBP+*ZQTWWרתש׫7777+ϪwwwwIF}@}P}H}X}D}T}L{u:_].TϪ)uD].S+?Tk:WJuZ]US5P3:uA}AݨnR_R7/[W?[m7շuK}OݭE@ݣ~U?RU?U?S?WP~]JZ_/;{G'hifhfihi\kZi6Z[X8xD$dT-Kk:hkghgjgigkhNZgUuײZO[rs~څZ-WiA`m6T .Fh#QZTkc8m6Ah1PM֦hkhjETXŵ mV]]jeZfiWhZVUk9ڕ\*jZ:zF&fV6vN.n^>~-hhjikhjiמОԞҞ֞~k "Y--֖hKermZVZZ[V+({5Z9^k-kkڋ&%e[@٩E۬m^m^ӶikohҶkok;wڻ.=mmWHۧ}}UTL\Bw+k~7ڷڿk?h뺡ۺGfzs~~RomccSS,~^w;.zW]{=^zoW\}!P}>\HGQ}}^B}>Y___Sb}ק3z~~^zB_Wz^Wskk[[ە';;{{^???????N\BRJZF>O/gX_/՗?zi}J_z}^^ߠo_7/-+Wk6u [vm}SWߥ?O_ӿC߯SFVo~P 0 Ӱ p hn026ZFqqqqqqqqXjdӌFt L,llt1ĺ>akFd+V"J*oĺd1,V'Cap0i2h#c5 D$c1Ÿظĸ(24#nL7f32r(3ʍ1˸¨0**ژm14WW7777wwwwIxxxxxxx{c1X`,4)cXj,3+?4j:7JcXc53#02:cxhhl2^26/?[׌mƟ7cxmoc|h5>25>5>3>70f|i/;{G'㠩ii阮laem4[6f[X8xD$dT3lgf7;ggggNfgfv7fOc5ss~f3`A`s9f7/2G#Qfmc̱8s9h1МdN6ET؜f sYb^f^nef0gWfYeV9\*jZ:zF&fV6vN.n^>~3i֘3704261o3 ̅"Y3e.6KersfYgf\i2Wk̵sf`f\g777/MKfes'Us|||ac45wͿ{ͽG>cg/Ϳ__0415e~g~o<`hdK4K ˴,˶˵<+b5[-V+jkckgo`hdlbjeYӬVt L,lluZݬViz[}Vuu:ߺoZ~+iXXZY[XZY~oͳ[ "Y+e-XKerk*kZk='=dLZkzllm^djm^Y[oX޴޲[o[;wֻ.=kkg}l}bw+k~7ַֿ[?Xbfae۶cgGfvs}}nemccSS,}`naiemcw;ٝ.vWζ{=^voαϵϳ\ A`{=f/G#Qvmc8{=h1ОdOۗؗET؞f {]b_f_nevgWv]eW۳9\*jZ:zF&fV6vN.n^>~;iۏ؏ڏٿoϳ "Y;e/Ker{v]gv^iWksv`v^g7/MKfe{'U{~~~acߵwٻ{G>cg/__ego>`hdtGu4Gw t,vu<'4s;-N+id9ӜNt L,ltq:ݜNrz;}Nss9߹:r9;8u>u>s>wp|/;{G'砫kk븮mt[{6n[X8xD$dT7mw;ggggNngvwnOuss~n7A`w;w/rG#Qncܱ8w;1НNvET؝ w[^^enpgWn[V9\*jZ:zF&fV6vN.n^>~7ָswptrvqs ܅c"Y7.vKerww?nieRy]v׸kz ܌]<>np_p7/ܗ%}ns_wpnwvw(;w]{n}/Cw7KW??oo߹߻vp??=S==3=˳=s=ϋxͼ^ (hkzxzy{'x'z'y'{xzY^;4;;;;;;u:{]^7zz^..{/ {C0ow7h/y Dy$o7ŻػĻ+z4/Mfx32r+ʽ7˻«**ڛzWyW{xzy{7x7z7y7{xzy{wxwzwyw{xzy{I{{{{{{{{o7[-yz)o[-{+?xj:Jo[/2:o{m^6{/{[W?yz[׼mޟ7o{}>y{x>>>}]y/;{G'`D-G"vĉ/449:2*:&6rLq#'DN99rJHV]HH3"gFΊ9'1)9%5-=ɉ9//r~ȅȀH^d`dPdpdHdhdXdxȈȨH42: SOdRdrdJ%ʆȥHqdZ$)\0}`<;^U]Q>0}PW?(Ae i3jP;NġJyxk>(}pa~zoc78|p+sH.:,AǢxcvV wF'hZ-X vja%&)?qltp- T$g9ͪb!;\,d쾃ء>KrWƍWSdFi*qZDrz;b*|SKJKK/wjy+<-ONwXUV_hN0Nr瓛LJ؂9MҚƀJJ<E( ö(*ET) Ǔv;ؚYY=+^͔wi]xhBtȊ51?4rpfU"xnvEu*.#UY7?"i. hfQ {$Ok&It"[S/÷8|ra4ǷxEs]]TթsNUueвѲ߫.GLnj(cW$7;*cf7$4OAQ ܬkG׍MpuDC~2'$iCT6L!Oʜ Ijsa6J%*m0eVj- a0h5X}4u]gIAIHR Nehxu\4_L%t{6>\ΙMXaȍ D`4a<2?D $a IX³93Gy<6k:ܜ4fi'uE׻0-1VޝۅQLx5-3iEVyt 2033ʻ3Ng1B)]^!s ᩼냾{gDA6ҩp@z6f,W42ͼ5)}zx 337}$*8޾™1j,OfFTGGf14sfm 0q5Ci8Z[S1/oۗ[[[[[cϴ7)ynynynynbi)3xɿHEg/_$k֦axu͈ٿ^Z0̂ArX!TiՈNuQzXi&tF٧J/2QNd/XgUd_b 00L,.Kýe}ʤ>uRUzi^6XK,.+ʓu^:X[:/-IȌy6D~%~5^S9~ļ:l2U3'jZڐT[L պ_?{l7kMHbOo#ڵiB\w3Wdja5 o F%E[~ccr YkRJ Fә]>a*sU>鞐cbH!y.h2h2h2jl5F!yF!yF!yF!yF!yF!EcYվbn3j!s^x1{RKQMuQeήQ KbBӢtس)1 d3+#ШUQaUgC4:wZH\]]U@D!ݱf\_>5-,pUoRE  (ltQEj$q/3b9k#+QWu:3]5Dƚ"}5ܽ7ƛ|HjTlԐhݚ(Q ݍ+a(FD|xr(XW m.<"6L;v2-3egZaPv*SLvo'vo'vo'./ɿɿɿ U.TE<1("92Q)U7 +Heӯrw@&KSna:(|GiS/]V[/0H:ـ*p'w *QdUNV;Y.C U2TPfUnVY2/h_X^]4z^`y( w \*puPfgٙ][nUV[.ŶW\npU%^]Q[;29~+p?Be~XR> } \*pi =C=C+pGA(WZ+Pj +pO= +pOP%)QJl.GUXQ.G+V` X` X` XrTQ.G<[KEn-TRBE RRJIt `Y*tR#,EEEEEEEEΠ<)EEEEE23(2(2(q"g)q"g)|Yܒ*.b{{g'!6?`uzyFo}xO!ĊQix&6'ơL{mmr;,m"T9r:ou#c' ')j(; ppמ)ƐKo GS@xySycu cz"6)@u<p ,Z2-p͖1d*r{-1 S/7RT4 yb_%>F2cadL CNTqTnmmm:1XbZC'xNDt>6b ce3ƜfFFLJ, ^xANRZVR662s/ >Q3*mR #(o؈$5 4biz6RZE HO&9iW-g5RfZoG#=Zr”jBKlF  KnhFؤВc53Tb$|z^4c/~`uTppϚrl\?Zn,XF.DdFQZ_%2rajHFtmG+a($۫* -N9+viB4=24|-H/Bt/ (rb^HM\;2ʃULٗK]6UƤ:h}U[49#u~uU̶UTU`|ON[~i+SiiiivL;.`ŴiSOȿȿȿȿȿȿȿȿɿɿɿ{{{'Oy{(o=PCy{(oK_"ȿD%/K_"ȿD%/G{G H{bDkz^橗yez^橗yez^橗yez^橗yez^橗yez^橗yez^橗yez^橗yez^橗yez^ɿɿɿɿɿyyzyyz]8O=S<lvO0<SxFJjgFlv%ϔ z?9h$3̿-   Qmܭg;*lNjM'R+02ϻxǴi速@@@@@@@@@@@@@@@@@@@@@@@@@@@+Y_pOɞ@@@@@@@@@@@@@@@@@@@@@@@@@@@3#/"TVs-D>pPv##hP!^_˜8gDMFgLrrgDRNFR1MYlo _i-ؾߧix+HH]yEmLۙv0 [i7%x ><c1lx 6< Vx.wYPx (< ǀc@1Pxnc@1Px (< ǀc@1Px (< ǀ˓ P+ Ϡc1h4x < A c1H,Y"0A己6={ޣ6ic}ȯi#_:yNޣvo'zwk'vS=:uNݣSԽ   ?:qNܣ=:qNܣ:~oK}{tݷG}{tݷG}{Ou'w'}{tݷG}{tݷG}{tݷG}{tݷG}{tݷG}{tݶGm{t'^Wwb2RoGO@'٘lr?;ݷG}{tݶGm{tݶGm{=iXP-l=p.ܣ =l.#AוǪ匏Ƽ+u7O4DF̜{{tݨG7эz#Sۑ҆=-V.<"6L;v2 ͘eyꈬ챹&[53P]39V|7?xɸ^^> $S7P1 U)sQxeޥn/>Vi5i^ 96l>7OA)=Xۨ~* Y`Ȫ@V*VHYX X$"ɷHEG_$"ɿHE6q_$"rF5jޚ3 1g6xuCfCx&Mf!<1o䵾'CٌѵfŋN,EȀ/47ġ^/&,:A{f,,<15 NP:Xdou:[ԖaCTH UǨ P ڒq&ڱ3=RY?>X92F8ɱ0-iKٺ([el]{;fozj#bB3=T}2r; .w@2/>\lprgXɑ@C2M55cW}@]_<9RN&`C@62Xuk'OHC呾~b ;Z[Ec*Ęy| G^e*}~iJ|b<>^e,cQH. e+c}=QMf?gBƴig"TG֘'aWVNeO*f;e0HZ0Xtà_f[BO}XZ6FhD[iD[iD[iD[iD[ M_ŜX{@<'&'UQmQmQmQm/H)Oi8K^ Rrc2zu^]qvܥwi]oۥvi]_ץui]_ݔV=h_]Wե}ui_]Wե}U/ڥuK["?.mD~ ǀ;Xsy"<-o~~W=xJ{wSk&37ZΟBkgZ`ZdƴiN v{z&C>o|a|*.@LSlm7 2  2pI:}NmXfŒ3,Nȉ@"Wy\) bPpFP:gE y=*N"{\))AEbJ@VO^H/W+rX"pU"W\*#@A[ Rl H3P [ 2'R2;)B'*9B4B^D$<JQh 2bC:H ȩ2|cx Ә֘yiph, .,?!&Dě /(v j0*ĖialXY0k#]hjq0\\_]: vgaed3WR+̳PCCtdybLkiaCߴzeY`(^V6Y^De*蚼X]C5'׎y2ZLM6(߉H s2id6B'BEEop4j-t(8+/W=0PoNyz/7zdu6JmCx`^Lf3uf,ck2Q_gu;g$A/1cS"F4v8:' rcF9"qJ`eZ oM11F4J|V۴Lϐ٦ O;ƶ-N9Z^Ӫ3::3併i_&Iyl!ꇠӛXF^BGE&g->I!mZH!@ *jQp z%A(~ W'_CVV7nT_~ I phuWwơ7}ǡշ?zV~U_WjT˿J[Q |UkFoאSNNF3ߪSmz;_nR=Þ,ٞ|=>~}w9)99\No8o()qI|D8q9O$!z%_Oew%K+^uWw8#RO(+ԋN*=KYJʞB]O˞|YvȞ|e 7?&1emd[_F=i}Hz%+ 77M-WR+׌U֪^j|GR]`,WR>SjkPuᙊIզ2ODKz橶S_x9 s[* ifcʩQR9y˫Ax@Y]$2W Vo3RJKl' la;yN`B5y5_u.uZV^uSEru 9mbg/bSt/>?SH&]]2_m<WۤF :K:" u_N˞-Y와K+I gg4uG fF)BG%se~`'JkgC#uWi3b}!6`E.Sg.sqj)wB]> o9X*3VRo&\N(WEI((G s-[bgr[{+gPQ+b̑R-)Co*ujeFeF5oM pr29M:Svq8Dr$9MaY!\[-RL)cѸ[%ǡ`qn9ɡ%.vˑ$ǔ0}1z:mhc0z3VБcjB{AOjxTRzǤȽOz9cRI-M9ˤ8zqfn~ͻfx^]?wiH%u.x__~?Bı͕iFQ伐] |Og?k΋6K?z|_@K [8>qw=+zJmS/?kuuYK!_ 6bVvXġ!k#(ѝ8";b$ AٱxMdypZ^bClSM]+R)ok ؅{=5<y]Rs}ЋQ0\0pď:N5}P\Tb߄6u'FՏ'qś&r5̶ލ9Cue-NVXsk6X..nnd}ź˺zzfhbjކйOOw]gw&%* ֡]]6b}E5yԔO)en6ɳPʹH?R}R$OVqUL9%kw9.Џ<y%1[Z荒g ._ ?)kYK~]!txv"S23=Տڶ1W3zň o!~P*hB4GU֫KxJ&l \kukuX[=Rku橃ֈ5am..>chb}ٺúۺzzb=e=g'kvtF7 ܏}>Q{z^<= E2}V_oҷެOg0ݮ_ֿӯ7me'渳1}=n {}=`cCUu wڏ߷WWێvRN3˙sst\9qNv:+ssXZ~J-yUOP発p8F>R2ӲN(3*kc2c X("zToL-Ƿɳ@[ }誵Aa%1xc1?2|)ccvc4;91\ל]1|G wDE ?;fG8Gb2q_W/yQU{+S<lg?w6ZdW>ꋰ|_V_E1WoWas.柨 | jz}9?8lL5 ϙWvDV.!M)YKsoTZV.5Ǯ~vΪFIhس>pXջջSR{RHXl{gF?'" hne;[Fu~-nBde]ߵ]M݊m݉==f aJF2a|S+~p/ O%l##|)kυ.,Pύ&PKiuOԌ0|.C Cq&ry"+npWM6*fvI3{i+ݛ7 Osi-}do;SY1p_ wO$=ۿ|g8? kA5>VOËۇR5x\e[/h!aR V8ĸIX-X9Y82ǝ9'抟8@!'-~?.~8 O$~bO.~Lex1_4kӯLM$BW+dZYz>R{J}ՃzDOMB}Qߢw0xLoO^ M"n @BgHeA5|g \"xuN(1z]f ݱ鈮n 2OK(W ~9LJx[ʜ#[BK7$~rBe >Eqcctt.#R-OVABdL>%֘+EWIN2ZˆzJA6W} G3{=89o}^۬ە,>m/ڼZ>R-ՋbuOjSv Xn@z!j%P #Sal*N%QdY<ᇨւ0gXwXYu1~|zG -CamKga\HV2ǯ? R0ҘU^a}F_.~!s~MS3VFוyF\v99C=ycJhe$3a<)]砞As*|F0p7&"1x9rV1 eM k]&{C&O C/Loj] x7t=ʙeo(r/_wHaSOq^ }1ĎG#b BJOxzB2pW>$Xi e^ .i/ q)4zj4P8Km !?( '=T|c&2K |w ,H9'J߆ G EJ\6e9WoU־ن5oo~jߣRVl?g^N_R anRgH|YwNV4|Ƕrvqusu|ca07>E)ZY;Sf0L 8qI5uL}DcIЅD[m8ݥS Jr}Nߠo__w{Q}ު+USmkDR <0H۵;d{>{d_h_j_a_cƾ}c)Xۿw8Nirrpv 1Ή,q9g&;9:"2JZz&V6 ס?6Zl=ӣ<$-k(jZ (֓燒ImP}>}rxsP>#﵌Yӭ8/"?#~30۶jqd["&B_In/ ByA(?6t K(#R'5:IY(_ WByY( [By@|_(?]BS(wI9)'#$z6u+,{rB!@z0.&*S>ݢLh(Z ]=%2eK/IIN<æ|iEg^r~/KdP,[)ͲI]!.!G(ByV( 'B^g?/R/i*5'%XL2O pq&OcI)|SQ<7o`j4rsEo֟ɨw0ɱjbD67ǯ&WU-x+%OvD1ĵN|&ֈ4" ˈ [S7LO}A^/E}cgVM {!CyP5> 7 ෦>ba~iMnIYMg]kz8HSWn4>Cϲv·ǫ* f̲,A̲__aVC/7}>3: Yt mU7 \/ؽ d?TploFo]ڏ؏!w=? <p0MVi'K: Nf\}}w<9Z|e;ٌt 11*.PzY,Ľ';'$%qNuNUY,\,C Jss![)S>B1g p™PY78P&gs!ȹw]\ xs)^\xs9Ε{s559A;}zS5xBI7k?[?g? `f  ܵގr~iEEe w5J~~c++ {ʫk:J&mbyvٻŬ[۱a-rluZaN;9}OpNva'KN y;aOqN~sp>jg583 zg=8Qps 'O_\ )Sv>?|<61'-)6Էuf/1{jJlfm'[,Xvh}R+kz뮥bi7Ogvw;c?sVl,qy ]~ua>K0.~c?o~3h/ῄf 24h[,4uӿ@?GAc'@JзSg~>}zQ'7|V%oÔ`'v 0v%7?V[bs^fk&pƲ^`̆}Av׈/e#\~/ vƲwru\^ `^92ɲ_ ,-cߗXQK~&KU/M9o[aC$i v5bJ % ˢPo,u^co^c^ 3"|\IoIہG GZ0s{$'n4f !;Zy8u[JE8QGJ-Qb#NÑŌtyh9JXY#YJghj"=j GZ7䙈g8< @ѤġC8#^卽(]GƑYHq$08/qԩ_ᨓg1R882mY GJZIpf,ުlZ3LE%}}TO[Zl xujR{Zy+XVjS3ONT3>z+ U\D_$ߟ|dM%W'V_ɯג_f!y~P]׭++U2{fLΞ=Kegg* 1i,ydDKly֬ r -2Ct%)ϠirFchLhLZ4&%qDcEc11 И$_XЗQN+=t%+]i]I'EWV?¡Տqh-zEoѢ7ћMFI')$c!zJ%ECDPPZt(-:JY4Mʊ&eEIYѤhRhRhRhMMjMҢIxrZe))}J>ERO)ѧiKBkJЗ1)Œ 0:a JYGo||?& }}'.uu^}~лW.zgSϣ~胷.˴w܈vy P{byT'ZxD W_E};lRx6?|Էhٷ{\c'@<eeI< samV~3Wy)2G*w1P\۱oԴupnGXŽ& `>&’̺D`ShUo =f[^プI,ㅰfQwW j=X3sm^1}=2GT&);s KIh"#٪[բka\rpPZkZDZ֍×E41)ҧ@CvkFHk4+";*a8lu8G"لzz7:u$[ma'q8) GB=#~#S?QS/S‘QoȪȪ)Y˶0VlJ[ [9 hjPd56[̀Y-s*ZSͳdxu"ìDkau 1::~}Z::p7e$UI ɑXr U&oE;w ڹ3y'{Uc}.WS.Y7=1-Ƽ [E: hFh-"1S4CfТ:a)GDS~(TDSIfK48*!qTZ⨄Q{K8*+qTx:8*%qT4bٕ3y5$7"h.ڢDD_iʎD_~+-WBD_ }$JJ6̡̑NH̡fx,1MMl-"2-7zh |3Z뛑`H%~`KW/–X^EѢ^"ql3-%eHt"1^RFQDzIE-e,Hԗ"_ZUDi]ā cD iĄ o6gfԵH|%dΔX1'pD9ZƬI-cYC6%dYO6X%QeY2bĖ)Xa6qܚ8DM2e H$#E"Ϥ?2[$ m"hRFxDi-eϔ4'c~Ĩ9Z"լ-jV@X-kJbWtH P؁1`,Qb00;d>bt]1cd}B]{ ֵu_cdݠ>yXa?M 49h6v⟠_QS ѓD[-Aܡ=x%Ķ%&q 87<6Opc{a-QT-o植8IBⓤ'uyQ&2IKdE&Xd#2ɊiJd//$^hF8*,Yj"ioHe6Gf{~x2k_}'hE/E()Q"%#%#5GJt t b3d5YVfjRfQG5juyy15qT3bjFSS͌y%_%_5j,*)YURU+G#joW_94GV戏W_5W|TF" #=f33>j6>f33>jfQ Q⣚G%G5324>j_ƇG(+GeG >Q|uGg寤 _'_U;P~g·qW} QBZЎ-i<%sQ+S݋^:Q'#շWAwտ'}_S?Dޯ~,m,ڲ[mE+H3_2#mo9G["E0@i6I˂~z`9&^ n ۹9oG'1y&RBtJ-N-uJhi@9=u:p] .>[ͬΩ9 )ꝐUG3+<*?_nN?e\ؘa+K`ONJ 湂ٰZP2cI8OYH|k4a7VU+\&Swv3>l"78Ҝ~[Collabtive-2.0/include/font/freeserifbi.ctg.z000066400000000000000000000112321237252063700212720ustar00rootroot00000000000000xceɒ0̲̌m۶m˶m۶m۶mۮ9V^w;3wY+#;>gy4 `C 8 BC $CH 9 RCH =d 2C ;䀜 rC ?P C( Š8P JC( g_|PABF= c 04c02F c 06cL01& c L05c̈03f c̉07c,0X c ,4Xc2VX c u.b#lM)6[b+lm-;b']+v{b/}/8 Cp(8G(cp,8'$Sp*N8g,sp."\Kp).W*\kp-7&܌[p+nw.܍{p/x!_+|o-?'_+~CBVFbeS^QAU0\P!U(ZQaU8^EPU$YE h]P1U,;Ўx*JD*q`$J*JR*Jҩ*ʨ2*ʪ*ʩr*O`O^OWTAUHVETQU,0Z+hUQU5TMUK-zjFjfjZVjڪv:Nꢺnz^~AjajFQjƪqj&IjijfYjyjZEjZejZVUjZ֪ujڠ6Mjڢmjڡv]jڣ}j:C:c:NS:Ϊs꼺.K겺k꺺n[궺{zGzgz^Wzުw>OoAVZkIi:C::#֎k:c:VN8::N$:N:NS4:NVfu&YgYu6]9u.[yu>_u!]XEu1]\%u)]Zeu9]^Wu%]YWUu5]]5u-ںnƺn溅n[ֺͿymu;^wu'Yw]u7]=u/[}u?_ =XC0=\#(=Zc8=^O$=YOS4=]3,=[s<=_/ "X/K2\+*Zk:^o&Yo[6];.[{>_!}XG1}\')}Zg9}^_%}Y_W5}]7-}[w=}_?#X?O3\/+Zo;^'Y_7]0`(1dX7ALP7!LHʄ6aLX΄7LDD6QLTD71LL6qL\7 LB$6ILR$7)LJʤ6iLZΤ7LFd6YLVd79LN6yL^7LAS6ELQS7%LISʔ6eLYSΔ7LEST6ULUST75LMSbj:gid&ifieZ6igڛd:.G1MWcM3̀GflfnFfmƘfo&flfnffm昹fofYlf| Ҭ26_g֛ fd6-fffev=fg9d#9f9eN39gΛ 梹d.+|W͵u憹in掹kyhyjyi^ykޙh>j!)dɒ#OA((BR( Ma(,"QdBQ)EbQlCq)ŧQbJBI)%ԔR? !B! 2QfBY)erQnCy)T Qa*BETJQi*Ce T*QeBUUTj/TP]G5FԘPSjFv jI5ԎSH3uԍSI7ԏHh0 3B a4FHEi q4&DDi Mi4fLEiͥy4BZDi -eVJZ75z@im-vA;i=~:@#tq:A'3ty@]+t'%\ݤ[t]G=GSzFW[zG}OWF#+lٲcA8(Cr(a8,#r$Q8*Gcr,q8.r"NI8)'䜂Sr*Ni8B!B!8 3qfY9gsqny9\ qa.E\Kqi.e \+qeUW\k/\p]7FܘpSn͹Vܚp[nwNܙpWݹ^ܛp_yAS|Y>_K|U[|]?GS~W[~OWVYm%Zg b`6 aCP6 cp6`#H6bh6acX6cx6M`D6Mbd6_6MiS6Mk6h36j6is6s}>m![g-jⶄ-iKҶ-k򶂭h+ʶj궆ik_lm[ֵl}6lc6lsgmmض~{vlgv#G ^c~`AvbavaGQvcqv`'Ivbiv3L;ζs\;η B.KR.+JʮkZήFn[Vn;N{^A{GQ{'I{ʞgh/jioN`g}d'}f}־@d?/f:3;._. C. ¸. ""H.⢺h.bX.x.KD.KⒺd.KRT.KҺt.2L.Ⲻl.r\.|.+ B+⊺b+JR+ʺr*J⪺jjZWqu]=W5p ]#5qM]3ܵp-]+ڵqm];up]'u77p=]/q}]? p 7 qC07܍p#(7ڍqc87Mp&n 7r7s-r-s ҭrݚ[66-n涻 ]nw q{>p7!w8Qww'Iwʝ9wƝuyw]ts暻7Mwvwݟ@|Gq= g{_W{hu~T[쾸~xxw >>C0>>#(>>c8> |B'I|R')|Jʧ9Ƨ|zg|fg~'_vg}}_}_T#o _uo_s/.H_ +֕|?$B_'⟅L5Y'5}-iFofB!B}|_#B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!Bo[6o}?w}wO"B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!GQ~q~]5Od?Ʀi~g~~_~_f~_Wke_@7~~wܵB!E~_.aCollabtive-2.0/include/font/freeserifbi.php000066400000000000000000000570061237252063700210450ustar00rootroot0000000000000096,'FontBBox'=>'[-787 -300 1678 924]','ItalicAngle'=>-16.45875,'Ascent'=>900,'Descent'=>-300,'Leading'=>90,'CapHeight'=>669,'XHeight'=>475,'StemV'=>123,'StemH'=>53,'AvgWidth'=>412,'MaxWidth'=>1657,'MissingWidth'=>700); $cw=array(0=>700,32=>250,33=>389,34=>555,35=>500,36=>500,37=>833,38=>778,39=>278,40=>333,41=>333,42=>500,43=>570,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>570,61=>570,62=>570,63=>500,64=>832,65=>667,66=>667,67=>667,68=>744,69=>670,70=>656,71=>722,72=>778,73=>393,74=>500,75=>664,76=>609,77=>896,78=>722,79=>722,80=>614,81=>722,82=>672,83=>556,84=>611,85=>722,86=>667,87=>889,88=>667,89=>611,90=>611,91=>333,92=>278,93=>333,94=>570,95=>500,96=>333,97=>500,98=>500,99=>444,100=>500,101=>444,102=>333,103=>500,104=>556,105=>278,106=>278,107=>500,108=>278,109=>778,110=>556,111=>500,112=>500,113=>500,114=>389,115=>389,116=>278,117=>556,118=>444,119=>667,120=>500,121=>444,122=>389,123=>348,124=>220,125=>348,126=>570,160=>250,161=>389,162=>500,163=>500,164=>500,165=>500,166=>220,167=>500,168=>333,169=>747,170=>266,171=>500,172=>606,173=>333,174=>747,175=>333,176=>400,177=>570,178=>300,179=>300,180=>333,181=>576,182=>500,183=>250,184=>333,185=>272,186=>300,187=>500,188=>750,189=>750,190=>750,191=>500,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>944,199=>667,200=>667,201=>667,202=>667,203=>667,204=>389,205=>389,206=>389,207=>389,208=>722,209=>722,210=>722,211=>722,212=>722,213=>722,214=>722,215=>570,216=>722,217=>722,218=>722,219=>722,220=>722,221=>611,222=>609,223=>500,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>703,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>556,242=>500,243=>500,244=>500,245=>500,246=>500,247=>570,248=>500,249=>556,250=>556,251=>556,252=>556,253=>444,254=>500,255=>444,256=>667,257=>500,258=>667,259=>500,260=>667,261=>500,262=>667,263=>444,264=>667,265=>444,266=>667,267=>444,268=>667,269=>444,270=>722,271=>609,272=>722,273=>500,274=>667,275=>444,276=>667,277=>444,278=>667,279=>444,280=>667,281=>444,282=>667,283=>444,284=>722,285=>500,286=>722,287=>500,288=>722,289=>500,290=>722,291=>500,292=>778,293=>556,294=>778,295=>556,296=>389,297=>278,298=>389,299=>278,300=>389,301=>278,302=>389,303=>278,304=>389,305=>278,306=>834,307=>545,308=>500,309=>278,310=>667,311=>500,312=>534,313=>611,314=>278,315=>611,316=>278,317=>638,318=>382,319=>611,320=>424,321=>611,322=>278,323=>722,324=>556,325=>722,326=>556,327=>722,328=>556,329=>646,330=>829,331=>547,332=>722,333=>500,334=>722,335=>500,336=>722,337=>500,338=>944,339=>711,340=>667,341=>389,342=>667,343=>389,344=>667,345=>389,346=>556,347=>389,348=>556,349=>389,350=>556,351=>389,352=>556,353=>389,354=>611,355=>278,356=>611,357=>426,358=>611,359=>278,360=>722,361=>556,362=>722,363=>556,364=>722,365=>556,366=>722,367=>556,368=>722,369=>556,370=>722,371=>556,372=>889,373=>667,374=>611,375=>444,376=>611,377=>611,378=>389,379=>611,380=>389,381=>611,382=>389,383=>333,384=>500,385=>850,386=>667,387=>575,388=>630,389=>500,390=>722,391=>929,392=>654,393=>722,394=>864,395=>684,396=>500,397=>546,398=>670,399=>722,400=>631,401=>769,402=>333,403=>929,404=>716,405=>745,406=>278,407=>389,408=>829,409=>500,410=>278,411=>495,412=>853,413=>919,414=>556,415=>722,416=>868,417=>603,418=>1014,419=>778,420=>757,421=>500,422=>611,423=>556,424=>389,425=>730,426=>455,427=>349,428=>611,429=>298,430=>611,431=>879,432=>704,433=>811,434=>678,435=>611,436=>581,437=>611,438=>389,439=>619,440=>614,441=>461,442=>445,443=>500,444=>614,445=>500,446=>389,447=>504,448=>220,449=>418,450=>570,451=>333,452=>1355,453=>1133,454=>889,455=>1109,456=>887,457=>556,458=>1152,459=>1000,460=>834,461=>667,462=>500,463=>393,464=>278,465=>722,466=>500,467=>722,468=>556,469=>722,470=>556,471=>722,472=>556,473=>722,474=>556,475=>722,476=>556,477=>444,478=>667,479=>500,480=>667,481=>500,482=>944,483=>703,484=>722,485=>500,486=>722,487=>500,488=>664,489=>500,490=>722,491=>500,492=>722,493=>500,494=>619,495=>513,496=>278,497=>1355,498=>1133,499=>889,500=>722,501=>500,502=>944,503=>660,504=>722,505=>556,506=>667,507=>500,508=>944,509=>703,510=>722,511=>500,512=>667,513=>500,514=>667,515=>500,516=>670,517=>444,518=>670,519=>444,520=>393,521=>278,522=>393,523=>278,524=>722,525=>500,526=>722,527=>500,528=>672,529=>389,530=>672,531=>389,532=>722,533=>556,534=>722,535=>556,536=>556,537=>389,538=>611,539=>278,540=>424,541=>455,542=>778,543=>556,544=>731,545=>618,546=>568,547=>500,548=>667,549=>444,550=>667,551=>500,552=>670,553=>444,554=>722,555=>500,556=>722,557=>500,558=>722,559=>500,560=>722,561=>500,562=>611,563=>444,564=>422,565=>621,566=>413,567=>278,568=>800,569=>784,570=>644,571=>667,572=>444,573=>664,574=>611,575=>389,576=>451,577=>444,578=>444,579=>667,580=>722,581=>722,582=>670,583=>444,584=>500,585=>278,586=>808,587=>608,588=>672,589=>389,590=>611,591=>444,592=>500,593=>590,594=>590,595=>510,596=>444,598=>516,599=>552,600=>444,601=>444,603=>430,604=>440,606=>440,607=>278,608=>569,609=>500,610=>504,612=>582,613=>556,614=>556,615=>556,616=>288,617=>320,618=>278,619=>278,621=>516,622=>559,623=>778,624=>778,625=>778,626=>556,627=>556,628=>500,629=>500,630=>732,631=>715,632=>667,633=>389,634=>389,635=>495,636=>389,637=>389,638=>394,639=>394,640=>556,641=>556,642=>389,643=>333,644=>333,645=>433,647=>333,648=>278,649=>500,650=>557,651=>492,652=>444,653=>667,654=>444,655=>406,656=>604,658=>513,660=>500,661=>500,662=>500,663=>444,664=>778,665=>445,667=>700,668=>542,670=>500,671=>429,672=>560,673=>500,675=>752,676=>807,678=>609,679=>510,681=>815,682=>606,683=>525,684=>490,686=>556,687=>556,688=>396,689=>397,690=>172,691=>243,692=>267,693=>341,694=>368,695=>440,696=>300,697=>250,698=>408,699=>250,700=>250,701=>250,702=>300,703=>300,704=>340,705=>340,706=>333,707=>333,708=>333,709=>333,710=>333,711=>333,712=>333,713=>333,714=>333,715=>333,716=>300,717=>333,718=>333,719=>333,720=>278,721=>278,722=>300,723=>300,724=>333,725=>333,726=>333,727=>333,728=>333,729=>333,730=>333,731=>333,732=>333,733=>333,734=>333,735=>352,736=>374,737=>227,738=>264,739=>340,740=>340,741=>526,742=>526,743=>526,744=>526,745=>526,746=>519,747=>519,748=>333,749=>333,750=>480,751=>333,752=>333,753=>333,754=>333,755=>327,756=>261,757=>437,758=>437,759=>400,760=>278,761=>175,762=>175,763=>175,764=>175,765=>0,766=>337,767=>432,768=>0,769=>0,770=>0,771=>0,772=>0,773=>0,774=>0,775=>0,776=>0,777=>0,778=>0,779=>0,780=>0,781=>0,782=>0,783=>0,784=>0,785=>0,786=>0,787=>0,788=>0,789=>0,790=>0,791=>0,792=>0,793=>0,794=>0,795=>0,796=>0,797=>0,798=>0,799=>0,800=>0,801=>0,802=>0,803=>0,804=>0,805=>0,806=>0,807=>0,808=>0,809=>0,810=>0,811=>0,812=>0,813=>0,814=>0,815=>0,816=>0,817=>0,818=>0,819=>0,820=>0,821=>0,822=>0,823=>0,824=>0,825=>0,826=>0,827=>0,828=>0,829=>0,830=>0,831=>0,832=>0,833=>0,834=>0,835=>0,836=>0,837=>0,838=>0,839=>0,840=>0,841=>0,842=>0,843=>0,844=>0,845=>0,846=>0,847=>0,848=>0,849=>0,850=>0,851=>0,852=>0,853=>0,854=>0,855=>0,856=>0,857=>0,858=>0,859=>0,860=>0,861=>0,862=>0,863=>0,864=>0,865=>0,884=>199,885=>199,890=>0,894=>333,900=>330,901=>333,902=>667,903=>250,904=>819,905=>955,906=>539,908=>835,910=>961,911=>889,912=>320,913=>667,914=>667,915=>637,916=>740,917=>667,918=>611,919=>778,920=>722,921=>389,922=>677,923=>667,924=>889,925=>722,926=>650,927=>722,928=>778,929=>611,931=>730,932=>621,933=>722,934=>748,935=>667,936=>858,937=>741,938=>389,939=>722,940=>590,941=>430,942=>548,943=>320,944=>536,945=>590,946=>536,947=>548,948=>550,949=>430,950=>482,951=>548,952=>525,953=>320,954=>564,955=>510,956=>589,957=>522,958=>482,959=>536,960=>629,961=>536,962=>470,963=>536,964=>464,965=>536,966=>643,967=>482,968=>715,969=>715,970=>320,971=>536,972=>536,973=>536,974=>715,976=>508,977=>589,978=>722,979=>931,980=>722,981=>660,982=>715,983=>536,984=>611,985=>536,986=>620,987=>524,988=>667,989=>535,990=>708,991=>428,992=>671,993=>633,1008=>550,1009=>550,1010=>477,1011=>278,1012=>722,1013=>411,1014=>411,1015=>609,1016=>500,1017=>667,1018=>896,1019=>769,1020=>536,1021=>667,1022=>667,1023=>667,1024=>670,1025=>670,1026=>762,1027=>637,1028=>667,1029=>556,1030=>393,1031=>393,1032=>500,1033=>1085,1034=>1049,1035=>747,1036=>736,1037=>778,1038=>746,1039=>778,1040=>667,1041=>667,1042=>667,1043=>637,1044=>778,1045=>670,1046=>1044,1047=>650,1048=>778,1049=>778,1050=>736,1051=>814,1052=>896,1053=>778,1054=>722,1055=>778,1056=>614,1057=>667,1058=>611,1059=>746,1060=>748,1061=>667,1062=>778,1063=>742,1064=>1136,1065=>1135,1066=>779,1067=>984,1068=>664,1069=>732,1070=>1069,1071=>779,1072=>500,1073=>508,1074=>486,1075=>414,1076=>486,1077=>444,1078=>982,1079=>476,1080=>556,1081=>556,1082=>564,1083=>585,1084=>757,1085=>552,1086=>500,1087=>556,1088=>500,1089=>444,1090=>778,1091=>532,1092=>764,1093=>500,1094=>556,1095=>556,1096=>806,1097=>806,1098=>644,1099=>744,1100=>470,1101=>488,1102=>757,1103=>586,1104=>444,1105=>444,1106=>524,1107=>414,1108=>488,1109=>389,1110=>278,1111=>278,1112=>278,1113=>772,1114=>745,1115=>556,1116=>564,1117=>556,1118=>532,1119=>556,1120=>990,1121=>690,1122=>804,1123=>751,1124=>1017,1125=>752,1126=>900,1127=>728,1128=>1236,1129=>927,1130=>1044,1131=>826,1132=>1401,1133=>1016,1134=>620,1135=>476,1136=>858,1137=>769,1138=>722,1139=>544,1140=>796,1141=>584,1142=>796,1143=>584,1144=>1268,1145=>1023,1146=>895,1147=>612,1148=>990,1149=>690,1150=>990,1151=>635,1152=>620,1153=>444,1154=>372,1155=>0,1156=>0,1157=>0,1158=>0,1159=>0,1160=>0,1161=>0,1162=>778,1163=>556,1164=>664,1165=>470,1166=>614,1167=>473,1168=>624,1169=>448,1170=>624,1171=>448,1172=>733,1173=>485,1174=>1080,1175=>982,1176=>650,1177=>476,1178=>772,1179=>564,1180=>772,1181=>590,1182=>738,1183=>499,1184=>862,1185=>718,1186=>778,1187=>552,1188=>976,1189=>682,1190=>1085,1191=>787,1192=>667,1193=>480,1194=>667,1195=>444,1196=>534,1197=>778,1198=>611,1199=>640,1200=>611,1201=>640,1202=>694,1203=>500,1204=>1004,1205=>518,1206=>742,1207=>556,1208=>742,1209=>556,1210=>716,1211=>556,1212=>844,1213=>530,1214=>844,1215=>530,1216=>393,1217=>1044,1218=>982,1219=>736,1220=>534,1221=>814,1222=>585,1223=>778,1224=>552,1225=>778,1226=>552,1227=>742,1228=>556,1229=>896,1230=>757,1231=>393,1232=>667,1233=>500,1234=>667,1235=>500,1236=>891,1237=>646,1238=>670,1239=>444,1240=>659,1241=>372,1242=>619,1243=>372,1244=>1044,1245=>994,1246=>650,1247=>476,1248=>604,1249=>459,1250=>778,1251=>539,1252=>778,1253=>539,1254=>722,1255=>500,1256=>722,1257=>500,1258=>722,1259=>500,1260=>732,1261=>488,1262=>746,1263=>532,1264=>746,1265=>532,1266=>746,1267=>532,1268=>742,1269=>556,1270=>637,1271=>448,1272=>984,1273=>744,1296=>652,1297=>452,1298=>814,1299=>585,1306=>722,1307=>500,1308=>889,1309=>656,1310=>736,1311=>564,1329=>889,1330=>787,1331=>858,1332=>941,1333=>775,1334=>765,1335=>805,1336=>762,1337=>938,1338=>869,1339=>765,1340=>756,1341=>966,1342=>992,1343=>748,1344=>469,1345=>731,1346=>941,1347=>745,1348=>966,1349=>641,1350=>929,1351=>774,1352=>779,1353=>784,1354=>841,1355=>775,1356=>955,1357=>779,1358=>927,1359=>555,1360=>763,1361=>641,1362=>656,1363=>824,1364=>869,1365=>768,1366=>754,1369=>300,1370=>300,1371=>270,1372=>307,1373=>270,1374=>324,1375=>322,1377=>818,1378=>548,1379=>601,1380=>608,1381=>551,1382=>547,1383=>496,1384=>548,1385=>586,1386=>585,1387=>548,1388=>269,1389=>798,1390=>594,1391=>544,1392=>548,1393=>513,1394=>583,1395=>560,1396=>551,1397=>397,1398=>567,1399=>447,1400=>548,1401=>411,1402=>810,1403=>464,1404=>548,1405=>551,1406=>595,1407=>821,1408=>548,1409=>557,1410=>312,1411=>821,1412=>550,1413=>511,1414=>668,1415=>602,1417=>333,1418=>349,1425=>0,1426=>0,1427=>0,1428=>0,1429=>0,1430=>0,1431=>0,1432=>0,1433=>0,1434=>0,1435=>0,1436=>0,1437=>0,1438=>0,1439=>0,1440=>0,1441=>0,1442=>0,1443=>0,1444=>0,1445=>0,1446=>0,1447=>0,1448=>0,1449=>0,1450=>0,1451=>0,1452=>0,1453=>0,1454=>0,1455=>0,1456=>0,1457=>0,1458=>0,1459=>0,1460=>0,1461=>0,1462=>0,1463=>0,1464=>0,1465=>0,1466=>0,1467=>0,1468=>0,1469=>0,1470=>433,1471=>0,1472=>155,1473=>0,1474=>0,1475=>400,1476=>0,1477=>0,1478=>347,1479=>0,1488=>593,1489=>498,1490=>339,1491=>523,1492=>561,1493=>266,1494=>291,1495=>559,1496=>576,1497=>266,1498=>496,1499=>501,1500=>510,1501=>542,1502=>581,1503=>273,1504=>347,1505=>512,1506=>552,1507=>493,1508=>491,1509=>537,1510=>561,1511=>544,1512=>502,1513=>716,1514=>571,1520=>532,1521=>532,1522=>532,1523=>396,1524=>432,3585=>590,3586=>578,3587=>661,3588=>592,3589=>592,3590=>699,3591=>447,3592=>534,3593=>692,3594=>578,3595=>659,3596=>899,3597=>804,3598=>633,3599=>637,3600=>484,3601=>730,3602=>876,3603=>915,3604=>592,3605=>592,3606=>578,3607=>670,3608=>542,3609=>671,3610=>621,3611=>618,3612=>621,3613=>617,3614=>708,3615=>708,3616=>637,3617=>589,3618=>552,3619=>484,3620=>590,3621=>569,3622=>637,3623=>526,3624=>599,3625=>802,3626=>579,3627=>668,3628=>778,3629=>560,3630=>514,3631=>510,3632=>442,3633=>0,3634=>423,3635=>452,3636=>0,3637=>0,3638=>0,3639=>0,3640=>0,3641=>0,3642=>0,3647=>665,3648=>357,3649=>624,3650=>529,3651=>486,3652=>475,3653=>423,3654=>500,3655=>0,3656=>0,3657=>0,3658=>0,3659=>0,3660=>0,3661=>0,3662=>0,3663=>657,3664=>548,3665=>548,3666=>592,3667=>614,3668=>631,3669=>643,3670=>508,3671=>744,3672=>622,3673=>585,3674=>721,3675=>1381,4256=>475,4257=>469,4258=>573,4259=>650,4260=>502,4261=>506,4262=>481,4263=>746,4264=>491,4265=>495,4266=>888,4267=>488,4268=>464,4269=>745,4270=>483,4271=>489,4272=>721,4273=>464,4274=>578,4275=>590,4276=>611,4277=>491,4278=>663,4279=>489,4280=>544,4281=>479,4282=>527,4283=>488,4284=>560,4285=>461,4286=>467,4287=>546,4288=>483,4289=>487,4290=>562,4291=>477,4292=>491,4293=>471,4304=>522,4305=>518,4306=>621,4307=>716,4308=>517,4309=>519,4310=>518,4311=>796,4312=>518,4313=>518,4314=>934,4315=>517,4316=>519,4317=>787,4318=>515,4319=>514,4320=>788,4321=>573,4322=>620,4323=>593,4324=>639,4325=>516,4326=>714,4327=>518,4328=>572,4329=>518,4330=>555,4331=>518,4332=>562,4333=>509,4334=>572,4335=>677,4336=>523,4337=>517,4338=>595,4339=>480,4340=>519,4341=>484,4342=>838,4343=>517,4344=>516,4345=>621,4346=>522,4347=>410,4348=>389,5024=>718,5025=>768,5026=>633,5027=>878,5028=>1001,5029=>371,5030=>576,5031=>754,5032=>531,5033=>774,5034=>692,5035=>499,5036=>668,5037=>829,5038=>575,5039=>681,5040=>485,5041=>607,5042=>885,5043=>974,5044=>588,5045=>583,5046=>726,5047=>947,5048=>558,5049=>832,5050=>1096,5051=>780,5052=>595,5053=>869,5054=>752,5055=>710,5056=>761,5057=>802,5058=>760,5059=>656,5060=>655,5061=>982,5062=>684,5063=>801,5064=>805,5065=>1042,5066=>755,5067=>612,5068=>707,5069=>889,5070=>584,5071=>623,5072=>536,5073=>763,5074=>763,5075=>549,5076=>1052,5077=>600,5078=>730,5079=>714,5080=>714,5081=>697,5082=>543,5083=>943,5084=>718,5085=>630,5086=>660,5087=>692,5088=>841,5089=>861,5090=>617,5091=>733,5092=>898,5093=>896,5094=>781,5095=>612,5096=>830,5097=>948,5098=>886,5099=>757,5100=>796,5101=>578,5102=>601,5103=>797,5104=>623,5105=>886,5106=>730,5107=>827,5108=>648,7680=>667,7681=>500,7682=>667,7683=>500,7684=>667,7685=>500,7686=>667,7687=>500,7688=>667,7689=>444,7690=>744,7691=>500,7692=>744,7693=>500,7694=>744,7695=>500,7696=>744,7697=>500,7698=>744,7699=>500,7700=>667,7701=>444,7702=>667,7703=>444,7704=>670,7705=>444,7706=>670,7707=>444,7708=>670,7709=>444,7710=>656,7711=>333,7712=>722,7713=>500,7714=>778,7715=>556,7716=>778,7717=>556,7718=>778,7719=>556,7720=>778,7721=>556,7722=>778,7723=>556,7724=>393,7725=>278,7726=>389,7727=>278,7728=>664,7729=>500,7730=>664,7731=>500,7732=>664,7733=>500,7734=>609,7735=>278,7736=>609,7737=>278,7738=>609,7739=>278,7740=>609,7741=>278,7742=>896,7743=>778,7744=>896,7745=>778,7746=>896,7747=>778,7748=>722,7749=>556,7750=>722,7751=>556,7752=>722,7753=>556,7754=>722,7755=>556,7756=>722,7757=>500,7758=>722,7759=>500,7760=>722,7761=>500,7762=>722,7763=>500,7764=>614,7765=>500,7766=>614,7767=>500,7768=>672,7769=>389,7770=>672,7771=>389,7772=>672,7773=>389,7774=>672,7775=>389,7776=>556,7777=>389,7778=>556,7779=>389,7780=>556,7781=>389,7782=>556,7783=>389,7784=>556,7785=>389,7786=>611,7787=>278,7788=>611,7789=>278,7790=>611,7791=>278,7792=>611,7793=>278,7794=>722,7795=>556,7796=>722,7797=>556,7798=>722,7799=>556,7800=>722,7801=>556,7802=>722,7803=>556,7804=>667,7805=>444,7806=>667,7807=>444,7808=>889,7809=>667,7810=>889,7811=>667,7812=>889,7813=>667,7814=>889,7815=>667,7816=>889,7817=>667,7818=>667,7819=>500,7820=>667,7821=>500,7822=>611,7823=>444,7824=>611,7825=>389,7826=>611,7827=>389,7828=>611,7829=>389,7830=>556,7831=>278,7832=>667,7833=>444,7834=>507,7835=>333,7836=>333,7837=>333,7838=>792,7839=>534,7840=>667,7841=>500,7842=>667,7843=>500,7844=>667,7845=>500,7846=>667,7847=>500,7848=>667,7849=>500,7850=>667,7851=>500,7852=>667,7853=>500,7854=>667,7855=>500,7856=>667,7857=>500,7858=>667,7859=>500,7860=>667,7861=>500,7862=>667,7863=>500,7864=>670,7865=>444,7866=>670,7867=>444,7868=>670,7869=>444,7870=>667,7871=>444,7872=>667,7873=>444,7874=>667,7875=>444,7876=>667,7877=>444,7878=>670,7879=>444,7880=>393,7881=>278,7882=>393,7883=>278,7884=>722,7885=>500,7886=>722,7887=>500,7888=>722,7889=>500,7890=>722,7891=>500,7892=>722,7893=>500,7894=>722,7895=>500,7896=>722,7897=>500,7898=>868,7899=>603,7900=>868,7901=>603,7902=>868,7903=>603,7904=>868,7905=>603,7906=>868,7907=>603,7908=>722,7909=>556,7910=>722,7911=>556,7912=>879,7913=>704,7914=>879,7915=>704,7916=>879,7917=>704,7918=>879,7919=>704,7920=>879,7921=>704,7922=>611,7923=>444,7924=>611,7925=>444,7926=>611,7927=>444,7928=>611,7929=>444,7936=>590,7937=>590,7938=>590,7939=>590,7940=>590,7941=>590,7942=>590,7943=>590,7944=>724,7945=>753,7946=>891,7947=>912,7948=>822,7949=>853,7950=>796,7951=>787,7952=>430,7953=>430,7954=>430,7955=>430,7956=>430,7957=>430,7960=>864,7961=>905,7962=>1034,7963=>1038,7964=>1031,7965=>1045,7968=>548,7969=>548,7970=>548,7971=>548,7972=>548,7973=>548,7974=>548,7975=>548,7976=>976,7977=>1009,7978=>1132,7979=>1141,7980=>1138,7981=>1154,7982=>1079,7983=>1071,7984=>320,7985=>320,7986=>320,7987=>320,7988=>320,7989=>320,7990=>320,7991=>320,7992=>593,7993=>620,7994=>746,7995=>762,7996=>742,7997=>773,7998=>691,7999=>683,8000=>536,8001=>536,8002=>536,8003=>536,8004=>536,8005=>536,8008=>899,8009=>928,8010=>1086,8011=>1118,8012=>1020,8013=>1028,8016=>536,8017=>536,8018=>536,8019=>536,8020=>536,8021=>536,8022=>536,8023=>536,8025=>959,8027=>1085,8029=>1108,8031=>1027,8032=>715,8033=>715,8034=>715,8035=>715,8036=>715,8037=>715,8038=>715,8039=>715,8040=>946,8041=>960,8042=>1133,8043=>1148,8044=>1059,8045=>1081,8046=>1020,8047=>1016,8048=>590,8049=>590,8050=>430,8051=>430,8052=>548,8053=>548,8054=>320,8055=>320,8056=>536,8057=>536,8058=>536,8059=>536,8060=>715,8061=>715,8064=>590,8065=>590,8066=>590,8067=>590,8068=>590,8069=>590,8070=>590,8071=>590,8072=>842,8073=>877,8074=>1011,8075=>1031,8076=>947,8077=>975,8078=>907,8079=>893,8080=>548,8081=>548,8082=>548,8083=>548,8084=>548,8085=>548,8086=>548,8087=>548,8088=>1030,8089=>1066,8090=>1188,8091=>1199,8092=>1196,8093=>1211,8094=>1134,8095=>1129,8096=>715,8097=>715,8098=>715,8099=>715,8100=>715,8101=>715,8102=>715,8103=>715,8104=>1060,8105=>1076,8106=>1264,8107=>1287,8108=>1179,8109=>1204,8110=>1137,8111=>1135,8112=>590,8113=>590,8114=>590,8115=>590,8116=>590,8118=>590,8119=>590,8120=>667,8121=>667,8122=>752,8123=>728,8124=>775,8125=>250,8126=>0,8127=>500,8128=>500,8129=>550,8130=>548,8131=>548,8132=>548,8134=>548,8135=>548,8136=>884,8137=>859,8138=>982,8139=>968,8140=>839,8141=>500,8142=>500,8143=>500,8144=>320,8145=>320,8146=>320,8147=>320,8150=>320,8151=>320,8152=>389,8153=>389,8154=>599,8155=>592,8157=>500,8158=>500,8159=>500,8160=>536,8161=>536,8162=>536,8163=>536,8164=>536,8165=>536,8166=>536,8167=>536,8168=>722,8169=>722,8170=>1007,8171=>932,8172=>842,8173=>550,8174=>550,8175=>500,8178=>715,8179=>715,8180=>715,8182=>715,8183=>715,8184=>971,8185=>853,8186=>1004,8187=>875,8188=>862,8189=>500,8190=>500,8192=>500,8193=>1000,8194=>500,8195=>1000,8196=>333,8197=>250,8198=>167,8199=>500,8200=>250,8201=>200,8202=>100,8203=>0,8204=>0,8205=>0,8206=>0,8207=>0,8208=>333,8209=>333,8210=>500,8211=>500,8212=>1000,8213=>1000,8214=>333,8215=>478,8216=>250,8217=>250,8218=>250,8219=>250,8220=>500,8221=>500,8222=>500,8223=>500,8224=>500,8225=>500,8226=>350,8227=>560,8228=>250,8229=>478,8230=>1000,8231=>0,8232=>0,8233=>0,8234=>0,8235=>0,8236=>0,8237=>0,8238=>250,8239=>0,8240=>1000,8241=>1618,8242=>278,8243=>556,8244=>834,8245=>270,8246=>468,8247=>630,8248=>469,8249=>333,8250=>333,8251=>727,8252=>778,8253=>733,8254=>500,8255=>953,8256=>953,8257=>338,8258=>931,8259=>333,8260=>167,8261=>332,8262=>332,8263=>1000,8264=>889,8265=>889,8266=>500,8267=>453,8268=>479,8269=>492,8270=>500,8271=>333,8272=>953,8273=>500,8274=>521,8275=>576,8276=>953,8277=>785,8278=>410,8279=>881,8280=>620,8281=>620,8282=>179,8283=>621,8284=>569,8285=>179,8286=>179,8287=>111,8288=>0,8289=>0,8290=>0,8291=>0,8292=>0,8304=>300,8305=>219,8308=>300,8309=>300,8310=>300,8311=>300,8312=>300,8313=>300,8314=>300,8315=>300,8316=>300,8317=>216,8318=>216,8319=>362,8320=>300,8321=>274,8322=>300,8323=>300,8324=>300,8325=>300,8326=>300,8327=>300,8328=>300,8329=>300,8330=>300,8331=>300,8332=>300,8333=>216,8334=>216,8336=>350,8337=>296,8338=>320,8339=>337,8340=>298,8352=>667,8353=>667,8354=>667,8355=>667,8356=>500,8357=>742,8358=>722,8359=>1008,8360=>953,8361=>889,8362=>889,8363=>532,8364=>761,8365=>742,8366=>631,8367=>1435,8368=>579,8369=>609,8370=>639,8371=>742,8372=>576,8373=>500,8376=>524,8400=>0,8401=>0,8406=>0,8407=>0,8411=>0,8412=>0,8413=>0,8414=>0,8415=>0,8416=>0,8417=>0,8421=>0,8423=>0,8424=>0,8426=>0,8427=>0,8428=>0,8429=>0,8430=>0,8431=>0,8448=>624,8449=>625,8451=>925,8453=>623,8454=>737,8455=>631,8456=>709,8457=>867,8458=>500,8459=>1035,8462=>556,8463=>556,8464=>792,8465=>737,8466=>800,8467=>427,8468=>835,8470=>806,8471=>855,8472=>666,8475=>747,8476=>955,8478=>722,8479=>722,8480=>991,8481=>1050,8482=>1086,8483=>667,8486=>741,8487=>741,8489=>320,8490=>664,8491=>667,8492=>806,8494=>551,8495=>444,8497=>723,8498=>595,8499=>1203,8501=>537,8502=>537,8503=>350,8504=>537,8506=>942,8507=>1050,8523=>698,8525=>1028,8526=>396,8531=>750,8532=>750,8533=>750,8534=>750,8535=>750,8536=>750,8537=>750,8538=>750,8539=>750,8540=>750,8541=>750,8542=>750,8543=>750,8544=>393,8545=>716,8546=>1039,8547=>1040,8548=>667,8549=>1016,8550=>1334,8551=>1657,8552=>1005,8553=>667,8554=>1024,8555=>1353,8556=>609,8557=>667,8558=>744,8559=>896,8560=>278,8561=>556,8562=>834,8563=>722,8564=>444,8565=>722,8566=>1000,8567=>1278,8568=>778,8569=>500,8570=>778,8571=>1056,8572=>278,8573=>444,8574=>500,8575=>778,8592=>964,8593=>964,8594=>964,8595=>964,8596=>964,8597=>964,8598=>964,8599=>964,8600=>964,8601=>964,8602=>964,8603=>964,8606=>964,8607=>964,8608=>964,8609=>964,8610=>964,8611=>964,8612=>964,8613=>964,8614=>964,8615=>964,8616=>964,8632=>964,8633=>964,8636=>964,8637=>964,8638=>964,8639=>964,8640=>964,8641=>964,8642=>964,8643=>964,8644=>964,8645=>964,8646=>964,8647=>964,8648=>964,8649=>964,8650=>964,8676=>964,8677=>964,8706=>494,8710=>612,8721=>713,8722=>606,8725=>750,8730=>549,8734=>752,8800=>570,8804=>570,8805=>570,9251=>500,9674=>494,9675=>738,9676=>732,9711=>855,9824=>618,9825=>645,9826=>587,9827=>582,9828=>582,9829=>645,9830=>587,9831=>618,9833=>333,9834=>556,9835=>778,9836=>778,9837=>556,9838=>556,9839=>556,11799=>333,42790=>778,42791=>548,42792=>839,42793=>615,42794=>652,42795=>452,42796=>478,42797=>422,42798=>675,42799=>627,42888=>333,42889=>278,42890=>282,42891=>349,42892=>278,64256=>602,64257=>572,64258=>569,64259=>842,64260=>838,64261=>577,64262=>662,64275=>1105,64276=>1105,64277=>1099,64278=>1105,64279=>1361,64285=>266,64286=>0,64287=>532,64288=>552,64297=>570,64298=>716,64299=>716,64300=>716,64301=>716,64302=>593,64303=>593,64304=>593,64305=>498,64306=>339,64307=>523,64308=>561,64309=>266,64310=>291,64312=>576,64313=>266,64314=>496,64315=>501,64316=>510,64318=>581,64320=>347,64321=>512,64323=>493,64324=>491,64326=>561,64327=>544,64328=>502,64329=>716,64330=>571,64331=>266,64332=>498,64333=>501,64334=>491,64335=>593,65533=>900,65535=>700); // --- EOF --- Collabtive-2.0/include/font/freeserifbi.z000066400000000000000000007664361237252063700205450ustar00rootroot00000000000000xw|U=wNz#眜 CwAHҤJWQP(RE  ^@n"R@}N۽g1{fϬjf&R_.f]vyf8YFZ4mּG QЂZth߹ћ3h֫EEm3k*]-j__var'odII})Bx ?fUA*D![|p߶B,=:RD y =u:>y7޵鏦?xq _q8*'7}`ap>~xq#=h~gDo~.\(D?:ůn7Ǒ @}~oj^z9#bΚ+UG]+.l5gT}nׅbثx엃R'w% m\]%-ψZRcTs]-5D)Ԫh*lj(PR@g٪oh987I1UQqTVZ]xneLE{YXw 椛B9N5)GZ޵ E#m*ז VN Z Q.*#2TvD"մ阤M Y/8~/+]F͙ӝZq;hczFNL40&r}w_^()9mT杅fΩȖ b#>"[kbYRa(iIP*Ń+0$&Fz?D]?ꊚ&"~f87W>C^2`l=~v1 {[+*=bJ|^Sx6c_Z*ު[JϿgE̷ 73ֈSXB߉{s5&Nv7eo~Ėkg.zbٮDiӿzwӻtS+iO'CjMՆxQ~?Ę}kNbߍDmi9H6LqUE0icEaŋA1@ޙ/}›S1E_jpWDZOwgOwS4P'}c\ Xk%մOatރiSʸ5S:;]'>7N7ԯ|3ϼ,WM,r.]i:r V/۹G̜X?ȹ|O>Xvw_,s_N&*>*E%n ~s:[]mwo:*geˠ4~ц Wb7 ?˃em.Je*2ur 9kvae_;G] ?oDOF"MGAkgTi턷24ƒ3T7m:8)BT8.Zsq64m 1V[-qVOGοb~Jh܃iϪ56A_˹jÚO4-N7?2x=g.sؤI[HA8D޺J=WѯtUb. {cOV7,;ggX@JqC<$Х)G~mw TnC0n@e!57P2^f@}`;ԏmS<{Cv h9md:vm+:BNP;5/Sehntfcqڋ }y:[.ܙH; T~4ժ5~D5arnY|f\62j0ys/'_3཈#S"$R_Xe9KZ{]սze<9{'r޹~RWcz򏻗KK8s~`Yl~Y3ۻ7۪qϚk|ԺL)ӯf;ySԻ0z`LOd1S~YϜ=1ΒSVnBɜ5}<_}s]Hi3r·cP9V >a[.xDw{aʡx+,U~ոǣown Q|Ѹ5+ø2#t)z2:n]*pSډm_w vǴ/@ܙ<)+U]vokՑr8 />P1 ʕfg }/_CX=Uy{Wq|EpĪ#vt*v6٪7md%FսIũ29j^7H[=;:s=3i:Zvz!cCYGsGNr3ĭ6_4{EFn~W޴R*K@OL_nbvG1AĻԄwY!F?+o_3OjhĻ%4ъrUteQv֋cM'O/{ ԉEQ5/P@l*"1L-i =}DߎW"}zI+scw-5Zւ&-k8z}r9y-Cx'΢U D0 x}Q߾z֜`p!|O ._Yރysh |cTsu|sY7[0oqC691m[/u4ޥ&Sw?_05u}u-=i?n[[wh-Ýߦ;qPߡmFZuÑx?߂e%oGop?Gwɻ┚;>_._~_qK&bX,m]7Q!y?׼}9\wbjn~e9}q^rwך.ĝOuw4B{ǝ7>ީܓ2评@c^w;OqjԲy˙pFv9O w*w&QKa~>#ZD&ŪQߨK!}S}N3I7/_g09z;vE]r;7@&w0'x?q;O'cT٪ju(wo-y+5~EbT̎=5]_IB?%kf22ײrR[׷+b~ m6{l؞c'ne؟c+b Kۭ;ǭ笗֟mҦۼlA0[nK۲lٶ[=[k[;r۶l8׸จq ~N|0YWVVZ+*W6l\ٴqG}UVjnZO6@F%rmF[m^G@Ӆ~oԲΟUoe~ M,?@ B=!j-ի6=BKfC眛@O; XОکلV8UKN5+}5މq9 Ǡh N W? ͅ"NA !puRPt:)WI9p,P }Ze Z̡fyFF 2Zv'!dp9ED--XP0ہĤo]siABe돏?YB2֞22 oLZܚf3qĞ \m=vzzx!*]T+J̓|T+Q%63{<ޤ-L\U*O{es=8C!eQ-{+[?+u*3 UpTc^v+!D 7`A+D^%*5D  "Q$d"REU]Y"GSEq+ȋb-3bX%ֈ+bX+֋UIl7TlV]l;N%{1!:bxIC/1bQ5G@=QC<(ztP 0^_liUv1cxހs 1S,A2=====˽x(@uɽ{Gw8r>"'w!*⼏朌 a},XGlCvh_c|kM>تy e~(@:`A:uYuYuYG=w}l]ǎћRL4vlkk!6oH\4DFoDq;6BBbBlQ81㍑1!o!oQݰO7э5_7ݐrtC]J_ +Ad)Ad,=@҃oz37| oϺ[_|ٗ~ؤzY@v Ac<A!J Ea0yڇu$v F(ލϏǣ(c4×c8ޏC`gwrMD8gNq= }&>y2>o& de2L&^&3w2:M䛂lSw qa'ho:|gkffc<g; Ywll0Fl39nsx!6g.:̅\xCy̝y̝y̝yn>#|d y>2G }/@=d] u.Dօ/gX?S=ߧzyg3p |g =lς,xς,x9<9ba)>_~w9ᵂy+w%=VU/>Ys^"^FF+ k++ȾXY,y=<ֳ~=6ـm7 FlBMۄ71*n&7c:ϯ3:r.RΧRt߂,[V&>F,my;X9-k'rdm~> ;]d.w3o7=tz߽Ϟ=`=`~@|߇>G^t9c}O}.z⛃s}5#s}~_`/{y!pCC!|=10<30s0rfa:#;.Gw]_G_(y(~>bӣ(_1|Wac;=1^ǐ:1y>ǙDZqd<xy p۞@==f9_3ktݿ&7t 7It< '$2dI$. x/EE0/"E]D_b_ߡw1;^߱;t(W\v)#tSr}=sǯc{Y/2~ ~D b s`˟'x^?!ϬJ\{]'>c `TM-t> ׯ+s~cowGJUV J@n9.qS;xC6ta Ci2HQE!y^!$4ZXxbXto lCO;s3 ٙgGW;qw蘰)d"6N¦IțL?ۧ"g8i5b<![f!DLdD,ѯYZż`g#w2|z ,$% УbGH6]!*1#ccti.E<7ox4ŦXqϐ-hH=j-Fbt*W1kZ̶6h}{|]:сyȚN_gujxc0z }Db7:6}M_tǚ~|['.1 T-2AtΖcl9wX_!#pǏ#y{aa$3F#E=\QFhc{ .c8l1xl7?G;;xm<6OG0qx;& 5'7&0'2"v?'&"D6&DNqDNdp&)>٧`)a OEi{Og:33c&sfaKqI-.t\xͅ7Ϻ]q!Eȳcۧ-!>} ƞϢsȷ/Ee@Cb93p{?؟bgv"*Gٻ2rG^ 9~gx_Xs ?]#vy=:<ӿ-n*woM|} /++c17txdV66;Bvc8aB„{CgShB|yZB#4oy3g|B?G2> +GX(x&cbn,Ƃ3q`Cq`wk~ϼe<:'&ǃYqkg6̉Dql2 '!$dL$1 NBI$l= NF<>3>w26ši*8STT|7 Y!4d,Ӑe1: >8'}O >Zg |19_M'ӱtl1[Lӱtl1[L3 l1 3 ,xςlpk3>3>3>Y7us3>sl:=ړ>[sU}lAeec#ay{^_\4=2xGl#F#y00000-w B|-  -w"]w.BEȻy;~|k1S`?oFiFy4v}?>0rǏ{-tX%= ֳ`=K/TR|/K2| _-W2| _-Wϳy<ϚYuu_:ׁ=_z׃O=7 o7o#F7o&7 MoWWWWW >o3 f7     777Qo0 79RrN)9VJ)%J9-%7l!_l!_l!_l!m!lrrrrr m+9o+9o+9o+9o+9o+9o+9o+9o+[777memmCmݶvtێnm;ݎm3wi:@ȶ[@ȶvx hoa[jD|wڅvovc`nd؍'iGޣ{=>vb݇#.w᧏܋{^OOO ?n}93w?O} ?#?Cw^gsuXw?? l| VO Aw=Ab C;KQ?ʞ _#8'k0IOƞi5F̞Fo跬}gt8~ :*Nk`^B_ 2"{:P™\c:=X@`sw7 >qxFq5n;So>-'-&]XrR"[zM(Q[ 㴱fKLAD_ٵJ];?[ڥ=.WMVO@)NZ?qpZ:enlH|S{%Vwʿ}R՘ٻqM>^RP<HTޞឞSsX&mޏI4,"4̓PA;MakシQQ!QKxyŸmD}тieM{P m(qs}57@< |{\p;,<%23(MzSv;ņY%OHl]M^ QNq^JAj>K2с5dØ^_cR|}cC)y &:04ESE G+bl_ŤYcSfĦ=O~Q|^Aw;Aa\WVsݓdyFgJvJo3ẻʌ7 kŠWMrՓ=iEU]߰eSYV\"X^=;~l<{;PW04ؒ5%3:N7zy f 9UC%N@)/͖[v{޾ ޺JL\S4n7>Y!3I{}angcZg7IkPs^ quZ$[Q7fԄVId Q?/kJ$_U{| %&{ S@םccv^4&((6ը:C>k^˷WGVZ*(?M3nHwyQ;9y<> i dS烒(6<V0L\f+EQE܄`EVUS43]ݸ&S9Ol˵@ZxZTRr/Bs3$b4S3]MG`н[B=Iwht|x5)G6N)L%u=h'Ewh!--0+ǭMMªD#']# iM5%nVW'HdzY$Tȓ^i^-k 6yu )ꛯW,`dznnLiJf/mҳ_ [%GɓY*)s4v732d2;?Ok%Sc T}T;٫?"DM.J9S?ˍ\ջi`H -<\J)/Omݨ$AJ`b,\Ƥ{-!\|Ցh H@Lj bv]^M=Rv3d2RmS#u,v@:) 5<)x{{Vg^Ug9NtNe$y6|a]m=="͉ngMYi'#eLv+I*Wpzl䢨*?χ@ʒFTj U+DF{r-%\7~*¸huܪ? adJm4lm!OȗJiծI[<mͻo>/y 3MxjmPVTKdTAcOϚ1p'r\u_\z`&zŗku4~_ȼ:ԗ`n jKmܰ_LgC} XGy~xkrVZhc, NWVzKlAА՛0;ԵVF~ԚqО;ǂ)Y\kGL|‚[5nWOLrg5 bzy<rVUkoRAD|RҮN͸ {󑅽G8DI\l(V9+PUHF-{VmMLZv`RxrֹrM #Pp۫ot+omG.&v7S*VZVSQEL &.Lx`/ LYvNQtNMFN`^B72ʧwq/\ؚZdZAYysfnY"֔#8(4R ֨kmS;BfW/Y7LZe$:y}*)ISǑVkPzGs %es2>KlqcVOP Z]\_K*,X'J\l_ilV g Syd{w$k|(:1ZU$x:;9\/ĐƢU7ߏR9%59'cruj;T{+)sx\Rkp,X~~֜.tc]r 5s]O7_q cQ*שETvp.Jl6YVMS=W5mgG %mxa pJ2'e6rZEehٖDLˁ&/-66qg('z+qF߈Ӟn.jT}+H:6\SCdpQƨѭL-̹Svc\mUU2`ޥ6]`h^46|3|h5S'LS_Tvώ٥r9"a#>Y9,7\ .7uRy6Ca-LdGO9MCBj7ePRNfv,Za'H߽HPbY8#3*]i1vRlˠhW>m[uSq }>aәD[LRȶ;} R9Zя}@խYH`'i"ف<='ĮRݡ=\RvP;g80F-,-SHNʵ&n| L6B݆^=c(t_ޡH\?@kHsQ%Ֆ6+?6>m~Fmw1;KtrMX,w7'ϲM>w&&6zHܣNS/ݥ(H>$ju")ڷ+@de!xyaߙ?K.ⴻ}!WaJfkwe~䚪G@BDyl`|(i}LkLeu>m Xj2T*cul2v4u/%Ya4hH˦yP>6Fyr:,h~NEg\Y) Mm@pKUo?Brәvn.2YM)M44OjcPlAm(nLLa[ZM-W\9`6 NWM י|ۆ6ܣ] 9+D=C"MɘabŮsA~a8@S+2'kWEJm4CyebCe ;Zsuk5.wΖPKX3oI" , ޜBj"p,ٶ0gMńftO}ȱ퇱,Ѣq`~LB &x<2eʌW8Bkv$b-ѝV {z_!0c?xy¡UB;^JR@2a}$),!1h֩ƸaWfV-bF~qr[ϳ7^eסD :Z\#q'L.ϰHA[XqFbJ3osb4$?>I( a7_7`ZF@3ѦNG./~Ned `ۘ+s_}\$8 M ` T`I/ ^ ـ S27a'K82F E|F+E60r)0ꖵS/90F!7'΋gHY5k+.Tgy7Zb벂܅, M46/5 5SQp(vŹLT9VnGK4Ŝ߬8Tgc]_m* ƾWXۧhi 9ReO6.~Cͅ&|(]X"~>h%5U͗5jzI*8<8lM5ͫ8nUb_v n:6,v!#hy!ylxQUsSdEs sgJϴTƃu <҉+m 0([-Ӄ~}Ќ}xjs50͟9JOϏxEԯW4Q_bUf^Ծ9 y<]hg }kZ->b ]MzƼHr^k'6190m>cjJCkMwMT{oH>fv 1uz0&!=;%);B5B()J)s1]H{ݡr4ĵmT2J"ZM N,uzWy"+&}IIH%*˛wo iD+TRZ ~-qmHOR[y"+czY 4yz*M/Ε~夀CrSG}w;oTFI4S36Lv;&/7M>éTd[n愝Y uXjgh?rҾnqZ(Dbvt}j*X'A+lFv>BR䑀Xs_?Wunk0 c*ލPn\c MKhfϨ~|WŲ~7נ\w;19<_>xt&KuF.k0iNvۂp ֶ65L∪'R>a 9Yz-/OXO$-FQcR.4z?\0o`@fډ IƧrr^a^A2GV{"a<75%ۍL_z^1ywaBӡyFId-|"̐,K q6Ҝ Xb`hq9Ime(O?nk(tECcZ.ອ} VӧY!+Y*/ǭ On苀!Ϻ+ B.֓p146tB1N#^|V4eۙ2ݲ=TXzƨ7w#cJbX*wıq>d* t)R&K]j$VӖj(FZfק07C`) JuXg/4,HN]i0plpdw#ͮtrWH3/q .8n;U#p3a" Olw_4 3K'`(^5YêrY VM';fwFSiO8MziuI3|Ϲ=Eb=P.@2KT%= z;EOֵ﫴=Ej!f׫Gl=#zuۑBF u_An GUeL4/;t<[OgYY#鉦dk;Cv-TI)( 瘼 p,a<8 YL%O\鰇Uj q;i)'!-(X]QR36HF)5L+AR<$# kD> ː==bvn`c*Sp0H3j_SA1C?a/#bN|;⋟G7^$Ofd0~_epG]N/ WQc8 >oݧ1دy"r,oeՃ2Ceש%UKA|'~!u ysV8ڔ.Fܺ8o8ˆbw$͚See;vz٦c_vz`|y^|x;:C4 4+ڜؾS}vD2>PQk`"8aB;v #+XS0Ii'wZuÆs'4FQEA :&jXbAk `5ҕY<[l䳂"L;)dk4TBui+m ݒ5~.sMsM˺rC._sW nIn.ϕ*Y U.p k[7p욋9 xm/LLR׾s]xԵwT78߫j+?_E~_0t"\ϭhJ#8 pkg*:Iw-W֛<@!=ut.ODsCmꎾ6;#Xi[`rʁ},}WF A0WEK%q[kC #3$TtYpµ1֣&*x rN NiOދAi~/A~ڟ;7&KqULUWյ53%Gǵ@T>9H, -ʚ˿༠ h?wv&~% .9!$4°ݙWOs9=j8y늨xdcя_6$kwp+usۿE>5yCM5B~};[~,f/ҸħwDc!չc;Ch- "#t]&:B(53<8&mko`Zذ#e/O_ts7d`rnv/Ka{Og^s<xmVRXĄ)CvwR^%9CjrA %'&^WD&؟åUٻm7  '?P0I+(kwu A;4);^(=0GM+<ʍs7 4R|d UH"WشFAQ6оѥ 8jwԎ; C/ p9/D! Eɇy;8 yG 5N V23[?S!wlNc?BlYޖ ~*Iv]m}m:){FKIZu,}B7|p~09=m;!W?)InA?F$$9gpN4hWN圗b^AKB8[%T=ӐYN$ g䬧OYNfO^`&w_ЪZ;끲X."g$H 慵};xaD7ҢyjOLK8KP\\?YQani߷D|̎,7i?y!>-! $k&ߓsD->dpڲL}F.QҨ IZHtaZt-f_LA-uه$XQ|?&?!>*ϽmuU? dr? ח?=9V ^^u~Xu:*`ITgכ{%F+1=S1D@+RXF)ɹA!(CQR`.Qk+^עEk#v ֿAH 7kkؤ;}OڬkW]]9?Z!O@~)="9ȯ xrv߻uU_ :@Gd#5+өj4Mi+sۮsuti Z^[WQRgOB.>^YpjFTnV5Í{Ʉ';kWSYܮFwI*x'yCJX&fR e|O;`N>yp.ňpToZ&OJnRYer.O}5:4a k=-Vs*"Y[&LV+2&$ Z`LwhȠt֘, 5'ʫ7Utq:BvNR!__jj`ĩ"Q-|W]мZx8h)}rbqNރ$֪źEgKB\FuV t%̭5zB%QD.sJ7!x3z"s$tmb &)yoA*( -9pHh4| @]W N" z tk]Ҟ=;sV'6;й: X1v3VKݗv\V5#H^> EKW\Ed,VtjmؔuuԺEnpWoxtNshO j1MBg4Kkk-0 \ Gz:|i>< 9?TE~HYUS0H0LBS6/3V?E=ScW siKiͶr' J+:-K z gT3:Й Zx_J1h\hwCk NR/\{ wYKf7eW%̉G'l)tT-y(* ]PU0=vUsaT~}ks~7X$GA,ݰCۘT&3y\k%`ݍ/nS?+X J^b)6],ii+'z`R,IϏrFXL2מ:Ω r1FF|TQTQζy1NQ>}^ob|шFbK<_'_91Z)*R=$ϨҰo՜߽C#Ӿf]СfVRHn?nu3ڪs_I ЋMV A3V@D;]hWk4bs`>mɒC"&>xB  »Y^\wkBxmʕ/\D8+l=f쎱umm~U}9<Hvb{G'0W-&ժʊTC },nb6-օg tev/.cuQ?zP2kw7Ρ\h^-!y8u5O%š&}zJ/ 8w-=ѻy-7(Y ɒwGvmߤW_qg .1 L ZUIyau$ =.rS\<L.bұLЌԭf'kjI+29?hvN%zp&IӬtH(_lupb;?S5[V:%2M @Å_<Cϭɵ~1=#)WJ];֖%5̒sF+.uVO#6|1ϒҪ8/=UW6>~@UN;_ɜ]/:1l,4xC]kHԝ&q `%Ќ_Gm#} 9K )/f`LGʲF"Q#1wN[W]@ ke}ʪ?rDxh2ࢿ@A)q7&w/ԃ af&ur$BE=htuR o^٪iJ5;7& VUt z1-Ǖs?տ$t)+keP8/Z: RrMV!sPC!ƈ1b7~NGǘ`?bU 'iR$Y;sOgxP5tbz1U 隸W )--<2hzc-j6Et':nnBZ/7zKiD9'7 QMA>d6C&)IϲB1n5nj֒20Pz,>PT-р -k7ws@CqX9 $)ChQÙ/!vRR& Q'W,r <͑G߻@p \JTf_Y>^5S&.7iIoHToO4~АX,[K,?bC8 `a=h1}Ą}ࠔrGoKK*銦:s XklH%`3@>`+ጪ,$f1]q.G&D])9dGF()@|d@g(beİL:*ZTZ[M{ nK9CM>@1=? ?+vYM&[c?yZ4vR 0yl$lig(ȦY? *W\_"x&kf)Zζ-j܌]쐨dr8ӥ2zU٩+ .\~ҫzz.38]ֻVY8%MKk|BM8/(o\eÉ.Xg/)9^znsNRM$|RGs# R@/z@١5Hb_|_`T2+>kWV?= w:-o׭ǶgFo*ИCg7'& Mu穼W Xpov:Uv\䊴F^d?ʺdC dh^763&g$Ά,8'z|!${^aioV:Ο Vz*-zΨs1Y?CgB" W{BZ46:Azݯ#~]]GeZ;=/7e/*~#P`DftqI <86dR&bN1ȵ^1nyu~/$LsX3EBM3?/}ӑ%Yndtk];goEwD7,homtΪ70PrD g v̑$;LcvVMs|0`%.0sRߝϡׯjN[hXB,'_GX#U |>#z hfX좢(;c&5i/>dRSn37v lD ۤ~6&3?OtNlz-Jf}RvG ̦ڒgřjtp%=2Qpn+S c `*nkɍЅ{JK$ΎA=gG;E+O~Fr cCj^-P;i. oq\]N9MBkDch'0./m4-8rFN#rp2]^:  suY|?j݃|5HTooCbkXOzRgq<u T2U^D&*>#. #cC?tMrct~Rw!5CfT”YrZ^dʳp20՚ng~j%IPk|D2#MBG2jaaP55Yz%|Vyg7&Ldz϶Kv.Nʸy|/7_D<ż5{W>sz_Ч2N] |fy=ч?4H~l>( d c}/W &E6k~~1apkz%O+HʵD\^W ܍?4U!>~!QVo'_=\+ A l.  ]-SZ[-3i!yo% *ka&Hw~K8cm89`| 皿sZBrHxHא"Gvȱ]Chҥ'lb=er3RgWCH:Nty5K51sϤdT VjNħh@A)J4sҹm 6Ej9xzSE?9;yhZ!\8-j$8ˆ;R%F1[ָu4bҗNam?6Ql'JQ#e4R VVs ܿ^̑#/·@Q=@ABs^DGsz5>|>5Z_k+:߂]e^,@,J=UMWu[JW2~g d|bo@.qd}7]`CƯgO??~_0%dX~92>3[4˅ ϙ9W E~d?Wן2~}~2>~sfI"osd>~PIԫب5BҞw9Dy)|G bR[OI Cn&O[4ϮcOC,`S >$䳌h7#`"ta:in2K$Jq<ɚ-V8'Q7RoHQ4&W?/[6&ʓJ+SZCU=y؋'yt=CY&92uf&fQ[%R$AQ]d`2ÝfIDoOX-LӖBʬ7[=zAKc]=$^#"rG?*z /f+8YK '^|%r.#)}VbX5*d OHEem!6HKvT{.,- k-z|_`͔!45J;2fKrEei^G@72ՙ˹bh4y,6'=jt(m~3`r)UKNX8O˽TP.窏햷_pDv:(r )&חK?pWA:{ a]s`Vo+XKMsNRϓ(ƭ2jv}gm#AmGB4[ՌTM=q"nw8+701ܷ}LP͞vu:"s$bH\ҊJڨ\=zZcvΦ.~189Q_!8 N=$ʼn4= &Dz ]ʰҔ]@!v*%50ޒ.ކ7+SY'5M /:QzLu^K$vj!_|'O3%Jߣ"=ҕEw #_5-$$p[sߗT7RB)Z9c4h` z,qQ2*hmXk͵u-\xd6;g*ρE|p(.*}I_"Z ,zrA Ola㑙ѩ[V;ߚ9gg((V(!28q8P+Wae,][AgLb L, {y_ ) n w&nnt:{&L&dLN;GPx99'pb4|_jȎO,eǫ$ M|vVLP"כj`U ?wDNpH7f"`Y&h3g)3ɓ86; XzYh$̺ۏ^k&|~Xz0ln DW_Xg3љ* s a4,K -r+!o|}cc[poc6?գV5V\Q3`\pyobgگzp[+ݑgFxiiw+nza?n[yp_hr~NE\ޞX_?qc/1_kWhi.(7wCȮtt%Zeii!S&׾̗Oz@H"fIVۍp{Tr'0hmA>f`*74wJ. Q*|^H֝bI1437$vWCCKR8Ҵ=^l&W{P >DztJJŊJ‰^a;yˆN !e9%9Ɏ+aЍELoizS37mMu:/X%]gəfWRXpݣHxt?)Ne.,+J"b-*(*K5熹&75o;7=czZ6)z+mZ!"]--5P&SD5d-ՓӘ48rY b$3_ܘ z^0ROo 49pP=1A֫lu)JGN@<JYfN0|>mh`):1K\2ɛݗ$3UUcw404Ҙoߝ h5{8R&Y_7Y~ҐwN z$h)tprܶ'[ c?;Y"QoMÒ|NFrd[; \TXًbVm F׌Z:Uep9lGm#a@&x6sNKaBVOg]M"tVh6C 7nadv9Ѻ|}ۮ؃oQrT 4R4vTAgXו5RخZ*N"c%Ӗ/'(u֑Ι+-͓j{i{-^L߻\hayTV 9 8k7ߩVuSc'Gc*9Akez㉮Njd5*RmDݽG>\.Q͔;-݁a=S+(CVHJ;a N̲j Ce{wjeiyZR&Hb#ͼ  |+JHr /#D~I2JbWS}; |KaU#O6^dY Yɯpjk~HEjR\@|anM&1nR*ĠzmJz3@ Vb+LGs'DǛh`:|⩦# չK/P |obӉ!Uɒ!Uwt.pC﷭{ &(LHw*&zMk8#&˕kq=n(SxA/~!bA`|L Q'!|+MSAg,τuPe dVG`ӦuhU9;˪ vaWd!fգv^\%&m-\yGX]n\c?Lb}L('1v=Á-sbxHPzd32>_v VtUiHEzK+"g] J;V@Շ;b=z-.?wBܫm&!nvOj:S[s2/i^M8t &_/7Uz3wŖqZ)u-ۏLc~ȶw4>QѻA-NS%Y簬q]qXP\)S\J7Nl3@7j%KBr2;-5BBu&I߷JrCp=1ƫ{diOL܅u 9|7IߊHb6Up(]-IU8& ?4} F>kgCҰ;[XKDsbj0F!R-}F>1|QO/h9\3ຉ][Cĉ۸p;|xM hXmjHX5r|>yv* eHqL{M{;=}]7ϕXGiG-sPҴ,{b|{7"#8C(91+`એ :蚫`TGVpv/58@_Խ*J' O8Y7b8YU ,Y9NCN ~m2_cL !ؖb̬h)ʌX\dPP{ҭЙ=CQ?tz:` <4[k~n2sHF>~gx{ޓ.C4h{@MHo!эWA4g);0|GAXD])+qgMAlO@Ƞ d54&zuq8pGg)s(J5(jǺo/#O3g6Y:|^m6ȬOc*./{TIr>y&'4ўI{dmq70mǺ]=d a75e@cO8 aHN 1/+x{wd d8֨[P˷} xKodȮ$`Z@S":r{Q Im6tAj /*8ϏHu.4΍M+H,2ڇus&7r9mb\ysd668`|NlfuJB`TDLo-7f󳑩cUG.@{Z.%vRpkepxj?O6\!%ߖp%ĒR*qHZJ@aqh4;-M9Y#d&aҔ oe|omRL Ᏹ~o=t\Z)W,a[72M%471y] Ƙܲ_Ey1m7bXFmA uߠFZBTk#@Y2[$Ǹ\`ӈ'mxe1Ug}{1M5 pI|٭ 9HS n4ʙLw":sDk|v,*)G+σР-fmiE{%^K׍jV!1֩{NĩlJn4%̊HVMonv1wpTby]5Op9S?ˎEMt)i5:ZWxu5e6ϲYF5n}#zm!VF=D"*5Q Lq~/@Tǜ9 V&Z zYoУ6H",K}`Yv']Mh+R󣳼o=n7t^"xb$ƿdp[j<7i hm]4F4ʨ<Y vk-(!5c*rtgmtĚ?XT ᵀʣ1&oL _8P{'̲DG6&0:ꏱ} Foea c-gv)4[BnE۶*[juholgڱu HSҍDumzF6sH/^( 6[#4vfY8? MƨejW LRUKcho_HK24ޙI.uo\RAu w 3Z C<*Y!v6qc\pGPgp ہ܅Ʋ8%\y܄hY?&S7FC)V'cJyW'pq"l8~j6ۇpx*94O  5e[JGor G͓ Xrݱyط*,m)x8-;i[.;NI6ܤm S؋:dۤ{/ABQLv6`H\م28ڦdH=\ tHOVgCwZx?zv0#N|Wax?Zg1&걪ǗɹjF̰듡T@(i@{=kzMm~|ڣP`јUiUMI|Xu F04z>ez `eI<2&7~{!^\2ٌ6ܯG=_;wﵖ o.8߽O?}U5Ok䏓PwwpM-9c|ժ_3]stlwOw7CI#LJ9'#" |_/=uyC ]&Zv)({Kx hIFd_ {OI\D=]g'eg$T{3$C7#>@m d݁Sd12IbP A:]s8w.Wo\IV R> X[D:Ge?[d(|}b.\4~g[dH"H03L RoN~G 2ў֮ݱK8=) G?A`pVwˀ?M곛l$2!{DC$X\L ".Wf ]CjQUTWdX2;f?%IɡgT8C_??e5 GL2Qg$ W0]-I:pI:@_7(1b&ä!%_ v@$ ٍB>Fm{PZ ]2 {'x\roPh}(b!7Ê@JQ[Ll#) -i߄RFN[0 oDr+J@;x|vq7? dFoh؜< < fij66MH6}&J1̀燞'ݺ@Bk"#Z>6OE3QQnS@G$l,iLlFmfx7 RP/g(xoP0dqX~߂X`gOEBXܛ- !+^x ^{/v}.&$҄{ B7bWehHTE dcr1\P̎6 ]X~6lQ6g\ր, :71NFјP M#OH_vk_[~z`̤e£^ͼ+_, ?@kBFb ]ėd+;ZmZ#KaS@nV9K=`^<rk'}k|#jbP%LuyTuXa\2:G׼$SD!= !wC͢4n'""NEPWv $]Yiē4x4Yf}zƮB8Q| }[ w s4v~*6SM‡|~]v[]%jIjA!.ʜ&!|,M*3%QvXJYENkUs2F{aEbTFÝ1.VjA4̏cFSs{ d4ӜJSd0JPsA\E9h |"y!!_jSoSɐ2@=ACB^Q?%u웹Cȸ-;0 Ak2IlҵaL=زauor1E{hEW`CaHܔ'1uvG$(hZKc4VR,ruruVP>d;Pwc3k#, YL } gRx 3J)^Q ^@.W9]B)- yJ}2r/4ȿdzOl5JΔϫF9_X&,!%,wX90  gc'2S!B2V"z !;VXʉz{PTj]ެ5fFRiެGU~dC&\6mGc3.J *F^Qo H_\v>ߓ` rЅX)z.Y[r(wD_g~ҷׅ Oe*rs*/ba|! 095}"jk-"V|2j" YWBV>Z9\WNag8 Z Bk?2G|bT|.%I4ӂCaRjaccCūق*=ӭz~9*o6pJ c$ǀ46 S2'`fD@vYU@L:yI|lo&UteNo+y\On~&кlyӧRﻏ+nDbFEW-($ot- a-TyR%'>/l[nPkTc2vJXu858jgtn<h'kXmǚҁ ;ޮ:@eǭ[X sג s=)Z5ehVS.zNG"K|Y7VK҈ pxf2ۋmE #ע%ra^?gB\/p=]/iu0n}誁sF$, S݄Vh퓵NM& ceL{ԎXPKCc > JɍK4x>ڇo>iV9>jwHz` G%UHb*=W= !r#S?Ĭ[ipͪy ,yYCתpw/z4O]22 ac\# >D0JMH2UPB:p2{gUg'.rm~N*`s&YV6XeHs2MLno\ 9?g}4xo`zq[{[fYW;Pm06eX k(GcQiLDo'h 4V@0H_bY[&m,g P5j2zf%4oynOj`qNƜf鍰 KdU<]6%u@]23eNY%rjmj?8;I1]D7>p-!K.圕1- ,҈uK {~ F79 ;s5XUϕ8ύ݇I.MNS)fet&Ӭ3笏cن nKtuM kz:WpvƎ9SGtua50kq :%DaV"1bqJ\UnsؼschZBIcҼw4=XA`x!-O)F "^]CW6ڡ( uؼ#-l t*#ΊMja*HcHou%hI4Zi0;#*8VCf Ӌ/=0Uf2Ý3r"YUtÁʖ,6 iЇ!6yނS֮PUY1"bDOOFOipyVz}T+GN;}S/:ut|%{֮z]‰O4ʈNOY xb/ |0l—¿5>Q9%m/͇0> (V]]֢ X3I9]@65i'IzN;` A[tc=5Ϫ4*Jz. NaX ۔H\(_D}K@ $44*v M[Cm0B%Nf!P1gT~UϺL˗WyгGNbutGE˵+Af/t;M#-}Z_rBg;MeIm ߲$opģ q׆mX VAb c+Am@:.K]76fؿ~]0Еd\LxLįw쮔ӒwGͭ'laѶF+bC^=\AV\=`#5xii, ]kVť'7VIsYV+sU偃0$rxƧ-3wW.}ߊ2/K=fW^sh%2RJq$(kGWD2V:=uueZsgΧgh8CV9P n۪ (r%2JiYۡ aZ5YB&@4=I1J @}j# Q: #K,Ƥ&$#1dDY.e?7gđw97kdǘ2{W=&A:*sHTx=X\ߺh_xíkFo0o U?Go\s'̍aj%-s,>O`D/~TQS WUp=S0fк[kʈlb$K .>.t"QRE7|OI׿.]l:g$ Ru)|Vz8+,ՇcMmt;(6wM'~gQi?Ϸ xzudm*^Tls[wX} z77ZuU [mEbEb8R CRnaΗaeX c꼞 S:=L<]ig]?8ZgPha7mJxORv]/-xƚ|`I1L5r(5I< 4ˤ%]ekhT~w5+#vOҋ9^H@;ku󷶮-@̎um,vC _D&45q5x)JyDSӲ"´_1+d#{T d 1aT7FhT7؝J8жTxu5ԆE{~֬Tǜ'ٲ9X)"g`9{sX|>أTki `ɴ~t:A!Yݬsֆ&5ެKKɹtkY; ̡Yړt̫GjZ$-%TZ|6; 7o5Vciؑ\WjJf61,I֨5`n\6v> = ssog-Ѭ6BdχWX]&_/I/%7 hpoHwv=i EL.?uXMT+uP;XAqMH`ձAS|-d1JM?2()Qڵvk [YxmzY۾ 6Ӣԫ}֑p/mgTHGGLLf,)J NEH;xJ:v9<|>ե(ڨ\)?Vٱ̣bԂ|zcƢRnWH qTDlH[JnR3 h`1N+iK3 0&[񄸘cc6xU \)v6,+Na ;A  <ؔx\FSMx༎yL,b͞ŀk.Y[\gThb+ڟP;VՐ{醞/-d1w=h<0qxL*Jxeac }ԲXHT8\Ψմ5lZ9TA~L[ K'\cYgX |?EVy H,+k 5B,eE:/3w+A{T&169u`&Xݒ NwsJ3;: lj-Ct$(ShrlCB#5aFMt v$h'L+v睻p|޽+@O6qdԤM' ԛhtο+O~dYO9߷ԝ ~h쁒caW̥)[ⱎMOl|pp#>͖9ٷrbbNf%ƻbX` ya9c,)Xګ^0lhJS(ݦK ~MxL]u|l['Op=f -&x0S 87&Tsv%+a-mAGšu՛<@ۤo'8a qy`Q݃IjU-cE 8b2ڥ$}='bQx RL}˝\&[0G;ڜO Tjj)V]QY3yj247 >Y3c5hx:ݹ7:0?]^2qĩ,9yZ[s_ko-'{HUI1ZÎxG܀@|'T4d}Lw6Ͼ@$juoՋѠxŅ-(O|og;8T׭'Ƭvtݸz3OOG0<#M%F4q5:7.aB) R 4"mw5B\g8n)kj-!9¿_qsK9XU۾eIN iK8u ynjƒdYZ)Z 7Lq͊G.[snG]!jŽzFGyw;$KkO6{Tk ̲Ȓ m\uB0ss*>i!3I`վ_l}Ilu.j.i!{ҾҾ #ۅh5/ Q,WqbTQ b!dvOK_<7<8*u0v;t̉tuFZZ8_i1 ޳Vutʽ1$Esy>S׻wKP?b]Ȯ{Ƣɛ8c^K"LI =400焨zǦ-09bOo~[c;u,sS|/Q0Xx)^Jyŧ]ADb9/ |^+ߦVZ;I2RM)t]ϩ?yU[U GrĒ夞X*XM°V+զ:9Qo)%Q{Z -]Sw.fCd֤<9g.<Օ8oIIj9szFÊkSOu`!q')(Ko4ٔd0a.TՎG3.qVV-AEZH^H%t ͉%6,1/=ɂ\=6ݡ\D]>]MZ=XU@߲; ]tWɴ2ߩn4DGoA%ҒeOYs/QF֮DAL-h.u3kBi(XK8d2MޜSbk)jx2;*dca?c,x|ڪ[_=~ L&[e;ɹ1B{i֎UEWȾlbR>w(:BXzk^&%*UɋK(cBT+͜#:mik`4YH(uyzrMZ=^*.M KΛ)^l4YkOsu&xZ1JmzdŊ (\ ^iXު#/kf$O@ʩᰉ+UՆRlMGdGJ5rUDZ}1VoイmWי.yZ} ,;u_7fIiپP)0eV;#:MM˗j3gq)ćeXfhrv}+%},|`["8?`|Ogzd503aהyɋU6GE,ƚ(f|=rD}{:s kerT)4s΂[=hMR;Y{'VmLANh>Z(WwF&y5i?zD^|pXP2_Sf##e=AwtAU"%@Vl)'KBrkmWNԽw|չ7gfgf{׮H+z,ɖ nƀL3z!H¥݄tHInn 7!=.WslVOs󜧝>z=9~σC5E/Ȏ9B>P/ŀ$?3bX 6 :\s Zߤy ]rˇAצ=?EI}&jhߏcZښ4k6bKK[W=_?G>Q7kI|#'Y-mNM*4證tZyq~;BvuK5C ;;AEWvj cpΥ' c*+qpu2/df^zd|l I+&4;"뚆e 2OK@yNZt{WBH;'q`,}L3O%VFni<5D2qgKAm?y X6k^2cAk9g*Wq#%#VwߞuW5kz۱6&Ǖ xu]yA~:+\,^d ֟lӫӥG,̾{?yEb/K7~wxuc?QcK#W&<'WVl'P<[ Ku+Jf;⃦94g~(T:Mg s{sǂf| x w&dEwue۝|XڗvcX6Q{# W 9¦qζ8aK3%ZbD\q4ߥ!UPH*< e2>2&;;1WՊ\_.Te:JVuJ~K,2UgQņUC/=* |"XPȟ:n3 XWS nr0 CGBT[.n [Ik~:3{ߖW폃m+o*|$gwKB9kɇ &o &VƟ5^$֥x8b.V:Mǻ]+9圩@ۼ}R]o{mphflt^~̫tuP;a~1T8Ȱq- DF$]SkkL.Hb#|Q*6y(#lN]} : 7 "j|]/_(_pB)Zۄ *A44PРb&ZTFU(iQpLJW*2G ;djw;*ݣ3jNk> 5*ծz0ud׿lupa-uխM{D>RɥտԽuu[iͣij.U)!A38/pLTUu ]̆_Z(xF;;o'!ZS*4m9_Ǖx 5(%<;5z~ï׈z}0~-Dg޵v[o B誽V \+"5E{z8¹VOBz,>>h4EY vcG7\6m4w*,PyHŴ2_horOK4d/5B&gy"½xN&U$*+x3*:M_vt2VmqGKqnTH2476#a;cVDVYJ& 1ftMj岾YpDS!X\.\ϥ//v}7J_w?{6DL+føQ: nbcW@U1ݮJh5UmAClë|RǪp?YFbs"@#nH#IT_Dm 'n:n\L6]2e&KXB-q2IG{K+4-*i\ۗf1'H]ѨdPбr'Wu>Dz!eAuhGu8%5Q/6 *<E|-_窙Q OFH) tcͬE)Z^2@ i߈kGV$y,ku$YK, RhQM)ee&ƣu BeVrqfȯ JP@*UMVE֋Hbc\-g{'(!bi*;Œ67zo%;<4hy7m$}qoK9[2첯2ٶ~c/_L{γoDWH5mEAZ@z LEK& Q2M3,nokT1^`m&޽qar' OX'|`^E>o$+"U~[y N'e(͵@": ֒MR7XGh@gcMlJn(90rD 2ՙX*m#ی湁L郱K.l:7= i"l#ű.nsT`΄m)}lP mw\x m_1J`LE "_o5M4 AȜ\,hqX9ք=qn3[mѦFr ;ק~ kNB=rGcaSKs*bPvrZJ}FZ)uzB<ņȧ$üFR{o0B`f͖)W]PgA9T솛zMbQW@Fi[f9`T{xP0;*nWXOgyrcAYgZOM:MWd [>:rSYdr\;x > 0>D+^6= 沈z9wހB/:p>יMm 94yz߳6 d{>V2{52J{[{mϔ{k¼PC`pz/q>$yߟB{߃k@NȂi,’I1AT02&hPptK5R(@b*f(dZAf$㨨Q}]6- b#ZbX7+8{p;>ڳX!eJ?ˉrx}g⾼7 `o\ŦUTViJp۟1{7M%$|kƠ>1/:ǒS<3cY?y9A1kBlFZp |^U\?AQCFɊu^1]vf"bf:<Hm{-ek,2XX{ "|!#8C *9zg!mr9oWDw?ye:k?<w4%'73Uǂy-F FXfp-\pbvg }d1T&Ш(gyE6\]x&nϣ4!(jS,h']jE njncpq>IͬŠRN;GN t7hHI7X+3}Gե8yθuxP*xz3d4g]?9G)/" x=R4Q87?w>|{n\~ 2GNg](0jya73D6SJ.l_.K\ŬExQȇӉ|C{E`M~ڈL=&dSH3}h{˭ffD?&`W G[X=(^jzi\՘)<ɲf KC oaWVť"nP' xΚ?ymޘCv kL?L<u0ʚ efjT?rޗ}~]lcۡo\Rf-P|Z2RW_(o-}J1,)l8Ff5,5dG\L :.i 8vXsf4<ʍ-k4 +O=&uwy=$g:BYJy6O:ڞ._jJZUzT*Ch-Ax[/L.# ]=#P !_|`m+bsd.m#Sj-gc7JȽnach!K^֪ Ugrc>bj_m^#ܰwMߓg,\dM8{'R[jwRڦfl?o:\\< ^C.{ZDח]=?ueADz%l@ Yx@!(%4E` a1esٶA7R~/WxxVeu Rg{alMFEgq(e\Aj7YG՛@. ;ytm#O>Q4>2'k? A5+303_xh|qY~YO{̒R C`xI>b՗!"A|=/M+j:!ަ!,~BwC,zO+±h[X8W`drm+csaw׵ƝtL_ϙ^B8DnlCP^[t|F-T&NЂX o{pCg[hgw4һ7;ٗNcTG׏ƺK2{DO/F9niLl7_f7igTЖwOgO߻qc3QX624=ۿ=RZͬgdېL \F9tsRlvlk_IšPۆk}>O#A;<6ơ2!FFwOz(&_9aQ O%r"i^--S@bz] ZCduFi?9 F~#z^/jqjӮJ^@RV+v_Y,LT/3-k;3)so ۿ%ljDz9Q! L%{*t20ݺ+o}> b9״tmy*.BhΝ3x+\sS׭;vA`P8F^7!vNfQHr䓿4]>}7g?u'su97<䜫|<~ r/+:N0Ii14$%0htؠ+rα[p$b&u:ow㒣yM4_ub2sqålE횏#G:泫ڻ*T =]5w ڝB݅~E˦ ١T1جRwЖHʹsO77=u3{xkiCʌk"ͼβ!U \8lX~lapax^-MU+LbjpNy]:?bnn2tA GVO]3Q' Q-;=Ԏj7b&ÑuwNy P܃k0~% y+hp! >͑Hyo[TfSx9K x-= mךQ~!|.1aD>7FpI8+#:]Lٮ%lL+n¼MH'֫h_JFaA$ǡ#Mrv,~:*!$63W|tX!^GڀŰ]!;)!2|ܖrZ0 h󞂟w=<;\RHТe ]I*Yf3Mi9-@P&^Wu&8oy+: 6 \]#u&Q6 M;4Ŗ]KņW@ ˯ է;9Dng}>|5WIdᄊ@]QZ}-9&[D´P3`tD e)jnFiH2[hC.H|NAA7Q B\i+ \ gqR&%O?QJkE$X(9OgbϞ8{Ӓ''$~IE˕.z@~зG%5, ѭEMuAm;ԠؼHJS &<V0B/#܁|*-;>:5eƈ^ Io)j$ ˨ΨY5Ueڶr^K]C 9@J 7fAjH}Q45-tŀ7>tCumuw" c;$94Hn| ݔ[FE3ζ Zލ%{.;P (f',H0' &_ZAӀJW(=TJCD YP@)Iإ<u3CI-aиՠuzcBӅ2Im@4  #/$dĐit0m U&W/>ΠJE ȑ\'e6Goۦi6ׇcl  upؠ5u1e.ڱ]ݑWj䄝6AQ*p|pѢw<' ,#>лhTQJk456܊~G-phQo,% ~-%@JFn =Ra4\ĊIDV>D^wa"{PmjC~qsSZUqT"2@<ߜЕ+;^i=A/h.VcЁ96wC{po,?NDQ9QjdUhecJuͱzȦj+:cPG"&Lqj(0m^3P V[q߰?sQsDȮFnѷsQ7n  P+E D=mg4Wu4poE,&֐vap B 2`T1tQ ZŠA 2K`u" s&\0oh mXޛB̊}GA]rՈC=Db^{$mchb(n fωvF-,#Ž_mۭp-:$aJ1v=d"6ьFN]]TSٵDJkT{ou}T. ܷ{VxvQNwҲ-g6La@Yխ Cmcw}aAr\W9}m ?37h=U³n, 5( khg6gGC1^bjxz57 QX;[&-d6kvKYk]wE?Z3J2Ng.z1q]fmX 2~Kp^OT{rrVSܧ !vQ:N-0. oV[183zlb5KnjS؇Mq W˻| e4B`Z㟋 (5YO?MH/(Ä. å}3찙可R\nd ,]%)kQdیxg}*ܑQb)Q֊@$1\q5>N Nc0P#ⅢSX ]-X<̵D ml[d/bTs+rk$x/hDni47nfଁ&& `fN0z)WRWl@vs;㱶.̹n-#R5F1,D$cEpqL= J82o.Fb$C[2MxK?a~s{]v@6 -1/uu ps|y;j44nW"14Z']I$H;y 5z"9ܙ Ȏ;:;楑.^;.W1j{hSo;ws^͎X4ȃɰ*칻-dJZauX^H` JVa޵dY"ъf3a5ۚ ݂$ TLz1a-WfBuCP2WDxW~LI. w+5hn֍%m7xu<*DT[r)>I˹<0$Ɠg{i1skN\3 O/{lHgr͉ۄۇ[E15&[ TRnm j0W(]Qe%Tq5ߖ^/  ZW떿su^~c,\gZ ת]i z=١62yT-E^ڲk۳Ԭb1:-[q w`Ŏ1jؕ_8M]&fֿhQ<xjϣ'"5AN) Z'kJ>Y O[S nmL-  Ԣwy<<`KRliJk̬U֔jPrzl|0;m{"v`>[S +1?dD*Q.Ǫnқ1#߮0̧OPEzWr\s70֏ x.P\؀ ?8^<|F+h1+9L˙:m&s9)N>CZ%uط\n#NVױ~vCEg,t;+;=@N%%4g. زJ9 y ( Q^V1q\`wQj_%[Z̝t̹֘XM jW;r8-հ~)NQoz t>G򬄥;y|"Cz Ylw 3qwDB O7K'js&nUI8g~>Q,f1Yd\=N,!=G3%~nC3NɗY?ZCx Kx7ѻa=N|\0x!fxQ/aDw g%otG7~<_!CU~qVg#.myM}n 5ף9*&N!kX%}-s&zlKX?qxk'#MFq\?ϒ<'/@m o0kp,24}i>sCd(7ՙV/UhV+2Z+znM_y< oό|+ ;фż0a}3CyIMY}\mqbI}rbek%E Y޾k I3Ys.gb~5v"~gz9 QB(.=Ֆ`G&k+fLudR{S?Yv?sk}B(zi9w_НMj[6{bٽI>wl=!_Bb ܊4빥.xBB N6=?m2H8wsG~В9 m }[hw|mh4JJMEpU&1RO%{)RNЗ]f"\R-hx}5dЯ1並gpӺl[iĨ8׬P%֢' ]>7OܝCIXRU>@ciCX_{ŹAor-|,V? iQQo7fQA4oGVk|o]'R &)[yRP[::swN&(]~l=t^錠9ڱթeS B|߾CpםwTcS1RwHF9.M<8y1ZLm/' 2BCO򇐾 r锔B~t쇮Bv)7P:i'._ W'CgP> g|1>]m>C][9PkL p659v7~ ;D(K~"Gw[ J!5r` =lmЊEbDҽC Œk;QTDݲLiƔ&mN=X"ZuaC|~Z|3,"?ΡsZixzH~0$Q^_ lb评L yz@$P%M&WYR{εgftRP yٷVbFLc^U c{XWF\Q}QTvv{ܩJсJY򚣾h-||)/E Gf6^] h#r~xN^'#E:3bv}V-nwk/?Dޜ17g-QO;!Z9-\d5(pdF<{Vq2Q1Yd I-t))7֋/u_3M3 W5 Mn$\3y ~ ygeJ5KMsԼ\&Tʝ)gJ_$kVRR 2'/;,]@#5^H6لB>|ʪ7j|ᖅפ0P6; /jx6SmHnG;5}U:P:'\S ޑz퇉r̚CMܱk_n(GܛVWjx&]ZEVHOt>!&S`jJ7NU?MbW6 QPrW(~c+XVa2Ш"T(J!J9TY _AP/y784uy]Թx>@z Amf1V ߅H>q2b١͗oPR)N~őwo?qoݓgeі5Œήg=守=c^ol:CFH[H,ljTtgxӳ@|Db})~bUC0hpG5x9d0VdvJYSz3->MmK֍l^nӛI <\Wqґ8 }RH5˜\~ <'EyQ}dfCL".(T+m=mt_4zT=Z9;ә0kBOĪ߼ضn'+{Yt/WxPOD(ls0멅>KJ|jɔ^ Z啉OZE3%;ccw7;: dBMd4TI݊I_b3G^G)ӆ󿈙J< .e|0CK5QU-_CY.nǪUW(=L׳,\\V(8=~|ۉGsk1Xy+=≛iaYf}hB(wm.T/6Tۈ]&pG2):ȷn@_~_e0 'ʁ;u}]C[И6?H2^_+ [+@>~{b4{ڱM4.}ЌFe⼟hpJ '?70MC /6Jp3P{_^f BK"K'Cʎ~K߈>AvZ_}\Nx3O&P)_C 4m[NuTȑJZTFY#d1U!3fT!UzBn&ƙ+GA,G`~~ݮQв`?gCyA}6qEv6qJxr-Px>l/Qy,L SErN)dz֪B=m0#gP=~HglzmVZN I9_|uDt^:2]A_BN^8$J_hދĎmuJ)fOwwZYZcI1BZ&3zU is1kS. B!}Za,؀!q +$p1qF [ΧϷ;]}κSM}͝Q)yp`k[keXܿ_"67ky^1 AM_(uN!z [ 5#uvy~a$FI2BxEI$# X)ܳgcxWyck 8^ľ> ü bCᙏ]i{Ay.Wachث1дڿIycm ,k";%c-[޺01Xh'L*EX, ,,oXt~ {>6)$&N c$xjDCuES42ˊԶ3.g6ܳj~wXǕ_=94ճp|c{KYRyz\=M$FhT`>ѬO!!dx_Q&-GT2ow$JM( p1.r mHF#|=&{46A:^{Cn ]L ߺOovlwFH;fm sXuH_9sڭtN\_\#H|D<" :J+;_/N\x&0%/yv@"¹ZY#-5&7HhfM&&@\ vŊ`+*5}v%8jvUR 0Kg;贺aιox+336ʨ6+%!V3ׁ1h%^Z)4& ژDHNMչLsY"8" Y(Vt*UQ-hh[ZQP5 0?5 ~Jy&@&zWofLa%zOl_;`7=V<=ݕ@ԗHFoN8pg_x Tꩲ_r:g$)FX#mG]Y[ ev̏Mt Ȝ?ҞD{B/Ha;46?!s\cjGNfXo g> eþc{^ou}#vT`[OyS)%51`vu[u C]q} &݉ 72nzgIvx,uKu!) UiwkԳCh wB;"}Xx[fdt8x! ^%a7f!,VKN_fI_T 拓PnZ+b~"!GTi)NKp~Z8|YP,@eކ8iBy1',D9A!x;{d,ԻM8,TE$?̥%u{X.G\_cr,_PY!j(r! L2ĕ'\pSgs Sn\{vۮ^6ڑ {=G/ŧJ:%٦`ty[9 Ȭ ( ustf@,r}j:-i҄]ip͔BtQJ7owlG{|¦4VVP$xmM'0_ShU-JȵnIGj#pOҒPL  R4mW(k47]sDêVvl _;]kkm YW.JNվrYW8`&fi ɭz0,1>E/D Fz}=wP,].8=aBP^X{RUJڢ*()@amR9~h%@Iw@ĤR#O0EK-1`dOZ TsiA 5[_NJёS J)rmrC7+3tCvRL*ڌ\.ʔ2FmH <@)@4u{M!y<#gNXW$䷁*dJ3jPswIOaZ֘>1S>YP&2Rm5FV0Jg HR-wpJ{P.~(َ㐐8ad8ifViMFVAQi&d_Gȣ'!3QM6įd"C_GYa=\0- -'|:y!B +EȤģ2u h5JPrRjUY^;!~o JX B +ԁ Z+H):w 1BB2hoPn&#+,#?; > I#'?NoGp<,QA9?+W\-o(k'~g K0YHI- He#k ֠Ak2 R*A$Hv"Psv/ 014魝vZJ8{I\ﭜRW<3iv6g6(r $!$ gc1ll0gc7gzvW{FltOOs=;{(i@J 8Oϓ4#I$s <3Z T }n2x7 K(G zzU2,4F鉶IO"@sl) ]wVDY,);VnD{qлn,'cvُ|k0eOy<~ ["Ma:-3t0,z yb =^D YycP&_#9k>~V3kZYpi_S [F0Fe 0Q IOI,!2leΔBjT% V! 1Y%sHDsso78n^w%~lDY"9^U~ i8qȒ#mC6S'7!Wyl#wۉU \'᳾ocM?vzl+^I_7L<7W1(/gΜi`\ܹ\Fr{q(>߻]|,g}gOv?18gcoEs 8]5ͦ+M}>N}?)Iϣ |UP"rR%:̓%eF"jP zʿ=gNK1)*Q}_ ÈOfsy+? En ,H<x̵wz}Y maFrT b'Jk"I穄RJ״>Aځ+A?H=y~ [[s2ߏxuĿ;_ysuv{C(~?Xul UYTC">~4/s/8jNHx EꟐ5w^! ^HxFo'~/AаID;_4q:K{|~Ι+u\}?O}?osqhlqO\GQ48;C ?cs+K S:O +H| :x^ 9; Nk 4{hL}e0d`V$350x tgp`pV~3b/෢  W?1/]vERe]2ـʆz}9x|YR]^Td5it{ͨmbH(Wq$AK ^2Rf5IrvfNF9ᘨߊe[]+o&LFTDP(pߑ6{E1]M=DO=D|_;t{7Bwvr׼U{o}G> %χi!w%'Uu A!pԊ$h2sT2139U(шJ P"4U?p6ɜ }/$ U4fc8`9SZBLMɱQ`bqdhժ2 k0}(A >T"lX:2{=+oP(eo߿2:o%emˁx!$: &V(n9=Lu0 8ءCz4?C^l,4v_kMe)^;:Q^A.!W))̒h')"G#A,J)QGLr M"hf+RTlmXڞXOx'וOk$<{mg&7^qdd}g?M,z@?0 w96p|?#gÔYG%lnLcX52^Irv)΅ga;oʐ5ғ? ޭVr)?tvMfnbԎB;٠V04 J,!Vda$|DYSi܉%,mB4Yˆ+Rzm Ȯ>$cg[U;1\Y[-.ˀpXKdS|3c`sA߸i_&3|+w\7r{묛u;(8^mH)YIUA;$`@B~4]:Q8@+٭M:TͣU\"`oS94J˛ޓ'2XMc\&;="Ue?2_?VH2Tٮ+v~"P݃!$\NmZ>dCEYOL&)]VM^ic2TCANo!V*-\"wƧ ByzD뢰lFQDW4KHLq/M~L*A`֨i9e[uR5fx&8iEH"Ybn^$iWB)x Q1kVE͚+ (Fc$rxlz(]s'@6OTE$>P0j*A: X wuNYK[zk0΍fBtE|m;1JՃ`o"5ĥ֣2h~n@zËy3jP[q}g/-D#ߛ=O11fap;AxtΠ(K!g $u@f ~V xT a y^+'tL S{H+YW87UP&eEw"#ʰmg$7Ha$!Ї9ˤgV98Hm_2K-EWF RDRd~4D4 fr4ECrm'L~xBޔME>!BJV3ʂ !MI+J$ы%&Wlor7Nc= 7cphj~zt}J!xSc}W@.{@l},䝩bÑpū^?D/ݛ_+Lov~LsEڊhҥ!_9ʹ7GxRMw70)jTw q 2k }72r}-zW 4_נ57r*9:&&mp\7{o눩}3ON7}w#~AEڅ)^D۹M8wJ7\ ;r>ag'h fu8|fEn;ā:/=[6w:= JwGtw wmpjv򟹅x6PvIJ睧$:6{SxznDr:z 9k#nuҤmpoH((3ȅӷV}{pć9iJ,KiP9Ϫ[oCl- ԒS E=0h{/=ӹ \tWX/ +{Nx{(Faڇ*%,D$;d*AH1}]vtȦRL'1 z& _5N3 Sj2r|9Am:}/.[-.e}7\y*#FpN.)jb"Ο?u#}'=9Y{(Oڷͽթ88SZ9v yG;z{zvsW jC$Y47v ҍ $>1׾n+   A=4T* ^?J8?)?5!DPջϩJ1sa#˩Ja>҈{%OǂZtH$.#$sXs񰝩:*d>#F_J[1VW6c_ʷ;벛yn%7sbZLo6V֋.ͺ:r1m4K , BZ ,vpdۿP-z&Z7/СN3xy8[i,y &,ڏ:_Y"]xy_6k睛/ 7ȫ>Yp}0%_dҩl:j^M8/=]M-~#vf:S`Y@ayWof oG.4}g|w.>h2.{-wڃ]niЉd} =ةX,x& K6GPƌQ:|G08C) @oUIVkyx- Y)* l@m(_ #:g۩8saL@o.7эL)QZ1݈qv^/P~/o ]41fJGa$܂.`9<TM7+«cs`XpF’ڷ7q6~=WX9/]=.y[/ֳTKjEI>$g)o7)쒮Tm>3a#T XU;c T j-`FB%.9z,KQx[98@}pC&NVpђ L誮Ou~(ͽG3xe59tGG8G<3is^Dsz8z8GB}?.үG L`"^ŸڤK!sxO}_7!i#{O^x C /1(\=#_^>حQ\ac?T0"Q!m_١ۓʫA/BV}:WVT‘YCL͢%J 9E 9^P#_:uow#] {tHXظ8C ҁ%n}î7n![Xn۞1UT˳$G"MX[ITp5{Vn]g]so3~Bh/e d=~gZas+BB}I)lm7jnF];m캚nQv42'?\}s|Khܺa5+݂FWBmҲNc^Պq}*:@U?6Ew%@j: x`G9|:RXگqF:A{ќ:ԏݓYN:L4Ǎ\"\D+s`nң熃J`FlNx!De'/51 {;nU袖|c-h>&^y:?1LϺN}dފJӗ"y1Z5 I".;Ӝ^"E#p%U doV~`VpҩWAevgz K>27b G΍`cNEh/'37@CF(xsܦF8&.TF:|]!V`](3L` ^Øtc%~;Tc̾|i~f@ -)l F'_AP?O/vE:4ÉN/?rBr/$h\s1-/.ph 6]dx $v/<^&"c-Q\H>ce*̈́696;z |>ĦXv~d!E'M=ksA"qs%oeA[ n_>2[ER1H:]S3Vk!HT+ڹ֖Sί?%NL6aqdιCB4+>_KFhW<[+❃m81eV䘮qFuL3ęrv~OtNFgމܶW47+Û`>lOmVٻ$sfJe$O`· Kxkj=(,V/ $}@LotWʦ[YxIoØoVAm8+ƷXZ[[^/swvy5,!4W`-bFRYij/0/SJ8GnyoJ~d?k"!8z0H .ҁͲ { eZptꝋh8Ai2g>! 9ވ0᳿Lc$%4s9Hmt|0fja#W #ZE>y~i 9+#CyWHQ@P*}{\~*:2UxC+η,}, w8XF`f$c=da*7^ CwpoxE2k:vH08l^ϨHԍWص %7{5vu'rV|5(;F,U#WiL2,>ywd~(!qܓ7<߇!]ϯ2ܥLGOxƔ8`USNߣd؃M1Q3ss#Eq'uz.W.`![ RL ';.%)M>JZ枫wN!]8VJa]@XgrȼţKߛ1VЖ'꧋"_}]% }*A#-l}#(v->jn/C~>:*5(j։bWuWaaV3LtQ\{Ў> P"t,˜.XIK!w Ʉ@b8]SDPtB+'0˜=䬍YcWsFB-k>8{7(]H. x1"~[ݚ(n#|.CZS( 1+"L]B-E)M$ o*4OɑrH.Š9jh=TМk> Dw"Ly?\z;ȣPDcrp 5#+NE - &`V2[O32F^ōoN| =`zErr=JwӦS7 ڐj%qyIoV27o@Qdcl$+aJNZlLR+xd9 D'J!5*$h$L0aLY eH(ިݶ xAnCx[ਫG> :=ı]`(SKRRdoDIGBbJK*)WP G4TQhˁ.8ꛇP7uSHj"I-,VJZ2/9>C+ǜFr?x!̍p%2A,Q4x9Osp2 bZr.ɨ]soe>2^)\[/$Jw_~w>qOS[9<ڙ5] ο>wCѭ/l?>fzg k +1D[`#S +m߾z[_l7Ovh۩2{\iݿ2ϭ?_^zH7VS B0ڕ޵ n0k'Dgn5:;O:8c;vөh{XjRﮣLÈIݵҾFٶ6շCyvj<7, ۣ9ŭszSвxRCh\XzF4?$;w\9/H:.aǤKrzE#q>O8qGcZ8UMJ[Y† ɱbHDө\~.bWijg]bݤ8齃A ,NGʤ6"Ct\h "N"rɪ׹N{]NJ^?%@2gDPl&`03w^.pKG xuչ4z ]?|aonx tyQ.q(i o%to7[npW8jBϘ*ZuGfݹ2~ 4xhTrGYS\s;]G=ɺ%| ;`_zvvЦPC}{5{®܎E17q>GԽG`;KpyL_2 +giS@Ja]y?fbd1K8 &%٠GpI_5Lk~ [JP%iVb,I6$V9GMQ%AI<.i%_˅X~`xj[!@1l)!6+H p0o6ar^m\H6fTA 2 PXAuHQ28.-ҿ48ED$&O P1*b fb/t6(C "gd-=z4 ۢMAG #F<%qISA1qLZ@045f}1KF3[XaiW݋,:64YnTq=t$zj2q!JHXfL9{F|^<$encPPT/r=qvjMӰ0ɓf4(ؙi żTfR7Y֕η̉-cs7+fhl'ѫ쀍^,pi܎tQ9D{ %e}7FdF q2xk'Nڥ@n[Qӣ8|9#j0]m C r揎qM8Y}q̹Skkck(:; tB7%4Guov7^'k\d?=UFt H<#00 `B<7os1x{~k;%G2ձpdXF*?&䬕WӍD&T7ɭ&D$kၲ`^E]vYeG)suoaCta}ݶL<2\/yF0-~ P ԭ?&\xjE0gȑFBm?)Ȉg=,;"wT뗻t%{;7u,Ag; <}QIw*73Ex_bB38V=ΰDt<{,Hhs`#NϥN|V#Y+A[.̓ q%VŨ8s:RZNJ7D2cUN5$mo0JDru~e$'uNAgp#fÌZL$+Rᒢ@k|7Xko:) ੬`^e O o ZQxcE<.IQGjqa1 FY )U,ߕصȤA,ҙud#R# v¼(^]%Ї]~QZ-5ik&\![ǢHpsy*?I$m(llLr`ir0- !k6ܡǚb-ǷlX>ԹP`O1"\K= e]\ 9 B:CDISH>?r)oO٦&d 7 xUIKzYIcሪFFL-}&Nс *sT3( P2sFsvd-߃-ae?{KfRecYO(dx^& ?RRȗ1C|dbzfnVοH#w5f"N 4'_'sfz_GԗdR#[A UF͠tOT;#ǘ@[YM, %KQ~uyx ݔLt;"Gav~n_(؂7;k_bb<:ɕuߋ5˭=EE[l+NgFbV%Bf[!?:5r tn1-^H!I2G[ǽngS2>}[yF>$z+>`(+ISJe߷yGX"/r{:~'cv)OD3u4udn.6^d.qt'`04V:~}{g 2W/_ ,8>6̂Ph\B{&>vL/?2r@א*?suwjD$’.:[?޸o ^/1 9݉Qv7#o `SQ DT$Cxtb *@DCQoLJ,1{r`!/SU>YD$gJs_+zӠ ܚ!d/ }}zҍ =ά#weFgP6R{k ڂѣQIkky3VB]vȤ#æ?K,^12wPBn;Y}k'{}'ĂܪʮZʽ;g3 VˆV\|FkXybuCrgmKm(8>F\*Da2 ;eaNv=NB(+W:4΁@OVjشg#i*pLOy8r##0)D:$dnrG!,΂+/38 9Nxkz酟lwe(Jul#AljH nmu0M{,#Q̗rE8 LL c";.x =^ߙ.ԩ799SEFn6۽ G.'Hzeyn& +[S$NߔrA&:PvIu~tqM6&ȉ5Br4kpDGANpն(@HO1haaEC௤lg=qrE #=ٲ)Tea\'Q" ]ô^IBԙd{v'HͰ3b`P[$6F^-?~ӵ{n=꯴ j $`D1 FC9^p\O ,l֭#]xD ׶K-/!{Oa4c13\ǥO(?+08Mm0"‘\8/?41&JG[ 5g(Է xL).0 |P =V)XlȧGkK46sv`+LLY dʾ΢Z|޾{/{ޭw{dl:$H ]@AT'EA (@ x|-g9sԙ3pn>6*wZ>NsƯwƷ7SIi|v "hD2Si!oಉ9ELWۍSgܦVrNPއDA+Myk&Pq0)T٣.7_|, Y [}:$olZ谐0@si:@~`4ܺ~ڹZnT6D; {uj5ŃP{ lduQere0M碽o;,') ƤjW׆ꯩ'C\$y6L הc!71r1w>v~UPyp2J3Z9Bɍ/K;lhc_}q٘ھRG[1j9v"%v4u&RU2Ԇ̲0΁r8KeJ rIM}D\h-榷;ټ@@WD6|YIOihKH3m87`2T_:쭺O{)͎`kԌ]!b"qmzH?]dqkA"񶏡9#&5s *O0PXӛG綳oGu)DgZ3LFF-0x3OQ\ ' U$ *C "t:Y@_O hb-n^) acݻ_:!Z]pdk?{r{Xm\؜o~b63܇3qk++ʽIΡ=h_Tö N+n$7,[%2*dF$'*+oR&C->@V\"f# :e3~>_n a]v̙s|zPhͧCE`8kF"NvutQ)OzFj p2jgrMRٖ;"]y+2!W3Z Nnͥ%AbV]aO9Yj ;ސ}rs%/&]!|:99PP:,wi@HYtxv-Ks|atXs inCVKUx;6yr+?2f ~D~nbY}Q$9ZFI y<?F5o-51}O-2)/fCiW瘴w3T*TYBqH0sN[UYufQpUzk $ӬPc\n8l9a0EV',MlIV!bRĄ듢WM LΜ[ H#lG~p*JH#5.Am}Yi^DlZӹ&dtZo}vқQ)FT7N,- z ?C^JdVt^wi@:B>۵rԚn*uڀT5^(¦ωCp{0XA;*G[xpԭ{QN+YN&ZuRKJm e\Lrv`SkivA>BT>UנXTG6 u#㻵w.::Ym~j΂gJQJwkjTTo3kHr\P?Lv (x֝(c+H qX,AY|z^R:baMϪt9Y.:.͞ɼ0xm}GBpЬϕcf48rЩ7R)ҨQgR2Sr%<~ K_0ٞ`KBz??~z'(8a:a4CiG }muk ]d !]#&{?dGk7~ 6\i[,#rY/N+WS3gр5˔=mƅ)o$#TO/ l$O֕pQ;8N" 4á2IPV(vҼU FI}|B)lBĂ tZV>+ &QQ (5?֋=pp0c2Nb{i6k9~8^*W(>7[XfdjYg6 `AGAܣHQc2Z~~'-R> |Dzv^=#uU+%IRV8FQ*Xӑ _Ԏtl-^ N Ӿ]Rz/EjQjJ#=pM3|3S{STHlN߭der3Eϓ5.`@=V\T|~LoYWia;*_ZNV5j*ךܭ6QnQfSP9ltN"f9duQcn+5 `#tRF^^ͩ0o%=*h.sX3W/r\D PM*a_0ݠV2E/\Қ v e5+))`5* j9UCd Y[xyzl5dG㠳`cGAKd#AxvYhBW*ҲR~q^`luy}y&B/}*%QUBN(yX( 0@pI)+m- :ZAי<4P+MZppߘXL3V E'l^`)UXcY):@QeG@@.x,uV 5hށL b\BYqŐB|r[vG-}ys+ 3eZg紩pr`U T뷸"6UoL|(X9èA6C=t?ckj+[f51=ëvtK)&bZ,/kHY*AFCIsKڂ|D֙ezJ5))FK qOƖh.\MQn2,Qnx#I Yʸ؍Lp-G+UjtY?-L˦y+9F{/{`")+=0xkbOg^:'5:7-~8rmTm_fB>DHmj{ҬVY,42D$]p8DG: ;q2@ɕ0w"+2}|{M9 o"fsD@wLqL{?_;Oҟ{KɑYQAj[Pxgn>f8q%=\|?Te[x4pF1гkvE{M `"7o ^{c>{hLegC2RϺ"]9CrMbҜ .nH;K`axhs)AWK;[ c,cYg=e%˥s{8DzJI#Z (ErW1 r"BfSs LiXv H5'vU04R_xt@+d_=7Fb; •39u^B8׿w38H8*CAhR?ntOHL9cX̑wkI.Ƿ8S&Hq;)O[gen/mL&x u+liZWvMSVeci<ڽk#9Gt/#ꆑxYnAFST. dDGglނeem:.J;5Ho/_(lp۠6ȌS(U4Fc>Pٗ|ov-*da#7,pZByuM瞹lpcom+z:>O˘57Ud}}cWז{`YiM= :KCFD^D#@JN>(Y˶S$ ֳIYbѹZpWv#ZnAZ. 8Qg4Qk'[[|!$_"2*D`xg7 0ɐr/ݲur%R/ȀL_:%e¨LU3:gff@m[mPZp *huzOr8/2Yxg'm L"Eɣ JbІxݜ\ \\~kqay&Y>I3/1#fwy%h' ,*F<.w#x1OԠ~c57Mzw 6mŴerh QX i_zd_"Dl^b8!Fx@5`[ڡӱ| L[H {조Г3N۰CϵǿϳpsxwyA+Bjsd枅聒 #gS,9L=k*^ơU`+S$^>vI|hUhq\bjq6 ,=2@yJ߫;k̛q @73ۼKj'k`3b,.6]-~%P3>JBӣQ\g8mZp ?JCI'cyn߂wHس75I.8;۷R$yoM;ݥJLݹ5bhAoYJkyã/`Е`]kvR Nkp_2W.8vghuvI,"|~r[lØ4&c Q5Y&$~ww3xdZeG&q]PTogLFMoa/BŠEA\UR2XЗQRM~CA~$?%p41qvp?1B[vdKk3 (2 l<犷xʏDã >g1ppoUy,U>ɌOɔ{θUu{˄X7Anbr~ h0,R|Cw٬}[rfA՛- BCЯ, F]XjUHa1U?k SUoz  搿8kNEI|!)|k s-v\ X{.׹[:Z-Μ(m3l wp(bήڥ ~8cowmzt؍?DroӖ`4Fr} y]f${ob| B!fBL5Ґ^'lHzjk{y9 tdt6mE=\9@Lvɥq.ߐ<sݯ"*Oρ1SՕ)m;̥K/﬏ϧ'rjEkkˊqSt3x&[#cso5hen|q"sZ#!6ʀ_!YNHa +h-L#m} va3H-E(3G nZTc6ӊ ֙*zFT4={"ŋ_ omOP)u"ф ZV=3[-g={λ(=nzxG XmfV>%p.uvhy9_k}3`f.*Jbqvlh}?^%"V}1ʾ\_ZBv8Aiz4}Zk3jG}} p1x7g[%ޘy=#7TJ^@ +2Ĭ!u+魞PM*TJkk d@jI5M*?9s)u pVuc-' Y25K!/(/8/4[9u6PbXFCL1!MӍ>dU>z-G?f#Rf=XuhHhgk i{EGCgC>S(73/A s)OlfY% "Iiq`B)|APn2:IxXoS7sB [$0p\w]1لS?|gu8r)k5Z0)d 5,'_ ot* h]&N[]VtR~J]ˈ2 M,rcJ7&S 汾X4i>t[} XWGj$V GH \޳C u$=Y^cB :Mم6mhw#=3`%PF4КLqy{`1ctK9 %g }V^dm{wɭI+5mm)78xz}Mט).ok+ӓ(@k+0.8qWNPJTsqiF]-H`#I`mRI6{'R=PePW 5K]`M#m$JEbKģC`U*ih[% ™PIW%~NnԹMUFgvzaWO`nhs$]^I](?x[PF{}2 3j#*h 1CbŪ/wlܸ_>e,8DnJƛ[{_FOwrFiWF9-Voy-z&7!N-h?豿\k<y|'$vdiU"OMtV{;O5I'ָZ}٩ɝ׮JBʂ?A^B#eI6.]L.|:#+.mJ w5psgA>\?Mj !I);5n8)fXAšȚvK  gC<51ZE89M΢NᶹxT*v;l=0Զ"Z.Gѵ]Ui߶v =5ɴe<=e!:iX$/m>I]dSN:s5s {fn4M >DÊhuI7NL v"m+2]7؆uVLNse$b3ͳgnela-Nsك?],6]ܲu:, bHmmSq} _cyK0"/\c89]Jk>S}J_LgIWk yC/'5Wcߺl)Ff? [v5lrSYKōFn}HU~б!`ˉXHpN? uU}CVw9 &ա3,"w9$褅MiXQb(d76 :[;<*=l.[AX۲v=*y&W ~/ dpy; `igrj@ҭI'ٱc #aMl!uqQ^+ ?8GZS'rXbj#mzAʜtZǦx =VT_D=Z9 y5:<'ʄfēvQ&;ȣELk%##2mvtS:G1#|]qlXh-no߄/2C!ve2-؏^h3 ޺k^H(e)l&(kVctuFX0s[i< ޶HկU e=A0Z (ogkOiD#D'Ub-S,@K\_I(aUK4l y" o6Eh:TsLaGk^/3K2(\Tm~> ZTW]vm𝶶_xJEU2{eRx+WWb[fmB7玛oAl}9āń`0V`W[ײ/4/'Aoi.C&p$u'ԼIn?~CiN)3PjVl__;J7xcduWiej9@YO2b_\k d=qDS? M#*#8K}_ާwjlg Z]WkfcG%:} dR웍 #7ia}@F&!hSJ'yR̵NEb~Hox0 yYojZsplHBJm;Ht yC_A>;F*Ah 0޵  2haq~~J5O_(2ZdQi^RU9R\.ƽX[+@  (j__=Ū}bxE]pT{)1B</wg:ָP]?ן17{{/M5vɮ_ssڜ1IXFFǒcV| ;מeUʲVUwўN[/M5?w+mn:f{C\oYVy߇+8TS>b'U ) S詅& {㰗%뿢LTOB' Gޠ2.g>"TE#,x}ˢ؟z5Ȃ)&:Q}SU)NcxGov1'0Ml0zd $[KL B̆H'h tK<_U+ݴm=yf ⡲c &5Ӄ~3+!M ϻvZ׮-m;V9?pifo#+[;n=<#ivnLҏb<yȗ!ѿmPA ['4ܰkdYc&dXVV=Ii=mWZ*ϸqzlt4up7zZ5J[ln+Yb-~K:[x0b^y8kQc hww_IqXjV -~T@@1!lϰehef\4)m禋p2Us=֫ NV}PT-6Ӿ( ֱqVq-(,F̧!g0|_,YZVR4%Ƌqrd3j{W5ҏ7EzW\Y>S杜S+u2#;:NpOGjG4|J:+:zUKƑwm\6]mP >' 51;_:&Wڍ!l9l-nٲ%0>s&6gE$uD~BgFvMٖ$y`e5p„U-ѡ_NZuHޛO ̌#BSJYA+VVe+-Gv|fz5i`m7:D{`!j :&[ޮx{'Sgnjϭ՜t{P3NͦW9-L=:/I;6)PdGB7qyȣ}{{fLrTa樇ّ\_?ܶw7uoa\aIK&KʲtoO8I)$}h~4sTD}+nTzM'H۾|@ZYP5&~Zҹ =/xY<75No3B^,~N+JWjtמݞM\`֬arњR9lQSJݚOT|Fm۾)3Łd}g˭;LJqu7=9X}ǽuÞvKoәF x*$CqC 4lP5.JKy[YuPs! S a)zy/%e|ᮕF_<Ӓc#}aV*Q)Vc\tnFʮVA{\/!/xgm_=,5KN'>SNS+!k9OG5RtY[& ʟa!i:]zfo릹ӜA$:/Ur&LxÞz=  Q_O{bw?uuEa>(;zSk^*Pֹuc:n鄁HW̮| + Oiϻ*Q Iu,Y\\" g~xA qTx|| U4lC_&E>e7@a|CRb)CQ GkWvqQd5F_ b_,^;M21G\(¹Bt!nVkUzGpU՗jcoxcAYޫ3tZg!4_"Gt GݵVA'6qP(țEJ2G"8 Ka5]2,!{ ?V:NmCڻt؁'zvZ*I\\ۣՏ]BT\+ qLN>wbpΉ;:}7o D>!>e>eUӰKq`iN7u}Q]^ѪwiO -V/ӟ41/c*h`FziO~hn0HȜAWGF#Cf4,\&uLaOєԙ[1:=1b~ɉ׹ڼz .#.1n;xV " NFd}oZ_%_BG=7vK]tSJ=%94jq'M7)' yc78tہ=@)8gq{c5FE4o %+ ]_:>| <`]f{LXAj)kV=9; li g<7Eϟ@kKiTBȭ8p&@g&(9- {n@oᔲ#ctƪ}т0ZTgR Ԯ3".1C=+FZ@\©"ͿR!Tŧ<֒uSJFnAWF+,JN>"{2n]kQbV6lUnѪV:}z% R ݢL\+i_"EQ&]|I&\L O@ exG^mhqaᢟ 6zɚp ) {g'aڿ/dL[;tzNBރY[y<\OQG x3I?IG>Bמ |ᏃWĽ6݄@G~vas|Gܷ0dqqi@7 WNaGxW$k!0%I-GXmų#x6~JXb\b\ſR -!O?YĞT~MtQ3ay&C"ф?Hto-6 (/?C"y8G~>-WoZH4wE3|ķ, F$U^ :ˋVqȯ4;1\$9RgiLҋ"ۛq.iJDNlUG&u'-AGL˪z|rKGd%; ' XW"{>}+*lo4T+V/ h> PH,H# / >v?%uTrt uT yk$kmo)X]ї|rpj|2k;~ X@N Nns1ԄksnQn}?RE:%ktz?JKľ'X6j;f|)E ĉ# /bMqAQ_y[h㿱JG-dߺ.eWbL?BHGԇU#H_[nDE1ˉO@m|4Fy4 g{jV(S+gm3x kw~JӶŪNo{(S(fh.#\j2 A>ZNt;uyRêːC|R(J.Fɺ݅> IT^Ʌ_\p/wq>_1?Q}kS[V[^n#j>Ο.0ٞ3D&|!.ԌR/GڒQ 󕄈g6Qw_D|m{\?L?D0kl7ƗZфfqyAEJa0Zq! l{?\WGsB\ˈ^~5W,p_3|W~N ?/#% :g 1ߝXIvi._Ct^x.| ŷ,,qb^]o'ķqS콵bRnI.i[~ *5\PO&K3*nR1ɏF4x&YtNrf\wlTfKQ=j}IJHmp1&$Ą$ ӘѫVkgz)ʚoڽp(foq ua1?ڰv4]&cuVm2Wh科-g>pِ4qQ7K oȅI}}._t( R6IQH,SkĞ]_.6]^YVwAbigżG yjYg&}ESgr?S6WH6!M rR| A.`ǷSzސrM&_yo3Il(y2IN9[x,KU5 1#H/7 G`9$u{^H8ħ/%!8Χ=1a?t{/i/{/ńZ˧?,}j/ɼ>%yDZz%da0 MY7% 3{+.!EC_ 'SޅHu% ^&/QÄWO a k~ ߇> :Qa_T?^?G/_:_ \5+~IA|7nx/CŸ('P2'rh8λ"_c~@R$(g\"zvG<#157/jpOY?uӳu1>Qj[~S>MߵKW^cqɷ 4_'.ab\Iz a>DZ&3͓~3_- #qC+7!mqpXO1??T ~ |bxPマ,'Ec q{Q |M_ȳS߭?4\j}~ï'~Dq9Dr?1A?#LM3nW;Zz[II'^|>\mlc7 `j(&BPC'ZNB/ٷgfW:!>~3;͛7o{{H'_)Tn 8/b#- ? 2R >|\Gj?uw+d >cR+%DFFA1%Se'%Arbz=i?!恤Dgݍ->9̽R:6"os XޞySƓRF9P'v*?*O[D )T^_.'ԫ2Ke}O,}o 2x-GgRI,Ɂ# (O2[W!o0k>~>$Ҹ/?.r]fZ g?z0ooJtSeOK}$u+SZGmݨz,W#B!`RVANGȻmR ~[ 9~T1_6·-`Tg;K51_ABI5e=goY Byڦ Jf3eKqP}2d 2>ApD]vIsClx>!EMb}mg N19WId}WX+f‰>V§WڊG+p8J| gbtG$gr*B2?c}$ WPFBrIc9sB_Gpm@@?Dp!'b"㴃șri | ?b???cy>ZƱ<S׳B%OvDp,Ͽ$ϐIp$?S't#))sjG9f]+N<4_kxzu+J6|&>Lx/Jߎp4==saqU$.K!@`%xFoCFd[ p|TX7#u| .M"#f\5Γc5RzɒOnMQ+Y6=}$|.G `htZz-Ui n4π'{\^7 ρ7㭲-3TEcĂ"ol]!'SQ:.=K$W(V: _Y#dK3_ X{yC7ׯa ^'̘3r.(_/T< D=[oSV?b$Ql(nuYR8݇>N< ;e9C{~qsNmv b̪]`JgR+~CNzy'ИwzQZq^WMfuBw aslWOw8p$UJ(Qz1j):z@̬8t [+D˦cizPU.W7W\msŭ `uઝ( ,U6&у} &.i<4IFn!_~%y8M&>'c` %|pC);`'6Wcvl۴{&mt0ecW*XwW3T&&(W;pV!;zifK [ [)?,cvq1iJ4b[k9W_(⹸|*RYex 4\N嫐}A#aft"(&ѯ>ѱoun^&DpoćX%Uz{¢ZWv1 RB P  r2Lei(>3<{}gWppC(?@U#~x7ҙ_Fp׍2=/VFܱ;Y]z@ګMaJN"3[2Rnr׬M{+ _]GXK BH&&jw(kISs3&[@u2J6S{!;q됎y g!5[@3KiD0yhrדLU6O[R9ZәL(d䧩~sm1]g%Hw GďP+Q|P[N#n1v÷u{rW:yƹUV^=kE}@nSq::Ka"1dų|Fcb~wH& ׏Ձ]ڄZ'_?)3 4v|p[#7t/┞zo(RzpGRQ|$:wa<<Ϭ`?Q&i Lp?[ppeJ=X,Mt V}2jХqC@m8tO6 8̾Puu&=TRn\wgm115ex019 %q ie<-T"SH9x kIJG |2HoICQ>C/OOA=xrlINhW,A5w5 Vkɘj". Q8MF x|al㯗j'N<;slί3X4tٺp6G\ҟR@'+3m/;S'_)J j)"y4k '9g~|u6O X Rd}#P 6kj>_P#8_+vW$xH cKI,%~F~,EQ)Kkxm&so'8ĪPs64_D$[~TQ^B¦Ŷ~Om6\`Ugs]cMjV[9 ?#~HQT!-+~Dǩo|qj%ΗYeۄ.J<:grk ci,^zFX%}P緹fQ_u~}7 OuDl?{m:G^ "c' @urO2FnE?j;pMIy)v`Tkͤ/ bW'pDP oN(IYJ _u6]?]wkqx;Τ?Q!?@Ix5 HޏAߡ`1$` v8KW$*9lXO~"\a4">& YzW-  I(TʳxTj70rr8rr(.[IԏGcǾcK$V˚ 5MOY|lʁsv/j:v gnZlToJG-3i`O] ,h,zV]X@ip3} 3_?1m覊>}{)lvYr-wdxnv&̡8 ޕ6u/pی\S EqPV2*oѬQ> Wt =VMc\A&/ *!۽ٞ|1C:+<=ˁΨ`vq߾ Xsύ\&k3*&rn/[/ͯh+`Tn᫅㹔dFf1I%{sqKdV~΄Z!;,8$#g^㧀/ZAo&p$Ũ VS%Zd託|t|Q-R;xQm)(cx+(ceL,6>E*.4"+1Qs'v|q\P$ 2%j"X#ub$1@0{q/0RU;]4sAڈѷfǠ a 2# ao: ߿lMDG( 0D<&X{Xک[.)V |?VؤjnMx[s%iF]%4Du֐S, , *AkalB3)d3qhi[qqhf^}w56.;5XQhT163~.ڢm"!P^ j)ة'uc%o_{ȒLK#])ƙA`h_N[}t"hq';Z\ڃqj:1xDA%>y-K{dӬ37ԷL1 |>\ i`fӮ & X[kFh TlD#֌>"i]YaiE=-I268m׆Y4lw\v|Q}ńɤ"j|ju">@oiw_YX4,VU:ש̇;sz?ĸ6rD'"1MɢN/Bw<_m+i/L,982#K99-Q]߾Ԣ Y3n6e^/؃!ph32C:*-$KTދϚH+ @,~m O m5NRj`}/]xCGNU!4@fB@8z^pBa(ېMk;VAـlv77جHqH7~/(;sF9: ) K Tj\)V;8Uu0E%O*l!. JL,g*CX NdYv0ڐeЩ> 7T5 GGڞm\ÍECo|f{CB*DN2"|`s2}'ޱg)A}^!'nw9A0)(GAT#wUC2dćBf3JQ45y/d@5h ݙ0 U:z%M/ ,Z + No7;œ?oCGM}T /#>24T `Vml;k[bvWh|t>zZ5k,LUiF2ӑ:km}LګzfF^o z?|-V3O;ќZNmF@-;q[º0 ѦSCB>($%c\UdOX[2jG'm^ʑ &!EAۏЩԮ+YXnasg`ޑFuYe< ;֪ypù>2l_p(jhsƼ^8٬R{WtǶ-M;uB @ӊ\Wp1w!5/ɉmۂ>Ï@rGWlʌ5Wٗ#vŖfg=&a!aHMJYײB.7ءL`mgs6UۣWtP糏(mu;KF4=yovz]ڶpKŮKz|jCct 3"I.jh`yĕyR$+sD:pu~z@I>Å{z.M-T9M|"A\:>mM_ Fishj NoUm#a\BϨo7ڪ:OW+YII~iq*E-0L-Qzv%t9oJ_2lO1y3^1 CO1g.⹜{ 4ٙLvdS3^auǡ0n2,&h|eq? Tq_&%"p4rQ=眧>VJ=mb盺v.9ف̰o6w[4g.I=wS cyʒT"w԰R[)GnpOnBMyJ)?s% 9սiە h=2~L85W ůZM<;>VBZ MM5ɼÙU@t\0y;ntK`=C؎ qf< XRhlMX͚7;չ,iW뇦[~b]8ܚY;m7y*i1 "s1nPw.][5m=*bʒ0^Q4\{o/6 \+N?-\닓 %ɨn<k0_x.u"ݍni v58za]FMTdT= ^m .%k͠[/Km JK-x單uf ;%W -+_={8?=.vOo}lrJwRUL=]#1As6@oڿe>~.R.D).V~ O vu2I"r(^%H8 $&O^ɝ7ӷOܼ D쫨PoNꝯ K%z<+(ւWTbb)WrvYI}u%U>5Zn}I7L?-1E#4d-HxD_qB<ƅV]}.R?##uG3Xl]g:rwOۀ-;"mJAZ0Ye(^$?H#+d啌7 E fDHqT4>2͵.c[̪^wuF'VӚ]cjbwuXXYOO+ ^[kN㞐V0932I͘K- A-] ~l'שe;bnK5=դZE^Cl헖;TQkdߎhfyd@s2ʭVk}lm ?a XR ;xݻ",58k8)xͺ5=5MŜh8?j!h爫m:5t#7h5LH4'020$Ϧ҉cgr](+&^'%Z%kNՏX.ߕ 4jpx+842ްkA?7jf͜^gKpz Bf[&mϭ?Uz4x+I4p\Q2fCk%CfhL,k=sÙv Vc5ͩJ[>}D0r]DШ7>튄b`NWGҥ*ݥzj-ԫ*֋:hB$'͢ ,Ki#JTtB~u8.-HRi}E5oTLG,u>l0pU \*4M j*M;6 LV5s}q1?`6 H{hl/Ez`Ķka{H#2r7 8b蒣v^,o,ur:|&̃泡hf5F|;"@;1|r|NwUc̋if;Q3RV9F*Q8F3'7,?jMUKx+%~EOKLR6*8GŹd/OD9`֡PzqBGqxuc%QKlj^!͊]|!6'ciPv X,쮮RC{`%hQ}qUfM`N55L/oe+Guw-Ma{B ]|Zf"ٌ1jmʓvzj|4`?/GqD~P k,|t[sVk݀^Ҫs+< ܇ *`o]ߺK֞#.jqcv;Zm6;g6LJOb*jY"N,P7tcl)Y0X O͹yOnOGlpi{'X=_<",(D 3M"r& Vy}qd[F5UvVeNqU X[ecƁÙڜ53"qndv3gay6ME,^C vm\8$٧)$֠d.oђM N*)FqY˖hq)#JrcisrYW ]B ӲLnZ:>3U6`ՈJֵgr`1*YOrMd7͝ڥrvMh^>QY/^Z k7Qay_˥>Ca9j!Tyl˥s?eȧ.Fpn-4U7,^=sgT sNΠљ,u&J9sc5 ɤp!IFT>$WEFmߠ>Ռ.D桸X/Fi %V zNDϧ=RNĻ5J`x3y07mއ ]] d2y&ez6zD&+b;t|nK^b-t^Bμb/xͤ~*~P/٦0z?S0KoDΥ-I4IQLk@dx KKH;Jˉ0N>ez:uĖ_"U.7cVR>&]m_پiF  TuN> v $jݺ+jV}&gZPG*fal􆦥-5fHhm O vQ[V6BevDSJeuXoIkvv'l:i%͢?ZOnEI>(lmR=6c#sXwڧD_a`SfYHN=m:06i k,.>H !:tԏHW!YO6o$gx.6-O΀n^ڳ-̇`Qּ;bTy(ii̩qK66G'6zE6uIaW&hMQLy%mU:V7Vn>7v+"V cy1 TP}_ba|>(tjU&VKJY04< Dcaڼ% t8$e!f0[JϚ΅mHNۛQuzTtG3]kщQ.29癎B zŎ[4B3=10o~F2Z -MJFynH#b][,$| .?n*~Fl:Ï/RTTNJVU%}l )"`$P:P:FJM;F2uE&[T7ø}}tlNj)|n$צu = Ռc;.V|R_GPxc+F:}g:]]z"ՠqED!g(C_7$һB/CWN̰7I +H/pf9x*X~x)Gs9S.$^gxXNñHK| %]wg5-%z4`'q:'hD$x- w}M;*$^(pR8~xx *!!XPzrH}ʸ,磑ӯ' 5ђlw/ߜ$3x"ƩZ[ ZF} n&<.4qFqAd ςǙNPǨ/ IY1i1JW,'+ۋ),lT.n6Vr o1f >+˪c F^G+Yڨ13w):ެ3hR +W*Ukx#1zή$eb^FL¿aA弱Gj|g7ԑi`Ҩe hyx7K{ɉvlGJ_ v s0/ҭ2Tld\ Mɦp`|m{{F̨JqWM_E _uy;~|>?(?*8\ۃ2=,W_pPNί :Z)ޭzAx~4Q( 6+=h1tGqA%;oX תd"S>@ߌMcTM9\0Ai{FbG4i>wHC)_TDÿ?,EwRg,:=ӕ(1>I%Jⴐ~s1 ;4Kcp1E/2ss:}7<Կ ?ZY0n cهmB>B!$3 6AADHsrq#?4n6˦.'aEdTw(9.r6? LJZUMG51W\hʔr0 (lZ'< ;j_;ꉊR$M9~$UQe#4ɼJcngF±ko!<Ηē?0OuOk?r҄]CJ. uU6|ɺaQ~eH#ñ:mn gPu;s9xؚz_1(8og)=9BN AZ :s3p9aC$x7Qn@S6A,'xUR!FÂ4]90m|LY1RIxrSQ"Cx*x/{ ݦDkMr΁˧ LdZ:{];:fuyg]ռ+V7.,(ґZ#onX8*>sB q&tݨ6Q01ݢwI=,'_|#ԣ(.^l։ ^g?u/e(? 26mRmCR&{ԇT/G4g_xo<=vN/O;>A pbMI  bπ ׾~57s {ZKxC_ߦq'Skiw[}|EK{n#-MllVk'XdByGVBo߳}kMk&g(Ѿ2uقvH"8kqx?9őT pѦ㦁pG"0o^^5KwM,4-;iƽnj,K$ZKZ)וnu)PP5{s;"тsineCw&dkU5 H){>K\cK;8 j|YICN1lV񥭪PZ0F&:|Nmb`|W! {z`os͈08kh us5?Y[HE"D׹x^ݶZ}U.X3hhWVDʘ=0BZv^&|  }.E@GciQ\:yl{cpj|GI Sd,άP#c^/f 0 ~S߈[>퐾չ .SXч`>J;1)fNpiڅUBvNDߧ D>߉X:墜MMUNö|+ Ib|2|i5Mዷ㚎ṭzQ# (68 ;nr/C W1hD:#=Mf{j{Sv1Lk>_鞺9/p~/)cX;F 8tuΎ?*fi?́$Ņ%[ S|jʙ]snWw|_++ hvhՠJ["qeA2ך/jVE]fҶީh5: 72J),\/~So΋#f:U".9u^B9+tl4lfM* Ġӓ3bRLW[7U~|VQ߫+FבH7Ь m9ʇ8>/"."nE{\%촨Vhƺ,DĿi}❆XR{ʸ3/yh[- 鐚Ut6OVyl#t:Q7t®aDocp {BVk}ic^7-ҙqGOyv" (hfF#^a]"J.t'{h`ʣrf%}Ú'.^p t;5a՜pCcDι3ǵ,^8词r޺ =kњ*n.S3xW!MNn 2*0 "eg۬K;+꬝hVtYKE@wmkMY3GP+衦@[Cn=ȥmIyh3)9GyT"m)pV#G?ϸ{ƚa=927 Ⓩ=)0_$(?AV|A&WL wPҾeOx_Z ,S`PQsx.m87k*wW|vֱ/mfјM̥䓑|zQgXIu:k* “D?8Jzrhq.ZQ7=GF|bX$Y_ UCs.E?.U{)+E Hib\>.n»5o`UgQ"-U2yj:@L*'%hjgww\wx^kuv.]gb72E_ '/&RP_[Ht4:NJ9M$#tĶ"+÷ffB$5TBΚ sl;Uc XV;gtU][8ަrڙ0 3r-7Fcκ}(љ0?:`V 82`AC9.7'\jgKgUmYG+}ןi(ǎo{=V?qQM\ .#1, hdEqX:#Oׅ)z֜ؔ4 r]ޅS"9?]0:Vj}(yujSCJ{|Mz~̜/qF+ם/Thn8Y#Ą|g>.]} ?+}jF5r-_4ұl0$L->)uF0Zղ׮Hԑk4w$4Vg:__3^ڕq[_4Gmqviogz@|eypn;pE}NJed!+$vFj FZ Ƥ |/ШPX-,Zeq+/qf d&s >zCb-=$hF#p,NO9٤ѿ.Mv`mlqs>oM>zXaV3aXZuȰBxq'jUتg 2pQbB $Q „(*hˏ/؞ϭ8Y' 1u0Nd26#o_l_;=~΢: 5llG&i5P}ӟZqv{_nK[Ii@gJ 8G5qz";ѸaEɶid4}^ \(ZJ2>/SNf{8hdB4B2~J?22Uk478s0549u5|fVthl]]I]ݡ3P2)}ƀdwXFMJͨ~zSϵkQաڝq@ x$K /4ۖ<@L&fwVI&k'O,:άu>IQhK(g(ډEYqE[-ˎw'>~_~Wqi~.5}o~d"f7fXXr3V]82oqAsۢU+7t׬<{n=euzyz 89WN \ʟ}u,:=Z|ڿ1ͬT[+O[`6eu;ӽqթX|FS˂?Œeϓaܝ⎆3>'ڻK$|~zU+ן+,m]4ga|ڴe^)kt۴d)*WeyOOԳW>uʶKS{6%Xy®p qK$[L$זÿN kY=S 4~9A|f2*VYÍe;+֦N6^9SgڕW/Y1ْwIHiggW.߸j¶9^ri)MfiQKKeO?uI/չ`n^':ɯ7T%ZzMrZyٚДKVԔsaϊn I)f_=#7}QW}]6.:.\ϖ ?}iKn[u<6Ҵɮ/WWsScqEgwz7͞{N|t]{ /<dW8cǮp̭ޓFY;}ï~nH,,\\tZ~?̴_bkS9g]:k)k{RT)鳒ZjSszcnݼ9,_Dܘo4mZY(tV Mӿ8meW&6|esrꙙ,_u:Ϝͮ:}]b+~`Yۺ={?ξ>vZ \{s|7,KsTjL5訬F_~ׯKOfsTnQf3[9;gl?gMs-\{]t֕g6.+Vܶ_Eavf,׶qEKk:NnYv/Z/c/[SV,ʬYf`?9?9ҩ[.nZy|oeyfs:ϬN~jc1#_lONG_~fsx+*t57'؆Y+iƦK787б'偓gStiYܼbsP=9Y9L#fkmoؾwT^)CgfssVi%=vf|^?~j?moi6L>"T|>~q>^nHϸe晘sg0Y<nw}' I__|:kN業finjij5 Vu֜9Ϟ3WqvgY>5KN_xŪMx~?jjbys4nm:{jAۊָ8ԯ9w~[ˬyYZ7t|múskE]}şpyZV.^ɭ^|rēYg4k<7Kf܊Ŀj'ϚY-MMqm̺윕KV2qj+{VmXr5iӖ6={|e7){v{ik/x;ׯZoWZoNnE']C,I@l%J-V>+\4/_9x[[l4.Xm^[Y˛W?yղUMۗ.իgu$/k\,3w|=}>-ǿX;EsM_:usf>˴'7&Eh/-QןlnǼ~b&H _m.]jK.[jm ,]ﷸl^miy@ҫV/ײ>|s|ukǾڶ [sۚgO9ֶ04g;svUӢS[,iZ1NսŹK̝=wVߍڗoJ4Ѷ}Ms6joݲ7_eVfڿ'ME??h3w?i\bޖK2._tן_ݱnKjZ--M.lUSs&_iVQǎkhܜа K6x:8NN 1´-38');qC"+N|sGc~X1R:N9^=γ/_[.K2^?+J{kp;^>o›[l >n;q'lǷ~R39> ⽯k:o-|!~OS#Gş?'bƆ$n#nN"+n/%j۬M!HG,cCmLelcV\Hce%K*>K|v7|ӛ*4毋a{y|߽fґOKg2*ZeZOP^scb\rc71311cxJ`n#L2#Ίs||_wY;b"?._w͠xq+ms\<#UrN9m[9B;oз/Gx9+*x-^;7xou]p{O^|5W׌.>,~C|D{m>ďSQsq$u&cIl0[0g5.N$֙$n///W{$Ox7:M؁ 1V$"ő8-Έ✸dP|lOװiHBIf|jMoAXcK'3J57#bH%rn5a` 'x%^sS`;l>MM%Owe<%`mg9q^ >XMYo{mf&jmfb5K'Uyu|ʴ#9ǫP|bGwow=>/K2^?+J{kp;^o›V6n~|t?N܅ {؃Oό?]O.~Fy|_W}ُ9 >9$~]|XM{{ |'T|&>&\|\|"c=X[q.XMTL\.^kTk \qnM>C)Ny5qk&nm=ĭmMpnj0HQzz5LpSIWaC,Ûex o&ٖ)E/ҒM-Q7ČX89#&Yzn&zu#V$?S|&n.)q=C0mˌ8+Ή>ק_:^G{I<øxTO~/>| _-f?j fua#7-|l!~ȊOGgc'juĪ-؊ pa)j%\IZI&^*^&^.n5VGZɫg׉׋7ZTjuĪЯ,V$[U+#qZg9q|JW8*kX72-*]r^u4az,UW߂RuJ1iBTIEj@:(UGTR% ^{쌕Km1t,u)u)u)u&u&u&u&u&u&u#u uƺa^q|JKX؝vJppGpq+_ŚI:71y|D:c?ow=>7/Gx9+zoěfVvގw]x7ރ}x?>FGQ| w܉p7|ǧO.~F#'ޏ9 >9$~]|X~Gsqqқ&:u::cI0F$۴2lնYI*ɖkg׉׋77~q8~$_G*IJqV'WNUaTg*Juƪp1u7l/_g'I],:ՃTTO'ɎqsFڧِ3y3.97с3ҙt̹9#TcnKO'7[n'aGcI3q3vO-bi[fYqN bo67X憲0nc]JQیyx+>5[N┑i9\{; ls\$ع~ſC%x)^?x^Wyx nk:߀7Mxsx܆xލxޏ>!>|yۉp7>'g ƽs| }_x_C:7ioo;~#D^}*>?.>.>zhc=Ll0}%\ldMTL\.^kjk!^'^/ ޘgscSt{6s_cLq(iqF{Yg'ezhcLb؃7m53]~^EwICN^AQ܁).....K³=s]Ew]tt]?KR  «܎uxotވ7ƭv»|Ч<$~G1܁;q'p>?çi^ψ l_5r@|_3rH |?#ęT|~&>&\|\S4)rJo9ҥIҤkSJ&&^*^&^.nS!^'^/ +֥I )].MtiR/Kx)]KҤ(^J&lդb݋z)rJo9W[NդSz5)ҫI )ҫI )r%QM(a(a̵RMJ&cұ (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0% (a@ JP€0:ݪnk JjnR5*nS[ԭbV1u[٭n[ԭzV=u7Ŏ;ֽ%۔Aaj(O`X32S>e9xx!^r~_>/K2^?+J[\vo›[}v»|?N܅ {c'?sf2xgy|_WsmFkF_!>"~w=6G3~&>&\|\TsvXU*nkuVrv[Wm=guVuv[Wmmgu*XjdWooow;~%qG7+^6ZW7k]Awx٠xV{vyVvycŋTv[٭[ۭΪ[mUu|)^;Vx5YzībĎΘmd~!Y)>7c8܂!FeFy,~VQqʉYŚILVwZ=T'V/7OGCx/x%^W5z~ވ7pގw]x7ރ}x?>GQ| w>q's6OgYy|_Wxkx_7-|!~x?c9 )OO< [i\"n///Wc<=fz(OYCmzMCmzj_PW=Ԧiˢ3=$[u&9uFr<3=z(LmivΩJcz̵>*5Mzzzzzֶ$OˏՖX[1I_} ЇE,yWY||л._ kp;^yވ7mgy|_7-|KU%c2|El_|K]_|-UCKby-f27YenV!TŇPCU|U*>TŇPCU|U*>TŇPCU|MCU|U*>TŇPCU|U+BU*>TŇPCU|C>6cC>6t]U*>TŇPCU|U*>TŇPCU|U*>TŇPCU|U*>, ei(KCU|U*>TŇPCU|U*>TŇPCU|U*>TŇPu$TŇPCU|U*>TŇPCU|U*>TŇPCU|U*>TŇPCU|CU|U*>TŇPCU|U*>TŇPCU|U*>TŇPCU|U*>TŇ/*>t U!m U! U! U! U! U*>t U*>TŇPCU|U*>TŇPCU|]qBU|CU|'t U*>TŇPCU|(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0%(aD #JQˆF0iJ7M :iδfZo3Lju5Ӻi]ʹfZ?3V4K[7m-nZܴiC⦭M[7mHZ"ikq⦭M[77mHZܴiZV5M[7La0zi=̴fZ3{ֽL^u/Ӻi˴eZ2{]iڕ]iڕ7m-nZܴikq⦭M[7m-nZܴikq⦭M[7m-nZܴ,iYVfI[ǒ֍L[֍L[֍L[uL[7똶7m-nZ1m-nZ1m-nZ1m-nZw1]L+I+I+I+I+i}Ŵikq⦭M[?L[VŧUiU|ZVŧUiU[Zܴ-m-nj4I[-0ie&mL¤IS2ikq껴ajaZ0gN&g7gV˧i|Z-V-M ⦭M[7m-nZܴikf2b3NX1xxSe}X7L܌]S{p aږqVI#@Fg cuYFg +I@3$V{f'0!XOm&qHroEwN].DƝG;.3S*ճg3VfX=z6clX[Ͻ/Gx9+*x-^o›z6n~|tf?mwn|9/gSxg:| _>܏}#(>;q܉p7>{I| 3}_amFkF_!>"~w=6G ~G31y;9cw;q'a>?slOy⟋?k| _}ُ9 >9$~]|XM{{ |xԫ?'+OWs_y+[ 9py~,o-\+seygi`340cyWc Zݗ50Zi`< [yS40ouJNi`Zh?GQ| w|ӧO.~F=/K ~|A|!7Gow=?ďS ?d[5oּZk[/+Ly8Kmevjqzzuzzw*Fy(exnzA֭ZkZjVrAVzbVM\D޹qsF! z(]m }Z0_0_0_ӂyyyyyyg<`޿Аs z^G]У.Q<ٸG]U *RX f f :gdϹFP|-/v6<tr :9NNA'S)x2j,,,,,,,,,Q ZdԂ'<ɨ=OAϧSУ.Q z=uAG]У.Q z=uAG]У.^%9 w|fOy⟋? b}ُ9 >9$~]|XM{{ |'2SQsqq2_X ZЩ.xJjA)ꂧt UK5~xxx8q,U[c) ){q(iqF}]lR0_0_悙R0_0_0_h k^+*Z~K)/Nt PTg;<۹v.xs_rwLT/V$NfN 1´-38'cc2gRMu,XID̸̲YG>k}̯_3g~ZX}^e#W8skp;^oěVކxލxޏ>q'3g)⟋? [W׌.>,~C|D&{m>ď3O$(a \ͬYF}f53kgQY>kb-J޻F|8Ѣ>S-S=Ѣ>e}fTL}S1{O>STL}S1YSUa2/<-:~#پYMʨ 3 LM>77#bHgW>3_}fH[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[H[J:%$tK*%$UJ*%}{K*%}JI_RW)'RrObI_d"+'Ē{KI,'D[JI,'du=%$ܓXrOb=%$t`JfKԦDmJI,'+ +'{\rObIRi)鴔tZJ:-%NKIĒ{KI,'Ē{K* *JI,'Ē{KI,'Ē{KI,'Ē{KI,'Ē{KI,'DOJDOJ*'*'Ē{KI,'Ē{K:0%$ܓXҁ)'ĒL=%{K:0%$ܓXrOb=%$t`J:0%%}{K1%$dJI,̔ܓXҟ)ϔgJ3%$ܓXrOb=%$ܓXrOb=%$gJ3%`%%`%%`%%:S3%:SRCLI U3%5TΔP%:SRCLI U2U)'S)ќ>O=%ݞ{K=%s^%3%s^%3%S<%n*M%uSIwĒnOOy2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oS?eަ۔y2oSmʼM)6ejS6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަLʴLʴ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eަ۔y2oSmʼM)6eS9eSm4۔iN)Ӝ2oS9eަLsʼM)6eަLgʼM)6eަ۔y2oSmLaʼM)6eަ۔y2oSmʴL[ʴL[ʴ+GdWf0|M[|~n22jRQn8YoVaSj^'S8md}T~zzfclފx'ޅw=v/އS<yG1܁r'#~RWw/>񀑃x|y~Ǐ<|Vߚdq.d5Ku,V[zJߘon{؂fϖɺƯb2ߔ*%pYoLr_A X?Zo[ܜdߺ~~~~~f?`@翈9`d0k6 x{ u)s\yx>&s"|*O<[hoN {ly/އS<(~GQ| wd'W8'{92s>##o.c$@ <\m q &kFaykj y>_W*XW0y rwݠIq'[mqa:NmFTݥ2(=3yп3h poN {^ >#(>;qGwn|q͓E|~<#.9?*>ӏ'h|ЌozAafz!e!qC|=CV -CV -C֫ !e!!eoeoe!2ĥ Y0o}KC{zQ!=Dzd!GC\ʐ5$C֐ YC2d ɐ5$C֐ Q!=DCq&'[/>F!s#072us\0=us\0=us\0=̍ s\0=us\pq]=x/>]/˸6񀑃x|۞c1[&OFand溇a{8܎v x'vقfϫIa>ua _}m072gx8&ndTzTzF8y'x%^sk/LTzkIV~{kῈ9,N?o圷խ*ĭqNb{Wov»{m?|N"~<` x[խV~u ٪.۪.۪.O Nȅnq&VVj[VUHC/G8#3zgsD?+O1#+O22GpusD?4$878ByF(ψ>G##FȌGf=2#_<]x7~|j!##(>;q[]p{w/>񀑃x|cW9?Gp?qUqUqUqUQ#8+Oin#[0 &3#k8+O³O5'g8p#H9g5'W3BsF&9#ssFJD/}(79J[FyQ29*G]=GypHruuEiF]=GFͦMTFNq~Ӗކxލ^yP>}N܅ ǹ6OsF^ėq##.{99999JGi(m(g8rzVzVzVzVFNU<;!mJԨ(89999򇣮fFeg|T&QLãc c m>1\)cf^` yŎ3qc1g}=cq' {ly/އS<(~GQ| ws'coOe܇Cx.'xg5g5S̱]3:fFu, c<07;7;y2#`ce*&scMQ>[yLyAc1^bӛӛcf?~39fsLqcqq'ݸ7koy_}?0ra~xQrL썷7<\m q &ٻMn6yMnSl6yMnsֶK0m2v}}^mru܌89#Lru\67$wq;qbL8w1NuǹqwLq;q>88.ƹq9]Xu"#o܆xލýxޏOm=da|p>Hv.܍{p=geg|?0ra7fsuSq:3Lp:vN  = щ8oq+b 8S8ms\#x bGx[zގw]x7c{>AC0>cǝ w>)kω_ėqm##3.Ğ1LvN?aO&mM z;Ao'/?<|혨՝05!' Y=!' >aBtBtBtBtBꊊ"+*ܮܮ*4ܮ**ܮܮܮ튊B+*⫨*pEW\^^^^^^^^^^QUT|_EW+* '\^^^^^Z]Z]Z]QUT|_EW^^^^QUT|_VWhuEWQUT|_**"+*"+*"+2⫨*B+pEW_EW^_EWQUT|_UWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyUWyWWWMx<5y^f5NW*5<<<<]٨lx]3USyMyMyMyMyMyMyMyMyMyM]kvcq,5&k&k{x<<>|Q]xu/>/˸<0<*>&N$1222<<<в[mb˲*˒Xۻ˭ P60dFFqPT.`EӫܪrT"2(V4 @@(i2?}˗U|֧23"7ߤG~Mz7ߤG9vD#jQZG^Mz7ߤG~MzĮ#vy`G;"ؑߤG~9vXؑWFG>p#S89#9읮#ty;]GG8{3;ĻC;ΛC;~?-lrˇ?bQ#;cy9<3}z94ļ2=Ԝssa޸ϭG[ee͍5wG{~_0_tK+K~#y-߾o0Uu-[oY|{n';w6}q}ݡ}aga}y{o;;콣;;X*U4YlŻRgU[qXūw*ޕxW̊w*xS*✱W1Ue{q{źjos*hy`ūGo+V8z[q✱s*8g✱b*8g✱s*8g {+쭰✱w*8[qX9cU[ao9cU3VqX9cJU+UTūw*ޕ {+^TxSqX9cU3Vw{o|{;?q;w6U[aoU[Tb*ޕxS* {+8s̱ geW_8PqVvE'+^TxS*ULիΫ^Wu^u޷;CҺW[u*ҺJ~=k]_Yk]uΐ;C 3dΐipW\mhW\mpކz\mW\mpW\mކz\m趡W\mpW\mpW\mpW\mpW\mpWm趡ۆnmpW\mpW\mpW\mpWm趡ۆnmpW\mpW\m趡ۆnm趡ۆnm趡ۆnmpۆn\m(Wm(؆b\mpW\m(c~uֱ:^?=Du<:;:c􏽺?vdW޿: 'K_}`ͱ91k05g\7^kscn͝ ճ֟~c~-_0d>O_0_tK+kW^{~^{~(ǎ; lw7|_WǿwЇzkc͏w̺cS{ǿ/z||?}K_~+ny%nyk֯XUoX?6b<\kUN\eUN\"'boW?q܉}$OnmYۭ{aMn'&wN܉W;{jr't;q׎;szq'wJq'v<ٛӮupݰ"R܉N]pS;ڱԎEv,:cѩNXtjǢS;ڱԎEv,:cѩNXt<|0r[tSy3~Ϝz>swǩ>Iq>Cq9̩g/>y=rx̚Y7{6[f`fd>luG<ڣcyv̮3慯Yw[I 'w3ϛ_4~57?0h}[^?aSNsS9ٍS;ǩ~NsjS;Գz|Mz47777Ѵbӫ}:vTlQiGŦvTlQiGŦvTlڧi}:hڧivnQiG/}?sh̉ye^Ssfͅyzi2ܚ;I&OOϘ}>kIOsϸs/_`~-/Zd~-/[[j MwXaSYvTlzuִbӎM;*6شXMϫhzvݴ7Gs즽9i7tܡ麎MGt 麎MG"xmڛiצ9tjEI]tjEI]tjEͽQtKӎMAjQiGŦM;*6]iG&vTlcӱk?6hi^vhQkP7ܿ"yxܿ.8c-^K6en:t(sQZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZkEZk, X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@` , X@`m^yUWm^yUWm^yUWm^yUWm^yUWm^yUWm^yUWm^yUWm^yUWm^yUWm^yUWm^fTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmFfTQmF&O^4پwosP;?d~-G~:oiJwҰ>{.-wᓭwYtg.]ݵ];ܵc];ܵc];v޼ÿ@ ̶G336353,{.}osh̉ye^Ssfͅyhi2ܚ;I||||֟OYsni/Ο~[^~[^+_~?0h|ݟ ZCO\O:_9ĹkK9̷>[9mֿcvus[L?3qΛsי8͹Lu&ys{gO;]ydqCև+?ԵY'ϝr>~I{&uԹgRI{&uTbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt!Fbt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]bt%F]b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F=b#F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'F}b'xO ?;OyysA<<GsXwo̿u{9\%q Ǒ.Gpb1?Y8TYy_gӟlw=#֏gfl&fjf湿1fO,Ҽ=̡92'ymN͙97ai2ܚ;IS3'=k~W)߬wO[yyy[^~[^+_~w?4_Sԏ_ Zp G.Ap G.|Zޏ>x[[z[of;o>|^§/|^§/#b3wYc^_ׇхcG]8vtz]8vtхcG]j>f>n_cv͞70/37 4/#sb^ԜssaޚKse͍5wS3Y?g֟9/x+ny%nyk֯XUo4m~B~lsoaK0h{W_3lG0bVd}k}c=Ǣ{μ{uA?5uA?;uA?;u?~{k}8C~z!p5{Y_Hu6\m9=_Mc˽7={=z]\us;vq>;;vq>;cw}sþg=}{<޷+}{wsxu?nܷ[!ݷ[-0?h~摿uߪXW͚yxvtpc穯~헾ہ94ļ2sj̹0ozi̵1|w yZ-1gZoX0 !M/ju-[õ}ϻ}}Z }R7a_vֽowźoϺ}9vĺo)w]#kS]}Y}ɇ{p^y9̏ytHtꘗ:c^_K{D_g.u~K_:n~]v/}iK;]:z~iKG/u~}[sotŦKWl_V^nV^;?̉ye^{93¼q[s閕67ܙOS3'|Z9[_0d>-1gz||:t~K{G_;їུ=x/{i׸Kǣ/t PtQKǗ/Y/ôZ:tLҗ&_:|ioK{^ؗou}I7-r].ץ ~/\p¥ t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@t>@Cu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>PCu>P#UT=RH#UT=RH#UT=RH#UT=RH#UT=RH#UT=RH#UT=RH#%XOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DOt>DW~t~}X:W0'4?[ʑǹc]ZWCW~t~+_JW:ίt~+_W:ίt~+_;?|OOϘ8zOZ?g~%yy|-//1gz||=G +~x+_JW#;?̷ww2m?=t~+_JW_}aa9<ھ<x_սx+^y?W~վ;?̏y:w7[]-kˮ/v }{[a^?d{vqkѮsd}cVrZ:#9w/́94ļ2ͩ93¼1oͥ2ܚ;IS3'|Ϻ'K K+;#u7||peW7n|̷cI׎%];?wί7!\/k\;?õysCgsqk_ڵvu~kڹw.׮sZ;׮sZ;׮3SOy>SOy>SOy>SOy>SOy>SOy>TSOu>SOy>SOy>SOy>SOy>SOy>SOy>SOu>TSOy>SOy>SOy>SOy>SOy>SOy>SOy>SOy>SOy>SOu>SOy>SOy>SOy>SOu>SOu>SOy>SOy>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>L3t>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\su>\suB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /tB /t~W7Woo[x}x_7W;ACaXW?Qoxlg[8V7ζqՍoxc?V7E]o"xcEV7ζqՍnx }ɇ{~?}|-//2c~ܗ|o2>~#-_0d>//%eU[c~_w_~:(}K[JRҷu୳o=x[mjV۷wo+~][:v_oa:{o)}[JRҷUo)}K[g:qo+~-o)}K%^Rz%:_:KvdΒ]RzȒKJ/Y|Η:_|Η:_Rzџg#KGΒ]r{Η:_|Η:_|Η:_|Η:_|Η:_|%^r{?Kz/Y|Η:_:Kv,٥Η:_|ΗΒ]:Kv,٥Η,tgџΗ:_|Η:_|Η:_|Η _2|%×,%tYK/%$YKg.IRK/uRKG:_|Η<_|dΒ]:Kv,٥dW:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|W:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|:_|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|7:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|η:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:|w:Y#}QLrF{,˒rlprݎ-˶l{7'w+K/\ͦ8$AQl.8@FtCs}U?z~UϯU=W_z~UϯU=W﹮w)=,?$?9G?&?OH~]qO|U==sU|/yxzT>&OyΓ)<-U')ɲȪԭm_Փ}9/ȑGr"r&{r-|c_{j}oϯ+{z{fk{Ys_F׾oլw{֟#_/گZ%Q>WU}sUvaUªڅU jVU\ jV.]XUvaUU}s :\jUΫWU;v^UyUjU9f9f9fU:\uj]Y;\WyUjU;ݪVNwUcVcVuUpU{[ު=WU_՞UUnzw[yeyeڪYcSkz_[5klHتAtHM'k\6RsmH {kYsmHM3k\ifM3k4H͵45ao͵k#5]6Rsm5Fj\6RsmH͵k#5Fj\6R՚k#5Fj\6Rsm5]jMWk\6RsmH͵k#5Fj\6RsmH͵56RsmH͵k#5mMok\6RsmH {k[ޚ5mMokԴ56Rޚk#5Fj[sm5ao {k:\k#5Fj\6RsmH͵ְ5ao][:ֱuco][޺ױu kx{^:ֱu co][޺>ױuco{[:ֱuco][:ֱus]\:ֱuco{[:ֱup]:\:ֱuco]:\:ֱuco{[޺uup][޺ֱuco{z[:ֱuco{[:ֱY'-Y}}})}}N9i8~nOpܰ뻁 n8~nvn؆74 o`xn؆ݰ o 74]  o۰] cv}7nݰawî7t o|î o|C:7'lOذa?a] oC7 {e70 {e6mC7 ox}û6'lOذ ;fv6m o8~n1 ;ffae.7LDsD4LDs~†w7m7۰oalþ}o^߸lV6V.y|gn}M}z\\>9|]3?'}H|?+k, SOg9yUdYVdY[7<)[;+cya9/=2˗<2~zjw˅\TX_>>Y_kܿ鏬H&ngSn}3߿?~Z|m~> Cx{;JYg|ozG޿ַZ6w[n}[t{l'_g[~֟cmF.??ew}Ǚ3hs%wWG7?CFg}.}.}.}G}G}k2uLD&S7MnGLd&S7Mn2uLd&S7Mn2uLd&S7Mn릹n&S7u\7Mn2uLd&S7Mn2uLd&S7Mn2u\7Mn)n2uLd&S7Mn2uLd&S7Mn2uLd&S7Mn2uLd&S7Mn2uLd&S7Msd&S7Mn2uLd&S7Mn2uz73L*'䓾SOg9yUdYVdUd]6<)[򚿥#2+|##|#뗭֯XϬ|\ȕ9LVXi_>>Y_k]ˎfu CyeGy"]f[j:?󵯗#UFO iFy5svi\GvYs5Mf5k7v;~wt-;weZv=֦#;tr-.YOnH|:5Dv]<Oy35-35wFH;#]GmXuԶ;`mwk#Fv;`mwkXv6zmwh{6z`mwkXv;`mwkXv;`mwkXv;ڶӶjv;`mwkXv;`mwkX+v;`mwkXv;`mwkyiXvjvhX6mtmwkXVzA[^/h{mwk;ly[zwF0r;a#wF0r;a#wF0r;a#wF0r|uF0r;a#wF#wF0rLuF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#wF0r;a#w0r;a#wF0r;atF0r:a#wF0r;a:uQF0r;Ha#wF U:HARuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHE.RuT]"UHEssssssssb;;;;;;;;;;;;;Уܡܡܡܡܡ=============================================================S3/========ssss3======i{ϹCϹCO{zzzss==9f䘑cF9f䘑cF9f䘑cF9f䘑cF9f䘑cF9f䘑cF9f䘑cFW1#nj3r1#nj3r1#njcF9f䘑c33r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#nj3r1#njcK1Č3r1#nj3r1#nj3r1#3r1#njO1#nj3r1#nj3r1#3rQ1#nj3rT1#nj#U1#H#UT1RHg>#}F3rG>#}F3rg>#}F3r=g>#}3rg>#}F3rg>#}F3rg>#}F3rg>#}F3rg>#}F3rg>#}F3rg>#}F3rg侩雗>#}F3r7}F3r7}F3rg}Fy>#}=y_z~]ϯz~_e?Kޕ,"*.!)oo}b3^^,?$?,?"?*?.?!?%?-?#dשc|׳9^ez>ܿ//*MEߐߔߒߖߑߕߓߗ??{|PF>$Gcq|ҿ)3Y*<$˲"k }-~ E%L_Zb=aTS"_gӝ3@2E٤ϹEVNg̟a뿴~_y_{Mo~4^y~LWg׷[a}u~tzݞ%/xg?.;u~|u_ ׽^}u~7v 2b-bv K<8y2p,=dXz`Γ; ,Q<8=w8m2dMq_9d]0x`3.cځcځcځcځcځw w p]:[2dxuxuHuutwޒcс%w -[2p9pl9pT9p<90 v6i  v *U2~Á]%Jv *U2]%{v!axÃB7r`? gCjP 'O2d`?ɐ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwCЌ Ȑ|74Cݐ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwC! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nhƇ|7! nwCݐ|7! nwCݐ|7! nwCݐ|7! nwCbŐ|7! nwCݐ|7! nwCݐ|"߽Ջ|k5/ 9^t wz.g#ٱ9^#ٱ9roo#@1^+Q#yȎ͑wۍO!'PQQQQt#'yȎ͑#;6Gvlٱ9csdȎ͑#;6GvlndȎ͑#;6GvlOO9y/Ȏ͑#;6Gvlox#;6Gvlٱ9csĪ#V{FO:^:#sF䌼ox#ٱ9csdȎ͑OOOO3uĭ#;6G:^w|#y_'P|tIG(G(GO:~ґ|#6Ƚz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏|c=Xz>󱞏%^x^⅗x%^x^⅗x%^x^⅗xab^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eb^&eyyټl^^6//eyyټl^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^ej^^1/W+yyżb^^1/W+ef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fef^fޒr`oɁkzwށkzwށkzwށkzw`ɁkwoRwMJw{}՗+sK~W\y;pW\y;pW\y;pl*ɲȪyNzQ$_2<'֧֯ZY[+Zhuց+Zhg֯ί\da뿴~_YI]wժW\:pժW\:p,dϾUVZujՁkYfuA6 kVDֿtyp{S}{=7s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17s17tYqMG`ìqk1RG?OOz/}8Oy2M>CfsC?VPu.C?P_~|H>,7>*'sCuzkGhϡ}>;Oˡ;7ˡ}>sC|)%|wshϡ>zު}:.:tC>̺}ڻ/} l_`ؾ/} l_`ؾ/} l_`ؾ/} =_z/} l_`ؾ/} l_`ؾ/} l_:/} l_`ؾ/} l_`ؾ/} l_`ؾ/} l_`ؾ/} l_`ؾ/} l_`ؾ/} l_`ؾ/} l_`Bؾ/} _`ؾ/}Kӱ%/}Kl_bۗؾ%/}Kl_bۗؾ%/}Kl_Rؾ%/u~Kl_bۗؾ%/}Kl_bۗؾ%/}Kl_bۗؾ%/}KsXbۗؾ%/}Kl_bۗؾ%/}Kl_bۗؾ%/}Kl_bۗؾ%/}Kl_bۗؾ%/u~Kl_bۗؾ%/}Kl_bۗؾn/}Kl_bۗw+l_a Wؾ}+l_a Wؾ}+l_a Wؾ}+l_a Wz|+=_a Wؾ}+l_a Wؾ}+l_a Wؾtx+l_a Wؾ}+l_a Wؾ}+l_a Wؾ}+l_a Wؾ}+l_a Wؾ}+l_aJWؾ}+l_a Wؾ}+l_a Wؾ}+l_a W}+l_aצckl_cؾ5}kl_cؾ5}kl_cؾί}kl_ؾ5}kl_cؾ5}kl_cؾ5}kl_cbks5}kl_cؾ5}kl_cؾ5}kl_cؾ5}kl_cؾ5}kl_ؾ5}kl_cؾ5}k^cؾ5u{7.Uod<||||||||UK&-ow;e>7.O{K<ǭ?aI_)O˻]w{=rg~Q~I+,"~n\_"Uw?_ߐߔߒߖߑߕߓߗ???????oCa|T>&O'-OY?-U[eYUYu{UM[ٕ.|##|#뗭֯XϬr!WLd*&OOZY[/W@ndVׁ e$_#XN7s{nxύxϭ iFk@72fvwZj.۬m}wZ'mx'ݍK,d^F碌qwzdy'ݍNIw;nx'ݍ%?G7w=tûnxP` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` % X` %A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A ml` 6A m,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ERK,ER"E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["E-ml`["vt_:tu~O#{|V{b#{쏼ud#{#{|V=G>+Ȼ#eTy){e9GrQ%}~ί_{~?A[|X>♏ ;y)|F>+W垟$˲"~Κԭs#=ٗA<293ykyc_{j}dcd=G>+g#{GqGqd=G^=d{G7w<}V8}3?#{7}3?H{z"G^o=zwyM#{?#{F8vc}V=KrKr5(+G!9OZ?%gsܓ%YY/mnmd_/ȑGr"r&R<3~/r7{Nc>Nr9ǎ%8c;}q<6cñ;q!?;w;=r̻z'Y-ĝ\?қ"*[CS*%oۭﰾo{]~'>ħ[h8V<OPOLI6o ]p?= M-m]=}_C#cS3//A|X>"Iާgs7dYVd9uuS5X^|QX$'e9șNpr&./N.G'xrb 8;qDwr OaN O$#L6Mvh}tbщG'v}tt[St5)S4:uSgO1iF/ˏ{'<''ĩcS甧>=N1:$ ;yw{#Og9yUIJ,+&[3{/A<293y߸kyg;33cO}Z쩻;ک:;uwXԱީcSSrj>NMƩcSzlyʖlyʖ>SgLSGy>Sԙifߘ>놳Sw<:uwS?SGyNF6˼ѧYN$N 5:Yo},_.W3,&-]^eW/WOz_U_O~M ($,"*{\BRJV=.ɎXȹ\U)YSUwz^EWU${^!cXU9^uߩWqwOb|Ϋ_^wY3GgXqh +MyOS.[~V~N~^_/{=z}~_{~|PV>$x1|Bs~J>-U'K,+*k~ºuwn[d_<9XNTRǏ}SLf>3ggϜ)zzYF (c3g=*o{d޺3 9s}ƟgϘ3̙YƐq<3@{g{hϜ)++9c9c9c9c9c9c9cȹc9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9c9cȹs 9ǐs 9ǐs/Gc90d!; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!;w; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!; aCvÐ0d!; aCvӺ0d!; aCvÐ0d!; aNWw؝0d!; aCvÐ = r!r!_.\!7a;2g6ny~YGWOz_U_O~M ($,"*{\BRJV=.ɎXȹ\U<˛?w;;!g벟-owyW|?͓ev-u/,$,"*&.!)owNOGkY~zCaȏʏy֟]Ȼ=sG~3($___oky_.C///6~@>(#G1|B>oyi|V>'=ޒ,ˊʚˆڷnZ?oݲȮu9YKXl=~zf}`= 7d"Sy7yb}'|zg}Wo#@2,?IhXkufz?<a뿴~)ίe&fvwZj.۬m}wZ'mWβ|.E4Y-?Svٔ寋fD䯋fYjxh[Z_ҿ(mO_KyGF,'[~_ β̎c:;C'ˏxϾ,?OQ~#[~V~N~^___~kY~9#e,}~ίy=r|H>,Gcq#ɫr^eYU?gsM߹푞ˁ Gˉʙ<{^ʵ<=>wx ^Ώi,Ȣ"o (:U,F*oz}3?_A_?o'5_yv;+__A{ ?`?`?`?`?`?`?`?`?`?`?`?0e0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~3h0~0~0~0~0~0~0~0~0~0~r0~0~0~0~0~H0~0~0~_`/0~ _`?/0~ _`/0~ _`E/0~ _`/0~ _`/0~ _`/0~ ^`/0~ _`/0~ fX03X`/0~ _`/0~ _`Y(0~ _`/0~ _`=/0~ _`/0~ _`C?dC?dC?dC?dC?dC?dC?dC?dCM\Y ?dC?dC?dCS2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~*!㇌2~0!82~6!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!(2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~!㇌2~E/2~_d"E/2~Sd"QE/2~_d"E/2~XTd"E/2~_d"E/2~_d"E/2~_d"hދ_4E/2~_d"E/2~_d"h6_4EX4E/2~_d"E/2~_d"E/"E/2~_d"E/2~_"E/2~_d"EƏ=#~=#~=#~=#~=#~=#~=#~=#{d"~=#~=#~=LEqzGqzGqzGqzGqzGqzGqzGqzGqzGqzGqzGqzGqz8=2GqzGqzGqzGqzGqzGqzGqzGqzGqz$GxqzGqzGqzGqzGqzGqzGqzGqzGqzGqzcGqzGqzGqzGqzGqzGX1uSGL1;gSR>]??;1.fyNܕ?3{MW|+^Y\a+,s_fQ]̲̉t%ߣ'=QK~F-?+?'?/U_U_W~9\dU_iʇ|T>&OyΓOɧ3Y*$%YY5?aݺ;{/~/ȑGr"r&Kr-<~,O]gֻ< ,Ȣ"o0ƿWib+fJS%[@C!ߩlj\W _a+;UnWv;_+ټd?<[~_ ˛frߜp}Z|||||UK&owʿ~o?U8ɿ~7#S.3n|Nsts, SOg9yUyfIeEOҽ=qwTvј7$PCie 3l8Qb˲C'.EnvX+%q8A8$H(%$YJ*/J9euSz3ݟy?___,~E_~K}Wm{}-$PcO??ĿF[gy6O9y{GWL Hö`I@\RQ%.A38{м 4;87fz,w=97f_6G /iLO3$1҇tA= 8 2Dƃx"cAQ@Ƃd, cAd, c X@2d, c *]@2d, c X@2d, c X@2d, c X@2d, c X@2d, c ꫠ X@2d, c X@2d, c X@2R@2" jd, c X@2d, c X@2d,|. c X@2d, c X@2>(D F<^T/˃Az)OQ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^ꥨ^` H` !_9L>kz!rHʟW4_k=?_"KWpZ!r( [[~MuoӷuIoz[{!C''?|Sk[+$R/!r(?-CH iCڿHTi逿wtc\'3}$cܷzHR/z99߮^Cz9^C吵CZYk=dSWWOfPVŇ?HH}4UMlY\u\,N~%*+7⿥_-_jy~>Np~~ߙnjf[w '0Wz>MG>{1zNIgcN:g=K]B5zIo9wm-H??Oe@=oex,s-~UZ9dL>ep$˫SYFejv#lGَz~$M,1fﱊs_^M={%XKɈIG#Z1Ėuq*~XbX]1걺؃k={pz'S_1M'3֓&oko;Μk=/ gC$?>'0Wz>MG>{1zNIjN:8=K]VMWm:ݦ=O/+5AߤCoky~@?w]> TkߕWb߮ߥ:Ou^yo{OgGX`}X`}X`}X`}X`}X`}X`}X`}X`}Z >>PeX`}* TY>>>>>>>>>>>>>=@ >>>>>>>>зXa3X`}X`}X`}X`}~)@`} >>>>o>->>r>X`}X`} KX_֗%/a} KX_֗%O KX_֗%P KX_֗B%PI/T֗%/a} KX_֗%/a} KX_֗%/a} KX_֗Tz K*%/a} KX_֗%/a} KX_֗%XR%5X֗%/a} KX_RS%TRG%/a} KX_֗B KX_R%/a} KX_֗%UP%/a}I$KX_C>Te!ևXb}* UYB>C>C>C>C>C>C>C>C>C>C>C>C>C=@ C>C>C>C>C>C>C>C>ԷXaB3!ևXb}!ևXb}!ևXb}!ևXb}~)Pb} >C>C>C>Co>-C>C>Cr!ևC>C!ևC!ևXb}!ևXb}X_2֗e/c}X_2֗eOX_2֗ePX_2֗BePY/T2֗e/c}X_2֗e/c}X_2֗e/c}X_2֗Uz*e/c}X_2֗e/c}X_2֗eXVe5X2֗e/c}X_VSeTVGe/c}X_2֗BX_Ve/c}X_2֗eUPe/c}Y,X_ӿ___Z j{6{3:999jCYe-_5r5}>okG|COE{}'?=K] }*ݲMi9O/mzKܥ{t^5[ޠo[ߡG?;3 {~*-+PƠ=cPK_{!z_{%Zi"UZuz< }rmC}߇21uCR3AׅB\~uw@U0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R T0)L`JS*R e;AZa}/r}x_Vy}4UMlYLqZ4_*:~m*+%Y3.~~>];l}g?{2LHǞ'0Wz>MG>{1zNINzonѳt.e]6]<@EC/%t}>_ků_ ze[y=?(#{ޣFjџ_Ȩ_?%7ߊ4<>Oy*S}Y}ׁ} Ećć}ꈖq@\8_sOc՞>4=ő*5q"SG̿}y<yl>my><}EگJkNVx[>{ O't=q~O[ӟ|YO[.NZr{K't= ~O{B'B#4}xI|U|M:}ޤo9[wZnߣk@#?{Om3s Kogf=LGkAZ"=Dq8ay'a_ c:v@xcԎHuq*~XcQ?3rO!)cc:9,=LN1#cSa-_=bpqqqwr〷 x{Y:๧,c3O=4๧,c|;eƁ?1lL4H9q87'=;)>}I%kw<ӿQ}6~~/dw~7 g|{t.a>Otn<@EC/]Ge5|M &Zޣ |*5͟8i}8ه}8هq8ޫ{qo?mI?Ǟ;=F{η7;nwܳ?2矦l*TS9r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!r!Ǿ,Ǿ,Ǿ,Ǿ,Ǿ,ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚr)ǚro?_~`P??`׃?0J캞vY]sn64cv9fCGڿ$Ҙhb˺8?,cq~L3o?d}sZYZYZY۵b5Z1vulG|G{ZzN? v=ֵb5Z1v{@wY5k.y\|Ku=_wn2׿o>'`sp]f]3߮uo^|N9]gW5z?v wͅ]sn>?~YswߟK?"KW?s.2}Hi*:?3|8G8LL9s>3s}g3}$cFو1ӂϲo$؛yGW_Wd[e7Z~-䫵>jo-qGr>fwl'y=c?-z.%L+yڦt6{;<@EC/r}zw fϯ &z[{!C''?|/S-5\ȷ6ߥo_ʹH#o6ߦDܑ:lZF4GͿAa3}$d6\O1:W~Gd#WɴgcU2MZgB֦O> !}>E0=Iz1zt\go+iuA7|LӋtW}^/WlsLߠ7零|M?ӻG?t9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9tA|9te:HHCtOlV#?v1:N'3tΉi+MW:ݠtv>L/Eڥl+ޣy }Aˋ*e+Wu3I ߢm{x_om>{LTO'œY],ӧCtOgl3"~tf3LI3t6'ȓjɬFg邖%L}^K[Jݤ[ω=\w%k=-H_W52}g__.~C|m.M?L=IOe:HHO!:LOҧiSyx7>I3tyzY@|ײ9\?/nW:ݠtv,۟Sy-(KZv-W Z^KůU-ůߠ7-zm6}O;l1;!wC;!wC;!wC;!wC;!wC;!wC;!wC;!wC;!wC;!wC==-'{'{'{"w*q ?߫Ni:CO1 c.}^{[JݴSĻ~ݷe }AK*}bu-ooЛ=Eoiyۖw|${L92̑a sd#0G92̑a sd#0G92̑a sd#0G92̑a sd#0G92̑a sd#0G92̑a sd#0G92̑a sd#0G92̑a sd#0G92̑a4I͓F'6OmɷtcƜ'9Os4[tA]+ڟūtnME<@}Eq^<:s3="}^ۿ*.~ߠ7雾-z6oԻ6}_D?w$g262}y?l?ۼ ]9lڦ=x[|v\Z~6~Xcgs(~I|^}Uuߠ7?[4g3X3ٹʷ|W|gwG{4yF<#zy>yF<#zyF<#z=֏yF~G<#z=֏yF<#r~D3#X?"G~D3#z=ψgD3#z?#X?#X?w;`֏F~D5=֏`֏`֏`j#_F~G~G~D?6g37w2Il¯2Ԟf9]Ͳ9[>Y6s2=/ (yͳճճV2lv~r}^ۿ*.ggg雾-zS}޵{4?')9JΟBSr?%OSrTv39JΟ,w2O~2sꔜ?%OS ZgYx_ūtnM=S;yvŗ][}zhW5-/_j.~gߠ7[m-6}czޣ(G98QrpU(G98Qrp4sp#I{2Mg,-[tA˒]?g+;8QrpK(G98Q"(G98Q=ըj(G98Qrp(G98ԣ(G98_(G98Q___YYYYYSY3333C1c1c1c1xcTcTcFScFScNcFMcFMcFMcFMcFcFMcccƌ ƌ ƬY36367fo:ޘu1xcƌ Ƭqd:ޘu1c1xcƬY367fo``഑ ~i^3g/eMt9.Dwݧ }Aˋ%z^/W:}AoЛ46#8iF6OmvZ&ɧei|Z&[9ns\_4nsjqV;]9ns:uq3q;9ǭs[9ns\3ns gUqϸV8Ǎƭp[9nsV8]w`UqW]qGqqW]ן 0*Uq;.{1}|UqW]{L=&ruB2ЇLC&!fgz }Ȅ>dB2OI&$z =ɄdlBO2'P  Ʉ0;Pz ̄~fB?3Lg&΄fBL 3v&fgfgjgBL 2^&˄z0;P/fgF\fgfgfgF\F\ 2^&˄zP/*eBLMMM$jOJDIԞDIԞDIԞDIԞDIԞDIԞDIԞT/=ړ=ړ=ړf'Q{RLDIԞDIԞDIԞDIU3ړ=ړ=ړ=Iߤo=ړܜDInNrs'9DIߤ*M&1bDIԞDIԞ$'uI}88)u7)NqpS2[88)N-Nqplq93=3=3=3oh-KesyuA7r.|5Հ3e[^/hy^/WlNߠ7}GZ>wm-8HKŵ8H#-8Rq-8H#-T\#-H#-8H#-T\#-T\KŵT\Kŵ8Rq-8H#-8Rq-Rq-Rq-Rq-Rq-Rq-~Rq-Rq-Rq-Rq-Rq-Rq-Rq-Rq-Rq-Rq-Rq-T\KŵT\KŵTߛҧ':BͲll1z ff40'-z. }onW:ݠeKl's?x[|Qܥ}<+-/%UzMW|U-ůߠ7}כ-zm6}O;~G޵{4.X;]v`t N.X;]v`tA.X;]p+ VP`u V.XA]Ju ]`u t ]N Q.XG]"`uAϹNuN.St .uk N.w ]P ]P zuN.o .w ];E/w tA.EEEE3E3E3E3E3EsEWy4441U999梪\4\4\4\4\4\4\4\4\4\Tf,ʳȣEWy]YtgUEWy]YtgUEWy]YtgUEWy]YtgUEWy]YtgUEWy]Yࢫ<,ʳ*Ϣ<,ʳ*Ϣ<,ʳ*ϒ{f3䞙%,9KYr̒{f3䞙%m[r̒{f3-9cKYrƖ%gl=3Kؒ3䞙%,gf=3KYr̒3䞙%gl[rƖ%,,9cKYr̒{f%,9cKYr̒3-9cFFF{FFFFF{FFFFF{F{FFFFFFF{FF{{{{F{FFFFFFzeeeeeeeeeeeeeeв޲޲gYllluyrQgN*yu^e~4{gǒS/kZ^⳯jy͞kyAoЛ~ϛ|#~Wm>|d][ޣy=^p=Gz!;zN]}!==GzArkH=_ z6o;wߦ;#|Lvරom ngǘkcv____66v׶cvvv^7 67mmnnp۝ևOm.m.m.gz^̎7sO/:ދq\t~bv^_״,~g_Z^oM-z˖ow]{Mߧwl1k{4gV.f]xxWG\W EJї+>5u:}ޠ77-zcwŷ{_|~D?wmǾcUaǕ ;w*zSvcq;}DZ8k ;}DZX[q;}wcq;}Gw8of=ۼ/c{4?Kٱg{z=ɥ KO2ʜ]ޮ>aWPO'".Bvjvu"Ԯ~`v]jvjW/".B]˞cs,{eϱ9=DzX˞cs,{eϱ9=DzX˞cs,{eϱ9=DzX˞cs,{eϱ9=DzX˞cW[+c}hѾ#ľg%ľ^zsh_/ѾLwDh_]I}y_=a }Ǹe~]Vu1^Ύ3w%k="}^ۿ*~^גex1^mަwm}~D?w͏"8+⸮+⸮8+⸮8+⸮8+l⸮8+lv&UTg5츀APT !\."e_C FBB Զvq7 ܹ\@vIVLHٚ DXZJE? b+㗇939y~gN q#cDtX1b9F,LjK>K>K>K>K>K>K>K>K>K>K>K>K>K>K>K>K>KQpc Pc -`[>X - c }l}lTP:c ]]c -`[HB"-de Y+de2kZ!VȬi!VȬi!VȬi!VȬi!VȬ2kBfUHtDW*$Bf,d Bf芈X"f,b"f,b,b,b,b,b"f,b"f芘"f,b"f]13X̎J+fGWL/&b.&bv؋]1Qu1;b.&bvt芉b.&bvhA1ZPu1bvt]1;bb/&bb/&bb/a~KY.!{Kf-!{K-!{K-aKY.!{Kf-!{K-!{Kf-a~K-!{Kq;g~=ѝ<#(mބ`>,B"X8Ǿ r xO%-O*kĝqf83{qf8Cs/v{㼋uw.V)Rv5jJRv5jJR-efKՔ)eWSʮ]M)Rv5l)Rf-%Rf-eɥdr)\ʮ]M)R淔]M)Rv5o)[ehe[VeDWV]ѕemy[Fޖemy[Ftemѕ]ZYFteDWFޖem[FƖejZF,eRF,' rXN b9A,' rXN b9A,' rXN b9A,' rXN b9A,'K9K9K9K9K9K9K9K9K9K9K9K9K9K9K9K9K9TKTKTKTKTKTKTKTKTKTKTKTKTKTKTKTKTKdDN_'QII$sz |8vڡ(?꠨ݷ?(W2NS%T8U2NS%T8U2NS%T8U2NS%T8U2NS%T8U2NS%T8U2NS%T8U2NS%T8U2N)tq:8bN1NS)tq:8Bc*ƤѨbUTq*vU졪CUbdMTbdMTqmUL{*:*jp{*PU졪MTb*ƪ=T*UXEUXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXC5dx ֐5[Cא5dx ^Cא5XCא5XCא5XCא5dx ^Cא5dx ^CD5DTCD5dx ^Cא5dx-;ZbegTΨQ-;Z`-OjyW˓Z$'yjyW˓ZvF<ɫI^-;Z<ɫeP˓Z2`-3X $jղ3egT˓Z$'y<ɫI^{{{{{{{{{{{{{{{{{{{{{=zD]O׳{z'zsS^a={z ד ^|{z|.뉺 ׳f!ֳC'zvԳg/\Oדd{3}@3^370 TUz@ @j`W ԫfz@j`Uwx ԫU7/n`_܀4Pk`boj5PZ TV#5Q#5rm\O#iz9{#ZHoHog,vYz;Kog,vޚ&Q&QGi"'Ml"'Gi<ᙏg>xs?,`/m,I|>91%ñ!0|_`.̃w#_[V n;N f`~x< ߤc0/"boarxbdhSka<>v#Yzk=m#}"؟aJ[6Ak<`wvOo>f[8׭@i c'`Nfͪ#m W%_h**mlVD Cǐ1dy#H[5#"_GWЏ'ΒkV^Dp BGN;f;cwWx&Npb?'aOnm"N.NgI` LQ5{Q)jlrZ>#7p&n[6Zn;N A{^Ax+9 M>=cs)vUg SO3K-}!u3IIc`{v]`7$"{5Qp}pǎ Hj=_#oHLu!2'5Q0C <>H<A'(N;B?dR`:s[ߛcF磅E;Z(mv80pBߥ=,#]p'FCy p"p L3u4Z#t> }p>Q/[hrO'Si !|>_/—Z5  \F pwpMD{}p?<C< c!vv1v qS\yv S]~ ;؍`~}Sϰ[-VJkeDb6]`7\ʖ`ߌos+vu!w CuAV=C}CRIGZ!+-BNi0mӞ>EX1=;co^{@о$/ K9/\d < 0(9w `ӥ% ՓdfQ$r8IT$T/Id8UA J)Џ'Y/S;$uI%KٻNK[ୢzҾ ?{ p0LChǖ+:EsS#]\(qO $8YĘ"Vf 9,Bp4ta.̓~`/gI|>|>_/—Zdž e |__01@?&:mp;w]p7gكxb#(|1<a a,%8|rx*Xka 4|Fxޚ`3|~yy1؟b*mQg-TX`,^+"s%;+v7={^xnx`ߌ}QD&uvl*Q=;{{({8\cg;f&ǰD}Z6G"MN.v;W%FSRK;͌#vrO"fD6E=PǓ g5+#Į`:JJ5OP9[*wUpqTXSWMDLÞ/$bQ>7Mp3m;.m`~xŴ,Ůuxix6w/b*w!r*rRb*TBYJ/U(IZ*{TRkKEROeib^~)[vcӄNIpa CJJCҸ_K:%g$O $88jL̹fZΆstZ΅}p>.`d3JrcO'Si |90%CЅa2|JDk017Munvnβ{/ MIlObxƓ4Ħ ;+ %.]aw Oo8>7cf$6 JIlP(Ɂ=;{{({ Ħ#ObxƓ4Ħ VObx&JBŐ(TZ B$6 JIlObgiۇ=ot7`:ooooooooooooooooo+B-֚[([([([([([2 ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷP| ŷoQ,B-B-B-B-B-B-B-B-B-B-B-B-B-B-ߢX([(EP|:cB-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-[([([([([([([([([([([TB ŷP| ŷP| ŷP| ŷP| ŷP| ŷP|ŷQ|ŷQ|ŷQ|ŷQ|ŷQ|ŷ?6o6UFmFmFmFmFmFmߦ((((((((((((((zQ|n6o6o6o6o6o6o6o6kFm֣JY6o6o6o6o6o6o6o6o6olFmFmFmFmFmFmFm&mFmFmFmFmFmFsD#\oi=((]/xD8>~ai|P|g$\(xvD8 N)Si3΄;޶kM I9b9bN#V<1I|> E\ ta _r=| <>݀n-p+p'w32{}p?<C< M3]rTv1v q췸2XOS|Zk`-o3[l<?O/bvy#GhXx YU Og.]aw؛$훱br޳AsՊ稬Y>Ge͢9lPl?p2B ߬RrKU7k9B륝Χ|*'*'NڹGK;\"(9<sϟsx(w=޳ p@|@@g^#޳ mroԟZ@h}>U(}GYx*{V޳ U>Z@h}>Z@h}>XVz`x*޳ >okx[#Z@h}g=Z=5XVb5@h}>Z@h}>z R#{V޳ Uh}|=Y9Z@h}U>Og=Yx*{V޳ 𞕣 =t=+Go[9m#^`0p-}Cð\9.>-߿rwxa9p=ݽþA-,V;oV;2UÎa9 >Ƨ')4|>˱9 E\ ta _rUk0q Ļn-p+p'ws={>!0<7̇\[!Gac`~e賊65Ov=lsm3`7b& ߃<?؟b-rpx/7rzGh|Q;cw ;v+>f~y+Aލqxfwkvxfwkvxfwej`9p_V}[aZVCnSrZ8hÛ6o9;8hӞkFir㴗o8;;;;ׇ9C|ZBCׇ!>և!>D X7Bh}7Bh}QB|w.ևq B!PHT!yr>7Mp3mk;w] {~x< ߄'*`%_ l2-}!G}ħ/r.Cx,{e!>ևZBC): $fDIGQp4"ևZ>8ևx,e!VAg9/Hx2Dx2;!<^UU=m=m=m=m=ֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhֻhZszwzwzU.Z.Z\V*szwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzwzw.ZR\E]E]E]E]E]E]E]E]E]E]E]E]E]E]E]E]jֻTw3.Z.Z.Z.Z.Z.Z.Z.Z.uE]ֻ(wzwzwzwzwzwzwzwzR\E]E]E]E]E]ޥʹhKszwzwzw.ZR]E]jֻhֻhֻhև0ZFh}a>և0ZFh}aOa>և0Z 0ZFh}* Ba>և0ZFh}a>և0ZFh}a>և0ZFh}a>ևYa>Ja>և0ZFh}a>և0ZFh}acf 0ZFh}a>ևYSaVSuFh}a>ևY a>ևYa>և0ZFh}aVAa>L0yFh}<a>և0ZFh}.?7Ksӹ|k§6x;aW.߰=OBz.߭z.߭z.߭zPdO "| A6!0|_k0n p|n[6;.~`~xDZ]]]}-z+$<hSka<>v#Y& ߃s<~?BI%Xx vgCr]bw'|B˳\<:xfb'cς)xRgcNNǞ Y@˹9O&n[6zwp|6mp-#(<魔Vᯁuxix6w>? i))c$B$;Nnŧ ʷx;4yŝ.w?'2S2eˋ << oG8yy(N^{~TO=4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS<4CS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДAS"hJM)4%DДSwgyO§,=g>/Kp- BcCЅa2|J5 7F pwp p< (...>,$7cf5#QU#1 v3FA֎|(8ۇ=ۏ=Fs +Hd LE-h1d|(#% #C/a~M,?{6'ϱ s=/7Mp3m;.mv=x}p?<C0<c~J+`%_ lo |~Q1&hsggcd`IkA{޴[dr/'86 0(8zBZ>'Lɧ6v`ɳ]`SOp(I3.2.o@`}Aq%)4|pT>/Kp- W=| ,hY <Ï'S*)d; {›`oy^Qfa< 1ZiЂQ!ZalyDP`xa%s!xGa*6;xOৰUR ' P@88&!Jʻ3ѐe3;9,'fp EzPpDe$J`:p^k}Yzs`0 _W9z̅y=GQǖrxM')vaW)x+vpS ؃`bWޅS$cRɟaGVyTKMZ#裊>*꣊>*꣊>*꣊>裊>*꣊>*꣊>*꣊>*꣊>*꣊>*꣊>*꣊>*꣊>*꣊>֝*c>֠*꣊>*꣊>*꣊>֚*c~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~VgYq~V\2, pa CsL$˟!F)YGq"E$80 Υb|>_/—Z A*׼saWk7fnvp <qUxi1<_aؕاk`-:z؀4gn>a ?y1~ ^"D2{d`'ٛ|&,+vwOO(=q}o-Wh2k3U,Vpv<6.V ?]+H˟.sI2;di$3c˕̚Mfߒ,/g E%}ށ@`҇=ۏ}'geeEeEe%*W5KLt=&SΧsa}Z>8|>giCo|_/0 A*gY_01f78h(zUtYNj`LЖmSq0̓goǮ?N.(2||\p(YN~#A(]A:HR u;HnAvnAr;HR u;HR u;HRvn u;Hn u;HR u;HR u;HR u;HR u;HR u;H $à u;HR u;HA2!xGW]LϥVѦᩇe[Czevuۡn;mPCvuۡn;m~7ujvjvYYPڡn;dCvuۡn;muҍun,?P)XPCݖ?{NLJ?碶*ښAں2D] :!jJ/ԎQiG= ZF5;vG_Bѳjh\n|"jcaQPߘ#o{6;nN?jXqtU.E{|֕Ejm(QT1ʭڽQ$jCIQWNQ2#Ĺ-%jn!caZF~gQ[~COWDm>|ϣ -n ?"J M=m(Cz!-"w}ߣ= Aeݓ{5]nnbSߵ,j6cKoӨm(]_#k`,-uv?5jʰnmUEmu7`!Q[\)*YJe,V,%N Q^}W+W#.ۉ8eJ)Tq%,K"᱔o+xE7k#2[qC2Pp8!88nª̸Ԭ֚Uq2Y+D7Μ*[%z_,\uj檥¼Gm8dq a-U gֲEeK*\ sDs$~S樌\jMo21J.- dǒh%}m #oK# g=:jt~'m9 |-W\ΟdD3Drs DXxSE^V&)3Ō+nbesWOsIdW^R2^^ն*Fb\yئXŨO\F{!ڦg5\7[W\4&sğɢ]8mݤF-;_:rMY8gGgu^teGG.eFWBqut2bg]1cm}~Y]-+";c6rMmk/\#2sfJ_"S>ǬJm+h`ԳWkl!Q_索;r^κX-/埍n,+k/K3׫x#e8R \JekZvt/a\h]U[eٷXmorPeM/"VDռ-C/χ̇Gb^*eIt\/ucg3ƴmN?WU/֖+zI .^hEa-r=޶.&~h-]F=qfSu-]LM[}%Kf-_i[~-N8Vflj$h]eGF=e-X*slkEOqKV-Zt#!&)%qT˳e/3WdXl?(wӖ.\!Dzd.{_e`\R] Ws[%/xU\Jy*[a}~\|>*c -]AKV0D`k.[`f^60NK<{9Θ>6%e-%Yՙm,]rRѭfU yǧ;I{igϓ=aSS&L<6e{L<'%yfx17i83beZKeP$nfd0sjqA")V>uhY֊L|d,[e W6J/ۅ5k\SXCvhq!c)Wf.\*N+&Uj`2$&3EYt9m畩;P&]\Er ʬUh]jtExŇ9D$2Zٙ|'U2kW&ɰ0k5'G0>|[F$*qu}"@ki.$[Ʊf#_KZb/`r(G7quV~~"Rӥ%͖C*e*|(C!qآ,QA.WMX#,]ie9-.^ W;x_.,KuaIJC+/V+̥m Ҭ\UÌnJ1ҸWmېGLb&JiP_~\U;ر1uwc:3P6[]˗!b{f\tT2Tؕ,60 VlaP_%͎^K/u`HkWׯUҨ\{W!odb=Z_شhF^3bNzq&1n_֊V?|GIh.Q&~Q_TIR.eRW~.jB%1'8)JR9XQN)U/W*Vj:TܭP<1_6.| n G)O)?+^U;P>U>SQU;VUQ;]ԮvS=՞j/&Mc-5NެU;@uSWj:DCU:LSPGwԻfE&cԱ=8u:ANR'Sԩ4ʯ uRSTu:GMS>Q.*)\uz:__]~[>.Tb!uTL9.WWYJ恵lRmuFG?QL}L}\٬>>>>>>9yE%uN R]5^}MUTOԍ&uuEݪnS;ԝ./_RPw{Խ>uz@ozH=Qo|@-TbD=e \PO)JVkZNZ6շ3;jzVڤ6-{oߩW~Q=IWoՏ~^P~^T?U?S[5ES5M5C3^:hЮѮ:jZMЮӮnnzj7oiqZfOEUݦݮݡ jx-A%jC46Tkô;mv6J[%ic=ڽ8m6AM&kS4m6C%k-UҴtm6OOݯ-о}G{@jLmD[}W{X[-VhYJ{*-[4[[Ѿ=@#QOj?מОԞҞ֞ўrV[5G i^K{E{U[jyE FmYۢmUwmvmSۥ\KWnmWۧ(gwFI9FovH;юjojǴ|@+ԊbD;je \Nj)JjZNV5h3;ZvV֤5k-{oi}Q;IWoڇߵh}]}]>>ZuEWuMuC7^;Яѯ;zMЯӯoo{7oqzfOEUߦ߮ߡx=A'Ct>T;}~>J['c=8}>AO'S4}>C٪ԓYziz>Wߧֿ?g(yB}/җK =K_O_gn5ʫG??XSgcS3zПӟ___!\=OAߨo_7[6}CߩB+ }G߫~L BH/K[z^ ^ҫjF_z~Z[?7gMzޢV{s?]H?'ES3P 0 ӈ1X Zlt1݌F:zFq˸-߾e}F?Vqqq1h 2cbbG2̸S> Qo=b2oLIdcfL7f3dcb9Fn5ƷƃBci,62Kˌ #Xi|Xeda5G?4~d!?Si|V>'?/3|YB")_ɵWu|S%ߖu][;{^AQ'$7?_C(!?O?g_rSBYV)WIV*PժFժ:U&AMR՗RmVۨj[^vT;.jW]T{>jjTI嫔J&լZTWW_Q@զUT 5SQԡ0uPs\5ORGc|u:NNP ԉ*TQ9ի>W'E_ AUPCdUTjDjZ)kTMu:]Tgշ9\u:_].Tw%Ru\]TWW5Zu^ݠ~nT7-Vu]ݡTw #uWTAJ=VGcqzRDVO3Yz^T^TkKe zU֪_Mz[Z~֩wozGڠWQGojX}>UTMjL mi[;:]-Z{:tBW]t'=IO_SzKZomvz{Qwֻ]nzwSiQ'S:tnѭz__EOunSgtgL}>D҇{Ľ0}w yO<ē,=WGQh}_ i@KwӽQ^t^~=uA<ɺՋT/S74}>CKgos<}@G_/K2}BO_Wk:}A@ߨo7[6}CߩwG}^)z~H?я ^Og9~AK~Mտү7-~GF='AY?_yzX?ԟMzٞ<דyqKx^WyoM&{_x[x[z[y[{xSm]]ݼ/{{{x{z{y{{xӼF/^K{M^zzy{_{xzm^uz/fxy3CYޡalo7כ-N K|O7w%RG<^o当E^7 zo;+zވ7-xKerSy_};;;wwwm\<|;ޅ旗;ޥe JU5޵u zxzy{wxwzwyw{+yxz+{zGGǼǽ''xgg罟z/x/zk뇾eC}Aw ],ȁ|OOaDeCm K*NT[aaa0Heô;_-1ݝwYٝ5UI'՟QA`&$T+*5ra*3a9NfDZQjFe6100EAz*|젮l1GDd5-ɣ%3ÖC̈́0glO:8" 8$բq `v'-geGGrĬhȅ,j}taE>X`hPaxX 'r2 Bu8_@_@vtsBs:: u(aNF8\\O?Gy#%普1]ydؕaW֌5G=\Z}世FԑQ#Z.# / ۸]^f] ˰Okli44 i3Hې#@ډ44HdIv$?fBVoVoVoVoVoVo=Pa^mmmmmmH9ZَCv;dCv;d7!!!=[l;ݐ ݐ܁VwxG @~3LZBN Vu8i4\93 @zM]@xo3H8eVe4 Ç*<ג6 i#$Ri iif-H[!mGځiihd#7B~#7B~#7B~#76'FgJ@Fh؍)4i&Ih&Ih&Ih&Ih%DHB~DHB~}!߇|}!o4熇OB𡀟Eڅa.i @ @ @ H)OA~ S ?ի#\wC#UHMW(,r1o=&'#8udF/Ȥͮ ù`;owO- ez3 bv`>gi}|,OzyRٛYz맠#~Shc>wԕ`ړ&wqL1oP]ǼJ5 $2~xt]Uј顾|Ж5EeUTtL؛%ʛS(sA2&τsr&Fy5EFMaR#Q_Z]f^t+YF0X0B) M&*Iyx8BM6tUw|"$(v?Rf觭oV)=ٔHVŲ.Y ,I$bxd1<^7<:+ƹG'I1]lőr=$Lq@~'Fr"^Ы+,Y`L_h>Mg#0UҸA/&Y^veQRo&vu~tHM,\!|]\*=3<兏aQbB=&wFlLu6&ߣx * G2GG# h1gW.(~R([= MW܇f~ut2)`!nΪA#@ |H>$G#@ |H~*~KҐ4!? iOC~ӐYҐ4! ˆ s/`LI0&޺eT;W1bG++_1HG?<}YÛ?9+J+V ޞp[ܞୌe6RC ޑ]Mw֌=S@TS44 i3HH ! #T37C~37C>"T37C~37C~37C~37C~37C~3G o=R-I GICf'۟_?ܙғgsFoL$W&(R*ׁiie{iJހZa@9II oNRxs›T9 ZC+ I5THM6ARYokj2ܞ~/Y(vHRٮr,L G>!P JCIfI5K YR]\d^A.LSuA.h-)oIuk]5rIu@hW.nnnuUݐ ݐ x+^s%W.)rI!JuZR;"""""""^%. 4@N`,r^!†H ]RRRRIaC$H/H/H/ TOE.xwƻ4@"؁iioU۲lѬU2?#?Prv}l9;+$ >1+"\C*j*W?\"1/SШ\MաgVVXR)|*9qG%jvs*eF+Wmh ˲#eKW8" dۉ)eNlhG%E̚nZ.GszJS]f#*x*񢮈-xQOV-X?\ŋF*}0pKuh~R an. * 9eYa W=YG |yk'~0*qe55, 渨SqHa$FCya %UnYЕ%acxC~V/1BQ*͹au F/CPP4y鲰^P҇_K~/}>҇_K~/}>҇_K~/}>҇_K~/}>҇_K; ; ; ; ; ~}9^_Q s~WXB>    Rȇs~}?>܇s~}9^5Y#^Q Lq)]bwS^W4!mFڂ5Ygz:v" 4Bp$R)?5Z4BFh~Aiv*ZneZ$UJm^ $K$K$K$K$a$l-|h>l>C>C>Cz`VEʏV)5y)蒂.)蒂.)蒂.)蒂.)蒂-ҰEHC4l-VCvN-nkKKJ-e֛[1CMJ4Uj<\f5C&اi}afا4Cfh MI36iMafؤy4YK'-K8.}w-)qs----_ԲzVhZvkZaV =ZGҘ ߵu; ! 3@ P?3@ P?3@ P?3@ P?3@ P?3@ P?3@ P?.3/Kg~g~g~g~g~g~g~g~g~g~g~g~g~&h䦼eC=i /O(M"6!mFڂT_vH;f @p y ? >@|A$@| >@| >!?))OA~ `<0v`;liԟFh_rAT/oBM 7~p8Mӄ4A^vn `7vn `7-y-y-y0fl `6h)C{[^l Z!5^V ^kx 5^kx 5^kx `5`1wpP0\HT ᡂəԓ//.䆕lm @6 d*`qC4mXk`m 5tWG:8Wj\ p5Wj\ 2ò5kt7VVV4ӠtĸjnJN FI>4&H["-ۅi0mxo~h1GiMml$CnIIIԖIIDI~4?1D@0R~*QSe}!o=]ԥ -I()tJ B ShY RZ%ha -LA4!7 iMòiOC~Ӑ4,4!? io&o&oJ%̮?b*_(͍ _LEp~i=2{ r9W婓Gl17h>(Lbj,use~dI9^e3Բ3ܲiY´tZ=lS)ҦRNMmEoZ[VxK۴j݀yQ-.Cn2֟/APmMr(7l~P$;ZܒɹXOapa,3Z,^'LfI]ЭCv!޴{5`ŸmwõZ/"xċ$^D$""i9Ϡ O6z37z37xVatp[)S|MWUٞ`͌j۟CVmHۑf76N3{Ykad_T45&[Z.?AUKryGa9&1D|ῡ@w!,\&QڈGڄ)OB$OvxV}CG5 J!w#wsYcTN|7 B~ʔ_0G #Q16bFmČ.W(E& o`&9\PډNk7C~37C~37C~37C~37C~37C~37C~37C~3 b jPSMcސP UZJ+Ti*PBt+ކmhzކc?!CisI0iwAxY1Rpknn4: L:i~hoq$SItE,_Tg s!e}dSScŽ =ã%}\˔\qBjS|V ugk"|)j6YMpLcsy#<_#`HWSO4k]VЖ\Bhzne _/(}^mnF* ˉ <&h`X!]0/s%ߏhCiF`Ž֕y<VUڥ /^ҥ .^7OgjCgb`w rы|bbK5#|1r9ZKgϻ"ՙozظ8'EQ.q:!gD?&ʍDkq9M_4/7ƕ_A-%zPo\ͮ˿q%rGlj~͚8cY349߸zO.Ӥ|7.7Ig5f55r0|⑽%:5S~Iti*1BGx56FE95B1; e.Nt[\ϣ!H\JetrqWak[$n':lqtG>[<*~BjO_xĿ/BMV_5ڋ}feﲺﱆ?*?l+,{p_ %iJk-󟰜SE|I_L"~rL +bK^'d7a97's_p:ߐ K_'H{C?"*z}YMayyG}IY;?߻x_ޅʻkkֻ'{ B錋v35O$iji Eqbn2(#3ɊU\ ϲ儼MQe^amA3{fun'c~!s3<G5'#ҪDuw(q ng?(3=iLfzK_ŕl8kinS4aZŴe,n X1U"q8HLjEKũl-nsajo S!;'0GEHFjx_a&ץ4'v.{tw1rwYf:5b =i%l3ڈ;ubIjj%֐u-Ĉ8S\!n& 'hUfvGΫs^$}ιcqe9SOq΍8H_8gEzι?<9SvQkL:gv! Oc)4o>.Y1B\Qmz&GDWʵDKl/⦄ҦmVǯ7_mV..w.ͤT(nVs:mV\b=xK/OSkRoCXXg_7ےqh';:O5;}G#/9wwLO\/s8tq%~K&s$[zDqi_I~sx^"ަ#UcMvkvYR=w3Q׻eH%>b[mev4]Qwg]VD|%|2wo[Y+sGxx|e2Rv@ֻh y8R||ʝn% Y];;(eQ#꽇T <g,SiܝPIob#D!.WrS3c^tK.1٫!e{pPaFa\s 8GbP$9'׈H#"fw&7_\+$,E'ӃazE3"RDRU9JCH++F{b_NK/#Cı0QfSN[Zcs/PÏZw}tI( O(q (CC#Q‚Kou4ߧ9SZi%h50ŚjdNk&k::̚gkhZVZj}::Ǻк̢ՋY@ti7" /24_tIgs~{Ә.i~L_oKzrL9PkϘOLt)ӫ.c_{2rλt$_8LTN[o<<("6$ޡUjL;2md*͚o̱v'21]NnnyL7y}t86hIB5 Sm>5dkkˆhE>eͱNI)i%֕u=֏{W[[/YZoZ?X[>%3I;aOSivndfϳO{~h/na|~L`: gLOg ^j1*'`Z9/1 W#u>Lc3w3}\ϙL/fʚ-|.?VEbk^s] oo9[0r>O1ݝT{2݉D3M25ONw1LY+ e:Y\K?elCZ*.t>礈I9H91UB;8 Σ/Du~-ruޥBI _[|~xDt _ 7]l.(6ׂ,ҹίHzÌ5pslEiL_$z+kL{ئc3}Mp;N6q{Zp\8C@<ދΌvr`72SmgZKխk?E8_3>'ratӷW9e1!LC}4RY[0ݟs+2V'rݴ{ nghQwݯ݄d/qPC'9؍CdfP]y>NôZw`NپRVn$ɷN5nJ4ǴrM~&+vmǑ:/"} 'ъq$}mc_h_f_e`bEcs~̱8 ΖΞNiq;l(8sgs* 9;Wps¹yyyY||lh&ǶK bbsbNN N;;vAؕb7={).7WS] 7K- Ftهs%s8,9s9ݮ%z0 s+9;Luɱz$qm kY43SD L}'|hۂ0%)$){K99pLΙڮ`mfm2+J.s?|qpGq'O?8s9;pζ,%svٞ@ٞ\r-\99g8ֽ֕yT3ur^ilg|˼l7P\V.sy5sr/2qɾZ9g sfZ9Z-˞7هڅsv✝8'9YΙ9ڎ_ň*X`o'u6W<94v5G+ ݘn^mS)hlYf6SɱO#nGn)ySq$,mWrE%9M>~j=ES!IaG/kQoۄ Պug#rOScD[DO#<}yseBơ=qDH/l7(-qchcpwht̓ ~ ί1j.5m-&W=Y̺`! :w׮ -VY[O[/X/[kZYXhNvEY^jSa=FCL0ݞyjW3ǘ~飑7EeV31b=a"kj;0%曘?yRF<b~=2әnL1TE#([d1qNh#[^AH dSS1DιsrNS+v1\jڹO{cQ?1k||1 *)tҤbDt(UE V2,ZeXʰhA ME Iuy!y7y wѹU" :_s-NF!4҄'I:[Ncq=mYkNi46uhs΁Uy}i/ w`DE!xxq~).z}L~Zt*5L/~Fu\gž9oLwgtw@45`|;g|n@ߘ/f>3t`S9?|;z哙:9g7?fbzz~RW3 ?blCLc73z E_9M\NXl4B> ,i&Dyk\# ]~Fᯋ+?s}UC+VQgę;t+Gxjzn^Wd4ֻs.}Qo*߮\-Z1&̬7[C,1U&đ;Y琟ȿk -o?6Yb%`s)qޯD7EcoxOE,lX0bXfXd>t_$̗D15=-{=@lab"iKLu,;ʉjиΩ_v&:I$aSY0Qt>+=*o#l VkZ;IvhLZ):z E::褹:{y>¾ƾѾ^ao?l?i?k__߱oo??3ɫ';[;;89{;)g_gYh~G*+,3%p%S 瓧 RBT֥a?Pi)": hDLѺ_@O-yy[}B<$WUgkʾ[ 5c$%Y1V-O03 {)!b_T싊}N)~A5+K:x)QG+_:u :$$-:$b?VNJXױױ׉1=N|BD:ٛ&:&O1tNdcccj֪\YV= O՛,*I$<mmh`momO ֎֎ěX;[;1#ıvv%~k1e/k/1iǏO+ Ei+MKj<:#N6f1U:9WΥcFW<)uM4ZxG4q8C|KIi~<*rג>KyK4 M^=G̗$?̵^ݒzj;ꕝ$;O#~Ŧ"{CZ{Jva;FZI)R/)5bZ 4x ȷؽ-5[6rb" qy\ku)k8>_ח#Dp ?]ZU^}X6SzX^XbҡNC֗cza֔{emh{ثTLJlQkErDp#s"V-zgۥC}X/zv]i~,0y[\$ѦXۆqpɇ UN`lB0r.%f wժġtxNGQΥz "NdDcDgDfDaDeDL0"2"Na.%n#&n=t|fjjlFZƼBst8E:3:6,xc$1b7th.Zv(*Q*gd[Ғ%ڢuQfib1u.+(%Ռ5555ӭD 6L1PP!ly촯 fEkWa\is뵼 ~}|ćkXzn&ޔ *.nw9".:ZK;g|leV:pkYռǾLxS;aה7ی qYEuJRKvˬɚaƠDicuu1xM1nL5mc^C5md^V1lk*^&Uulek^&aulqfk^V3L#23EguuZˬe7$,Az^Jƥ-y;ѩWSx%Fpgچ׽qFmx[ص{u0QmQmOHa-ydUN?@-FGLOh٨}">ֳGFҞ4YM3_oӧy>,BF؝4͗z^, p%oe䟿d<}lOhl\ "Irmĵ P?6Vqہb%*giP ޘ+~8Zz`Tb8?>q\5DH"{ G#m60y=j쑆&|iUyt&GZÝ#f ÝxdTK>_Zz5@t״k/5#kj0G24|ns{ ӆiAmyOdi6DQ" }C 4`5bk>jcNFcь9cfstd6Z[ҚO5V>6SUGjPhP=Pzg !bNcNCd"9 Xs4cǘ#{Z!>Z%,h>FO6&z `W3Aܴ{ls9DRKmɥR᷼3Vڤ?y{_LCollabtive-2.0/include/font/freeserifi.ctg.z000066400000000000000000000115701237252063700211350ustar00rootroot00000000000000x(Ԓ|̜3333333333Rݗ%׽_ըGMj)` !P@X!DH@T!ĄX@\!$D@RH!T@ZH!dL@V!\@^BP@Q(šRP@Y(TJP@UաԄZPW|PCh14 O3 ZCh =t :C ݠ; z/B?` 00#`$08`"L043`&̂0< `!,Ű2X+`%հ:X`#lͰ6;`'ݰ> p18'$p98"\p57&܂p=!<3x/%;x#|7 j4hѡ`Cb( a0,#b$Q0*Fcb,q0.b"LI0)&Sb*Li0-3b&̌Y0+fsb.̍y0/X b!,E(XKb),e,X+b%U*VXkb-u.b#lM)6-%b;l#vb7=' p08 p48p2N8 p68\p1. \p5܈p3n ܉p7<0x <4x2^x 6x|1> |53~ % $"E 1Yr)(8BS K(%SJJ(9RSJK(=e2SJ(;堜rSK(?T S*JŨ8TJS*K5ԈSjJͨ9D?S jI5ԎSH3uԍSI7B}/4 LCh( 4F(Mch,4&$LSh*M4f,Msh.ͣ"ZLKh)-崂V*ZMkh-6&L[h+mv.M{h/t!:LG(tN):Mg,t.%LW*]tn-Mw.ݣ#zLO)=^+zMo->'L_+}_(T(VV9U0PURRUVSUQERUUESU SRUWSUP%RUT%SU RRU?SiU33QeRUUeSك9*ʭ*ʯ **J*,ʩ򪂪*ʪꪆjڪjƪj'jZVjڪv:NꢺnAz_TWS5P R5T S5RR5VS5QMR5UMS 5SR5WSP-RT-S RRVSQmRUmSSRWSuPRuTS uRRuVSuQ]RuU]S uSRuWSP=RT=S RRVSQ}RU}SjШI+Ѭv`::C0::#(::c8::N$:N:NS4:N :Τ3,:Φ:Υs<:Χ. "..K2. +*k:n&nϺn[ֺn;κ{Gt=@ԃ`=Dp=Bԣh=Fx=AO+o$=YOS4=]3,=#=WP/ҋT/ RҫVQoқUoSһW}{C>c>?O>/o~~~_~A>OoW e15xLp„4LhƄ5LxD4LdD5Lt4Ll5L|$4Lb$5Lr¤4LwL֤3Md2Md3M2M3MS2MSM SҔ2SB!12r+JbjZMS{m꘺oilin~2?ieZ6i4`:NbRw46>gf}t=5p3j(3:cƚqf}ld&)fffef9fgfYd%fnB,3 Ҭ2֬3l2l323s2s3 sҜ2s֜3s\2s\3 s2s3_yhyjyi^ykޙh>j_X;&Æ-;CpHš9 p#pDđ9 GhcpLű9xpBNĉ9 '89SsN8=g3s8;ss8?\ s.Ÿ8\Ks.ȇ0| >ɧ4|ȗ2_| ɷ6|~ȏ1? ~ɯ5ȟ3`ђUV[cZ묷l!lHʆalXΆlDFQlTF1lLƶql\Ʒ lB&IlR&)lJʦilZΦlFfYlVf9lNyl^lA[ElQ[%lI[ʖelY[ΖlE[VUlU[V5lM[ֶul][ַ lC6MlS6?ٟm Ҷmֶmvmvm/kvhvjviGvkvh'vjvigvkv]hv]jv]iWv]kvh7v[6;vk=h=j=iO=kh/jiok|#>O}i_}k:>OboW93uy\p…t\hƅu\xEt\wQ\TEw1\Lvq\\w \B%vI\R%w)\Jʥvi\ZΥw\FevY\Vew9\Nvy\^w\AWvE\QWw%*JҮ+ʹ򮂫*ʮꪹAk긺k울km暻ϮkkZ6kڻ:.溻z_ub7 t`7 unF1nƻ n&)n榻nf9nn[%n[斻n[V5n[ֻ n6-n涻nv=n;#;掻;N3;λ .+殻n;{'{枻{^7~soݻ>O⾺oW=y7{|p‡|h|xG>>c>>>O>OSO>O>O3>>s>> //K/r+JjkZzoFof[oo;{}|_@?C?ҏCMvx?Od?Ot?l?|/b/r¯jƯzofovp~מ?xOxcf?O3uJg]],e_Ucum '?>!B!+B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!?6?/Kʿo[ο5U?ˏD!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!Ŀ'p$p4p,p96,'FontBBox'=>'[-879 -434 1558 900]','ItalicAngle'=>-16.32768,'Ascent'=>900,'Descent'=>-300,'Leading'=>90,'CapHeight'=>653,'XHeight'=>452,'StemV'=>70,'StemH'=>30,'AvgWidth'=>402,'MaxWidth'=>1601,'MissingWidth'=>700); $cw=array(0=>700,32=>250,33=>333,34=>420,35=>500,36=>500,37=>833,38=>778,39=>214,40=>333,41=>333,42=>500,43=>675,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>675,61=>675,62=>675,63=>500,64=>920,65=>611,66=>611,67=>667,68=>722,69=>604,70=>611,71=>722,72=>722,73=>339,74=>444,75=>652,76=>556,77=>828,78=>657,79=>722,80=>603,81=>722,82=>616,83=>500,84=>556,85=>722,86=>611,87=>833,88=>611,89=>556,90=>556,91=>389,92=>278,93=>389,94=>422,95=>500,96=>333,97=>500,98=>500,99=>444,100=>500,101=>444,102=>278,103=>500,104=>500,105=>278,106=>278,107=>444,108=>278,109=>722,110=>500,111=>500,112=>500,113=>500,114=>389,115=>389,116=>278,117=>500,118=>444,119=>667,120=>444,121=>444,122=>389,123=>400,124=>275,125=>400,126=>541,160=>250,161=>389,162=>500,163=>500,164=>500,165=>500,166=>275,167=>500,168=>333,169=>760,170=>276,171=>444,172=>675,173=>333,174=>760,175=>333,176=>400,177=>675,178=>300,179=>300,180=>333,181=>500,182=>523,183=>250,184=>333,185=>250,186=>310,187=>444,188=>750,189=>750,190=>750,191=>500,192=>611,193=>611,194=>611,195=>611,196=>611,197=>611,198=>889,199=>667,200=>611,201=>611,202=>611,203=>611,204=>333,205=>333,206=>333,207=>333,208=>722,209=>667,210=>722,211=>722,212=>722,213=>722,214=>722,215=>675,216=>722,217=>722,218=>722,219=>722,220=>722,221=>556,222=>611,223=>500,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>673,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>500,242=>500,243=>500,244=>500,245=>500,246=>500,247=>675,248=>500,249=>500,250=>500,251=>500,252=>500,253=>444,254=>500,255=>444,256=>611,257=>500,258=>611,259=>500,260=>611,261=>500,262=>667,263=>444,264=>667,265=>444,266=>667,267=>444,268=>667,269=>444,270=>722,271=>611,272=>722,273=>500,274=>611,275=>444,276=>611,277=>444,278=>611,279=>444,280=>611,281=>444,282=>611,283=>444,284=>722,285=>500,286=>722,287=>500,288=>722,289=>500,290=>722,291=>500,292=>722,293=>500,294=>722,295=>500,296=>333,297=>278,298=>333,299=>278,300=>333,301=>278,302=>333,303=>278,304=>333,305=>278,306=>707,307=>506,308=>444,309=>278,310=>667,311=>444,312=>444,313=>556,314=>278,315=>556,316=>278,317=>556,318=>361,319=>556,320=>278,321=>556,322=>278,323=>667,324=>500,325=>667,326=>500,327=>667,328=>500,329=>550,330=>721,331=>500,332=>722,333=>500,334=>722,335=>500,336=>722,337=>500,338=>944,339=>694,340=>611,341=>389,342=>611,343=>389,344=>611,345=>389,346=>500,347=>389,348=>500,349=>389,350=>500,351=>389,352=>500,353=>389,354=>556,355=>278,356=>556,357=>447,358=>556,359=>278,360=>722,361=>500,362=>722,363=>500,364=>722,365=>500,366=>722,367=>500,368=>722,369=>500,370=>722,371=>500,372=>833,373=>667,374=>556,375=>444,376=>556,377=>556,378=>389,379=>556,380=>389,381=>556,382=>389,383=>278,384=>500,385=>781,386=>610,387=>551,388=>611,389=>549,390=>667,391=>866,392=>703,393=>722,394=>892,395=>682,396=>500,397=>520,398=>611,399=>722,400=>518,401=>611,402=>278,403=>863,404=>611,405=>728,406=>278,407=>333,408=>792,409=>444,410=>278,411=>480,412=>900,413=>779,414=>500,415=>722,416=>759,417=>546,418=>908,419=>722,420=>772,421=>500,422=>611,423=>500,424=>389,425=>657,426=>461,427=>313,428=>556,429=>335,430=>556,431=>778,432=>584,433=>747,434=>755,435=>636,436=>549,437=>556,438=>389,439=>525,440=>558,441=>424,442=>416,443=>500,444=>615,445=>439,446=>389,447=>500,448=>275,449=>500,450=>600,451=>333,452=>1268,453=>1091,454=>869,455=>1000,456=>824,457=>506,458=>1101,459=>895,460=>748,461=>611,462=>500,463=>339,464=>278,465=>722,466=>500,467=>722,468=>500,469=>722,470=>500,471=>722,472=>500,473=>722,474=>500,475=>722,476=>500,477=>444,478=>611,479=>500,480=>611,481=>500,482=>889,483=>673,484=>722,485=>500,486=>722,487=>500,488=>652,489=>444,490=>730,491=>500,492=>730,493=>500,494=>525,495=>446,496=>278,497=>1258,498=>1091,499=>859,500=>817,501=>595,502=>1024,503=>607,504=>657,505=>500,506=>611,507=>500,508=>889,509=>673,510=>722,511=>500,512=>611,513=>500,514=>611,515=>500,516=>604,517=>444,518=>604,519=>444,520=>339,521=>278,522=>339,523=>278,524=>722,525=>500,526=>722,527=>500,528=>616,529=>389,530=>616,531=>389,532=>722,533=>500,534=>722,535=>500,536=>500,537=>389,538=>556,539=>278,540=>424,541=>465,542=>722,543=>500,544=>781,545=>588,546=>568,547=>468,548=>611,549=>444,550=>611,551=>500,552=>604,553=>444,554=>722,555=>500,556=>722,557=>500,558=>722,559=>500,560=>722,561=>500,562=>556,563=>444,564=>405,565=>597,566=>377,567=>278,568=>775,569=>767,570=>722,571=>667,572=>444,573=>611,574=>611,575=>389,576=>444,577=>444,578=>444,579=>667,580=>750,581=>697,582=>611,583=>444,584=>389,585=>278,586=>796,587=>590,588=>667,589=>333,590=>722,591=>500,592=>500,593=>564,594=>564,595=>500,596=>444,597=>444,598=>524,599=>559,600=>444,601=>444,602=>722,603=>416,604=>426,605=>674,606=>454,607=>353,608=>624,609=>500,610=>452,611=>500,612=>582,613=>500,614=>500,615=>500,616=>278,617=>306,618=>278,619=>278,620=>278,621=>364,622=>556,623=>722,624=>778,625=>778,626=>614,627=>599,628=>500,629=>500,630=>668,631=>693,632=>640,633=>389,634=>389,635=>444,636=>389,637=>333,638=>333,639=>333,640=>434,641=>456,642=>389,643=>278,644=>500,645=>466,646=>500,647=>278,648=>278,649=>500,650=>517,651=>500,652=>444,653=>667,654=>444,655=>510,656=>510,657=>432,658=>446,659=>439,660=>444,661=>444,662=>444,663=>444,664=>722,665=>402,666=>454,667=>665,668=>476,669=>347,670=>444,671=>363,672=>590,673=>444,674=>444,675=>798,676=>795,677=>805,678=>554,679=>561,680=>678,681=>614,682=>554,683=>554,684=>500,685=>500,686=>611,687=>716,688=>300,689=>300,690=>258,691=>278,692=>278,693=>309,694=>306,695=>432,696=>310,697=>250,698=>408,699=>333,700=>333,701=>333,702=>333,703=>333,704=>258,705=>258,706=>374,707=>374,708=>383,709=>383,710=>333,711=>333,712=>250,713=>333,714=>333,715=>333,716=>250,717=>333,718=>333,719=>333,720=>278,721=>278,722=>333,723=>333,724=>333,725=>333,726=>333,727=>333,728=>333,729=>333,730=>333,731=>333,732=>333,733=>333,734=>336,735=>352,736=>311,737=>200,738=>243,739=>328,740=>300,741=>460,742=>460,743=>460,744=>460,745=>460,746=>477,747=>475,748=>339,749=>330,750=>444,751=>383,752=>383,753=>294,754=>294,755=>327,756=>261,757=>437,758=>437,759=>333,760=>278,761=>175,762=>175,763=>175,764=>175,765=>337,766=>337,767=>326,768=>0,769=>0,770=>0,771=>0,772=>0,773=>0,774=>0,775=>0,776=>0,777=>0,778=>0,779=>0,780=>0,781=>0,782=>0,783=>0,784=>0,785=>0,786=>0,787=>0,788=>0,789=>0,790=>0,791=>0,792=>0,793=>0,794=>0,795=>0,796=>0,797=>0,798=>0,799=>0,800=>0,801=>0,802=>0,803=>0,804=>0,805=>0,806=>0,807=>0,808=>0,809=>0,810=>0,811=>0,812=>0,813=>0,814=>0,815=>0,816=>0,817=>0,818=>0,819=>0,820=>0,821=>0,822=>0,823=>0,824=>0,825=>0,826=>0,827=>0,828=>0,829=>0,830=>0,831=>0,832=>0,833=>0,834=>0,835=>0,836=>0,837=>0,838=>0,839=>0,840=>0,841=>0,842=>0,843=>0,844=>0,845=>0,846=>0,847=>0,848=>0,849=>0,850=>0,851=>0,852=>0,853=>0,854=>0,855=>0,856=>0,857=>0,858=>0,859=>0,860=>0,861=>0,862=>0,863=>0,864=>0,865=>0,866=>0,867=>0,868=>0,869=>0,870=>0,871=>0,872=>0,873=>0,874=>0,875=>0,876=>0,877=>0,878=>0,879=>0,884=>199,885=>199,890=>332,894=>333,900=>257,901=>333,902=>661,903=>250,904=>841,905=>950,906=>559,908=>815,910=>877,911=>899,912=>270,913=>661,914=>581,915=>611,916=>660,917=>611,918=>606,919=>742,920=>672,921=>333,922=>667,923=>641,924=>833,925=>657,926=>678,927=>682,928=>749,929=>611,931=>657,932=>596,933=>676,934=>722,935=>611,936=>812,937=>743,938=>333,939=>696,940=>564,941=>416,942=>506,943=>270,944=>504,945=>564,946=>509,947=>496,948=>520,949=>416,950=>398,951=>506,952=>533,953=>270,954=>491,955=>488,956=>501,957=>486,958=>430,959=>510,960=>608,961=>506,962=>423,963=>524,964=>425,965=>504,966=>618,967=>459,968=>693,969=>693,970=>270,971=>504,972=>510,973=>504,974=>693,976=>534,977=>587,978=>620,979=>820,980=>620,981=>640,982=>684,983=>504,984=>555,985=>534,986=>548,987=>496,988=>610,989=>470,990=>633,991=>410,992=>687,993=>544,1008=>534,1009=>534,1010=>485,1011=>278,1012=>722,1013=>280,1014=>280,1015=>610,1016=>500,1017=>704,1018=>832,1019=>703,1020=>533,1021=>704,1022=>704,1023=>704,1024=>604,1025=>604,1026=>668,1027=>611,1028=>666,1029=>500,1030=>339,1031=>339,1032=>444,1033=>972,1034=>977,1035=>703,1036=>664,1037=>720,1038=>728,1039=>728,1040=>611,1041=>610,1042=>611,1043=>611,1044=>682,1045=>604,1046=>976,1047=>592,1048=>720,1049=>720,1050=>664,1051=>719,1052=>828,1053=>722,1054=>722,1055=>749,1056=>603,1057=>667,1058=>556,1059=>728,1060=>722,1061=>611,1062=>728,1063=>666,1064=>997,1065=>1005,1066=>710,1067=>891,1068=>594,1069=>632,1070=>1024,1071=>696,1072=>500,1073=>500,1074=>442,1075=>344,1076=>503,1077=>440,1078=>932,1079=>402,1080=>500,1081=>500,1082=>491,1083=>487,1084=>624,1085=>500,1086=>500,1087=>500,1088=>500,1089=>441,1090=>722,1091=>500,1092=>741,1093=>444,1094=>500,1095=>500,1096=>750,1097=>750,1098=>545,1099=>683,1100=>433,1101=>432,1102=>700,1103=>503,1104=>440,1105=>440,1106=>500,1107=>344,1108=>442,1109=>389,1110=>278,1111=>278,1112=>278,1113=>686,1114=>696,1115=>500,1116=>491,1117=>500,1118=>500,1119=>500,1120=>964,1121=>684,1122=>708,1123=>690,1124=>975,1125=>646,1126=>800,1127=>628,1128=>1096,1129=>795,1130=>952,1131=>730,1132=>1260,1133=>892,1134=>574,1135=>400,1136=>812,1137=>694,1138=>721,1139=>500,1140=>745,1141=>533,1142=>745,1143=>533,1144=>1193,1145=>967,1146=>868,1147=>602,1148=>964,1149=>684,1150=>964,1151=>684,1152=>548,1153=>443,1154=>320,1155=>0,1156=>0,1157=>0,1158=>0,1159=>0,1160=>0,1161=>0,1162=>720,1163=>500,1164=>602,1165=>433,1166=>611,1167=>500,1168=>552,1169=>424,1170=>593,1171=>424,1172=>611,1173=>432,1174=>992,1175=>932,1176=>592,1177=>396,1178=>681,1179=>491,1180=>700,1181=>532,1182=>664,1183=>491,1184=>776,1185=>690,1186=>729,1187=>500,1188=>908,1189=>660,1190=>1034,1191=>694,1192=>730,1193=>543,1194=>666,1195=>443,1196=>556,1197=>775,1198=>556,1199=>574,1200=>555,1201=>574,1202=>660,1203=>443,1204=>798,1205=>581,1206=>674,1207=>500,1208=>690,1209=>516,1210=>640,1211=>500,1212=>785,1213=>558,1214=>785,1215=>558,1216=>339,1217=>976,1218=>932,1219=>664,1220=>491,1221=>719,1222=>487,1223=>722,1224=>500,1225=>722,1226=>500,1227=>666,1228=>500,1229=>828,1230=>624,1231=>339,1232=>611,1233=>500,1234=>611,1235=>500,1236=>889,1237=>673,1238=>604,1239=>444,1240=>722,1241=>444,1242=>722,1243=>444,1244=>976,1245=>932,1246=>592,1247=>402,1248=>525,1249=>446,1250=>720,1251=>500,1252=>720,1253=>500,1254=>722,1255=>500,1256=>722,1257=>500,1258=>722,1259=>500,1260=>632,1261=>432,1262=>728,1263=>500,1264=>728,1265=>500,1266=>728,1267=>500,1268=>666,1269=>500,1270=>611,1271=>424,1272=>891,1273=>683,1296=>532,1297=>409,1298=>719,1299=>487,1306=>722,1307=>500,1308=>833,1309=>656,1310=>664,1311=>491,1329=>794,1330=>712,1331=>782,1332=>854,1333=>711,1334=>702,1335=>707,1336=>655,1337=>777,1338=>782,1339=>710,1340=>663,1341=>830,1342=>917,1343=>672,1344=>469,1345=>666,1346=>858,1347=>685,1348=>856,1349=>618,1350=>858,1351=>709,1352=>719,1353=>714,1354=>731,1355=>702,1356=>874,1357=>719,1358=>844,1359=>519,1360=>703,1361=>608,1362=>586,1363=>750,1364=>780,1365=>714,1366=>684,1369=>120,1370=>120,1371=>269,1372=>307,1373=>241,1374=>312,1375=>300,1377=>786,1378=>506,1379=>542,1380=>541,1381=>506,1382=>503,1383=>478,1384=>499,1385=>541,1386=>539,1387=>508,1388=>289,1389=>750,1390=>540,1391=>513,1392=>508,1393=>503,1394=>531,1395=>518,1396=>500,1397=>243,1398=>473,1399=>406,1400=>499,1401=>407,1402=>793,1403=>414,1404=>463,1405=>500,1406=>516,1407=>758,1408=>504,1409=>466,1410=>288,1411=>758,1412=>510,1413=>501,1414=>562,1415=>543,1417=>278,1418=>280,1425=>0,1426=>0,1427=>0,1428=>0,1429=>0,1430=>0,1431=>418,1432=>0,1433=>0,1434=>0,1435=>0,1436=>0,1437=>0,1438=>0,1439=>0,1440=>0,1441=>0,1442=>0,1443=>0,1444=>0,1445=>0,1446=>0,1447=>0,1448=>0,1449=>0,1450=>0,1451=>0,1452=>0,1453=>0,1454=>0,1455=>0,1456=>0,1457=>0,1458=>0,1459=>0,1460=>0,1461=>0,1462=>0,1463=>0,1464=>0,1465=>0,1466=>0,1467=>0,1468=>0,1469=>0,1470=>440,1471=>0,1472=>126,1473=>0,1474=>0,1475=>418,1476=>0,1477=>0,1478=>350,1479=>0,1488=>537,1489=>537,1490=>350,1491=>537,1492=>537,1493=>350,1494=>350,1495=>537,1496=>537,1497=>350,1498=>537,1499=>537,1500=>537,1501=>537,1502=>537,1503=>350,1504=>350,1505=>537,1506=>537,1507=>537,1508=>537,1509=>537,1510=>537,1511=>537,1512=>537,1513=>537,1514=>537,1520=>537,1521=>537,1522=>537,1523=>396,1524=>396,2404=>318,2405=>446,2433=>0,2434=>300,2435=>312,2437=>594,2438=>776,2439=>469,2440=>513,2441=>535,2442=>561,2443=>604,2444=>481,2447=>580,2448=>604,2451=>540,2452=>620,2453=>570,2454=>485,2455=>484,2456=>471,2457=>457,2458=>408,2459=>452,2460=>591,2461=>551,2462=>771,2463=>414,2464=>404,2465=>522,2466=>415,2467=>450,2468=>551,2469=>477,2470=>478,2471=>449,2472=>448,2474=>535,2475=>611,2476=>443,2477=>534,2478=>492,2479=>474,2480=>442,2482=>542,2486=>507,2487=>467,2488=>523,2489=>419,2492=>0,2493=>419,2494=>202,2495=>189,2496=>202,2497=>0,2498=>0,2499=>0,2500=>0,2503=>294,2504=>289,2507=>774,2508=>825,2509=>0,2510=>356,2519=>219,2524=>523,2525=>420,2527=>469,2528=>604,2529=>481,2530=>0,2531=>0,2534=>500,2535=>437,2536=>479,2537=>507,2538=>497,2539=>500,2540=>482,2541=>503,2542=>517,2543=>481,2544=>443,2545=>443,2546=>429,2547=>383,2548=>432,2549=>478,2550=>539,2551=>158,2552=>365,2553=>280,2554=>357,3585=>512,3586=>453,3587=>512,3588=>519,3589=>529,3590=>561,3591=>411,3592=>437,3593=>552,3594=>452,3595=>509,3596=>707,3597=>707,3598=>574,3599=>570,3600=>406,3601=>607,3602=>686,3603=>749,3604=>494,3605=>497,3606=>509,3607=>552,3608=>461,3609=>565,3610=>527,3611=>523,3612=>556,3613=>551,3614=>570,3615=>570,3616=>571,3617=>531,3618=>493,3619=>433,3620=>513,3621=>491,3622=>571,3623=>439,3624=>510,3625=>594,3626=>484,3627=>554,3628=>616,3629=>493,3630=>496,3631=>417,3632=>392,3633=>0,3634=>366,3635=>366,3636=>0,3637=>0,3638=>0,3639=>0,3640=>0,3641=>0,3642=>0,3647=>662,3648=>297,3649=>544,3650=>298,3651=>329,3652=>328,3653=>326,3654=>488,3655=>0,3656=>0,3657=>0,3658=>0,3659=>0,3660=>0,3661=>0,3662=>0,3663=>725,3664=>624,3665=>624,3666=>624,3667=>624,3668=>624,3669=>624,3670=>624,3671=>624,3672=>624,3673=>624,3674=>645,3675=>872,4256=>453,4257=>448,4258=>546,4259=>619,4260=>478,4261=>481,4262=>459,4263=>707,4264=>467,4265=>471,4266=>842,4267=>464,4268=>443,4269=>707,4270=>460,4271=>465,4272=>686,4273=>440,4274=>550,4275=>561,4276=>580,4277=>467,4278=>630,4279=>466,4280=>517,4281=>456,4282=>502,4283=>464,4284=>534,4285=>440,4286=>443,4287=>522,4288=>460,4289=>463,4290=>536,4291=>455,4292=>468,4293=>449,4304=>454,4305=>452,4306=>544,4307=>629,4308=>451,4309=>452,4310=>452,4311=>702,4312=>451,4313=>452,4314=>820,4315=>451,4316=>453,4317=>695,4318=>449,4319=>448,4320=>694,4321=>501,4322=>544,4323=>517,4324=>560,4325=>450,4326=>627,4327=>452,4328=>491,4329=>452,4330=>485,4331=>452,4332=>485,4333=>443,4334=>500,4335=>582,4336=>455,4337=>451,4338=>480,4339=>414,4340=>453,4341=>418,4342=>741,4343=>452,4344=>452,4345=>544,4346=>454,4347=>410,4348=>339,5024=>711,5025=>678,5026=>604,5027=>667,5028=>796,5029=>301,5030=>516,5031=>544,5032=>457,5033=>716,5034=>703,5035=>383,5036=>628,5037=>709,5038=>455,5039=>601,5040=>472,5041=>574,5042=>730,5043=>939,5044=>498,5045=>528,5046=>667,5047=>891,5048=>505,5049=>792,5050=>957,5051=>725,5052=>595,5053=>733,5054=>698,5055=>638,5056=>720,5057=>732,5058=>624,5059=>638,5060=>565,5061=>903,5062=>655,5063=>681,5064=>675,5065=>949,5066=>683,5067=>547,5068=>693,5069=>732,5070=>529,5071=>569,5072=>536,5073=>677,5074=>631,5075=>495,5076=>973,5077=>543,5078=>607,5079=>652,5080=>652,5081=>693,5082=>514,5083=>803,5084=>658,5085=>597,5086=>627,5087=>659,5088=>679,5089=>706,5090=>563,5091=>618,5092=>767,5093=>776,5094=>731,5095=>492,5096=>808,5097=>823,5098=>796,5099=>689,5100=>716,5101=>518,5102=>521,5103=>719,5104=>563,5105=>776,5106=>634,5107=>822,5108=>621,7680=>611,7681=>500,7682=>611,7683=>500,7684=>611,7685=>500,7686=>611,7687=>500,7688=>667,7689=>444,7690=>722,7691=>500,7692=>722,7693=>500,7694=>722,7695=>500,7696=>722,7697=>500,7698=>722,7699=>500,7700=>611,7701=>444,7702=>611,7703=>444,7704=>604,7705=>444,7706=>604,7707=>444,7708=>604,7709=>444,7710=>611,7711=>278,7712=>722,7713=>500,7714=>722,7715=>500,7716=>722,7717=>500,7718=>722,7719=>500,7720=>722,7721=>500,7722=>722,7723=>500,7724=>339,7725=>278,7726=>333,7727=>278,7728=>652,7729=>444,7730=>652,7731=>444,7732=>652,7733=>444,7734=>556,7735=>278,7736=>556,7737=>278,7738=>556,7739=>278,7740=>556,7741=>278,7742=>828,7743=>722,7744=>828,7745=>722,7746=>828,7747=>722,7748=>657,7749=>500,7750=>657,7751=>500,7752=>657,7753=>500,7754=>657,7755=>500,7756=>722,7757=>500,7758=>722,7759=>500,7760=>722,7761=>500,7762=>722,7763=>500,7764=>603,7765=>500,7766=>603,7767=>500,7768=>616,7769=>389,7770=>616,7771=>389,7772=>616,7773=>389,7774=>616,7775=>389,7776=>500,7777=>389,7778=>500,7779=>389,7780=>500,7781=>389,7782=>500,7783=>389,7784=>500,7785=>389,7786=>556,7787=>278,7788=>556,7789=>278,7790=>556,7791=>278,7792=>556,7793=>278,7794=>722,7795=>500,7796=>722,7797=>500,7798=>722,7799=>500,7800=>722,7801=>500,7802=>722,7803=>500,7804=>611,7805=>444,7806=>611,7807=>444,7808=>833,7809=>667,7810=>833,7811=>667,7812=>833,7813=>667,7814=>833,7815=>667,7816=>833,7817=>667,7818=>611,7819=>444,7820=>611,7821=>444,7822=>556,7823=>444,7824=>556,7825=>389,7826=>556,7827=>389,7828=>556,7829=>389,7830=>500,7831=>278,7832=>667,7833=>444,7834=>444,7835=>278,7836=>333,7837=>278,7838=>659,7839=>534,7840=>611,7841=>500,7842=>611,7843=>500,7844=>611,7845=>500,7846=>611,7847=>500,7848=>611,7849=>500,7850=>611,7851=>500,7852=>611,7853=>500,7854=>611,7855=>500,7856=>611,7857=>500,7858=>611,7859=>500,7860=>611,7861=>500,7862=>611,7863=>500,7864=>604,7865=>444,7866=>604,7867=>444,7868=>604,7869=>444,7870=>611,7871=>444,7872=>611,7873=>444,7874=>611,7875=>444,7876=>611,7877=>444,7878=>604,7879=>444,7880=>339,7881=>278,7882=>339,7883=>278,7884=>722,7885=>500,7886=>722,7887=>500,7888=>722,7889=>500,7890=>722,7891=>500,7892=>722,7893=>500,7894=>722,7895=>500,7896=>722,7897=>500,7898=>759,7899=>546,7900=>759,7901=>546,7902=>807,7903=>585,7904=>759,7905=>546,7906=>759,7907=>546,7908=>722,7909=>500,7910=>722,7911=>500,7912=>778,7913=>584,7914=>778,7915=>584,7916=>807,7917=>585,7918=>778,7919=>584,7920=>778,7921=>584,7922=>556,7923=>444,7924=>556,7925=>444,7926=>556,7927=>444,7928=>556,7929=>444,7936=>564,7937=>564,7938=>564,7939=>564,7940=>564,7941=>564,7942=>564,7943=>564,7944=>661,7945=>661,7946=>794,7947=>811,7948=>792,7949=>803,7950=>661,7951=>648,7952=>416,7953=>416,7954=>416,7955=>416,7956=>416,7957=>416,7960=>740,7961=>795,7962=>923,7963=>940,7964=>996,7965=>986,7968=>506,7969=>506,7970=>506,7971=>506,7972=>506,7973=>506,7974=>506,7975=>506,7976=>879,7977=>901,7978=>1036,7979=>1035,7980=>1099,7981=>1100,7982=>954,7983=>959,7984=>270,7985=>270,7986=>267,7987=>267,7988=>267,7989=>267,7990=>267,7991=>267,7992=>490,7993=>529,7994=>655,7995=>654,7996=>705,7997=>713,7998=>570,7999=>573,8000=>558,8001=>510,8002=>510,8003=>510,8004=>510,8005=>510,8008=>797,8009=>867,8010=>1026,8011=>1022,8012=>993,8013=>1017,8016=>504,8017=>504,8018=>504,8019=>504,8020=>504,8021=>504,8022=>504,8023=>504,8025=>916,8027=>1062,8029=>1100,8031=>933,8032=>693,8033=>693,8034=>693,8035=>693,8036=>693,8037=>693,8038=>693,8039=>693,8040=>852,8041=>909,8042=>1072,8043=>1072,8044=>1032,8045=>1047,8046=>930,8047=>946,8048=>564,8049=>564,8050=>416,8051=>416,8052=>506,8053=>506,8054=>270,8055=>270,8056=>510,8057=>510,8058=>504,8059=>504,8060=>693,8061=>693,8064=>564,8065=>564,8066=>564,8067=>564,8068=>564,8069=>564,8070=>564,8071=>564,8072=>821,8073=>854,8074=>998,8075=>1011,8076=>992,8077=>1001,8078=>866,8079=>858,8080=>506,8081=>506,8082=>506,8083=>506,8084=>506,8085=>506,8086=>506,8087=>506,8088=>999,8089=>1044,8090=>1179,8091=>1165,8092=>1227,8093=>1229,8094=>1080,8095=>1085,8096=>693,8097=>693,8098=>693,8099=>693,8100=>693,8101=>693,8102=>693,8103=>693,8104=>1037,8105=>1113,8106=>1264,8107=>1264,8108=>1219,8109=>1241,8110=>1120,8111=>1132,8112=>564,8113=>564,8114=>564,8115=>564,8116=>564,8118=>564,8119=>564,8120=>661,8121=>661,8122=>661,8123=>661,8124=>831,8125=>192,8126=>332,8127=>500,8128=>500,8129=>534,8130=>506,8131=>506,8132=>506,8134=>506,8135=>506,8136=>611,8137=>816,8138=>889,8139=>908,8140=>881,8141=>500,8142=>500,8143=>500,8144=>270,8145=>270,8146=>270,8147=>270,8150=>270,8151=>270,8152=>333,8153=>333,8154=>497,8155=>521,8157=>500,8158=>500,8159=>500,8160=>504,8161=>504,8162=>504,8163=>504,8164=>506,8165=>506,8166=>504,8167=>504,8168=>676,8169=>676,8170=>905,8171=>901,8172=>783,8173=>333,8174=>333,8175=>500,8178=>693,8179=>693,8180=>693,8182=>693,8183=>693,8184=>907,8185=>833,8186=>963,8187=>875,8188=>952,8189=>500,8190=>500,8192=>500,8193=>1000,8194=>500,8195=>1000,8196=>333,8197=>250,8198=>167,8199=>500,8200=>250,8201=>200,8202=>100,8203=>0,8204=>0,8205=>0,8206=>0,8207=>0,8208=>333,8209=>333,8210=>500,8211=>500,8212=>1000,8213=>1000,8214=>293,8215=>465,8216=>250,8217=>250,8218=>250,8219=>250,8220=>444,8221=>444,8222=>444,8223=>444,8224=>500,8225=>500,8226=>350,8227=>350,8228=>250,8229=>500,8230=>889,8231=>250,8232=>0,8233=>0,8234=>0,8235=>0,8236=>0,8237=>0,8238=>0,8239=>250,8240=>1000,8241=>1601,8242=>247,8243=>411,8244=>611,8245=>220,8246=>440,8247=>660,8248=>469,8249=>250,8250=>250,8251=>629,8252=>666,8253=>500,8254=>500,8255=>953,8256=>1000,8257=>314,8258=>931,8259=>333,8260=>167,8261=>480,8262=>480,8263=>1000,8264=>833,8265=>833,8266=>500,8267=>453,8268=>453,8269=>450,8270=>500,8271=>278,8272=>882,8273=>500,8274=>497,8275=>500,8276=>953,8277=>512,8278=>410,8279=>855,8280=>620,8281=>620,8282=>179,8283=>621,8284=>564,8285=>179,8286=>179,8287=>111,8288=>0,8289=>0,8290=>0,8291=>0,8292=>0,8304=>300,8305=>235,8308=>300,8309=>300,8310=>300,8311=>300,8312=>300,8313=>300,8314=>300,8315=>300,8316=>300,8317=>216,8318=>216,8319=>318,8320=>300,8321=>250,8322=>300,8323=>300,8324=>300,8325=>300,8326=>300,8327=>300,8328=>300,8329=>300,8330=>300,8331=>300,8332=>300,8333=>216,8334=>216,8336=>350,8337=>304,8338=>340,8339=>317,8340=>278,8352=>698,8353=>667,8354=>667,8355=>611,8356=>500,8357=>722,8358=>667,8359=>988,8360=>953,8361=>833,8362=>869,8363=>512,8364=>741,8365=>722,8366=>611,8367=>1340,8368=>489,8369=>589,8370=>619,8371=>722,8372=>556,8373=>611,8374=>408,8376=>524,8400=>0,8401=>0,8402=>0,8403=>0,8404=>0,8405=>0,8406=>0,8407=>0,8408=>0,8409=>0,8410=>0,8411=>0,8412=>0,8413=>0,8414=>0,8415=>0,8416=>0,8417=>0,8418=>0,8419=>0,8420=>0,8421=>0,8422=>0,8423=>0,8424=>0,8425=>0,8426=>0,8427=>0,8428=>0,8429=>0,8430=>0,8431=>0,8432=>0,8448=>604,8449=>605,8450=>674,8451=>954,8452=>556,8453=>573,8454=>667,8455=>518,8456=>667,8457=>822,8458=>490,8459=>824,8460=>663,8461=>818,8462=>500,8463=>500,8464=>578,8465=>613,8466=>715,8467=>417,8468=>777,8469=>751,8470=>783,8471=>792,8472=>832,8473=>589,8474=>729,8475=>892,8476=>711,8477=>755,8478=>616,8479=>610,8480=>879,8481=>1156,8482=>920,8483=>611,8484=>659,8485=>389,8486=>743,8487=>743,8488=>663,8489=>286,8490=>722,8491=>722,8492=>846,8493=>613,8494=>533,8495=>363,8496=>587,8497=>690,8498=>556,8499=>1021,8500=>387,8501=>537,8502=>537,8503=>350,8504=>537,8505=>417,8506=>906,8507=>1155,8508=>655,8510=>586,8511=>722,8513=>663,8514=>485,8515=>485,8516=>637,8522=>516,8523=>778,8525=>906,8526=>378,8531=>750,8532=>750,8533=>750,8534=>750,8535=>750,8536=>750,8537=>750,8538=>750,8539=>750,8540=>750,8541=>750,8542=>750,8543=>750,8544=>339,8545=>608,8546=>877,8547=>940,8548=>611,8549=>910,8550=>1176,8551=>1439,8552=>940,8553=>611,8554=>936,8555=>1204,8556=>556,8557=>667,8558=>722,8559=>828,8560=>278,8561=>526,8562=>774,8563=>712,8564=>444,8565=>702,8566=>950,8567=>1198,8568=>712,8569=>444,8570=>692,8571=>970,8572=>278,8573=>444,8574=>500,8575=>722,8592=>964,8593=>499,8594=>964,8595=>499,8706=>494,8710=>612,8721=>713,8722=>675,8723=>675,8725=>750,8730=>549,8734=>677,8747=>416,8748=>750,8749=>1083,8750=>722,8751=>750,8800=>564,8804=>675,8805=>675,8992=>686,8993=>686,9251=>500,9674=>494,9675=>791,9676=>791,9824=>626,9825=>694,9826=>595,9827=>776,9828=>626,9829=>694,9830=>595,9831=>776,9833=>333,9834=>555,9835=>722,9836=>722,9837=>415,9838=>377,9839=>402,11799=>333,42790=>722,42791=>491,42792=>770,42793=>586,42794=>532,42795=>409,42796=>437,42797=>389,42798=>578,42799=>580,42888=>333,42889=>278,42890=>282,42891=>286,42892=>278,64256=>526,64257=>500,64258=>500,64259=>747,64260=>748,64261=>518,64262=>665,64275=>971,64276=>969,64277=>978,64278=>971,64279=>1219,64285=>350,64286=>0,64287=>537,64288=>537,64297=>564,64298=>537,64299=>537,64300=>537,64301=>537,64302=>537,64303=>537,64304=>537,64305=>537,64306=>350,64307=>537,64308=>537,64309=>350,64310=>350,64312=>537,64313=>350,64314=>537,64315=>537,64316=>537,64318=>537,64320=>350,64321=>537,64323=>537,64324=>537,64326=>537,64327=>537,64328=>537,64329=>537,64330=>537,64331=>350,64332=>537,64333=>537,64334=>537,64335=>537,65533=>900,65535=>700); // --- EOF --- Collabtive-2.0/include/font/freeserifi.z000066400000000000000000013034451237252063700203670ustar00rootroot00000000000000xԝg|T9g&@*$!PB' @({* E]@AAE RD@ ]Az 5ϙ{}ܧ콞kL7HՆ [f1PܦiF4,5q0TD(+3ˊ[" f7I>XܢN̎6ڹ"&Ʒڿ7?-R&V밡6]K< 1g+ED=;(enoDg7d X-֜wv?t+'>VxސWWÝ$!KW_~eXwmgb];i yӿϽ^ܿ~UE\ߎž3 z}"3ppWXf$/Q1|$FR=c[>OdOg5s&*.FoomBiTgqN~Mȟ)f1K.0R^?(b)7-SVI9-1SIZ2]O:5˱!ƦMahDuR-vfu䚭'eHBf* djn.d*/UK+y?>q6O8r 3DFKC|P]XRCqH{%l֟Sy?,pHvfj/H 5CC*9y֌qOi)awa2gՓ6~vފxu$ [=@Ro-aW/xELԋe-cD(ܐuՔi)H*(>XogygQ2 zdS%ӕ 0%^1zSځf%q?/ꈃ X-vX./9{F,s~h7Ki3?8_ьşaˆaۍ\ְxIAhܓFN{k~ޚ~#m̿OgyJL b欽2/aF _G.)qM89Gv R#f9}1gB<#)>Q ) voZEOkd/T'r>Őud* s`F gǚᣜR=5wT7՜'JnkD:wI/)5dJ ?=~tTGf찳8UQe~X՞bQD怷y?z`)Ywwikyiojc:z;戹&G._129oa=_[lSnй:lqPɃYO_}{Yj3r>y#Sc c.{ /G]^r pSqu i~]!!6~ԄU×~#Or2ASZ;@u4P7H u,5}_F/} ]3+5`^o>ԾW.}Ouj@_U\]| 53#)1'7KW/4||VNj L>z} C3PVIk8PZiJu|X6z ^P_QP|} (dS]K> rr론ݯR 4+#g8JP:&$MMyO+y%}zDv;eSQE 'ĭV gޔex~DC~δ}@_0w 20_pl;x٨,(?S9hDESC}z37@5 `CFG`s:RMeEoî~E]w~0! Շ\W;' >xvΡL9-@,ל~q=a>k`#6A爃 DIgl(:OZm٬EhYxxfQ75W\W;_b=_*f} VSĪ78z5{ڒfgC95(֣M[a~X9ì2oiQ/0k}\-&)ւ q_o1{h sѬ7} 2=zۙyb'*1v./wVdu ,cu^ E __BYJP9`7]ȩ.?/SVVliqVÎ V t6hW}UC@U?R>jycں4*J%RH}~-$O&"hW^Zsી@ u0-yV@GV R~یeeu)mZQptbWJ ~P:P/]O%ptލz3dڟ+17&էJkuPcȣR⥤2T◌^WɇEBX[I8{acwۓgZhOQF2{k,{hrz89,Cj&9A>jRE7xgv@]\|+lhe+g+a eWs+rN\*uaV({N=>|v+Y͉YӬG*$\NYIQV}#,y,Eԓ϶QŕӬx(!u՟_3Q:TB {9Jwaa"ik3w̡__6>DM1~5@21ŹkڑXCs3M;~FW]8 v k 11Qkokp&jmRjRgXgxě}osV\$̞q(ZEVn[iaEDr>JQR+\_ب4k(v >= ~ۑT ~!Vj_D ρ^;,ZS k<'Y[n 1r\0yK1>+2ed*d8㇐9י:G `=E~mwbi/pv^ܻd7B=uch~1bFI`mxthVk;1} Eڑd|1\mB$QΰG=Glf٭3HYDl`9=>Z,'Je] M3}8W6. pb^9}2U*h(.g/!2טÏ%[ -Qeco;fz u)֞{|.[c/U?FS@~}uTl0O՚7jKL[ެ8k?>{j~>ky}qgi9S?ku.R6:9Z̰0g:>Fkմ ǎF =}Lۑ{ϋJy}jsqzѾ.y囟af#sn߿[Ϫg w'=:xDm|߽8xF6n[s LcF1Z,^` byK[-okhe/3>/+Dg)&3-2ݒ&-m,We0GԠmGYEM1AM˙ ZYuUjE2Y;+6WY%hi|_V4a*sLp/˴dN< _>s!QN [KqhyL'6Y֓5O>C>1?/Pc^-ҾZ_λ.Rϝ̋6;Yif^s09ڑo"G |`|~ JUo]}Sjkz4~Ϭ:r+StQrJVPPկ/xRs$"+3_N*r9Rϡ>dn~3`9s?9S̞f\1?+Ty3MC״Ou_8iuePEOd\#QQ|6`䄌}8QDF\'5hρ\G(b/r~Te_o9-IjЏVߏǹbvJܴGY>"ԭ5CӚK]@} | 9Iky ;T79 \wj5Ҫqn7BVL,`gR,U*kOA/mXOػRզi4-o>oe$uM^xtv4;j3tm[J}gym~޲=3a͉v;7e 3jEmyG.;~eԜ%{қ6^?nrF-# =gaԍrYSo,pur߶,]]*K(xK9v֗M׿߳_S+C?P(# l6<[\㬫Jm|AjQ{WWSf)yׇJr7DR]Xgr|Wi+YBR>w[BIY ֊YRGERZi#J5qF' !½MSDzd6ԗD}rXk_9+ eMI~T9U15_)?$g߉c5o]~LJSUQKoTwrO?r}S)逸;򯰇.Oԯ38Ր0 呑ԝ79eN݄-t\=UjKrϙ>VRY;_UPo@ΓJsB|XW4iH ^={ b5e }Af0ZN{vѿauW$Zپ?6~. ZI'%^KpTՒYot#uzmZs{ˆI40fM,`kb\[Bz*@%u%{.U %@}s^ u#r\*ɚxѦh.$?VOV%l15NM[Ԣ6L0XphBTu'Nפsu zarU,MfO*;ȇLgy[1MS~#&I4%gUG$n|=_'K11`57TA{ț02F\@e`]G}@M18Uն2779G|wW "̣]t^ܟc$L-Աh!H!FW?`{k w_x\>Q~dZH`dODy=)erVNFy4RRcKsC.ܵU7=׹>@XY*PSKG GPII ! 32LhFwTf-Lb)i7c9|G?/7MMk|NUu+{PIﯾCWh?CkΑ]8Tc 7/~fm`~g r|WUoa㻫[wVwa\8>\~'=W,\t O&nsN+NҐm6E-~Z[AV֎ַSW]ǻNu5uW;\wz7O4l_xUWFZT_h+/L,L.[X0SKc\;ݶzYK[cm]:uOcf]{iKG^ 5r1hlƠAǂ~ &q0X7 iQaG%jÎ={cGIR]XBa H)WаC?o׿ӿֿkDÈ}?Җ+9k~vR2]7GiA9BqJ(F)j"ap3.ﴽ{~Up`pQǬ ķ; ѽį) 5\.;s0wZ;~/;q.l2&3;܋8ʼnJQ̿?*leU?U Y\wYKJPyK(eۦD P)/a.)T,U$ZJ UIu!5p$*:"u%UI}i@}HKi*i.L2%KK ɖ#Ji+#_Q: k)ody[ByOB>e|,'Z>eZB6z(K,ȷK n]zLJ_2LUd97+SOyJh{d+kyeןf>.+DY(.]VveMr5G=rY+#\>qYU&T/d̐2Kfkڰs[[_qj[) ;NM 5B y)>A^Jw1&Sұ@۱)AM&ǡ[3*vAjM SN&SBmSL l 1y^FJw b4t%P(ᶦB8ٲr' IQRRSM^osN]>45F M)-r1uM]<[׼R<)~_IM>1O&iy.Ykez hyh>-ۦ,^k+y[K {?-GWhT1x_ Ja_)l(m]>uh vҖA2/Qc9j~`+cK0{o0 gث+Go8 ;F7<@H[*Ѭ~[ ۣ[*ʼԂUб U[4Ȫ _U`C Z zU78tî8G-G8j8dUǷ:x&}j2&vׄ&kZ6բFg-|W kQ[6$D|ĸ$%1.qIKb\ud N{ӡ}S>u蓂m)蕂)螂)7uWG*L*K*6TbV]z~Ȫ,filMԃ mHN4B~#7Fĩ1m Gm iHCF2Ґ4d!#4|o҉O:؜ lnfo_3ĞLd'6hEm\hN}O ln-6D:fl[Dv|9bBּkͻּkͻּkͻp;\snnmhG8ڒ혃y;X}=:GԞ>3K%|yȳY/;ˎ̙ё8u##sv]WvņnۍtYwtANOlm Go`{_8"Џqez ćara`d o+ p ǫpt>#Hdk< Q:urx 5qc@75GǞ1<&~ic& e"zNDpL$'9̷7M[$|4?Of-Z2{&m2qFmtxF6wmX !k!k!k:33;xzqȟȟq]f,tq6Y8 ga,l͚2l48Fd6y?_&g9áqK.%^s<|Yd,@CB;ûwxwu.BE]|1/~ y.<,Eز\\Wއ#\Zɾy?FO v|ʘO>%W#{52Vr`XCL>'?1ZlKŶ}dz}q?O'bz?D=Ě1\`>1l8{|_ȳ_'Y7OvB߈ow #4449z_A3y5 |g{]2ϢYޝŖYwCsp#x|9}|xOȉ ^$.9s(ؐǖ|_l`BL\Jς*}bUJ^\EUtJ a5r5kp^#utN_::cn{[oW77כsd݄B[n[6pWwܽCށGwbvȽܻȸȸܻޅz#_{]̅|]0. vɋ>6' 8?@Cd>dC=$Gyc 9񄾅[H, )Ϟ3=C",CǿzQ DQ|_n`.x*35䂁`X 6 <EscjȴSQȲq`78!>gtqe(ssQwnγbUQ{Q<Ǔxzc ; .-.-'8 9ٚ7(m@[r:GУ}; |#qu'|:ӕ8unuc\7Ns]z`kr'~=q/MnAgӟXǮ2r k!kʫo8}Gg$$?_K:F` w,78܏îF o"M1ĻIțStno#o*94ݦs3 yx7[f˙?R*lt?௹㚚QyvckÇ>>1Z- Ԧ 5TBf!}C Ɂ:Ebt_%Y>KX¸w{z-2.}@5b >$ J|VU?+VQO ~>U?^m5TtPu-2bZC laTܯgzn %&|5~;_ ϷlA-賕݆ml{};xO ?||=Awy3q~f{\F0zF&;]G{A?zޣ%7pe1|x|yx gg »_ȏ_+IxNS91~Cw39Ҟ#?TT@\d%]&?/ÓO,;+̓U*qX{jBc[62j5.q]n>=!{=#t~L'p{F"bQ~p^Uf *`j'Q5/ ZDT83~``=TTwӷX*jb OTjcȥFQb\QTQ}ʋlՏ~2`Y*\\Q#բA2,GYt(Br-7VԠ`H`8CC#5>IEUB(l*2P?UN=ȬT ;yjƖpǡKmQcS h/jMZ<$d'_2nuguKߺ؟JTtm  i"Qk&`%~k-9p¿й5sə6mѩ6#yረѵ>̳N|w%ߍ=У9Gobқ}a_?vLߗO: tm9>}r mU_ep5E"6u81<oTddž o">H7~y2ϦNaMm*ciN2Xz&4 Y}6~6a\ſ|x#X],fb|{=|>YJ.E2 y c9sw>Jd%9‡')?enF3x>Þ55ע:/zr=؀_67JK}M+&n3:lo[X;[c؆ma6lmv:ovlNb?ǦpOq?{?wqwqwqwqA|qA> 2F3!<0z0|ѓZ@= aw|G;z?JܩTj((Ccw cwqzǯqJݠG{}O ='@_qA} ǯp$I8Nq=:uyr ;N1OA߰wNp4"3 g g b9999yySۨyu[cyl9-X3.0?/ȏ"\Ėr"kE͋㗘˗󗘫X.^bD\"O.3/3/2eֲ_2χ?|χ?|χ?|+_ W+_*J*JN\%'W5br\#&5|| אy אy אyױ:6]ǦtculTc lM76tn` lM7&6ĦtnbMo߄&-o [߂mo߆6 mo;߁w;߁w ]߅.w ={߃= NV / /߇>}??C?!COݮ>}+~cr19{L=&cOȱ'pan>an>an>an>an>an>annm!2 ѻ^|/d2 OOOOOO_<g ]a3}=ES=ESWѯ"{tбG{S4 x$"A '\MBò^4'9n`@P sh (n7d{x%ˀGUAj>'|/:?bo=rJAvβp%Z!W0v.g_aCcK8p#GW o$#[$U}+`o@l9jy_rԢxE(tble쨜 БV9]* /ѓynU᫊N1_ cclC>a`h5_gfl"ϒ7̺[TM/ոFv=YǮQX5 v gCx15 ӔH#Nӑ?҉D- {g&㳈q--Zl |mf6ʆ?~˦_6FVKDזy-ے-TK֒-%sΡo:_ 9͡o+klEV5<ѹ5[ߚ_6mmС-iGaO;޷y{b߽M/#kJGtN.[][tJ<nnɯ9#k=Х'{G/z37}w!wS_r/%V}?>vg|M2@ځD|5an!/+0|5h{_p 'ÉFH~5^ch|?_ga :A<x9=_Gx\MEI7NS*OCiOsAf9 dEbt^Hw;q,&?8gkb{>y,Crt_#ޭ7}?j>53y<[ :xKlۄF 1<w dGr|/C{3:DfY~/r}wq;}O3,Ed\"_׵|K]7U2zkCly['O3t-:.K,J}.X,qbnX\ʈuXRNbCR|X<6œ>^ܗy\x3·֗~X,\~*@P>xJ, b )&PƗ#6yȭb'JH,хRXyWXK36XjTKMdԎKbXƊ%yXn7w=d54Ƥ}bi/,X;--vuZeil"bi[,)t u n<̞U > ů% ?.;?ϣEtkr r3{]cڇ{ -ONXXՖblX-j SypD3B:Unbu?(bZ| cX=wzZ l+sx|to$ Vb/xR,%@Ub-x_nXm.b FNHc#k8#Ϭ&b X!Jȩ^QpG1&X+#2㪠gl7zX⇪guDob}շ5⑑O5&jc~A_=.\Q6 -Wfe<հ*5rouSk[U_^iݲzD=u֨]Fڴ+YC3ZFW)_g4?w'.qv>Nf4bi |HY]R+jQÂ2c4)S>¯{nH|2]j(%# gI&(3E>Opi,FߊzR[}טF^% 7&iի։r{}ھ7^3.uqz8\tr0Rz\wbƍ+"<,:F}luӬW7Vt:SVIVc u=TgrKd)О<]#fHy#U,Q·TXC[O0?!5lJ_ OTyR<|KG4 *Wt:#L`隥}KZ|݋Q2K ?be ?ϒ%}<=}J'ĵu3Nm<1H!{b}C}CVWbROL=;u*>ӟc-nw'oT_qi+V(תIjv?Vֳ$(񟍗@LnsZڂl~^ߢTƙk(D٤&-Ylc֛UֈW VKVS)wl$7wfF#ѭjآ"-[YYfǬ]ֳG=n:j)6˱WOVDsuPY!j+18{Pw4dC/_rG VU {XMvyKFtT|YV'ؙΪ!)ww"KVW-K4锻Z:yB3ﴎk22"Loikw{nꭘȤXRhR-3:WFDPDP-w#5E4륶Vr$ O2 #yhi0‘("xmnuJZS !2"׮ܡijF37*RJG +&ef&ULUYIqw-~N]m*AƊs`1\"eLyvfgfgfNv7$9pQÀ|(O.削S#>yf ADdSTW}e-tw_1h2.JHڀ m9[*Iz`4v~'~ogjE\~DDkC::H:zPLyfJ tW6;=4ݳ/ު_Q?s7Mߜ ;;~qBVqYOu|k::wŐE~oE.$0z $ ψ]!)P^F%@йJk4˲4V[.8eUۧ)Q̅Gw":P/EE . UEU,J1 SRNA/zeOt.y 3=MXj[ <E_|d&W' z~YR.bFѹasRtd1Q#L4g#z OSw}q Ʊcw<1EpqM"H4}!1Db?3tk6F&j:\ \G?.Ji$)M0;@lH#tʥWKj*tSκf.-OFJ#*>ފ? ( )4/}df5L|0Y^Pj`UϹRTuAh_n5HZ/%K~Qfst\K, :ʑ%\us%\R9*F\cT(axM xlO&߫vdK; "fYm3ݣAȩ08T *o׏nw&3s-,+Ø%|S3|s=փtJ3Os&sފOʸV!EVбrJ, J.\anO"¤RZC;F;Cʰ১1:B dGl°L _D`PKCgGAty߽ #( gɵ VlV}TY)b@F& h6[mwkwlc<NeD]W/ܻgĒOl\s]/h?X\s~).t4i ;̞{vln5{ΎR&ڽ-V]{t?CZ2yo"C4$&>e$n.܁ %(zKCISFmc~)T_L6NW5T kbvkd@*~~!> Ca[ WÁv5ۘ*۸z! "މ z: 3Ɩg* RR8aM;0#wx K" L՛%900BeP;bb\chmq +;Qty\2V1 D;edF76;pZ-҅S2tϨ( Ae/FZy0?pѺSEƝfc5Zn=5cv|h!LW^ٹc`-yM NȘ4Nm_рF0a݃&ȗA"7ފ0!^[Zof 雡zUSKWeCxbWu%^#U]<&%m+yWPҚ83.OC;ӧ#VG}^㈞x iCQ sЕI/WYv&VRs>*!䐨PW.<>PG[?睺O[=r~w><1i :5|G|T*u6DJ`uuƙR$THYC7|f1Ey0dЌQs(^V׌!TOF \2Do <75ڌ4(_`Hp(`aDzU.@ԬCz+omt}*!h$~+fD) Ka Ufp4uނ0voWo>%xğ^nh!^!ܨ%ܰ y sR?6 }2<.4 nv.:p7Zٺ Q_kZQ4r9ӗ◯w@1ޮ4X~\FzA@}{"g5@[NU=pX.\m+:{ :R:.um 5Td±legK[)R+G 8|M,q3yy %LmH=yΜQzKqIC{WV6/Ԭ1ҕC{{Fn6+;ՃV㙅Sw^{.4d{xAK몺T+-iκV73/j)EڦodB+ <ڗi/Є7:buZ< 낾 IP (~ \;<^UdM̥{]:խk;V={Z4n,X 03,]yoM[?扬'ߊPD1|תP])Z^ ؤOSlZv?~[[H[- F8v Msۆn\wmbq!5DI,dt2jr]YɎkUS 3dE⭡HBYخ1XjJ'L fEC9ScW20tSy3濫]1ekHJ񎝉3EJ$XaŊw"w*=F:{z_5wyjHShyDk|Q.,4Kl٠XОooxz{W_*Mv&i<~ 3HXF¤?bcF:/3fsYιn));Nb' 41:O^ߕq9?tZDKfnXiФЕ#"mmuP2UMVSbH2BϜGj[^/8ãBgޗFJ+VZ8^݆t]{nCB#ي"-|rG8zp,ބsm gV6!حuAT?JoD|*p,"h#ZB8)@D|mM`zC9A͚U1yVN]Gƶu!vb|=p0 Xir&#س5\@N "d$fWue}cC)ش^^欁6gdk'i2jU\r/tZ* cS`1m42*m/ XD[p#xaڑޱwvU(5)P}t󜮩Vn;m]<6]?A%L1x|;SF<iz4Wl@ ezFwGpBem\7厶?2_XJs8#QG~Ţ\ k~5گc: ^Ap̴dy׌oš=;}Ai$laݦ#m }[o7t)c˴Vx+ ON,! ñjL掳!=}.U4r;NbYܴ07np[N&Y|d0C5v5jYD.];4ȳ78m];Ϸ-8A_S1WE<5Ni$My)KI!ޭՃa}W)) p5IR;%"/tbUMXi)\ j9V1NnjQhä#&ZOQ*DZОOUfoN3v|w_l__@ߏ۴6yRL"ԅtIl #8Q{8]gl@+.#ő׆R_oJx9SJ=|DqYJyBB’~CvP&S]O*&x]liYjVV(h| J5MP5Vn?07%٠Vg<ϒk6;ybǷ|-<| sbHKa $_uY6j֦7]]屹x>6'W3gg4u%lx̆ʾm&RF3CtL%heks_1\]q/L?[@ +[bѠ]Ѐұe}]U]=bwi5/hBD[WGIMHe3y֛!w0=> MYb!băD%D1Dm6f:>W{?ΐ)e^N_ldZ^u⋢i3[->li= C&5e_ Euަ*, ,l YL:{k!:aWЉsND"~x l`)$:{>"J^,!BU@Œ8gTM8ipLZh=8ZM2v)8=UEGwz3cMv2#jf1$/p-'leBW Ѯ$[Yߓ1u\^o2~erXo|NixY-X:EEM LDq$ߙkly YYΚ2r6߆DTm{NO`]s҂br$\uXl1p]|!9u1Hx'֭mJV?/~(B-\8ҧc*6 2ccp:p3}Qa]".~M,~]SoW_/Y޶p5-=}Mտji]|~q{%K}:LB)Ea/3:1J aڧ_P? 5U^Qu'mv?׻boUŤWO׹DGVi/)=bË g#>n *7_*dW+&<(f HHHG[RMut8&7MR܁MCn; `Țaܶiܓuh&!?iʴ)s~RMnw63T<֞qzm?)7&nez |a$ўHRB30 L6dps|kZ38ԛj&jQj?5=u{ sߒ,{Y~¥<~7ދ nkI qT+D]kɶ( >s!Nn`X̨)أ+,vHp8-B8$sqE=T29Q`G lL=ITw1p;u.3W{_;)EVGw1_3T,$Fڀ>QV0$1p545e<%{Tg`&R3!#AKG? ށb=-p@c -:8P(3>.%yp9X堪 ?yT[[2OomXҚZYp^4D&#sx I+~oFpB\3mb`H7*:nw9._wMk™861%rXyЃК 1w¼13xiMx9 XUk-CfgWRg 3@jNo}Kb:s(S,ݩ7/Sk&vR ~l7nA}eL$%,]b@?ت_{KCKFUN!7)GF渡w%TU-ʃ4ZܲItN`fF V\ e9a&i[ 7@jQ<}w{#̪,6o!6PZ¿6Xi5LOLObT/߸/cxwK)dC!%3XZ[i6R-ktS_$gh fx_όb@3)V.B|-T.=:Z@j58fIQA ,ʩ<\/pP{ ]Rt  h3s,cƩտݙm]i\hfh=jǧ|]f}ߍ}U/D"11Frac0F 鴇dfwfiXs IeC-U/b2)K׊@'2PL_XI3(mZXm3rR >&wZD)ۿ%ȿ=h 7^sEh 5aʏ;Eoo;TG<[^x %^ǿMxaZǿJ ⅚I$5K)_( 9 6jYHKtoIӋVqʡlV>ovjɽkϿЈuE}лȭ],:[N}znYH[7d_ oǧ#}f< ϟT H1?*$#6Ck< ͻFANh lp&5mɄlb:22!ِX_2kAUU?T#d8Õ8Ũ!5;'D &UsX+[:&Ɲ9틛uk Mod#0\ Rt(dXEo{Űu  ~^YFG7tCx<;i*(wV!~@:^'ޟ.י\~w E=$>TƲ \?j 9]Cv kZU#ŗ:zn@j}V})Wb[ hWd+{wlݹ۪@ľYuB8pNHOf]iAuC)Ԥ|P<+谒l\yWPЇ~~Hc<>Ojpb6y" +ߏ~ӞwIP95L鄠-1jKޣ'w+ {H{Jff~Y 4^PSWrWiE!:;'q.lT1x!h>Y#ge}8Vgrp쭚Z>k6kli vVu6c@Fk.!IY iC?ZȜ4ҎXK5E)>az5>Y~ a,w5Vj_KA:p(I{4S?k {JiY9.L1(u3pjn&T}15%o vvf 8 닗ݕIgCMnܘ%"/D;T*o@u,rMyH0Y9㥗gjF&gfצKsbB_no_\Ǥ2@FG*c"G"#âkoW|y<5"߫]^&b\xoo?+/h6_cA-7!}Ȟiϒ=pH!9~o$gHo&`52&)&*َgwWRSzZWARJ <+nʭЎghI^Nyz?tU-l&h|6yӯs/i#C׉#-?*zqY3u}G*%եq#)xMmy&a1u IM@,U @h_`a -JFwp.=[Rjpkdn[U~GR),XjR;֒sC<-9ؑV%b5oE^g:(T.:Y^-s  9Mt(#B"J[sA Y\Wa"LW+Cž?3!Zh괪#s-LGgjC86 JƫuP0Iqq.|j֮FHP­J`4cMF&omdF3>n^Ӧ(5:)oI \,lpF|q~-Iȯ!Vi,'Yy\[2>&b"+8Y &Ndٰq}d(^*xaYB"ؓK=R'] N&ǰKz>-%): ϿMfu}x [ʪ|zZ~`BDơv%֫fIryUa`#*:Ϲzqk:tnP0@)ԎݭlWԵ:vp ᦡ8\kPj!R2jm[}?q_YCP5:諸NRCFtr1\BF&ю;-BO"j|64WnH nQ>|#ވw~G+RL0v2czcW2d, ?'(ɹ/[!˪YHҽW2]E}Q_!~x_ƈNxJ< |\%³2_ JM:$"Qh~95FCpEu>?̟_,/_цHdol̑(>+զD>0lWW{9)Hlcɽ&Fuwn`~)SK;|D3\Ե0)n(f{~kApyɞh W毤Q#rgŌ!R*H;lmD-_3 UHR~_ko[p~W嵤[wƋtTErV)/h۸f-OO6"=6.eݾ|xo*]=+cڑO :C{| 4n ;,:e^/#>C{3bͮ\R\ $K~3uEQݟisk4ׁ;ͻ֢Q5U(8+4R\ݶeɱ o={K^ 7usVXUn4]so}BpZܢ,` H}*TKb3m^Y?.<<mQO~~!Y _uvΫq[1ntM1=9f^cB 80PE.ァry[,'PbK<Ȯm{P7*H8yԊ` `n  )B }[o!&b=aGim$|[浫h1wT"vg«}G9\m,.]Y0}]T?sKK*D&gz8VMo㌆VHΦ]0C<顆6U; @^Ќ{`"$ǎwƆJx9r/gV]ݼ`ύ0mQaM`Vp!JwhPp2"Jfֳީv<@P*@鄨~]4 &JL vM~iNϼ!%:H[COdkE=mG,oY?wukFS[~y1UhϢݖ,{4;CZ! mU>çF͇vm^vsWo77`kS([6Vsޡte r}W^Y]D߿z:/G@ Iȓ,I]/MUg%i{h/[)[2҆2Z4phOĥ 1jUZ)`=ϊq l45Fbze& @+{:[m qiqQ욉F<#FA[4*%`gB_!Glv:bkjmcI*OY z%[:RX>7LjMthH6ysBH߇Ȋ 2 =gmMzs5 s=qHlL[sG_&kF5hǹ k&{^Mcrivj:.% TOס[Q2n#2$XLTL5Č{+t {G2M FIr*U~0TP}Nb&:Mv84udR8z{n?wwJgyM_#O }! 2Rč)Gr:F!>ղJ3s+aF)ȥ{PzC0{s5? M3?a/::$1!kO +Ln4iٌotɮ9^'~qIq+ը}Zkvx>YuP^w~4 .shok8TאpetJWEZ^Ӌa}V8u ].}RR6%|֗ y|q?4sp̋ʹ@B|oV>w'gE'UjXJHS4Ry~ޗ LVj[vSkE 9To$=tiB^/'tz=p&xfi{JVc8gCbgqHX!]=WKu?f*3G%zÒp ѭ`R~lkgKW=߱>ͯ}SP8 ^_½#8i Q!c:QʱNk8K%2>CƄ>@:u}nF" s$LAZc_yӒ`PErx&*tGxD8RK*>`aVRkE]Eр$+Urs-Jfm8H:WLڵx03^ 7xz,1&jVeXK0fz|0р2ѶɦZ qu4z֨;;U^s*y]s;S I +EkD2Fտ莲&k sR N~fHcLlNl^%_?5*=uUzg]oT3aQg;(l*h=ca}AzJӐRa322N]a atK\Y`ԛ4[m5ÍA`pWoUn/QK^[*ӱ@u=f<^p zuUSb,>FXiUҢ1 @ *#o۴gc]/ Q[Zݝ#[<{-Kf[7-lXݺaKq E5Zspo^c4֨(Ro*F7s;ݍu| zlpoSw;e"i; ji,dKrɾBƂs}]+G|k=@qhx-̾>(h}RO; G0怇I}1$,uꧭ=2`!kz͉x]JeY6 cYld _c1ύ/*A?}g_;&Ŏ8vCcTVH(78pR4m2-p*u}cmAk~װr<5Q7X9w[`HeyFez}~711&[I]+X9u(PPRVѯ'4buox{2U͈ 9bFg5U_eu4UApes~3j4;BGpN aՉ;bVӏYÀP Yp FG7;C6q1{ 􊟥3T`H*%}\%IiHZ/W U*C\شr5ΩL;Z?Gw] Q2dUV޾k<{~RΤVa[Wވ4w%^҇ #P&$\^tDUwB+#Fv}6EsSr&oj-ۆ@/N?* Î!\j$ՎJ,]MBG Jv *(備2XL&1Ss ^L]<j훺zfqkw"J, 7n/cv:Ƽdׅ)##jdZ^o9J}> *\]_neak%:lZiFioxļF~G!S¤2_c$~@afS_\ UL"Kjc W#&/52.|Tps >6^5;[5`n:qObp1p*=:S,!n1-+US3^pĶLՎpR⑅xJe@hMߪo_Emb=yo-(k%_H0[kt5m ,w:¸ZڟzZE|zH*C"3$օdC1u#4Ȉ}/2wI`tAT uڃ&U[~zەP஄^Uz*-ĊdEɣ, b?ux|6Tzj E鮱L^Wy]4U=Bɏ=/p juҋkĜzZ|qFc1 6.Q\3L/<{)]0$2=4~jKU'BX) ^;t e5RS[$;*&O?<D[3 Cx1BQ,>)mRL Q%xA?SG^G1xZ琴'g+x@Zgkmo/]~el ^baq\]ѫjWMZ=7ig7uh2?//1Mxbv$oPOKfͿTk P-JNC j/)3݄h4u5B;WTvVIz4ej)JљdRlIYfcNabg=UhvqFCaMR<̙f/XYh4Ҍ7yk͊ܥs,hDzAit׉'oWj<)=ʏ?بC??'6əg|ВSq{Kp]p6w)Ht4ͳ1|qĨ:a9'?x8:^8_ES GUyBs4Dz>ArD9,S@k-^U^6Zoצ}h  )^@\)?:NW=|>6n^$|_]bv54%j*${j<^6i5,сҰ$ ,y<~,Gͻ5t'7D[bqjtn@8Ԭ",L+?~i]J-a1{m*J!^w5*CY .(Ȱ*c:!ж^鶴S.3Ύsܾ5J(Xd ŢX9"^=S%Zkzw6wvXX_7~=S"~ ZVtIjO)CRܢĖ|X0Wǃ (Nzg'vwfvfseH΂%YD$I=1  *( =}}ݹڪS|m[]ϝ~3/OރY9h.;B5y \iqǷ4UdqqS cU!2O/)g9U62D|fzu@ C%o{j/ s0əJ3|"B>BAULuUfW}Fg/؀?hkmZdK'\D uLp.pI,{A'SLLJ7‚e grL$<~%%a`Q nnPkem̧hJq䞄Xtrk0U>vց`6²Vd6dGlib5c0b 4䜕/{q!IDCxδSTDZesP[=WB?x`JOdqQ)YXJ:ݎ0tε₩,,lGOxd# Gk?|,&q|6'qq$Zӛ-wf,/}r'}Q$r6Ag~OѾD_բIo/Fږz#ۏO%q̇Z`xHj=O}k򕤼Y妷I{i}sELAtA \T`揀m՘TL.(O+.Ƹ}N'B> -(I\Ob0sYvk괰\WLdbjK)Al8,/#@ }Z^(|%)6W[a<X2nj.%l|"/,_ 2K-0dI",4~)l-!8lTv;9wQ]cHQԊ‘L,5t]cxpNWKg F!՝4 C|v4?_Eߺ yץLC17@q6$/fs&ؽ];hOr~^?$166om%zK?>;aG4p΍x[\6L,ȩkj{̊8;\mhƔQ49/pr DψѰنvH0>BokXh*Q>=ﰾ Rp2KWo-s&<밁mвh[NQ`1+#;G,j>d,?$$ZǼ{1u)/>';UPz; -A4H 5C-3NgF7;҇y}*V?IPhɋף}z!rt_аO,<(\B ض ?o KxپMDQ_um_7^#}lk8Ⱦڛ>= w;;:Vxmp|&7)s]\uu<=)0,ӂwX|ɥ#JfiǦEVk]h}D|BLxS"i8a FsT[pSw3YLE-NJP=ό~_om0z{˾O!Zr{ X/zO >\>r3CsD( 4'UiP.슺xwp;f'63Ͱ6P'D A]b?.'vh ڻ !ISGAJk|l v}L m|r13M2#RWrΝTlNh\ƝbӟB`TNuXtz?r)5㼄Ԯe(ɇkFVtL5Apz?P)d*..v$@OF\o|hcEZY+LzłXl{>1|k~ZFˋֽ-Y>>mNߍ]SmL-MIn z2O.xX^HljRHi'^qi<5a/ 84^*CU:A\Ru_|? ]J_>ڊݸ`BvȲ \a%q  2L7ySzwwxW;12^ $Ka7\2@wHk$%GH# |04ʱQɝQ,UuwccV1Ȏ}7=''>xkd*.mg o\qS*,/{t-٠I)Ad0<ayAdbE.&KJ0ZOW4::,WO$Ey)o&mW'D͑:a=&7OxhĿ2A\_o)- BiUDTzr jz@zH۠miwB-,Jx^M0 Sq=nKH-0m4'+ֻArj6obhe 3s$8mLÃQWTfzzEi86Pd:Gܽx`>xumwX:)b@=ZT>\]\l\i 4ބxkgml.p1[ 6R__Mdங;67ѡvE7l+ؗ27abM% uh/*ZgNdN(I+~6 3tQ/xLJH']YH8NK;ew;1L{IVOrG^ogTWdtZ<ɾEnʹr멈M1%c7w#ɟ QcBMّ^YWtVdz;m21tYѼ"9t{2U;D2j #$g[)(m@~LQ%8h!Ekp{GQ4cU / qj ?qH'E礚GRK< NKjk*G)θ[t<٥M^E%xnH#_tEPGD2,L֗Pl?OesavĂ> b'!c4F'H`{Ɇ Ny-8FG-@= $?}4Sq5'ׄy9eVLBZώ} h7,e\%́Izj UP긋;Bœ.'2[hϵLˠB+9h"H`J[^?HbK paXW>E66C]S7>^b=6$ "F;q3:\2hFR+R<s&%VWSfSݼVOҞ;Lӛkif67dK{ "Y,__ ;=VtpH &vfO3 / O,{p/x*9#WtΕ Y%ӰP=&چR ƯvZtGrp-Aҵʯps? Z}YkNN,J|74X}b:r"gAׄI -7oe-+6wޓd{yrw 8jHYI)tDc%=5d6]rSAPn=案43 VlV܄0=3b3߷CpS0CfxɊ-h-u61^܃z~@#׍ݔWrOg^&,5)4LYl;c >l& OcKpYLئ*s~< ľ38W v@c2b5FO*yQ1Twg:=yV`8$8r(ؗ =hp'1#U/uVBp~{=KmDDK޵C4@C1r!zR> K1%.fhQk酻= ߇_B}yME)՛8N2^Y|E{v{i`rVa+3mBM9:Y,cWbΚ45Ő4ސ2A~0it'Fo9~Uv/{\@X/߳ZxC}f3x?Y UEs:fÆ?#Hpc9xۄx.kxg<·nvɅྌo u|zGYEK}V}uĉ6ߢa'巫=çޖ Yd d}mK8\EЭkƓ3 m]2k ;>2ֱ;iYN 3hh~ֱ`y48M&#Ø@C`'Nj䇢ZXzVVns;#pVD&ݽg9kknvP追 ]R[~ь$F?ӇOnÁK%d?6'Gl|$].-f>DpX yaaԇCŀu:/PH036>зo0vzpFHE`*~Pt%KQS$_$^pKLld%BxA!_29G䦲 C -I{+oOe/q G:)MqxnsnX3=#74,aj Cj c,f]K8q'%@iY;>K#ٱ۞ a~ruM XWy37trzn&s!Brاs5+L?A 44S a~U4o޲}􄅩uS+90|{c} K{j򶡶WwtئXxOw{^,[9ic6'c ? FwW'ڨonz4F$[ODd"҂+v(t0EEw$,u++w}`grғOZ- L#f_ws1Q>5[6sW]ZKd*]&("pcۗE_?|^{{{p{Dp t|Z%,-J-3]Jɜ7o{cBJӹgٺo^7aKX (҆eS4WF',G DJTC>e<1up'<#q.bBԯVzH>9aN', 9΍! K3~LVS$ tЏ_"2qlrCUtr袐+lR? /yJ '@Eꧏ&CڌVI֥[XΨ+$D{'˹pV? )|ޮ>"z #.nwr5Dž{N:W=CGL-^)fP2/3r-^^v\tV ~A]D+mb$#6i Bh+[.Lᴷ5F@=~ A4 ϯL壦Ԋ+L}BfڧtiMV"mwe}gMrOv%0QR G>#QLձܒuYH2p? ̷"}<޶digk>xjgUs31ūn_>4{#=QQ]-_GJt=m7~w>. n9| X`\z,v!R67USNIlꗭoMO7sg^NGw]& (kktSG,C!0tXȆ:l;uD=smyl#Q]u7O-v_--4b6+>Nw1S3,o;vPw_ ND.wi_{9|3]:Lё3B_)UhĞ+Kj(bM^pl,* Gs|jǪZ-[^m6B황ҮvHT%ُGNzD, w2l]GY\x[%ܞkA摰x˝JX|Opk`^MrH[ 8JSnyn7 =qr˚^Bb@i);=K;w&=[S ?ڵ BFɣrSL6鹾1Qi{ ~" 0 {nlc qbB"aFVQ+3㖤b>2SO~z }Y`]L}p% KƢr mË\6gC.۷t{*dLyMB~p9ҥIJ4+JKvaHZeITRYIzWp@UY%5^`ju3K)>RM! {b5H0֣I_2^A2È/B1 2鈮2*{BCa (F*J}+əZ]_Dʴ )ݗ-D7  G O@mta[ \1lKk p7!1-1!v@Neja8~&\0~iqXО茕^ nf^(G6m2eD>DSMI-j<$;2;8=˄֍)iQmq=pCrvcQQ>(M:iStm,6pVwOs[,a`c~dǻ\ >/_$b2Uz6尊8gJ4?Ka\KK793?eN3^2:,1T!ZPR8)~Be9aS@=Ux/s!0[Fkkd CXoE}/hT>t?aH"/P5u^QI_fyq4W 6D'}9zb: ٹř$_ΛV+O/34Fl%h0<& TCnF=EY"}*sw)elgڷUY:Elԑd%b, E{= Ԑ Qbt1<3 n=|t68xzP0Y#"FލMarI=6OFI6 Hm}20_ Kno~k fH.4[8o13fIf#u}쇯C?o$ E SS7[a=YY~ۮU1O3݇qo_8G,V36!e$ן+\7n? w}~A! .,Yjl5`Xֶj8f σa5 !ɬ?=*=]zوU'{^} %i}"4 'eDOLA(1ߘȔz9: !x{ed\=[<YOvó6fi 2.N8JҴ@Dh:xb2\=*vme1ooivVVg~OIyc5~f,_k_b-8#5M4èsZ}MUw9 BiϾ`v}`=}혮L'Mv[ "' zd)Q}'~m_х/fďւ(C1|-ZlmjN Nc$#@vvzngI]+A MO_ NOͳYmN2y5`xQ:YwϠu+<@$XƯ*3BGr ? A GVo0cUãpx=M~#ȟ`!xGAc3(@F@^K}R.cz%K4Cgqk55gq{=ASD@(<"lN^:VFF.cf?o:'O((V7k9(+azX^zQXVbg}RC%@`>]ي=%g'&֬."ަ07?*#G\鿒lnݼ4aD0lj#t8u5E3iC]%ZHjpf Uɗ,l;9[%+a 8dAx=j.Cϰf&Ũ3mcddT  ~3u]Ϋ_!v )`NQyb4ɮm<[< %/67(#Y u4 \DaM\ 1p&d HC4p ח T" P"]']Aggn'͸/™Ey'-HMRa\+̱ͤ#\dear=̓<}fJTr8Lo`Sh;ؐ{j Eh ka%,.gn~5NAhcVd,8/6s/vBK}9{?ۋg xd?}݉".E.d8à3Eڱ M[C{KN)U'8Z,P-@BScL"QgN%Xλ V*D߽ԉakiT­H]]ENSިE'㺏vj%t5SQ/zN!(rq;v]VjCoIiEgE֎"aU/e~d/gmP1χEtŨep/׉k!\ =ڸP}|6G1k"g2E6D&t˿]/tϟU>M^Ce֪3%S{ݠmG<މ~|k$_lAA"~ t?'X݋hI_`-X(r;Lso0_s/Teju|}oTjm<|/0B鋦:d|{\אykhuUHURH|Wt]'uRn$:Fpl hBjC~A>_7L;w:?f/2bE!CsI!lH/L[Qgԟe{<M+XBAe'(WQg28LftYms^IJ*<ڽN}h/%(oQͨ,01G#'dEɁILu$żYlpC;Q;CۑHKMCi޿#xܖT:Vvb~&eP;vE`|Ɔc/7+0Lݑz2"t^{!fdc(z"~Zχ\>23j.3 v(ߴǴYt1?qZvm=W݋_RVL|fcZ:>`@nfC3}g@o#^ުޣٴ5"K׵1L]sߤkcyWCw_!:ǰ%}h,4+%|^9FV[A]ض.X RFY=+EѠ=V$nz Q.-b4Dl`{ڠG%#}Q(S&%2J-ݏy7fPٽ,`;1.K)ڏQ]ˤ hn{IP[EZF}ܚ~,:BKy bʉXXD[ /iӮC"ws'L'G>ܤ-=}[߂,8e|/nRSy<>*sTqd"\&iezt&^d/o6=a4mmk~n?h3t\BwcpE]*W/4eX+Q? T畏d4rt^a;F5 LNqGh;Qi~-uwq* ~{YzǨ m׶QT?ׁOբڳ8Vﺶd! ɬ9v+ShN~t" {;b7=@4߂zݻ௦/ÿ`Xư|:HO2ww+`֞#舑0~w *"Ӎeto~[^" 7?7xqTg?|NîdtY?tuLMgVOA2ϭ"G՗i1+]\mH㜖7Si;fk+x8(JAg4´nd$i!;E0Y;mx!62-V9=svu,Y$/AYyT3CJvX)X<ͼ% T$BtJ7)q#<s "Kz?/FH&OvIx\}6];9?"E,74(-7 ͏lI՟ʔl<6TDL\"i#WquucXLh&QrV^7@|?Bx ~ |& pIC<> cj!8Qڹ0~'Ļn#8yP%\97'Ĭ99~uAS2fq]\aِ[DѺek$ۀЍ1X\`C7FgdQSg9y/%v#p\6A+څbq~>20`wKtGL9b^]I>{1F"8y76i͔6&Ю@.)X"N `sXv!h1ogbHἜ*gRlۙu(^4<(RgʢpK.z-xH@FqHz e6}C,}aq}M~G4ZcQeN ;DЗlY) d#S@Эn> hh,̋Z3C<s`QGV'^(>| Cqtq`ic4Ljc#H "p'hX%/|-ى-^CA&+P(M!|^ "?" `PvlfY`QV<(pLqC8tg9ij2SV޾>3ZH!rvCR+{>tC:4OmO*$V`ucq~/*y/hԟ*?#9:A-1}Z/_x*01A^> *?_oDkMG{Q\S3{z{r9lyW I (D0mm|$cc8c8l8Ή쯪'V CZMh{^|g;otdosJv>bsfȳcJЊ{ݴw7{b[>3mpG-cYQqް]ќI+xŠKHؘvA?!Qj&}:*ƌoI<j{*%fx3 M< Ե>a, a;,K'B";,"EKx-z`M'o> :]j>ubkXWK%8O~;L/{ $"uoi%@u|3xQOp&.hA\#qVc9gz8h{c0nM-}n `?cо+be7AUD.J5P[gN ?&l&X 6Vq =f*I!rEvW:Y3޺[-J5W hPɑƑd#׌o0]o=t,OD뿅н/ShSq缓إƽMgn=!p|nJ7Aֻ}KTn`HF~k1=qD;f-74lY)dt#bnU|hͨfQM8- G2d)kEtM6lʖ}RӽnQآdӛH_d4b82yI*R,~ϟ4_;-r+[C٤^٨{Vw}|f)KrwOlHĝ:8uh|_3\ZohՕ%٠bznVǑdvS|V/u|{-$UQ|{25.Gsk1O/.,-?O{1.oytc(&m<qTLY*]Fș/>)9k"G[z}˥g][9oL2zGM@r*r8G(@zpؿ'UnĮπXq˱Ξ +3ݥ^h91|X-*u< 5vOK!P2̹j0n)Le=c;CtO.f4u2]|[g|dfBb!xI"L6:#2gR=7up/}(m>v3BI ÜesC#*y8JQ3O- L%=b^9Hu蘑's!RiOR @ TRY7U:bZ!P[SIr^W;}N_tz4Xc>(%xV(Q&BP %2G;Iq~wr%U͠{t&QgfYў1ҜݡѭԨ)bڂ/lEY¯Y] ^ gzFhHEl*:Qêl#? $RA SDU[yV ֖B[;tsY5b 4 dW~9mMsh]j!xy[$au &WQ,!J|˷ Y(B״t`io[y9my{xkؾ+t-is9=ЉNi"xWSX,;bi-~Z`e}%`Nujz&|YpL1@# 92 ~QEfVڤYeT"6mYMLb]ܱ35j|;j;]~*hƸ>. NH:ꥂ[A(~fYu(h5:&=T`P;N'w CXF>M0Μ\{sXXH귬8瑍>"jn]w\k7iF%}"8r#V TfyWXf)tQΔ5C잜>82{ݑNθ}XpxI䁚B{2inDO47#sA+aE7#y`y]mPԜ.P[4FUCL`՚Bdž~XhQOk՘KeW swÿ Z^MI-f5˩#$L17U,rEnjf'Xa|p\px3 {wruRFl 3?ǦFZK[)W(г/ѹypcg Ǔ_ 94: 4(9N!|>^}'~fg3?ͻcċo+d:_CTm%W{pvH]w=F@pz0:Ψ'fh-ݓ;F*e܁x`]f]hy{97y~X;=g>E$j؆:P094T.'׬;ug"]`$=:CF{ֹ9/m ;=:y6Y۝BcZgz=ˋ#g;T-l9*ͪ u X @8Q( $^1~n*O۪UQFQt@1=qL=z}Tzdh0ę ų.y^xp;l}9җid:#jx{i5+V*d7yYk\r c݀iR &>}[@iTwhs [ƪvZŹ7ǖl0S2j‹oh\ 1%\R4!9Gi/+~F9*VJ\sZ]dlqs9XSC=6_v^}Uf=ڲOP U ÿܻg5PUdǪ(Aܩ1fKkI}]80xeud8auN=p)`!!vdF(53Wh 巸r&اX=o?Oxx߭22=>Jt׌,v5rxUVw)#`Vi/kov(6&^.#A[3&&h5Tʌy>Ep Z0vWc@`֗4Wt<.3V~>am+6l$= +98rm"y(;)K9uXӥ` eJ9bo&]}U`ϡU„^jrzQ9mKHS\ٕgLB:ÜjET VZ) yp ֜qWeWP+=77 ]U|o>;ߵiu2˶F\K@4싒RI߁夛ˍ?6khc,rʐޞ|#0ES*5uWBSPܙ}t+6BrnMJ6,g]VzTaJ@'-Rχϳudͬ|#_B\-ck7ѪEEzB|dd_`^(k"i%Cgwإ hh5L8N'^h)IpL&]V@j8|@6idWE/ Ф$}~RHL0+\FP;.b2h W)Rň,kӘ 7T*PaJ[5BEzeYsIUGje8hFqV4H,7"ދ>d8NT ݣE{DA ƦabGAǭ-_8J˟퀟ݿRܩ= h[e>U y,NKHyЯf]F8U Rz9M(ސ^8BNUάvO# cÏ∧?X.cIqQ) +'=+%0+<9M@CJ5Z>Xyn3P[mW ͉(ESU4Eb)o,"| UGme{{Q YON/Em,>Q1f UlN [9H3nG+as9,ݡ w[HM`>d_=2RP6JʬM/]Htٲ@[ìh:a[,m Ḹf/={|1Ӻ>x|1,fNXA0Sr[H.EJ y*?_ԭ{"c|:gP{Tϻ7N-w'<?^EaDazE 䫄mQ0Wv{! s?޺sН$Oy/9_"QsGZBj,W,/x6ywȟ2@\O'B+9",xoNaow3?Xz,|sޏ9 L-!& #{͗~- N~_#=]̝w]#HvZbX0R@a) ZV䋠Hr+H.tZ-U{|@y|(L҃}ԗvQ ` ݹ86Ƿ ]VkKzZIZsmQQ: ]':c^g:=z qRNǙ S+d 0'SCtm|Doeub -Vg.UXFGEŧ/7l<ߧhWm': .dEáGeV!2 IE۵~Gy깼K@KL!Z&w, R)FeQ~OrNA^ĺm7Vw"l'3qMSy(~˩/}iw؇RluY%;qFoœrG2=s=i.<ԳHg> гԆ[ߗ*[s[N&Jy+X\ 5־/~.˿P:iӌ\"YpjLr/՛HSo)#e7 ݝb q9Gw=0`:b~Bڜk=ɧ`V" 5ї(>F;aNĠһ)>F>A #KKg6Eei~y*KiL9hC_Q[II=Y`FZ3v掊ϴ-o "&^x2jYQ7Z3NgˎC*.% &./ipE]YgU;@1N3ݷ.Xk 582`ՠ@=d$S͓u5 .B}Y 3H1#kA'Og;\R;R宀NdC$4tCjC؅فm.R$^R#>AdxyCDT]نEA<97vxt}%SZЩ4kl]whm8>6-ta:[rq`J'mCWxbX]"kC*'4{ܨV"EmwlHu" 27SXCj$=⩑SX~3I}bBF2$Qfmj9IIZ?KEb:W&Gz na7MË{o2[lD)I%1Xx\T&)m+$㹘bPKgN?Oyܧe68;y#W\,$XB{ WO$le~5"OCAa&71E9^}A*@sau*֎7-obVze-Eo }$z,`@ߵY,;wKy,.y !`;k-}[Úxo;;C]WesMs{e`zrsj+ί.!EٽWܰdz ;FfX#|]D IfW)0xx*5?ph:5WZ.ۣpױ>{%[E;n` owxl-%K>s/^wY³D 6Gɽ NR qC2U [^ }.'}nhn fSKuKwX7^Ӫ_ l:PK <"۹&)8e5 N}`뚉Y<"~T;jƠ;@*ؙG[ <7Pb̥NN8sK譕Xͤט@w#y* 5ݜ4QM8Pqh]ǩs>LOq3Uh.0Υl>5[Ԫl2O=U-d`T]m/ V,<g:2%/U1d 0VQkxiRpJYCUwVB&&ϒb3unU6K~?6*#ʆ_5BmAWiܑ/r@{@l28Pn3-ߦ>ufs&R?C VxGc}`\+iUD1~\K=O= dԀ`Ȇt5E3h7CTiwoj';;^qa&;#:ʲXO~pPs{-N dRT#u),ģ&_IFS *!Ef#+ ԳO;R]I/I ;",1m?!Ax eKyS_֕'ر?B}Q;ʳ0jgzd(9wD)/r2pѩ*P:8vՓn$yf/xy}i^o/}mBe./\-cޓGWK8G^i|Ap°6|_/ID]pu/e|1cAfpoõ>jhYOfL0w>]O׮L=Y{vH粁XaP}wUmg܌b~>0++bZuʃ*͚UlTHF4DhWv5wС?j-(F; +TN[.lxS㽡Z[HĹpaU+J{`SxĦuHE/ww4uIwh07<56G@+Am39q[gGKX( vfsgk^.ATH(*vccOwךcQ}",Q 0^U/޺ayi260| O8\ eT_e]_&x^>;nh hSQxai;}+B^ac=TWf#M-'n!@`ܠWs="h"T=Y^M:3 -= TQ?o*Zw=֕-{숺9mWpA8*8[44lѵ,/3KLQɜjI!t6ԩ(FNTSFJ5*.2!급 FMněhXao@׿{,&-[s:u&_sV?*ALy^t*%Ta,&.6`ʆFcޑüus8#V`殶}*QbfPaGN6)8q;~3S_S3NnL3bNkeΧ6~q }6h}_T怾^1i`ky`;6y?\i- >}yyUNJ(eц~pdh r>#tĬ}Ga[usa{r4lBN5jHLg em&%]>#хA|Z[Aִa$v#/Oo ^p'bQ0+a z1/k+.ߒ\iuJ g#ꋌ%G*=$c]^Rf ~J9ӵKyxOVAžI }|]~(rN8Jwsk{]-B?<_i_!n@w='֚#ղl$gj۷,AȈP|RC1\V]2'π@-F*?f -F,;peli !WA ~Q wX++_tGOC+A|S4hEe3،QWO9b^ cǓ!CEr W/.eW!Ma?&*SI )?UE@gj 輈O:ܧOA]&ޠv"Ği^'qv 3>JKxrGX#E].`:O__!}e9\8㏓Ë]LsiN|gɅMnjT/ֽ&WKk=>״ ҥ^`;6:03{].s1 CX bk훹X72T9"}^v331e-|e䊛?M#. SBr8RHS%?bL66ؽgrʱu2^^Կ8 {\mD0Oc-+!@3Hya}<My篆`Oe,oruLe*5%SxVK oPߐvI:n Z3`A?LJWJ*E*$ E=C'I/eEVL_A66yZ o@ՄkC ܌QUE@Ǻ P>S?}WmyVig.s :L3ª/Yq͙+|嵿0XK67z)QEɬ^TXZKcn9֘JcB,==1YZNeu}rYâusaܿMRViY(ԣGB"^7IɶAt>B r/I}<8Q{_ z_wIhh@A!t,6 0lsf_EK@gE>u$ *]gc3)* E)bK}$K n^@GBM}eqI.ldM/ 4@#mT^ @E2t}jEioUlDi!S^Osz.H#SyS˃jA+Z6֫[Y.>l -%a:t/U?k?]8[&8xȺ :,C5Y&to o൱;nof?h<ܴw⣗i? @1g|ں]H"C.O wRQ&MfIҺA95}j%vG$1{, έ}c{R{=_|Qx*QryeS ,1=磜emW_*Yٜ~;Kk[{?#E>*:ꎏl.LuNC5i14-gCtYn84Qo%MWxMU˲}!do@j$65 t?!))#u,h27=_;?kyn?gh1̾yE'[uT"\(nW7:*eE,A(@M3"2Drj6l[H & ryןv ܚ{tTU'Lɲl=N5t.6!w+|~H*Ҋc8s.[\>X㬜:xzBKrh@}D wދ!ʽr26[y3cU)Qr1J%G:Y2:Kb阶OsuNq5z.pj:94j2@d6KO0iaMm~1f2ۨQ=qja9lU%Qc|́'x).!4nk׭FV/8_2ye hCxr+~OPdLfB`C}Mq/{iA 9Sٰf5)[{юY-u4 dU5MR-`s;ߚr1ҙNnc`/Fj#oF50xY{R ϱw*&?X,֊ ;X% © {^GqO;t71!P4>,+)@I hu+8 }'ݩC9+gCnD/#M\.Tw.Xc[-/>{79˼-/N(ھvO}?sp/l`IzQ6^){U;DEJ39[ cV=zr}-1ΐ&h22OĐ[u!Sb%gU P$뾹tOBfc1=+.Xu.}&\9d*#-^hy٢7aR}g%TwG;BZ=2Yv /v{8٤2kEFOqIoԋHxN4ǶORoi.BSJ.~UvJy_Ϩ}I^//E?{eJ#>v4FXJ_XVRr@!Q%efhngr^-"s HL_y~>d!ycp~qT#`RDFz8T5Ӂϔ ]b^ @JfȨ F5pyhPMI۩ 1/}m9 47X]fOp941c  L_v\ 88F>$'oEOOR-mF#Y0.uw{.Tca-98u.Z/PeL EG%!z8- {u`&DŸ%c M{1u|o%a:nD]#Kw[j1b5Bq{@@ "7P zo&eI#زO ڛ܆V[U'^fM&Oفg*[1Rde;4fC<9Fxdy1|[:}|GaQpmй =~ߣ0I4]D8]g6X~?\v[d-MK]&62IE\NEE'\3cM' ̲0+/.=YbZqVruweHYb|:ݖVQZK3XQ]rEKNUnJpmٙ:62DpEfhpQh-aYLviSl^~6Lt^Җk79& wJ`6w|RlYY8YU]*8#+2Uy^ׂQMc'SN*jV,nF}NU/d4i.nU_8[Cׄ@*csv4 tK\5N7R\O]+=& tAB: "K}cV^w)Lj_Σkm#p!hi9xV"C} ϥjhͬ}?8%gl3gOv7\j/,?P}9y:ߏ迦wOy+CI1U7kmR|y ZѱL=TemQײٿC, _'pP Ծ%Ք5^Ivnpvꎣ6'o]kzp:{ex L_7M{dC*i]qЏ.;q_vVʭ-~j3}uRyvsmz]ނuv\"_9{ĻB.93nB/$r/g/vYϭ{3ze6o X||f>wMZ2>I ojdA\wv;J叮 AJ* .֓|Zd)iI(g{"Y[m^JX{n,ɎXZKK*iXqi|H9 Rmuϔ{ nrl}PC9V{nsIƤt|"3/"IչlUB)6, FCsk?' 0cJ;1p=DUf}ːV4ʢlhM 2GlVIJ#ly!xCV +DO}r`Wȶ{* c9cjKP2-(H`V+Lݼzm63N chxjuBgA/ 9+|Zhҥ81}@N2x>wMO_Y>+:[?k޶#MYݯ-o)uUGcV 1%ҤỢsTycyT)0:Su8hxtN_{sC;; ãnupFV1nkw%LR!² 8&ҸOi8VwpL.*ـxK }YY%:W$Z(8O 3מY}Ը\wC#TL<__9 sd*9;*N6uT99o픰[~]mn,uqKۄo7%*/,[X]AFt.5Um$̯T1F)&"dz$Vg_|tqO7-Ǡ੥cJ=V&>'A4n)nD4J%ԘncsXcw:Wt2wKcنcs^5:&.;Q%pn\EzOZ-[nݷZ4f4}gw|Ʊq8wH!$Ba K;,adK{-ƞˏ3zU^Kn_|ء#áx1tK{~RKQt&58rɕO#z]aҀqmj l߬HCIgKH~eޙ̽T"=|d@%ـ/o"2vILW8W6 ";EfKYLެK4 .Z_3/ͻ{Պ-mf%׷;}6M^ެ2纮AM[lg<oeϮk"kZ62<_^Ýgq&>^W8o)6L e1vV(^ɖMGn,.6=Z_8%t; x|Ga"prNJk{8~8xRIX{隄fN+JKT%,2>zamn zxsVł/WIG|6 twg!ד]fp-9>swk"z.Ef0 s<۠uj^W"dbUDP ^P۷ef$VC 3.L$ {!#a `/V pI=|m[cK^cKmlZ8|e9:X}*]^͗ċs{]ή1‚X| mV0F ^@7 ٩AC 8/g "Y]|U4O= m]\zwK^ mM=%c$O6#cBc*Ut/ waFv@~iҕ(lH׆kTV&+~RcU#b5PW1&[}yﰘy>KΒi߿oyz1YI kkc>ڇx-f7Lğ6X~tcҾL]kj/g=< ߫bYv?@9.,dʦRNȝ{O|ح>wFZwi1WLφBߴ{S ||#$aZU?IJ>fqcawѥH)6Y<.Vӣk ƮdvȶjW30#zYľa :_hcRh[_HCZguZ M\WMgk[ t+^׿_ ghv \iE`4=lֹS+N,ja{fhM>dS3ܡ׿}Q~ן,W8vJ3RkDS@ X#spvXS$v"Q^"Ӫ5,JuVȹZ9qO=iVn>52nE}/vyO=vjYV^r.67\a_mx+cDž:kwio>.Y^R6>Vʙ垣G :R J&KI:j\I&Y6i./di+[ 9T$*B)68|v0TDB4#'6v>y0*1|MO<@,lFۂwtL޼rHړvנGݢU Akn4t[^X"5z]?N8 `wQޣo}6' ;|w960lo7Ո6Dw#/F!vdRx s^7eВ*]bTQ<.5}O}U V'gpRCm9V U,斚6\K\n%|?nkʹ͌@OMoij|gYGV|5uWp‘3gtq⎉"8km-S^j&% KO5'#:;u5"A, )e^ps {5Ul3a]mY!ph/K[}Ӵn!_qNC?HQ;d_ڀZpaZ '\؂daKWGudi*&,ĄpDnUA7#O\)upzkiLÜbq/HǫUwu>|C=׳[·2 He~ONƳh߷}헃喘p~ JϮ*Ⱦ;m>ĵaP~ԩʍt|5Nc&ވ1UE&0kZvS?a jrk7MYBf6G.{䖁JFn-n6_t[nd]i*8&},"UF;J,69Rx{v 3168]zF[:O͟v'6 FZߴm:ÛJW8߰^{댗KxO.mfwH~}{^}  1`[!tH誉Ll,yjsxºAsqMa5[.ʧ{NnZr̛;'`}QdW[4mAf/yƗ2 *fA) bAYS3RZ:er4>߄^Y8's̍{Lg W|&Z;ܘ7{3'"LCmT 5Ŭ{"woROϦ7^oewupw%\4Oݷ=tl5Ɠ_ijГAZ>ħ^SO^Ή{1yqOEUh}Tɴ z!/R?-8Iq :ܪ_) YCݾʬgt\AbcUƕ_A{Tx0(CaF6ɸNWwخ^o;BÇ*Y?r7`OGɳ[8ݣz-sZDmzń`!+EzHrXvLRa/ ђz1?({q Va n!\ABYZvVW\u1ZfYn _aݕE]?_qE ɤE0n|UjJLkBUq9">v -vi]"Cr2usD}Jhj}/a%X&g;]fd褉ۇx,uZA5I={Ic/X tt>0ؑ|h0f]gzU%i@; >7U-d<#nxgk&W%غ]W C#./C߾󊻇u۵w5.?4Q}dG|kkpGùF+.ٜvZ]O}|)#JT"ݭCyIoBbJiK޽{pèbN&HUMcP-W.>!D2G㻁ޑ$Nhc6uj Z%iHƂ4ݭD@2V#i&BK:.ڟKU\H7Nm^_]_N,ܼ8I_Xǯ7jxzF} 0;Y?xJ >,Z?ϽoK%/? Q÷f/to9ÝEӁ eZxf>2H%@Zٸ3=Mc$x؛4G^:"Co6f3'aydX \Fܼ3 /)ɧIm:;/L,j{ޥ l➓3;}kCK[&Bn \ lTE>oV : j$ |TMHY 4=Ws0̩W¹C/iz sQ#?e }lw7ǚ06f:|M=_5 XB%?n͓#t];|ۑ#Gj۵D-cb~x;oAd Orz2w]e}-V2LܿiwQP[E4e'';bդvBV^Qzt_2+׏ɢXVy*hiHҙJ\TݛQųPyM v汵O+˒{\O/7N[9<@ŝ[n_#\jMPn] $tBӭϙ!*R! 2VDܦy_ǰ`̠U+Cˋ#6l@W^i-$EgIPعTĶ%rr)Y+$FpNohԏz6tW?c=YZo-'Z&L.9{&8R;6'ӑCQ E/Qŝ򠏂7dZ`hچC<_$Wzfp'TY8|Ḃ/fLçLp! ;&~淯Diry~NJ]Ce7 XNUS8mN"BbXbpPP-vwoF`S[߬ g𡗀Z//[oO{nbr 4'Wq5[A{naj2:xb i@(  &(+Np=VGL_E;y[9\a 8eC{u_veЩ]]^ҩnueK,rw+i}cJ5G|GDzFTh홚5FF:Em $Qb1$*]JVT;2WV൒/"vGCtQ~wCh;,9p.wNZݱK̻T%R?]X%V~K2H]ƃn z1#۾~ёd[ Tu isMԋ*#I퍌8fx2>G!h7`(hYY7:bĠͣ琼>9Cҹda!K%92sUJp=qxp!*/g7;W ?^[vrXƁ>VǢnCo|LG76W/)4SGsiօZ}3M: vlrH {{mXU;#AfHk3iFqA^y!؟ GGqVxP}cKp75+ڣ AݚFdn;ŶP%mLs=? hu:q;-Sdj `=^N:_>oZuQbyU;dBG:Nx@^0Ut#]G3fmY3icRl#긿yUK=vތ8c<ͦ Ao|93Vze^a ql,V ^TM'2AՋM?5hNn]Ə0 i6DT- p/TnCH@Y YMp-< WIF,܎Eq;;,y/+izPg% rrgd}gY䋼{wXXgi@3Μʳ4I4 |>[č}!'UVI>Z#`@s>DS!J!' 6tg; le9qy6fc'جx=rG}2fEG} (rl_@$4Cx/15:c%gWH\nM,-EoH^9}еMZPp8]>.&6 O ebOX^D-j+ysjqBA@&`'8QE/)$ *C^[z EIIXbH895fu'Mߏt߁) l4?(jBAPGhֆK¡ يR)$kRlеz~mӑ2^YE3 ^U!?  Y|ɂh\fRM#u:( V.5k@R,g#kͧn:%w1cbԻM.0@^**@Q>[)2BrXI`8#w ]ǡe>tfŸ6){J;N|2y%_gi.'! AALEP%_T H Erh" "^}h)`k_#Og< |7*1tO!ugNlZn6rEz~ X ]+bQYZGL𯞜%gU.ERD*^_,J{ Ǒ~?ͦϓ'މ7c0AZGE A} nӣKy+74Xq͕C4TWq,+'M'Uuz8=yQeF ,X77=swq6)mGZ|^JsVMDBj$ / Ii"?#y'(Z͕?tv߃?MLsf4^WՎjs^GDKF/˛9o aݧj?}k|]Bce/ܷ ||};Sj78>sK!zxAEzvnC?-#9^H!#EZ?5Hi̧HoGф:pBvY]Ӂf=n$HD7;" S~D撁VVp制5<ϛW9d/m>tlI SMx\mئ=!CT8a5ևa~ <尓&2g#ys kVGՖekeAu&гM[Qw}1d~=$]Xo> ^3VHUh_MŽ`T!-Y࣑."J$ `g%(VA_QjV~/QX +8w Nx~D(Ec5Z`~wi*Uw'?'Rbtfuca 4.~4kyǪ+ӯA!v@ѐgx O?zo^Sx4u@ 7>@*r$x;ϻ瞢%obMrNI;>Jtq3sF99ł8 Z"a;å RɆJ-6JCIAS6 ExA}R/|mwpDHA2+H#`YguR㐔%E qu{+3c~Gu;5;ߺPFu!Co0@郍(rHpS2A? O7n ~߫PmAȂ ƓuRAExE$b/FRPCKzsbtIiZ5!?QHfggAݲbyd =D8aX'vw›C{v\Dkv=yY)V7;茫~571 k|ÖV u Φ%Yb2 >2Rg6l[>kRM׉f3F_$ֺ۵S]Le=LAcps) |3͋k8}7C*[ln=orJq8nъM4^!K[ܸӽ\HOЬGHz}՝+ XY7*DIb?T-@Ա ^Y(΃cp|`{zˣq'y-jگҦύ\p SؤqD#V,39kDP勒DH ݟȎ!lg|c7 YIEFFHva<͵\1Ws#T4A@sd=╫*US{ap͍U w6d2I. 6q};O K>$++wGFDX]s#:}-X?)Vc M΁hψՉo`PU4}Jt'=f]@V'rxzps 8l"ZîKGHb>%4[bs|x?f3;^2un-# b ׃XH`sPf^Fvj" 5NN#%!M!@G:ڠ1kCGV&J@Ϫ1QU:cM_mO** omvƹY, AP5'<`"HylT | $F6]h"X) ]vOQ%ƷDf*ppIV6Kr 8a:=F>!|0&2/eFxs 1ڐ0=Α{ŀ⯤"Dtvx`Upc<8NN;&Q]d~RcL\,0Eӳt{.tz4k5K 1#;K+9"~ɴ?^oR بM&Xigw!)-aABԨch[7)@}lSuP<QWCAãE1DFl<$"EPe mWg 8W*0bhE__F8jc: btvQYM=tqWD.CAkPpMMb X?I9KRE,C'Wky<.WC!.:&G8wbi9wO&gS/xB -:!ѿwmשCyoO,׈EQ@=}!zERAkEV7LvƣeXPك&Z{!p15ZQ'1|Td,kS%T 0`$bݛ(o>yGl"T^Ah-Wo+޹ZcqAC $?/ZIM1@rkRja6yP@# 9#ݥL|yg9Rue푮3BR>/CSh|ڧmFT>؝No?l*RQ!RC75wG_Z%6ݐx.;)ڵa쥂3  ,Ja v\nn{Rxxno7W,ouz5Mf!|":DPGЅUE1wgj:WM,`]t,$$$$].8\=v&9ؓr #Űw ~;TYr5pY Xxq;͟f14G(w\|ze:3EXZݒfZ31é}g WltzOuko<==@7aW8ev$e4Iraew|yMMPZ-n !( rPo8AЖ=fޤ>83fA3'9Z}PuI3f*. I+YIHLc1@*"ȹDW FQ¹=; KrZtM$˞QS5{1!j#}Ux=AZP~Ñ]d@pEk[ ɲٔs]?;W莃Bԑޮ6GۭZ- ?z7p+wx:\Y ܼvCC#XV pʙЄ2^%ˊy*ڟKzW`j>SKJ@3Y/x 1Q;or紆R^9U uA@hFVHEQ U2&,D|w-}ړv1xuIdKxf͆ ™DCU!OHTpmy%I N7%jD Z[pO; !C7U$δa^-=]-3/@[n񷨱UQGN' ͖>v(|`yyigw62e>ՕVg:fCNʧ|OD4p)uc7qɽc3`W,2.a-} UiWZVq,SY>JXsr }RP) n[qjnp-_r[drG?CitVbs粚Ҳk4{mD7+t5y EbI*.}um[=] s4aXmyY?KW8qSK=we! .-Bj\E9"а >5xqk)90*#a! Zd+b"P%WE&h!}{4b3AhEP=d5@T曤I ͅ'n56\J0`4‡=N.Glf٭gZ: "M5znvosvt;v"#*ea ,I|-Mѱ/T4eic8$!&+ ʫr-!Km+ɸCR43 42UP74o`cc/}ԲTEb,s(Ciø_Ȗ'B%5x-Jʹ /F}={Rc"d`(w'}Ci/qif֑Ǝy<[18KqicCkfo{AG%Q$6>ž\4gARDPmߤNkbH ֺtb|^CK`hrmjut /nh `Pӄл1ɗ"Vnl{\#^pM\TO9E)&'=gǘ?nTqTƮrK)d=|b"wikeyIWΤ ~xZJIXu QǠ&(斄S3|Rh<ff $^Q[v Th[,&zy}oFʢ]C4 R$06WG1Q5 ۃhz4jp4>Э]W/`bWBNYxˉjWnwS֞X9 ,k&yu3?c$+a%[a#Ys ?ޤOjEa!v-ifvg۬5z`O<#4~ 2z `F[)vC^F0P;`i:>*F2؛V*._h'w"- L }n.iE.Kc>tV-|'M`l0xֲ=#YNlh8>ƭ@ R^c"-؉-3/ L}xT& QJJcN%XbVx+M: >ӄ0yKrHT6A:fOU1=J^}Vv#$No/+L$Cc ${ sE2-.ֈN.K[,d~e/2{wB~6LR'x*$c{T_>/y }lT&RP^k yJ,=^9ڕHnx=Q'*n婔 }T% LCvH&n;jfp+ qet}uˁb|M5}$ŹbJȚp?-|wj!|د8[^@rUiA>=ux !xtJ9ۑq͖;{9= B{=3sʼnCUWOhʡTDN;3}[EF^2~ձ5:#ɂYN|{}MEJJ96KV(+뎗w%-aԻ12}4O F4=WP4@ zfoLmjf@q1ICSOD84s`BȻ7!SiP@uȥɍ+KCFZ2IxЦ!)CR1Zx`t;7i}LJҮRms1@=p^8)0ӷ9P. B}C;%޾gSWT23dف81eKCvQ?Dj)&`}3m|hsHۅF@XPG pQ;^qӼG(Nku7cڻ.d_z ,>' #d5a!mA{=%dW,lv^/tbd)o: V|Mߏ#{PQMi:Ih%M;%}@RlQ|_PrK5pw˩Dm,GcO &^Sx UkJ5[E.8z3|:ud28blY.>颜"͙tO:`Øtͥ/mcgS !(LjňC}i )Pg_gVf,rZͨD`Aj\fI/)ٻ>I1lQ~?5~E'u]=@' EvLPyUMo8Z}^e0?E::`W5=M9{u[ڪNոR00\ʝP2BmuEe:R]˻`|u:ẵv$I#㞴Q;3K( H^$d]7`~Ъ`ӹ!b! @%KqRΖZ`0Q_P7ԉY^V,tuC+R{XLշYn䦲PǚCp,xQ!/u΀`,(*7T=hy9GU>|˽ڕ@R:H^b$dA+?GrZ6QX%XNYm7!HCF[p.j@bb-' U٢YGp2M!""+g/0Hр.+la|la۴1fzk 8d܅q.[QxBAS@z=FeNA ATH& Tl FHT}. ѸKܶKHאzK.:d&/IxiI@JdT63 cBGJw^Ia %#<>{IlՊF(xגA)f55=<Scfv^ cj87 (MZ*&jLU+=6FȰϒ^͂zu8zj6sJ=0t~瓷5å3܊ Q~섫OǐCVBSZk6PGcOi)ß@TKnm!pB*NL|*h):%+m!+}|lΎANWy؉$@#L##Rɩٻr3McJK[m3,[|8Փ4JC'ޏzBӷm/¿ӫ&=;nHyOPkԇVг$k+ͨ <0+cl<1('L)f>:POo%'9_:iMnsݛ^ݒ'.f%oꆕx]OĮLEk-"hr#Ok;]rxriǽ->t{p!6핥yB"Ƨ-DPKr/Iw ^/H>WY4LPE ]eVU(?ӕ `QbrlJ(s!FHḢf LH v=;f";ZII!{$eeJ&V})3Xqb&z9%Z zt$Db#wPkZREH #(G)KW"1%''އL8=aWҵF7bHT{PI֘f|hp`-RC_LI!:WPȖ9_6(DFB4szz;$ybp9x/ٸŠI_-146ݼ'|#łW>qr*+EoF- \wrz}mn~>mi^4WyYl=ySou>L%|t1gg BLS v ڢMDXГDm:@%Χ́=k{aDD]]ٶu'Sf%d %,5H:KtxX-_# iͳWW^EzSh]yG0{kv֡(zCW.>47׿u7h!d%t.9nqWTryiZ\6qȾ o}kn/1ݻ'c²6usgĐmxOz%5ޯmÎtޛ.7[jP\~\4@1+mó Jqԁ3an6ݱQ8T1TI/_9{V<mEw;؀uèĤT;Q+f`M0mCp ˆrm&v51u6nȽya6d*PGI6arAkOb'~RlŘyq?K1R .+sy/ >c*a?o)Cu}G}_!@%L;I8hwG^6݇Zn"Tt3Tkb{TQ2lxI 7\ rȉUa%QYF$QSYRU1Cb$$h;\,0c(pD<.T#;&ک c䉵xu|d[YSōQ<NJ58t-h}п4',ŊWY~0SeN + `93FN˩g=Z8C16YР6AHrRے%1 2ԭό]GvڟS֎h9&_UIvnQn# %=ʁq2=f`5*/i>P<0k|B0HcPcdrK8@ \fxFr{jC[=%M9fҁw\J0Dv I9pҳŻrdz|M[лYv}q~_R3:-+W̿t.Y>l&0;5Y] &铊Ő i ƙHt1rT3( $>_ qeH R<ۿN"Q}Pn/ze$$eo!mײ{՗5n z߶k8c-XQG .ryNa IЧcH&5lGռKXx.d eOߕ|L1Fy{;_A[c<ve(;S0d(RfGN2IbYF\#E͝xn>?B:(M؞i?ZGo_Io6lZ  M\H &Q1*rcŃ Uj>a)I`g|0 !3k$ʑHY!mrhAi[N0b=mNJ_] j y!ds%=fpYgDv ,jeN[Fr19 9|Q}k]j4#΃c~Io;>~Tdc)+`N"krJ^tB߱;82n-st@p_"]`9d@V[Ksa6KG^l544N>4cqb]b5A=BW2 ws`cXhbf„̶囅g :M%x1v&j&Tcvg ;ogص_vFnlŵ#䩵SdUτ>ِV=8Hd{q t\uΛ52ʃ9:<:rxf}O_=J19Ѫt߁t6K?l)wr7I틙kW]M4C;Db;CQ | '嗌nX5DiG's7Z>UC n߱O3$ wk/+ʃSOaL#PJ#=ɨVov5WF +$*>z`̜thف5$1D߾&M u4lajQTe1zCNς'}>_2)&Kp3ʲ$ݕ9$lZ AM#N^^W"\oNM<0H|~/퓨x iYrś0!oo,xA"8#(< 7+p?:O6ikde1;HpQh $w!*7ԁ_"\xr^j{ ;vj<2gѬ$RѥVV]p4)ڤ3 Ht$2K߄ٶn0\7Ź=tBw%}xȚsH *Kgܗ $EѮ!o-ț`gFS63_=ŻV$]u++ߺE=G΄(jYc0O~9%{7"?qn۽y!{5PhG.V?ʁP\e4"$GNY껷ȋhg칾$Q__.ܓ{?_=H)]cࢮG=z xߥ߂;׃{g3Twv|W;B~8=X!,]G"5EQ n?DOg/v;^7n,9XZ2bu.!6o*mD6/ԟ1xIV1Y[_IWݓun F]Sh7zbƯ[&q&̩B TsY +[.]1=%E^ZU~X]\sۿ45ܟ3(7h'׷XDϴ} - h*7|Xbcኅ{1"dERT-l+jt 07&x[olbU|<wh! q;[d/ M~p|h=M3ExM:=ގLi# %AlD,Frs/YQJƽ0gJd/KPuC}=?ߌ @Gj~)Z޸(%/-2"up2z) /I]~9 ٪Om7.] _)~#=rqzmMBs)UʒTPK# yQZ9}pXvBLXۃb3[WKX%)epg=*|\5Q^ONg@ZI\̼Qpbmw"_5Q>Rc'JS4N_B^=aݙ L>g "ATA6<1Xѳ~C˂-?f ,6c<\GE)#h@×#NtEI҃BoGmpw X_(3Z_cO[;]]{5^Deԟ~GKGKK&ti ʼo^lr. QAYm ߑk׬yB0M`Mlْh#Ջn=#NC7 |rq?Xs;'^ L)BGJ,9z>$͍ 9g3͗7uAI (RcI6:N24d=E@iڢLE CfӷcP30$eQ n_1m2oG빲E!Ê "/|g<sΐ*'aϺd{[bcmvu(xB1to })Ğkfn_ΛG/!o %9et]YHnJ}liC0C! w ypiY/$F%'SLvwMZAU0ڥͪtkjqŭVX1GWޟM& i;R/}ie w|峻lEu;}[wrC/d͹]Lia!QAðoyJ xkϞz?6{>=aW=qB瓭jD3B@ņ,S~&/4PeBlEVgu~}q[<|f?t${natp;v30JL+*g2Һ9a"-rwb' k>a/i2 5v۟s4'bTV89+4${qyd?V;؞\ 6"5l ]cB A6#÷lP#b\ң>WmqWM7Yhb@ _'2* xP؁,7~N}ߧ`׹x<=/e{zb6"1LfB@%̋R$V+{. i.ۀ"܏^`9gaL7,ӼTK ۲W8 ҕ,tl\ՕTKCLos'I(kvfo2V^ ;nJ ,KWt(b+' .p CǪ|^PKF>Kւ,K}3ds mu%uzMl\vyKvvk=_ 3 @;|d~1U!髜^h&bQ^AgAۯ$*sUc`\7@ a}O fdfծDr.݃I4rq{ƴ S8il1n_ hDw黦WbAAFӳ4D2{6Op)L eAC8)/HΣAץ̸:[bA hTXeD:5I-`Adҹ0<hp)NxtJ<`[=3&I@ RT0!h#+G{]{|^ KPvpf+^qx%ȤͲ ˊ8{m@yڷi3T*>>Mȟo?xxNc;=kR>hFÆ0VO5.K YUTf}í5GXkH+L(`ՄR˜?E4A~'&ϝxט6~\+rz~ޕW <㡽qNbT%X\ 𒀼'T+*Te9fx+pn8HհȽ+j)UkE5jW1c7iiyY|}Y?+,]ABgomY$oT⑩$@p4a>EYͦ8C09PП]ݑ*~?m@7rM[rzMs{n۞r~/ނNݰg-]xn\#g23ks!Cg-n.nFtrP`s`ȓ"w#G35ͩ侕so<õ3ڌkG<%x ֮s]EvѫSڕw}^O9Y2I7'c(Oma<7ЦhL 3Vruڷ)SklXtȚgX/+f][QnД }&G:m?qu Õ+jS:3†n:eɸe  ‹D\s>ZS8퓫rGM0.?3TkS?P~DEllv=ADWp:&tntxj)Wm  | ZU 䚇-o>._yd4sͽFV} T>ZB]LNW_"w@r+z]ٖ1cxJk}`grofF+g׫rZ}>qEm`qvhV@yn’WM(,D)u^7PP0#Xj[u+IGU2РLhNWeloW7Wchڹ+ꆣ.gC?9|ݢw~Pa VqXl!SNуv9E \~{irmYpŽT !TBZV^Y c'ff@{(MsOq>6e|&kna`LW,Go-'+?ph 4PV5*?C."P杵qܽ>NMGlWꉀ'}[HjS,`<76VY5Jn@ Lم7O׾+ppYD lLBJ: ?@gU*!c bja%[ ens4G+.-n)qE? r\+Ɂh+j 3V*%JX gb?ćE{T&#HB#92nb:_cBٲmo#'޹>"`;Q-類$)7p;>zeauެcY 6H~j4Leo|.Ky0$9NQ:_\ b/JG*t#7}:9agٿAt *v$2M6!BѸw>~Mzz#q/$9RC|E 7'K|R-3>Zd~3??y,z pa%ǿ󩥽puhdnfQBΞgL̩"T.\ @ p&}O߉%n`0gMd3k-VOѡjq~FG7*a"*?1Z %aaOcǠ!lg@w[t+jKm{oPn_3y.ǀ)K?z]D扩1& F28**110.DJ+2TqeuZq935( r&;֖>I I 7@;UC~U've.e^qrā) בJ*3C^2">:7wzqvh昢<ǢZjp2QrbptFH\R G/ޑ.h@'r֩:G8('d\RYB9YH:3dld_ gG%1hi߀yzFDn|3iU 0[{@ٮ85uvh?v9UBDY;W*:?{}c#F0Gp7ST@AȾ6:JuAhQR)g/i?Yɧx,ℛ=?kkfnŢiۃGY$'w~b}ɡ֪ʼnΡsO͐gA5k H]\ׯ*[;WR+-E:ׂ砝9cκ61]%9jw3U.Nb xax?TSq8y%Ҷxvϰ w9 I|ˏEY)dpnsPMvqV͞VH{gh Ȧ!:(U$aP6b@&ZE%hLUi@^Ew%^o޲0s#\Jf3Vf;i/`wS' Yy"\+KDqЃd(rYAGm{xyҥ8ݼl\J>6A); ǵNV5Zh#Tv՘YLybD{yQ1Rh5fj֕ Zt$}_tF{^/NPԫH I&s%bMh'4dU,h1P>XW]np$ Y:σ^ !-,!Twown.BJ3d0P3cdM@7R:r[DSs8rt]b~lFKӁ&>:Tu2SW{Q")BX~бڴi]G2/`._|ѐ5h'J(PZ3:9ߺ=<oGp`cğXb/io GB[H^zBc}H)c1riNXɇ¡[x`RnU{ɮf84Yuk'!-VNLK8qf| Ԭqkh x1)ct95&ȩ.m(oh-@`^wȍPFĉjq}a+A2sӉqchڧDnJZpϕhB`*%[Y/k- ^Հ ! 1\J,eV7 6 YK+B3 ÉbPΓOOF $i_ %:m)ZZjDoXrp`J g@4σ%0qnJ}Uw|+ae4BL{QSztѼEfà&;( ޸(w8r_x'SET ^DH;ʣsP틁 #Q \YNU2A`p1bJ2mpfk1BȾmx+և ~< 2$5݂݊eۃ:}gOo ubJOS-T>Jh k"Hԗ>>:q}]+Hף6tӎlpMKNkhwgVLw_!x6m[ao52 `aJM$ v AZF|+O*Im=R~"3RU"ާ\cz$:yҮŲc1wnZ`lKgۦE0rhpԵ^ f7T~zE[mdbJv/4*ԕH zїۡ\n\tfUpbm 5WD6Yp\t?LV-4TJ\VP aXIYAjT|4cipVeQ/rs(-eQ)$G1,@!ُ!F~ңt@qz3S?W бc{@Ѻᰕyωx(G͵A&Dul9ke'a/"q7ƴU\x橻 C+PdH/K J)g֯$M? Xkb@ⓉA[Ja x(Ɋ|(ʋϪc<h :wH-Xξ/suGt;? eA}->*PE eėe CAPH޾ǃL=IST LN(P?|()A!w/Fl} } 0?.mOqGqUw أ>?{tDrG6q.q ޅfUœƭlL ycMX Q)t UN4%^!]J&J E-@~& d+cHP+W瀮6Rѫ!GX5-" 9v_zA(He pMNLO_C<:'w:v8dzagnk}Z y1ሼ&8گ\1wosr1GjTRaX wh'.> P?琶N: o9N\MsIMFtzRDĝ|k udbR.o8+&wTCαTXp%Fp?{-5~DM9E{t75ΐtUǯPd\5+{& 9C_"MˠA8qG|iM:c:en4 _ ;uS{ơ!PWRT9r*=:G)ު +o LcDRss?}cMLn25Qg#rEMprʤy8km;;].ICbwZI8 LZ7#ECVrR݌|`h^l'y[H)KY(!e% ~3CHT$gH,9TعLRu y[1^I{ ěNh&QJ~aVLsv-73at4MjkJ֭:L< 颾 j׳U^ެ %iuJX%19;ߒDj%"-aơgQʗh+jwÃeh7R14U-H:WǍ`KbCdb^ &'M;x'wHXl~UaT`ZkGgnJ;qzPj_IcD{b I NiE ѥ &|]cP#-KcaOD/-Hp:2A,2u@$x$툃p^ H NKl,+pGpQnk|Op<Y$!X\k4 Cݬ(J8i$i>x%jqPv̯dt$1G܌W/XK*b`69@*LܿrOOզ4)@#Ep'٩40ը'Y@YkZwW 2y 7_M)B ~4iG#I<@Fl*!P~oj"d>"^aGDrőgQ:zg}l[ ~q|H֖"2x b5_X{0l] Ȧ:1B{!ԎX*5ːϒ:&sA ѿeP/0;IU`l&Ȥݔ] rʣeU%j$RĢYk m$;%N]/ډcjc餮P6y0B"qFLٕZ"!u<$HOF2yjZ2dHd EBsGȥA_MLb¤ t3{и%nhb4SfObdH0&oDQZ#p&G-ۖ~T܉!q!u tFB}}qr`ܶV`oa<*Bhy?v ;m4mN7/ڌ`d8\/@RtZ )VVfﱣ#ӹcjMj3m#KeL5A%>#E38A͡1 o\'Q`!Y<ؿU k`$Ɉ/:2f @GGq/M7N7Nɠm\ տXLffu$w}~"##t0ꩍ2B4f)78E$f^PVg@ɵpyf'*Xq`sgA"NEIq7S G^ Cz ǰ.x꒔wYSerY0nlbrrk ?߬:A|ە;woָ8U(KF;(Km;+A2>\%aj dle tm;dq?ЦlpGiWW#G#X!;ɒA\eLAOh7ԡ_/ )M1qc`6t2h\v# 7 Uw2/( g(V51?:&$1 I!ԕ+I% ^QԌRm8' bvOW׬ÚOÅIE]V[^N -]&z*HŶ~lSq)2*g]\GW*c_WOj K9atjX{b.V@\>G)ߤC:q?֓b}S N#6GItY5 vm{sh7V듷-$yNm9MzIX=n"#v[7cFy?Z(a[!y*6tLޕ`T]e|[B8ϡ LuvqH%(iOc?<L"5"Ux]-)r(LJtw>\#wߔ䫴n:ɹ>@'I7N=Sdm B Y 82+ݹvQXk>Ì]3)D?נ@璉WW}e;b by YUnfd 9I_jD{:9 c߹1O'F4p`t#HSC"INbx-txj2EunZ$7SsJk}oDi5¼)wP.V^53v6"M:kc Rr2v=4fvEg /4(xGꑅ!䊎-KJxr-LY+mz_+PZGF4[2{Cۢ NJs~Z{YKD2+ ׂ9䶢*zGFr'lskhR ڞw?ߩ(`f&gZ?!i,$dϑC|?SVyd$ mx}?Ui .ÿL炚 82mD[eqhk0% #[`8FŪ^xA&t6Lg-k2xr2%h@ej&, k,@h~(H' ]Wy8/͂ߜ@/]~ݩ@&:RM 颼ݦ5DL{,T3/F3i1,a=uXI(L;*k? /ou|lIC}~CIddu@սxߩjL&(vot`mңr`ڬ-.~2x:8vZ]/j=.׬>%"L~7hV?F!Oq\(%ĚD0! Ytⶆd?R͜!DÏ ԍڙ@h-HBpFGJ'J1NBab'GtpvY%CBA<}UGƎpz#ՠ1aoJjGXPnO:Z RJ0g htg%_??ܒbf]keGGS}xiju$kK@ܼs]:A: #ZM}򫢕&F2)JȾVe9*Pܗ8F /H&*#{ ":gȋ<~'0X,@qC"#l:ĵN O`"mw+ҍ0GpK@wpKYf"𜐮!Xn&c wcA_MF4z^>5=V[w??_Hh3RБ_:pxyw"yozt͚yG-NAwLu&_Yp(N0G%|kNPS)|ջSUO4ρۛ xguY mxj?XeFQ跫DieiC{ZWʹ\UWVh$k\"{} Hzi@T;wdH1̛Alk\:ر|;#17 =x{:uݞT()KasⰘe|;lZ ㈢RaӨx59vX֚N1h~ƒXh?ףU;1yW85$~LLj@╷wCN'W&Lpy>*^PVBi> ٩TQL\WX{Domӧ20t|[38{庇6[ẏː*ї;+pbƑ-[6h 7T+mިfS_wK m@bsD},-ȡ΁=6+Gݬӆc Y}uEd(Q~aS;uZwjLۧAq4':%UTp_T0ˇOKE P#郲hCwqJܼkqHs'+pPcWY `)j,f>Ԅّ/JT3?20_)`ټMN\E&x33#7y]J MX_ZL0X̥jzh(m2{X8ʯ ztf%]>+_ UC7 'Z}w3v̳S˯B<*CEC{[@DR>`r(ۮv[;5Qcºܖa >Wh;[fѢiDꪰETé=Tϋp|,gD+V/lZg DjjVme+.G6fq4ٱŽdYWPzq S+އ <ۄ4pap PiUy.zgJD4=w4.yӷQo 29} J#ksz+ Ӱi|W*b@ MܱN%趻,.QGKC H9zllz`͵)$UT.bknX(#. T ,]et֌j,9TeI;f86h!I< QfJK;HJo NE! Б#f~#0 6IToEFGߍXIgf{#>Şλ ۀg6ku)c\@z1ڟ^-IBɵ&  dRPACjÑ5c 3Hj%bBAo\p:b]G4mhXIp,5,ǘ\ yŽO a@vka8}#Y'_l#n8yN^~"_YH\zCF~uga͡D_g&/ :¢ٴ:T V #qےd*/'l'\!;b4 YN]8Oox8h)Sv:R~/D_ƥtffX.--Ym!%RQahtm27m ޣxHVhvSnbU~ Pnhn9doHr0p'Y6f7J:ړ;_0;s@ڿ&2W Ɉ#q'.O&CݻJ9)W"õ额+efNj3gX!5)k\fIQD;ǩ .\GDvL5@,XMQ{b<MáB4v {-bጤtؔZݟFdzfXO+n Һᑳ<3O,AZIna jNa>QKjk)XA?T+aꜙ]5t݁|w5iJOmOnb*YX+E6JB8dz]kT8XnUT4;ʫRȰM")!q^^PsT!jڲ\I Ɲ|-=rP獹Gݸ_ mo|ۖ~19#orc# ?zM-U'b _}ؕ) N@xBZ'ɠ-v֨`s:7VOj( ?ZZgw3K8s .&0!˹U[)=ՕHz&(ҳi(}jsOlLj R_#iW# cV%+)3kI5sa8ĐV;gUu`YI΅pqy.LJG0Q=ŴhQxskH~D ,gh[glI5h$W 35-YNgT--˯q΍^:$iƃ9{wX덫GٍRdf%ZfpRg>x[OV!ߢ@o [[ݧׇ]ze zщ.N,D>H)U)X)RhOݞ_ k G_@}`ԫʕI:4:qj3^w0)PBW TS;[t 9`1:Kpw2kQNN  )2^ӞmNȔYps=Ҫuzdb΃hMy \~s$ 4c10U%A**f,SL&IJRu@[f\ >UP} nH9 ͆X|+LB_87ޓPjp"$(ly)|#~DdFs釴2* eDlXXm&^-eC]ӣ;&ٗOJ{Go'5,=Х^e d51I{.obI:<; ZN?UE51fF铏w=|phKd^o[hU#PPn{= us` H~u۪~̚Q%F>Gaߨڜ . D-=jytPjС`;wH[iu^OHCYk}T_púflW匐dyul$:dŨd8$J["(ǭf$P ^rP+ojY|®x3G`w#|1 N[sP~TxYbZv}}R6ԌY'\NݷN-vcH7BayS@qҋ1\+DD/3J܎"90j\ǍAv}aCG^bFML.e++&[ș[_ϏG lcKl3!7:2I|VqaϕgBl};Ndwjny%YP\Y)vOC3AHWsN2_9&qkm(9fP)笛9\s>悜lއ4|k=zGfHx%3vل Ghkb3[P4ZY/J!-$jĵB(Q 7ћ?Us)B1_lz@ :+ :]BIM%3D] nX{ip2NN5"/}Ƶ=oZF#s{̗ ^ ujRmoR=xy^׃~HUMj_ >+Zw){lTSjH1#?U+Tkj.[gТP+ȃټ4O//npm|)h@#7+Qp/w'ם!A3+Ws*/}^(9[J,I1hD5P?E7J/67C ?s C/tjM u[y`W8{W 劇JةRM F(wskַ@8KV,ᛴZ[tͿdpBri11{&j'j㊬{E\N%}r_쳲xxǔk|[??1EТ]]53¾}'M}wM{Oo6+*-כuXstJ٥M-\ϣ*.WjC5He+ۇvov¸c0hFz`f}XO\y䒒:ahk Qh5vc.n-aYwAۊ9o006vvmcS9º* wO5cr_-t '6ZfSK4EH /NؖYLۮ+e VkmeH3yTK %ٲ,&Ki'o=nzᡷSyTrYappo[uh\^X{hCuvumt~ˮFr-0 R* YgNz7C^l5wkځxuS`M~S2fZm'+lFb黮J^fۦj5qՁ\&Z!bCb -m D}*4`sSn`{A þ-ܝO7lkgiS-(bh>9< 괅c{T5Fb 6O7)ZeJt=>Vpsn8l}ph5#ak[p3 o!Ӎ>}jrZnxn~<45JzD+1*hنνJDB|ӷp҈ZwdlrM۰Fk$JvXnmƗ͢m6{O{ˉEMR':$:%4rt&Y2ݿI}& H@xûpb0Hw^y&JEuQX~$5V+LAA1f#]ןBPv/\=m0\Z%nND4F:7.3h:a6:5صV|a \ͺ%5uiDh'G'&@#|z6ZpءTA,pOTM| UV D9D.mɜjށ'V̰c|>[MZ)wsp̔ SatgrVkFji9Yq&1rA%?Yn5kSBY,IBܖl'JC {򊗗Uex|:pͳd?ڮ cxauSS`s!/o'f;ϯ l/2<?1jx9J| ǯV}Cu8v<..GGwW;@&#> G'zz?'? 2<wC*Y& k:XSٿr i_ DY[$>=\=璢ޛ-S.)E,rN ys! >s@| ao8oqAī4~ʀ2NST(yW{[\ /m#!`L oB/[z[#S=>7KOxϻ?y~j췂#\Gk&X3џ;5'>q|.S7"1\AQ,װ@"]QU8vP ҟbHM^֑l | bBǵr7q^ѷ'~2Jof[c TfRs!p2`HMG+:k0x"W)[Ⱦ~C-1Df!,R O֭UqjGm kG?`0vSGk&~Zu+vS҉ƸFy =\G0=-CX]??hFvdKA:~}o;>q7@uf}  G#RX^?)Uz~"F;;C;q4?-{7kcG-W33ĥ#L,']3k> 9L7ܔ*ѻpP<G3-EUrf,EofyѨ`fo.'ot~B$^K24y > 1H1c\-Q/]D|ouI[wxj_, CyfֱkMW4W-l`ZVkۃ? wD|9Xs~K/_ nPą$|&'|Ny!T|Ꮰ=;Ely<1]7R3ٕ'y'TOu}ț+THVZ<+7@ 'Tɿ~qWR 5Ȅk^y/uh8+6ٻM6[~`( OxOXl;2(*U]pUzEozI8䧭K+ W/[jٵtĽE ,F<lwo_鬑5ZҳF FB_.~-0G{~}{k{C7pmV裀aW{>Bu9LOU<Y![G7v!}RAC2< AWF1c@p| S~ڏ g XUXS/ؾw.ϝ/C|W^&L[ mWCyפ0#y~q)_y'k^랝e]fjI gM39 m`Gͽzv3a2ьɼk@F41jlZ'E<]DcME7 H#d =! &39ҭPj^[u+6^sgH"}C-Y'X#R}9PX}?}nVqWKIE>x|byyґ*5U #،<je~^'Iz߁Wc?Pz_}_i~zv6y* 8WSehw)_㿂g%y?*H G^CW~,ar<)6e?A7qxq]ouX;%pq>.Ur`"ÿ$1bxЋ0ʿ;Wlj6 ^gBy:xx3 i n.Cće ]|skSIvsmoְ _ׇ}lvUWU [vd媙': *ZfM :wL};%OՂki~DA[2C?p6{w,d3\C.YcH: 6@kxRpqS8a{کKRNyl]>aK3-L'nH'&3ɽ>^η<|/Neoyp <.[DT;~>`2Vrq;wo^u]:NwɒdMnl0Ř`bj B/!N ! NH~cμ}{/*LLFΛاhbf4}E]7u3t?te(<&yuC!'.?,z s3Rw2(mK.FTcScץ{}LT:m6J@k}tjx/=e}Hԑ7}y~u>5>9+bŶZ}osMP5=q=oC^ӢT:^tzc&':iFwARpL3Gt?;1q}4FuouUi8aD០[tqNj #B|6zj2/=|oϠ%si4 Ez>[B\XcK26o/k^?&)%zΛA>H_o^q%P^\\Y;X,f@=}uBܷۧdN>@$/ 6btz1᫔AZ^?D?MzIq^^ \NK|PCe[%#5Q~ ܲy5=ϒ}E/kx>yrz4ѯQCp//;D&?9tXǣD6E>1MGs zO=#L~Dg*r`:IA0ϖѧ`%4zKPFf~zDD}-?ޡ^+ѣc?VU:axG/Oo(*>75HFȜʹ sBqğwD +8E/;d =Bm?[D~@UQg~ ?)UF[HZ1@qptԍ%P~O t _]Co-×#\'T$5Nkو|kXHBCmK+b5"f_}k~Ѓ{1~ ӟ 'I|eJ #{F/s%|_gJizhϗ4nDvo-Wю> &;Pnxz3iu>/Cx!7<=v2=G=Bۘ ~M>QN%ub6׸^o0~2W\MzD8?/ZA^0*"wkIK^xZ[K=j~ J[%|?S_͟X/$r*[" k^.&zBZ=߃>#]}8Rt,'@ЃW1C=Ku}`'dD&'u?G܌.A/X`)CKDq3e%=} =_Dzwx߄ τwDI9 ƄNpsbtyEbLj~:e w ;&L ?PPF?Q >?ğ3q'C4T]e6%:tZzWw o CB޸A?I_ (G=W *+x:N?B;)f3po%|u9N#[gлKp_ ߶N|ԯ?F<~҇Q?z%?Mzwu uy$f'i<~͗@FgI%ܗ=_EgEwyj/=ϕ>Uf*ٞ yO$'`I#">-e/G{oZ)?~|z%9{2Gh累OV+*f3po)x8gZcɶJhm)$N~+s 6b樈'<{D\C;JΠG~+= }u(t=[E\X`\~.gJ222[2_<'_<> (÷Q/|_# `+DzG\\)חv Ӏ86#=iet`9%en$W`xI%]ĩ-ԣ른Rܼ)78jϞkJ*NjH?@2HdϐnO]^J}_o迂Ǹɽ'-Ƚ-w/"t1+-[58#0 q_cz< N6c ^B 2!!+ SX2 ]/xwqʑ2HՂN$'1,/g\/r 'K>?%ү+ćd c1? ?.hŨyF!$Ɯ7|yw Ƀ}"_wV"-|: & A|-O%o+x +Jo`w%-Qg%=^ ?-|ۤ F~ g>,Q " Jq;iѝh,DS^|~2WemY&L>Z{i( ѿPt~AmXp~K|(8߮rQ#>ӯ4F#NOw4F9'IcxkL'蚿az`gyt=gNc`eo6Y2s(  U&-֘-ph“-C= Q! p%_)m7ϥcϐ_G^P+n(,\Fqt8y|URoOocP$n*;{tFB՘Ƴcg_fA> h^VsjZQ;nYk$)?C1W_ TDǸ5IrXx? c&Xg^s+u 2{ ybY`\6x(`Zj˛[Y[)m;c^"t0~,HFO|Wraۨc-۷_>F MA PqԀfW+XS:k1le2klQ*2q[HUǹ X>?I)'hRvK pH[,WԖH, x4kmIhD1 NL*_Ģ24 kwm h ~ih h63QEH* ILjHNMξ-dq &qi඄lʐsccfæYGA"3]Lݖtb!9Yl]/ЏQhQulG̏xފ| xwp&D߿#QOlAQQ KϛX->;%Ƃ?<څ;ҟ'j.R/@8Q1XXfJxj9hb5InNK[hڱI{5w'+W5 fi{Mf:ZZюSWwcͷ.jszs vG欎tNOjڔ')(-DQ˩fH]u 41gZ P%f Lw{fJcn>y%9BMܩV"NƑW;{Nf0,v4Rx=Lf% ?or6w߁>'V!x߱52 &5.YUڟ (r^|?E<7%<(w W~\L=Fe 1Hg:qvg `w 60KpNR5|!/n=#߭Lr9|MLg5MmKG/9e55+ 1\rI1hGg33Hv#cM?V&*k ?`#E#!^YD6ʣMh9fq#Jt=i59Б4;#.Fgn%sK389mq1t@8{༓VPl;~UU?UzrVu;_N继.^%u OkNx}fP#]@ɓgP+1)S ko; 5;\[SAp@ܘYYwf}T?e+֑kt_C;x" ɸg~ 2@F %D pRnv?(gy /r3RӌtoT—U*ӒQcҬ1"E(Tu*Dv@|cҢF/cى\Va(Г sw58Tpj^#eLНBG֫3Ɲ$dFl'w!:!6ȷ`_x6/J<"4dd/IFr_S:8 9 )w(AGG ;G#X85A~CtŝFηq;\JTXc# ;V27|9j-zkx'@kr;y_)k~r4@4Zň:~EGo4?FWt$=/nαdMEM]톂6hF@׶io:{kp GCb'{5P|աMZ# t'-dᐍCV.GGBQiݪа=uq@sS ǁ Hʞ +ʎPPaed M=n6iuͮժҔD{lsk="&w1]p$$2MZo#gBAPbH2'!{-,]߷D~kc8ۯt c-\m_[ϸ,]k[k!>Zgx#=F?4WУ5NuH!>CfC8{t J`p2K9k%|6j)ԒV&}mApa@"Bz>QI/rrv8> Dg.j+x' s}{t&a. &Ul;UwU@ ߕI3*;.H .[-cȯ-b1xOn'+VH'aeI_=N r$6˫Rqn;汚'|)Lnκ%I:28ZDB^i؜WMR:3n:*F:yW"N&챃3Q^eB->A~R)y\ɡ&WyjLȂS~ab Ȇ9^Y*U@nuWf#4ti \ Fӝxe-z3|#mpjU '^dv]0ҟąy5>ۈ< A,V-NCLUx bzCX+2r̽ d {tU] Xs^v`p]usdͭm'j Th{J%+g  tdڠ_TÄP#E $O5TD\@$2uSH%0q5WN S@B s0PBm7~}McIM$xn+t4t1uΙm8׳޸>!qnUncv~(p'\qcD6,L7# ޾fD־@: bT,R&H%rB"F6rX8` ʦ ┇b1Ye^4as;j~SkiA]0[ΠwwPO4Ƣ1!5bp$3$5E$HW⿴T)aXu $'AkAb KLލݬ8eB*QJM ]W:|@{}i-fkT3e+,e$tptezcޘB !J^t߼ m)d等[Z$q {LvbLgEςxEWu/ -eRfJr@}hkg-cپz[ /,X?TwYϹ9kJ5l.5QnSZK?89f+0 Ȯk*rUx\ݩI,Z9AjSuӬYj+@UnNVڲn ۝/3ږh6\m5(KB]trnDs97X",KE%𲵌 :kϾO%t{r{0!j= x[ݻ4t{RTzE-yZƙ_yrҭ]y@ZZD Ҋ2dWjqYB >6i Amj/i#1-T,tIi\)p\X "EGELיvjFLчk苄)fKWBhԗ5>ԕi#t/6GP`6Tz+S  VܻtKD%;<=n,{0<Mu.eZC9?s!xaBjea7A1GNM~n,+N((_-o]ݕ]ӵj{"7%,~M?maS<^JN@>` {hwx)Q +3 R&ŕVd*b, @Zz}Ffp"bԹd7YAcmftXW jڮ&0^8j7z l%:Fm$,gUΝϺN#;}+X$kw"YKQmyse$ Z)x vW*[JG=Q$z*-ր5Dq^hb%^U[TʩF-IitVKj }(R}}Gk HSBݛw1 iAB/A`瀎ӳ9|FԈĐԱ\-MIinK1Qƺ .[ oI.yйkɆ@.fe4|,}/.i&PYL] j֊0[D2qd j*CZT.3ZY? RprQ1? 6?_ю@&mbv14btv53A}KFFYl~6h/qOWNs}w;j`EhJ71S1 X؜vXJͦʡ"f:…kka@qk`v(ƛGheQ>|KמRUT_Mu:]u2C-!"P12@`q[0jD2b Z<ꚴ,HW!}?.b:_g0gG~TXڣ5{ ={98:V7Z?uv[(2VfUxe&O?Mԗ /.:ӉɸCnH(br-A:2tj_Xi \J5ݰv IgM Gp&oYXy,A#vLH?A<< m@V) {qyX!ԂՃ_c̽ݔi?Α[rz;$ A4+d+ X2·^o"(yf)ÿE{7x[+b+xCC Lledp;VF0_7&'-3p:v_6+ {fu-pN[-Fmdy~΃#CL) >wꞍm?9ୀf::FWb{INđ^vr%s{VKksܝVU'[}J.%P:Jr:sWS`*֚mZنׁ wj{HYgd_\K<nj'fvEW;o:|fF4kL/}5Q-L|tVhtt!|' &KBD<: xEcAy5ÀϜzD羥d8{F,i1"𓮢 P5nY2?}} /y/״7Pj{]` /ݓO}+S.v{= A_8#<ߡv3C ȃ(gx\gy7dSg;AL9^Wޙcw7-+d(^6Z؅d{Fڤ_'{{ BߚW^*@\@+  -i͒\=HF&V6˪_5S'M=c)U+v'T$IlXhXA7(C.7=RxJB':PF)Wwux Fv\5⭐U a|-u =N6gKhl8z$x]pI__211>.hmm5.̭n:nn77uS7z˖uLUSUu9N S(xoGwP 5UsR5j9\Ku͌k4ǞSgSt/O?!&J wA*arj>Vܿ̈e=8x#tݏ7gWsU9x(~+w5Q+N!_S~!⮶CPn:C9*OKyv׶{ El_y} wPwax;!sY3u[%;B^ @ J?~m]HJY,wiEh}lÛJ[cacbēyR4Ɇ5;%R8_έvYuoq/} l}v#+#6 %~8 eq@hMyHT B5{q#0f^4ԒP==5xGW\SbE"Nr,9Thuf`{*_ޜlXՙ&CM6X7 6}U&W>' e*J l2-@ WV,sK;V _`\8]u7 8X-Y PWlw/Wͪמem` G(N=bd=.K`nO̟p݅+lʞec&]P#qZ$(/4 -I]Q[:tgN jlbۉ;dږQdoR)eQѹF{Edm+ͫyiÝ_zlbF8R_FiTFjY%{u],o3,Rdk QwS$С.U_f<KXscVfh*k& zmV˙5@{k:#BwMk//\X8Z)% ކ0 x?.D*ՐPk0Z)k-&#73~[MYqM2u9l-QŜҒK,qTWFN>2+tb[d6o]>#]Oԅ60-ۂ@o[x{̱0gm0u+*6t5AO)?γi,=e!NArBFftB(DK/ 7 PR\!SZMǠC4f%a= 6'uLl KZr9(k]qU€?p%,}\~0:My hh_Zڇη5Qd;g5Si@c|azu a3ƪjeΎSͯc.^y@yՖȢt˲{5SLdvzGݘr@#RdP.5odk"܁oH-[U^_o8N`CֆDI?nȻ}jM6pjc%@cQI=c{k𼴰+UUef?c-Wԗ&Ȫ}g?}lR&4D6֩iPw I=+-R/q/4%5.-Awn.B4M9U+AA *tk=pqG~U¬HM~ +Q\OM ;PGJ`ϐH] l@&Dj52:::ZEυM~؊lAR5vY*(쒟$>8R*GG"ڲBEQEI0RC)P{ rHpܷi_s:gJyt&e.\kxG|9S8G0~K[C^5uhc#N4.cE@cʚ97קYɦT-FYvԟ}k9Τs.֟ljy4^kq!܍!N*Əa|5@P(9(Y*'uX49 [N$m hT1R>I3J4{ edc=$M!:ZMj5]r]wϪҨ 3QAQpQEBIffOM~d\(d+uF(M( "<?Dcp"IѐNF"6$$'4FsUR=G_U˴gFO]8ou1>j:OsufwR}]7VSpOtl΀=s.gV%j[vҖݛW۹ ցEIGКNg_?븳&C:#ً;<6V9vRTȑ5(\EgLi cWFLEӊ;|륀1ZT`11kހQ'sn`:ڷPVrecEdMVWrQL6*.i dT+4m.]x{v`ww έȪS+*+,:QVpR 巄YVV+ttΚhʥFk[6lWU82!5lCGم{  Ў#r/#p0h:)(U!7G T x{ H+h0:ŠU+L#v'?%`6Vdȶ7bwJo$&I0v"tφZNK͓]fZė֧SMvOol© +쳎n y ]ve4OKr-"XZ\@&sHqLHjE\je@CPQ?D?Dt!$ +N9*flhԊڕ*-NⴃM^d.<M-u$,n6OV((WuJV% ]Rv˞\Q;?hBp*pn^(D5CjO(O8b?(ݭVoe7늵?&Z66+0=*MSkCK }[FjՖ.5RL'3߬Izf91pQ/d[ޗ:d,Xࡴ^`d'#dnht_3'{]Gx\ ?>'ӱ>~>xަpdž暌)͟I7>_=(١Lqc R= | ,< ^ɪ1?|qx9TWA`mIKf<&Ox,B*}D.xg{grt(7aUEA[}­.iu ΒԶ9J._6 *CnAGݺ*G4uT+M9Ӊ]WuإR1:ab/Y?#HQ9Ķo/P\y؃L %ǁLɷYT,X*#N!-VĢ^1ld^2Ǔ!ۀf \Vjg}zcO8Inٛ"fkポsRO2 e>y7oy=o_l-8)26ڕ:"l ]Y6utm@2cFz}UN`LΛUzߝ_m39}Ju3O` XF}CG :I.7H0c:ɨP 4mх?gK=@YA&B$]c ;wdΑ29W5RGo h,1gZ;[%4*{j|=?-8 S~< h.΋㝪 MT؀w{zR"72j ^0>h^Ϯj2 cUl?*fVZPqu1,3D ;(Tޖű[k*.ݟֶKU*W{2[_Z_9mqRL:zSo0^ѻuɦXTm} j&3F鷀gsTڌFW_$2j1\kG5ڮ͑桾%=9iSQUٸk.mҮPC> 8YH\xDYSP>^xbl"BwHNbȪ]XtHRiJ\}oNgErάv] IXw7 @[:U\]pŏxZFUj4Y[4Dʸnpph3<>^-%uފ>^(F".htWw $SY Ơ h{U iZ)*JV:I`NQu+AvږT3Hr0QegF|% ZJŕ(n"B:%#&D/m-Ż"+evC3OѪ-#]nlTg8^wR } Iqj.AA߫I_LH]8-l}WpW*jɷ̮gUG!%c4бZnbfeBYItVSb=oGq޴(q=[_KUBl_ڇ?!_'2YwPärWq)[Jy64ǮE31H?صmF"j*p]0+1k˴uU }vTHd$H5w9~qfv<5c>ȪD iUXGP/̭Vit?r-kN ݄|WO}a6N 6 4~o-QP!W*JbR\D"RYCVIbX-rZHrN4`,_zD{n#?qYחh?uXɚ\>Rq#g?w^0 S_*@1df&@)|>IEQ4B|~"l^'Eo gюmqClV͢s,ׁ<n=upOijG ?Yw*ǭ w:G~9MDInMoWF{;N_Nsyv&O¬ zwrǁ''&2W|s%k7)( (ُIܚ+^aE-܉m'p>Rr,>$Gu8>U=tsN9ߦ9N'SFPN  $$ lI",2$@7󯪞ۓd'~իW/?H]K3ђ+a>YY;y05~>Dדv+Y+~ɫ ay ? xSu]t{'#~/Մ%˸k^8ݟ躟gp{ E}Wiyǃ38=t?&G#:wb|< F5mh-n3ZRVuĝ^|at;<x3猒]~ڽN4}}{}&];Ü1F2u8u1}j95W}ή0ss{. I{ً3yr=?^"p/>ܕxζ+ٷycO5{*} ivhg:}{n_)3k`P:s9]ԾviKNs|OpC103 g7$+ u}|W;\A#_Tj 0 ~^S[[wjW8;6۱~?^܏!L솟}4=5&wl4ynQI $.֝lCeC}Hݵ]Zߵ^1P™4%pٟ?놦!t?|W+ M.hal?M$S 5kQp @eSqR]djlBH;[ӟKl\m-lpĆͱ Z5co+Hs| ukK1Ԟ XZÎ?:][3 G6"?2sFZ_>uRPRUt~Dސ^T Do^"ğ X: CW.h.?ZȋQPʝt~Ujmv 1rZzkl;pD8]x۷=|y(kf+L(_&6cx@¹ԟ.x.\c'I _^|rlAd@w /kqc9,ptM|AL>s]Ќ'[Vx%_H鯀% ]/x{<>-~c7+ k'A#t"%XOM `p qam!ElRxD>slDZ͇Kx8 91]xuapc-̡gHTa/X:zv5mie Pv{p}gsr5쐠,;GE0gX.=!v|` b[y6裘VVkT@!-">5OG'5w10}&{~ʭ /w~]w~=~C_&|wOy'x 7sҫgȪ2x==<{<<>8 fh`٭so9`ݿ38=hи1-ӡIrD"7x鿯3 ŧ @W隢 NJ"%?eɏlޖe9&ʰ^dz1- [Y6ҧb9I$TOQmE|vL3L 0t AպDގ`!ψ"|>E~D ]S!Xx Fd' ֺGiZ*EcrP .D~-@<|Qgsǰ|HUn-Jzϫ"#fO]?Qg^ÛNN? ){n[tuzPk/) {aomep.a$f;- ;k^ihi ɦ!l5wN$fEH*Z֓5o,PPsDwZ pn1ŶtU}o_vx2ï Dssx3;nQoIJ3E+va4/q`ߜ>g0E>}z3uNzY@mT_NНHŧк"*Ec{vXo*lo&R"YըsCvu`oX_νYkz=9/Xy䁉l!&]7RSv x~>1qn3ɬy|8.qs9מLG`[3T7FIߐb-7'Q2i(̠ k*+WW+B,@@ K!x y51qPkI#~g/ ~q{0Dr#ktd1 ξ{E t ;(җav:Çg|O/׃w2}7E ߽gRO ]tIt-:T`-2-'n~߂~uGOկhM 8Wk~V~R,ϳ`Mw? q^{E:OnͼvX:`/{(m>k>/|?^gəNo| šU}鰓`') =PUi=Ү1V{d2 l{d!C:>o;ڷ;V׻ tGz%PT.?s]~7{$**ܪtJ uk v *X=N5TAJ!ɳgCN/|Vl4)[5JdchrTKoi7I^i^j*RIP8+§͝uO Eэw-K6wd 7uhuг}Pu;L4ٙ.J1F["'㶙dR8`:VWiG$D xMG!X3b1ݗ<kdG fU:wsV/>F1QP-%UoTT|yp֑4o,f y&I=)žE?NZԏM2go^3YPE^yM_d:㵄۵/}k77b)sr.XXx\P6>pKr0aq냭D nO>Y&o-y@^Q7#ɜ 3(`ivYs+/m;.;77eKzȠMD/e\ܽ{)48Q/7|am荳q2~)Zl+aDK/ڱe`o~EkH~7vqT@~ >g=s=3iĊK\_~?r nq8<ϓ)X'J!c BѨrs>r_\K{F~o%mo9ad+\"_ξuOx\%:w>_IcJu~w/Ng6MjeN ZiRYٛɪvƦlٛ׮tJ岸NzjZXT4HȒ߰gn֌{QgzPA>Hdpd^مÝa^ ]Tx͚o} ?o۾K_=Կ} ]USi-sej9]c#M?zՀ^5 >xb`q>A2-R? c嶶'K,rX_tC;LRp}%'eE<Z&ٸOn'kGk[xJP-Ysr{,d,8Te|wջqD i} 밤{S:lDPl#y1Jѩ4c/ʎ;eP~y=CrMgPx&.IW}oNN,[ܙ39^S!HrgJ9-leqĄcq@l\sFo:9E&5@dCMgL`ӆxR5;088|9/埸涩,6[ ;XӟRmnz0lFs>*zn\npEq{3{#3}`x` e@dJ\U^_ʃ.s[3J 1"!$2^`&Yk\q0l Sjj=9Ol0Sa۔Te|`/L<}1jIx {N ZRL%cQ"ˉj=W5PqcP6:($%GqS.s&j>yb?M/W8/nng 9E~0=5ݓF0ScA9 L4~b)i˒ؾ^7low<YC cNZZ dAϞu<7W{Zkn\@( ָivq?&B2 LJS|N* g\4H3T9jȴHx+}DN3㦯9[u z.@t& uLpdžU#ʿN3.dJ杭eLϹns<juVɭ֎-ۜe9ҐT?O ƖN*:kΪh} GT{BV p|1$I0 l'n643/>@<8\, D.sq~^'C*l({9$2rnf$;vHZZ3'eU-B4o=FQQ5鋓-#qz2Qt}:#.uS\c:i`3y (4(nO(݃F5H%31Z4\pTfhPoF0$SGVtD Nn6xQ#bJ:.4k\zT:/4/*a * Ky@ٴ_1NQ|.U3{-R3f]9W氨bct/!%6 eXY)H D&^: kC ;kjdU`:n!D``oɢq*\-Yp}D|U*-t2LCӉt.Lfj #iɑJRE_be&*WJq0.6H۫$+m†$T*H\›mN_HLW|) qΐI0nŲB`VӋtBԁ^CvѯΙK;^+SrU+F+1o:>S>rd )OSfS5Z=`x?ZxrA҉z=c"Ih-d F(bzpR/rjx `m& |-^*9f*e#x!PTph7(tm $]{tx/(?@zQslLf0IA*&[n"?uć_}3U.`U5ٕO{}ݖv(\_`zgȭ%M9肔Ʀ\pi/ -(yR`zp/Tw,e:ӊ9c_c9j="СZR9Ow4\+Ŝ:6Rv \[ƜVX)b"m"R5T\5nj4AE:FR8mew$wt.&XEzs:d[ݏ) F^.d<-@tKپp8X!{Q#25[]什#ZLg} +9o=:x%ĚGTv$٣TEF^ ILh#}Gc(aH1)YF8ƭ7X D9TnZFL4J& í+Rf3s8bV({Pf5uG rW;$Y v\mŬyY\[5vt8nc@v˻Se_jO'__Wyg߭9bYMx;=ޜ)'4O}TF'|(G.I睮ʖh0ZHW¥vT: ~o z6iĽgŤrVcZFo%9zRL֦[9&KB2{牛ƁVԋ QV TVy]x1di1QHGFILn/F?5Q 7!>HwܻU&}ځi=Cr}YWT"@+9m9>(s~Ċi&ZfJ ̕uqNFʾa!v^h>'$țXy}ZcthlȤvx9 W _]>2mT9כtKL`n'q3J6 uB)qCڎQ/3@SҴ/ TNE=wP|l5~?˙7FgAV)4abwZ&]@0w h?lƼ%Ŧ#Q/t#|:w Vi%la۹ g(Ѭh Rˈm 67e5x 4s۝bssYTL'T4%_ +O+w$ɾe Jp~q9IS^oxL;f+~v7O!<{e9M#%55I}FV\6p xaO/ M,$Anϗ fx=y}>\et BcK[F 2A`3##GnʇƻqtyY녜0yet?;N}w-Pۭ3w֋B_s8W]gJ5pVX>x8J9hOoI`dZ hsbpЉ;P^p,~,'ZBwe0i'dP2gB$l ҝ&Ѧ; h;zGa: +=gXDĈ {LXp왾>TRl?qkxN5Sg x<_ɐܫT$e;dQ 'nd{/ꔖ v4ׂhWUS<`K:Vn)\:+ѩg-kH\<1kњ~w^xy׎XjU))͵][L|zu|<7 C)ҷUw5{Hv1G9f ]5 3*/4`Ne' $ W0OK2xJ_А0ld>ĪtG\X¬o~oV'e6WAcPW4rs-(gwpM9H8h({H˟h,l@!W$g$G2$(/JMU02vZ2.o<+HO]4j,1[.Ȕ$ytf*;R 'ʩpb t4j˜1$7iTthbR&)VySX(dRGSF6L+Hk{^祲/p*p'*S|(;UEW݂vƅB E l J@RI'pBjJt Bv<ĤN83|p|hQQ_NdMh:{+5>Y9Xw;39o%{o7ξXT}`ds-} >U '{s斱km o9Ka!KYD$l{D?#>Uw \R֫Xٻ9SIpe. ay's#:˂=UH}*;6$LA 5yNs#_1Xjh=X7^hnH|S`UNEniA#whM]:kYYYBZ4O"Fr1{˅EVMzSҁDozөQf hhL E@{7FeTҙ⧣6_ڑ9ő"3nnX) !{6&Ȟ>ڳlfg{28q+/(uo9Jʅ GzTՔDuC ^l^9T&v{\TI6 QLE{=7@z`e@~F B4/P)J._ ξvdwhJM-e X ֔S_oOC{!ՂDy#;;ΰ0n l|WÛcË&tysǙg%vEYmqwRaY^*WDS $tkΒ:}xdf6/mJx{ݨq${PLLSYⶑpU{?}^NEt*!)H2$o9 ~ӡL!%hC0*҃XVms!4aߓr5:gO/* i¦cpO|M֋K :b̑8F@I *fG~{Ht(Qa]2 !*oigsn6Yl-'y}/)Fvahr&*A=P68㷊 x> ETCS7vDD0kL_^1"2f/. 2׽9$Cls I2"\=w57}:L b*$2>XY|2e8O *lL>^a h坖w 1ea%1fi'Ph V8/͎ 5zU<4eZ* ` ݥX ,d8% kBeX!t(=[O"=۱U踪XGEUXhZHWCVkv{ i- ?t ffvZŅQYm'Wkힸ1a1_w(` +O}Aps4.ѹ.{+B Q/:i*1 I5/ Ft>Ed=ɱk.ǮOjڡ79?+ꚞX8#ڬ&]:{m|\Co'ۧqwK`Z(ۗ"q$x\X-F?mwcDm<&C$Td`Ճ>v5yp&oNZyQCR6. nޥU"}Q{ʡ'vzf(JeJGYZG]X%pEmƟJ RUØϡ"d[{1 \cajL7oΠa1@X;[ZASP -T^W9'ئR'rNq=FچƺbGhFx*Pr$[1[0x!.譯$oCXY<,JTCchI}5;eƦb8pb *b@jhdznI{vep?CxXdb*Tp, ݘ;,f5+ 6 ~י0 rА`D(hA:]}t^*{' W_R6).Bы14ns^F`F }q,I&,{7XaS1;k6ɚ?y$'[fp*|P$ԮPąΝ~P)J /4u X59P LzD.' '@1V?IS+1Q߸@WRAaTk!᫶E29^FӁhbU6! cJtbb!jT:b0l݈.5$pp&]3rUiS:4812T&˥5MΆUrg@Vl܏hzH̅+Ʒ^^k1]юQ eB(H ˳KFpŤpsk6S oy0q QDV06m0+ˁVCH?M5LE5P;Pti`?>[MI У8Kq!<91Y>Ʈ*Zz-vUvkt 7 st6Sܱݯ%uTŒXmYf#@Lj% m١PXD.-8C6?UQ/̆Ȅ/b'W TGKmh8[')G4U,ݦ#Ih9 }9㷭Vtb!5:_3JC5.h2m,O l.$j}gfmXꡣ|' ԕqK_ Y,,&P4/h7bR!)Zrj.!ۯaxxɪy,"+se5eՑȴqN?8}iE 5/y&'1t K#etxVYj4ExUa֩ع⑂ךyD:0-Kloய㼘e$Eopc)52Nnb#;EFY2pD 3A;h>;hDK}K hr{28x\V!h< ޵6Ý&:שI/N3_חDdje)1vZl,mbG+uCf ]GMpOR,sm3ZOm` )^s4#~H[Ң`S!{2%J{X*Sw-Cg5f [u/'.RLa2e+GJ>x6^ >&ۋ6F,ɶU#Yn[p;kT2#EX +]t\j $qkN]jOFM&</)aS{b؎oƦ_bS[Ibsvu7͂0qvro;+Fqr!Tf&CJbҰ%ip07L4dEzd<\nf IT;t<,N Q!Z(703)3=b.pbl3` ׹ Z}IzJ-&pLT'|q UֲA. PlG2AtA05%]d!xNlzL8xviUbǚ5J W%-/$ uΟ|ǑTi8 3%;%r1,ǢX/!OXâW[H Bv Xtv/']zT. ~XbxHz@ul"WrhC ⵠbMbVc^E`1E2I\s{EViٺ:4Gr G?GOn[Á_DR8Dw`6Lo:ey4md{nOt.8Q+u*%nkv6%ߪv,3=P#ռqkٵpC:r5ץvLqfI~ֱ@1ef+ʁ yۥ?g"*'*c΋Idi}ӂ|.  :';#˶_ZȒhycJ'Bg'֌ Ĭ!Qn9:Zt<$^\_ n ;}`i9G>JMwE 4sՠntT^ˠaW |-YPϯj.ZqAx=Fz/AՓ\ubE:1\WIL;왴Bd%m!2GT[Q2% S;xl);;+X̾E+6 fܥ&ˈT[! ^@`٥Xp4{DbDFVɪ<'~_itA a3WPVfeTF-E$KjHT? ҈Ydq,j[qw|@"Q}N{ֲќ,&i?Zˤ6o!]Q9G9!_6RR풚6vyV#{' '`zG;sÊΙL4 6(t9YB,N^qHNFmfa<ػ{InFJ$U/B_vlmtȭk!RBtY'~וW_U۬ J{# ^ޛ2^نSm$TPPl~g.΢b-tLmh2ŽTDbV:6Pdtcgar1ZO V.Zl"+]7d3UwΓdN\*ig4hTmE$BC#Qnz /yIdVfXb阣pRdv.Xl> W)7*⨒LƩu1YKQK1.jU$Km*<8KU.6UB#z, Hwd-lpF}/nȍ9t)D $'aD@}ߧ[&xvH쎞^RJؐEWbg`66њs>QȻr9x1'bQ/9kZ3j`LĔslrnBޯesCXˑ[Njt ֩m8wKBa@`G/X =X+\E>=26(2,w ڛXBhN-yБ)JJaSٺ`]whs=VbWwUWU0=Q#('+ʶ,9IgK1ϬmpYͲxX`elXط> <,|&i9VuGxߧOjM|SK6:Q+ $á`8*n) K*HrA[s[И[L,MDl>@>xNAQ֤ JXg 2eZbRkbx% j7%KR#[ӵW= .[+1"pY&amn>r­ U bu(аK1ⰵv{HݎG90vCï|h>O Z[پ:Y=ezo53wJhtϧSC<{QvO:fPNO"PcY9<ΦS<+Bҽ̒7i}- jT6 ɓ}@4[^_{ e[%X[4kO>Z;/Sړ-ݪU@g<ǰφv,x!tO_?4p(*ʫwhcwpU5ۀfRSl7|.B]wlD%_. }MSy8nNLBuf-5 B{9*Gkg,7G#lyG  FNͳ?0A`@5p.naޡY{@,QF*QNU˓p,SPt]>#KB=2zֹ]uGMցh@ rH97@ oly8(#}pųک5Kf#N)'pfNÁ%M8sm]9ɎZyZ'v B!alMy X0p `*APL|7hH;a9=ͯa-(cҍ{k W BAe][.!pr*QlI>xV45QL9r ,a5?2sK)x."jm֒\A#>{E ޵tnz9Q1s!_g)38T_v 6$;j9QXSWтrQ&-6tE8= 1xaEq+#RQ6G#%!+e`- F[Ih\_V߭^Ȏ(ێ7'V ;yrXPo@lh&G'R=S_.4?I%D7T/Qќ#SHIx:Qkg9M/R?lmsFf9p; U,pyn+sgy;xj')\:ƜCBCEF-MM޵&1"0 \􊔀%""ēlO E!TM,PR\}jmQ6>q{ n[p,؁Q|s p*#@3`Iȡb>C5|sd.JV N}Oh X@гqzஃg(L3Nf [fCuvjkZCÙ_MX+n62/m%Uñ85&~p{bڃЩ:0 o.qD%DDSm^( !-|T1TgdJP*x2&cPYV֫ZD5)b҂~xcj^6HDj fdApmhEW>uډ(/dH#YT)hq7Vvz bD},/kH3h`DYel#k٘[bl|~*an v-Hw|g6HWg5YW\n B&VD Կ~[ԉu8fbwm1^i.?ۮnrvC)E7ҢR&%0T|Y%U#kyѧ!v^KhxKԬ1( =|ڥ 2y-,e2OQcEP8FW:dF+Hς%E57] bf.GN?GZ%jӲuV%P HX$s?|z[^xݍ@&PoJ\-. M7GE(%ϝ16zdWݙh@BX_bMSV犢"ǰ ˆ OWlA1 41ca6[d] oz KrҺ+oԞ,Z]v;pLo|$3̴:Cx NE ` X4b;3&^IfZ2 kiQ \[|dV:ڼ/'"oEȔɌ36~&WKU.ue s25ϥ3Nk ZڹɑWl/ǯ-FAh;ko߈l$P+ { 75ޡ`gZi#%c^Q"5HMlX[ Q׹q <~6ЬZsk&bp--I(l}!spH"#M~VF)A$d<~Mp'b|Kb@1 %WT- u;bK_iDs<t tk> ?L'Džyf}+fݪ"*zB%Nissegu1} WZV݀Θ/wI $T&EŠxJcx#&aΤS )>1us*abc|G;edZ4M5'M4kL h8-J#cIipX哰xXf6ƓpETd;>4+-"YKwf]cҩ.hZl}@q-屨K$5CTQcd yT}sYn %TFk&^5\睒d_[Q^ }w{h\{Bm);k+,liNCovޭ5Aެw,W2iO9a)S)+!g8$JW#~>eCyyiiFdb̛Tx$G3&ꂔSl =gA֕f!^+X) rq}R2'JN9 )6JqS;WU+YoUu2AT.[QK`(, AM"]7FR`eêFCz_3O3cW'˄"dd Tk0u#ѯc l7xl8AC2` dD$MXA~sh%%a&e|m=R {(z_wȋlΐ-C.a@ M/1ck{uBԶU XQ1RXAjJ6-Rgz=aF;k6JEI~K.yw jE6 4-H!] Bַzh$*8[wa-*z#gAV̟lmK2P>){iר2eX&^+(*DQө~t;݀:iVPi4qɜ6T;mjT3%6xQ'9yCc+ <;FDX](B+lR'TCU݀2-@ǺQK\EPprT.E ,PZԱe(rӽ"^b!}+ѝn1X~R B65鍣'hqAT!)ZlKAp5um 7A+y$ʇݕ((jltճŃӘZXf.4<&+yc& /[i4#tq8 ɬ&BI[o]ɅzoZ7B,O(hxFO~ H;ă!Uޡʣ[hujgaNmjV(=8+x/U%_lWU7$(h(N 6[g__+lɥgxt6p/gm'S_#&LȺf>[aLigS;,?I´<) K ׄ-a  yG *gsnZi2Jg QiPDx'MnV muHSuzIie!WRɬ n~ j+-V b\DhDT-6eW6\VւF)MzI'w:["2-|uzkT5^OPgM>A5ָQrz9&f~6"ԻsPx?Rͬ:az~K2Nu^ϒ|i y]jWdGR^P$ 9$IFTq7+ƍdٚ<"UULvJ! DLrIŲ][" ֲBt Af Wh8=â7\Qm{!iK:u-Q(YWVЏ(A˔D_ )+xJN\PF٧"uҚ5\)r?ٷo^^_+&@ư%?k MKW"箦从ur~ae6N~р*1P)C?ZSDȗlA~GФjp-ȾEG!/ L-{(MP!!–iDHըWlU"rp-U)VI%~R*LzzeU4S},ʒ7@(4)KKs"!|֊Pby_)mG2jѤJ3%d+_llOy+0՗{c=qڰ@ ʈ^Y3, D7^YD#p- (fupy2.I0 i Mg)cߜDenAG+DEK@ kf ;62ᶰXJ(l?,T@u$Pܒ'Ԗ{W}nO}њe١}R>4p%r+NJO 8.HaM)dN߄ٮB^:R 3?e7bvREiatb+ARH(ҁsT%K%C^ؚ+Mo jTfJA$锿$uHG4VΉ%[[ޒ%W;Js̩wLGvcCF˺ Y|[RsP#Kk[F=x^@Aq/V; X2*ճHkk;t[ȡBo ⏰^DLTUg5 7 FYsy,6YAr"ڏ4OXhbKƙiJ7Xmm˴yIbA$,K$4" ]EFkm=1Р}ˍ'Wj 4 AĴ4;e= f1Lk'Nw,;/byz@M;Yx;aЊ5El#|p1|u͊JV~Հ8{5jZZ=wĆڋ:l%n# Y5聂BTGjWu痦]~c( =0]k<_Щ4R/'WږQ]z %Pm=[&5_[4of6/;+gb TV\f7TBo`J2YR8RW p}DUQۦ*-!zKTުӿEF+RM0;<_ٛ( 7Ցk!?f'w=%RR(Ny;t eHF@L 1 eP(a(ukq-xBqqR4ͤΠPD\XʽUF D8>N EZ( ֻu'B!֍*$n2ߝZ <Y=uI'f#4b9<-xk\(ff'ǑW9m{KEUGRđMYa|u #{oNCa`K\ئ$a$BQ7{i6狘$Pԭ;hQ?QʑziذsăT_(iyk3,ln,& :oi, aڦbZ1YS2::#q2B,`Y[aH({W%g3i4\/@,σׂߤ CXEsnw5 e6ap>p4MKb_;G(Jϵt GÊI4Aъ:_-e. {+M7\QcA 9%a!9 fW` X'e4ֻد.̴+`-TҎljIU/g"Qހ:Ɗkb#r <ZD*:YA Nͷ0+E~ޠ1|tjkJVηu DDo Ң@&s $IͺVy4z f \h9bnHXP43S)as) ~|-jHp%5X H?iy9Tq{h69pG͝Wluf+6ơ4N=^Uw}*NEHK+K˖FQCڲT犢5V+e[\nƒFO(&6k^SI#X̏<ev$.vx aA/R֓5qőlC0J`:lLf(8TU녨J&h+'%C jz46< mtW!FVrmԊ۶BBG,Bզ/c^ɥ/ DFe * .x|BI0՚4KXc=zI>ߙ{ d~s gJ-CPBH%@U|vF<*lga3o3"'>l`s8N_[)7(< ;/{'9+w`+IQ % Vk.TTftc{وBwqbdgnq]ދֳJ%l߫˫g!ѐdw'I6wn\_ ӛӃ?yNkx7kC\;o%28U9As (ߦgnNW Ɇʀӄ:S"K6rdTo5c?.i1i]4xGKy\7+qGj$# Us?ڲ̬XW c-ŽX^~0(*eV7;xDc垯R;pZPm(jdZnM(Ǎ%Sk7YE@։]jE65dͧ3k6-u}ѲvGE7Ӓ X-ITJ;I~6V&i1O0 $a9Pn&@dp^ 3?Tn^@YKa b`k2StŒYY黶1ĒG6UN.gG߸h85]A*UGg'Rb 2)T+]QKg39'dγl$Ccbxfi~4$/bY P Ab+r[.H k@$\0,6z.in[rmjs~dCAVՌ\ C%t&Ubͣ0pȚ ꫥ0.}.<, o oŮ< >a M0 >dPqkV6K0FL(f pYl &]~<=[RM 0Lc.v9b:jJu ~zU!*3LScT.Ωdws>#OI*,QRRuQ)o=5mB)1u?>WF,\$ɲ¦m`.g$f_\}ɕ-Q"CGY)՘mIOT8/4'QFvi YE5ߵq ,Xf|Ij@[ eg/پ2:DӸ҈Rct;.jcMݤ4 /'^:E+JO/2;}*}u '&<)qOYE(h)(' BfNh9{sA`Oc'%l_5H+J,@AϜ~-c֓ HYP|trqT}#NRGʧ2)_m |#oh@n%m:Lx?ul~!ttwGISn3H1yQ3(GuϚ`$O$WhMya`f-NA[/uK>x rmуRVu=8媑 G4/d7L2CfKZ_ 8(7= $%q qE2kOWQcnZRoL]VL"0(+Eà@>^R@* T] PX @{߀WAH2e\s6'r+ռrc`;$UeDK - έeC41c I g8y* ~?;x ~?yXG5 W뭼r~-hLCAnmԡW8JHS7y '՘_|L KOY]Y,ZS7{eY!xy4蚽оg*`: ݢflY"J"( gìRJm/kjq^7}v ?YzssNQh_3 1;L5[HZ҇CT?ak;OtU*w|oʤ%>@MPCrةܘ7:~Iw˒Ray[ inlfג'v$Lv&e93}Qg>uˁz umoT#P4W7Ndv]9ٵĩ) Su~=wVmM>0WĆ'ހR{ A#r% Us7㥦 5NZbՎ4vy G))Vz@hn0zUz ,#$C#vjl޴TJ`!w>ξNn"a!ܣ6P c^0G/7ORs 84()GE0Uɝv5;ɵOaAԍ/Ҵ󆌀kMϴ%5@ \oDDS"Jٮ3vxLIiQf^:&W8}/,IEKIUSΊ%hd“k )Yı~(h_II#\S1Y%> >_ T&F1;uMV-*ɮJ3W PkV:cHѱP*:$h+@ml4pBvzqZ]V9vG?d1zIb;p]p=2@XOuWxg},,*[觿U:Y\^{DVr#/{ُddQRXM6 6, G.IV≻ʽav8] 2 <@xp%d??C ӬE҃hswןx~qג0Dyl9! 2`<7m B b}DVW9O\AT'l#<*mjKꬊ3O7_JCّ;+ 4{Z[VAfz7܎"EZ2@nq%𧌇[@:qKӳ$C C6x!jtofۥvu&-mrD8Xb\6kk;@f )󨎂{yR'Y5>;)M3# Yo$V) ;ȇw]0x_xlùXXM]_oOs,m+>LP  Q _~a`90)d%fcīX"ɢJ˺iE,7IF(PqLp˔/lATgcnfp~T{>E_oN $^F`]aHE($4 \jS@\L(6Dr<޴d7Y޲8A1ŒP!Oզ"c\w],t uWhT_YW[Z%SW 隈d_G9C/AdSڶ$~+v5jc?;ՖE( w+2:@J~kLa+I̖q c[3ݼ-u/յen{+^ HT@Úi6K ly#vx$EM^ =L wD^+BQ(ƽX+{5Q^=dU~4q;/2{K3]͏Q>]"l <qM9rl= 5 Ct.W7~O-gsb5RGqu$ba5J{7F|-jm2\V4\!,~@\܂^t7ÜdaxI[$6u,-=),W=%OF?";{,28 Ι"PCG$]rqjRx %Sn I*nZۄ"h"*)Tg6^ W9oYBzu+Iy1|] *lp᧷Wء||,NjEA ߘr0$nMS;_3k~|"鄀@ U-:T9h;B*`0qؐf2q5oȩ 3A z'0rru7.|?oE>&mlGp!_sH5,7u|S'Zn ,u\EB"CkxWݐȀㆼܦ"Q?H}R0sI>+2V[ILXެvG3u>S,VNTgyC(m*e: 2Ny9/X B]X̖j 4B dUWBwlէN+rv:lV]suJA FvV}v9=) EU?;biD(F3ףrbw2p׫*,}~,8@;ZV|W\|a0MycB8/+NyF|Pl ñBo4w.uU3BR"J:V[A$rT[:uتJ$Q(;X%!MR30N`& cQ>mKh'*1껒@=` oyGpv#S];9=ōOM&X'ӣhٵjif<J|%s::&p2 0?O- Ԝ$ uAtNK&}CAآnnݕ fce "(,g##Mϵ$ujl h#I@CS4T Ru톲`W֤e 2{dɨc|׫x@l|~F湕XF (!~W$rWƅzSik$BF3KdbFo|B}^OI.PYlfTՒM7}ݥŽ9~z6٬wNP){R]XIouRmg@ѱy.r'SUf @ld̊󗭏ɢ[meC"8~l-*l],  j&EA2Qxkktm}#8>vηi& /NhR]m)^(39!~02mcSJcM7yh6R=ArԨ  B2ł.6޻w}ϳ{=UuYP٦PDVgکt_:Y{0ɎL4#K}ɛ72k̪zSwZԭ]XlHa 2 m61Ōw?|lczqofeUWk1>On=9C; -B7)^\VL'.JD_@pzנH2Vw~ 6wfzLf0jbq2@8:Y慕|Loy{$C2 2ivyσZjN-/XnkjD§-OOt_A~>}}{Y]~5c^Aact3aAn0ov \ oM딿}k#o{dPh}}g:׃Z㵕l~]gZ'`qnq-y{Ĭ)@=]`~B8 F b1>=N9,:MsID,9yg1m?Fࢥ&A,"ywIj~@oI@-ŕ-ԳXiݙC.'P(c'[u4oPm^ډ=Cq%c#Q ҡՑPb#]{KIa;`,\ۊ-Z\N@87qy)y w¶fp5id^P%F2uQʖuAHqm}fd\Ň.v*Z/-ʾ-ĻۚōPku0٘bYL4ohVs|䔡 H7罫aڞZ`UXD L隶R%-N_˓Gqn*Җ+ObsքtuVEi"#ɑb]DQkaȖYQx:s"nvWKv}bs;O.]i2J{2MjT %bjp}t^A+ݗE" =$¨2c}"o "ͬak$̳m>;)e5ͫ1WXߏ3}7yN]4Yv$=j$׼âº^7D]N),sRi/Cٖ41'H=Gd\'CDŽQDmT>^pW'P2!LipA_}I䯨>}D&x~ƅB/RBظB;+{xUڤ@iYG&zI2׹jEDZ%ʉLјl$M8f7-j"u:(WKf,NOtTOj$":_$?2LVGUw 槴*mɳ&W @Ed[kwaG:] !< y|uAGKP&]?6 {GP:}eV鬜ȃ,'U؟Yݰpe5W ]ĕ/?s3+dDIqpR~F*$Ha^Bl W:ͻR"H3ת#uJpcW~.5]g>wOQUHF'rЂP pu[JPljlPKZ9NzVkƓGRTڵ|5UW pQAQ^5?l#RW%ݿ+|by;oci\7#?tzܬvm0;<س<$ zbREfzѧQyR\[ 2GK"0~1(FN]x>!ZXnZ0^ j_ T2a#@sE?َikؓ*r:4 Y ˩ гm&2ؗG#ZN qtW+р3uB)_=BAb =b܎1P*;/q'8ʚ_#:9`"gpc2Ew[X yY:S'H>`=ۃٴEɆU31<$(TjI.ZJٲlQKLJSɶ%k:@2DT`ˮN&ru )v6 8оI$-qk19oLk{v>|>[窣[ıGKwp=Tò#0CD[hЍuc%Na鞡/ir2JYxPjܤYZH$u3/xD$DNuG{L%O*(j #T'3OZv1=:t''%fK]vDeIOQwԟ [%WdW2UJ4L\X䘖yf9NtbU.ZP2Hމ *op4%*r Ku)ȿaI!J9_G/M}UXI!3VTtfPH"AǗU{k(Pw0h/n{ Gݼ}6˨V %hyeQMUjl^;MWYO-U X2B qm=Te" Ю2+K1!xo8x= 9☆VojbId,o7[WpHjBXyNUOWUS 6wr5JyLs+RU ")WSe6MSN$Z W)"ն X;2:`:fs-K9gӺI%Gm.C`1nTD_|D*{~nյ/IVK !Iz|.r\؎[Xy :Ao9Nҝ\xdCFI{{d^0J[Ss*(dΨLa?UHFCe͘lkڔmqD/h_F0-mB5eM/-\kMQga W$sBXchWLf U7M7`{:Xf|4Oy k-Bv//]GN*A51X{g=hK5N: sU2+/2$M5VQ)j8 0z!# i#8DgYðR88ap,P*FBe}dr;]wVOouN LMpbo=2I/o&q G{)71"D}n3X+>ՠ9?R~BŢ^:%IW疉~8Oe$H U@R [s) xmbp=HMt8C yWp)A8y&lz Jri6r^lm͌0vm |A@Ovd,5\.)O܇V V#r8ʴ-Յrfg^XQixҶovHifn0<R2@2,:zmmSt +@op\a;-^M_$BNӌ@7NjmLYjTB@jI>l/j^-5#o)b稠{n[7waӣ][mG\<l]EyXCF]t3s5nX_lhZʭi ݊@\_9qO[2Grٝo»<62(!$'M0H$Dy]j,w^%kK%Q٪I.nȕ Ԭi<4A@!"Kp)&V`5 88N/ ,{6K~hA3WL $șˊ43G~=TS6}\AݮJ;?ͼ9ŅIaa"j@Aӛe Uq;x:=:.VeFGΊ`YpgpbXx\(~%HI|#0m\JbjX9\ oZzt֔ KVYFޫxH^0u&ZpxR/!S'bYt7G2r :rm)Y[0ԱUf)~Ay7As\7U +ܔBQ?ml[N`f3p38sA^":JnɤA;e! .̃乳VCAEp}{uT45\s<[Ae:XmqLUebrёۿ@M IZ~իESv'.JqUUİ T2gHKeB A#A ɷ_,:C<죮/{>g7tǀ=s~4}n-l3|iiK rNzH4u@թ"~Cqr*)Cgf9l4 pFo}ZcXs<AWe$i&KΎx0[sm >_jptVLw0`!suL |`GV tt*NN&{ު|[ F{@۫Q(T6*jI3́TPn)UP"M)k #jt5:oa`P0_nڠ) "]$JFV@[L&đcx3L{KLF#Kŝ7hFfd(E#\ev T_ޞ⌷*]SGSTC=ΉK κr~O͵v=HhF<e ʊk7&p~SJ̍֝ċ1YJ1/Fw#$}"÷߷#RQ8ȃljm[7JM̃j{Iuj!֕b;61i%CȉdӴ @WX~[Zї?/s%O JdBa|9g15DCR{w08"IKd]MХ% X>BG8s%Kkpx:/KdekGCHeX-,Hزl1vcawlm߷tʗMoTvhk*|Gh^3bdʙ ^OO>.)v d ccM;)q>=ХɁf5Y7?rFȹ-6]!pO`+xC"$trOi'%7% ȌhoGgG(Zx[cAIZ+b3ήvU"@)CADDYޖ8EA~v>PUAs#ȅ#E$TO1Y=c,3dLy ݘM 1BI:&0^BHN ĉS(YꥪFdDL0Pܙ͙jb-܋6UYF %2@fe-lj]}-׊&MZnK$ې7aLo*8*iƚ r22x]X2%I]; yU'FbEQGsI `P-r#bv&?5boJ%GT0^C4G=^4QAD~T4yCO؀iM_#3Lx] H^qo@g>5g\twTJd;T LW1v TXEpHKޭVaٚkeYT 0Nފ5-9Ivg4۵Kx>[Bݛ?2bϬi>h ғM X:I3 Y zJ7N[`OY,Bwgv1/ z#{:mڪ9_K!;{6RUiCe"?;YfU~L.8u%GOŞd#(PIntKoK\H )z7篛*b'|mt|yeL-ӥRӇbw骡xFw1( Wx;W$&[jMdGuJP$<>ޜBwH+*'&8b } bN ;<#$ $5*|n=v&kSJ8) |fs >]sj_#JZ"H;H;VHz{խ*~VU2kU(8>Bԁ|ccV]uvq5K^ t+&d55L{qX4g'VDVbr*x̤0E5s)nׇ&6xZo\95. e; y)ud $&+;׎bXX`,;_D_d:;Y۾cZdK lgON 1M{u/E+RcFn{;j @$ Q,uwGY.X2-C6]Q]d ْ^Aq-<1㐏 V|깹Jr xNJ9c;TOo[?}uH[QԞ)Y4J2gf>=;OA,9x:d^A>s+02݃%{{Ϫr<)I#X ;Qdz&L=dip GmIhWjNz򞚟GnX:G1cN ÿH,F߃7P紖m.Fuxlqb%"7T1/A%Rl c]#/<#E ӝ5'T !ROYsHq-]b"V⌽+brYEv0#`*y)UE*tql $k خJFE (h+%1$Εz"(ƴxO42s$l6W+]vu~jjcN 掃QSކz=I W؄.Lde>_hz_\XH<|1"TJ뵕3 wo.8GUS.4}̈́l}E_'0aX#yKyYrq>Zt4 [:.x^*\2]zqUȓ0˜'{k"z#Dۥ#wϡ4S[+>`:I^L@"1FTb?7+Tkĩf *Kjj&ĭF ò$)3+($AMᱦ ͬb[iG$3ϸUHYŲsjI_N~?>JC2Zτ *FMܳ>lesZHv_;ৈߘy,eX}#}tјXsqqWf6 Yr !C%q?=gxo:O$4fm@Բa ӹ7htNg<5:jL( ]b<&H?jvs)U)p[wTߚy*>V+1VB)]7_+zb&:_.7Y"u4x~ .=q55JtzcS$bb9_jMaU(gg:Ad.ŽQE#-Hh8jQ2 R|0%xOSclvP 88@Pon=@B٬ƆA\s.ϜJ(}L\JA+D$h3 Z g)8]Ҡ:iC;Z@[ϓeͦp|{Tt4(.CWV)(?Q@Bʦ7$qQJkr1 "cJ<@=o{kMHoql/كAU we,q =.c,I~k}Vx>4>x@aߟ]R(NTi[ _%`2xwd/vِvM`Je; 6qmPxVߢQ}@_r)e׸/(yk"r" ozZ$ |vkܿ .Dr=J6U Kzp$̩_@ YqdȪ.O ZсB?#Rb>Yk3M=:,ZW]UAW:t./~&mLw4 zX"iFdn&cn%I_T(ޔ /3V>4,s+?QH2jYx %f췿%*^&=cGN ƿL\xR7 \=r==8Y5ҾS O td:6qYD/BeJTHOKn1T)ʬe>T-~Ӟ _a"*?Vuvcr֐Ԧ`93M.+ANr`"gOѨ W8lLs jI!$7 $LQ3>HHZ<DO$"XAd`.KFWz-4}Oh-'9+.:le(Fp]cޮ%l=뾍\EryZqqDxʀ#]HL]Ŗtlƹ=:io,nkEIʚ*T4>{}2m4C(Q~) (쮷ߣnGL%sJcv~Jj%J`i &M6^, c'#D9'rbLZʒU+I TǓt]:[:6'rK<(4 @Ѡ$ A`ƫqIAY&:IrGh:oy`ҷ$ jtq/Y[$,cw Xe{]NO\"͛*YXyd6*˅XMޫA5!0Ʃ֎@= EhTx!Ⱦk"J=dʍ|A ({ A]R.. `O.ʰ]Lɼ#BMX5wNZP`^)Ljl|;Mkl.#j8Y5mNܨS3sĺLf"#(tfEEz)W-Z\YEŬg+Rg[cX-KN6|p]' u;'RC!ㆬ +t p,%qtRʞ<}~aVNHaa%2{ZO]Q7k6ˏ] Opt 'E Nlљ]]dEHd/niH0ؼ|Q wnl'#*kCBxCE#zsO4#auh37uxF[UyJ)y'| 3- l嵜ey p7E\T/ ;on^H0MNb+Ui5|O!qqEN ?GDja÷|,\tsqh֋-ڍsK4E'^9/^x,[v}K'j#/lnZ1u7 ϲ UDJRp T6Mc&?&4f@.U.f{vS.v{|-q87u<߬T9pM|~N_h'7KA/ ͖q\BX7̾^IqzçY'6yB(GV(YܠL:[0J֗416XpnI_UWU\DPS; w>3LRXԀv XH v߯@[.~**~a.8:%:]%7D=+c Hdngr3` [M֎JB) $Ԝxj,;&E}yG/r lJ{& fOܚ[{r|޽xmqMk ױ!@) ?zA\fG ֛jhJ7lUnt錚MmJn[٫=>vOIlg2$ TĊS$" fU 2jR A )Xv3eʃ*|G~VL5: I8;h;r {/$(D T/[k.]pt]C8Ir9M~ $8Wω߼F8(VōG7g=lr¹NԍO巵눎u/:ѩ[r$R\ɷxM{zqLw -OxUE3u-9K]I˙ Z@p]LG1kEux_%e)_,y܊"#QPN-7$[rj)ԐsOG(84Ι&ʾ拍c lӋ21t/XUI!8N2y8#9LLd7낇p ڋM y*6y=[UX&CHN6ːS.-mx >F.Zpvi1TzS UwĢ[_쇝ڧn;ˆ*,ӻYA Jxa=[]yR}z+f&WXg!Ut\y,i߃*YcEa1-NR҃X)vk>f;i?V -1Df αK%kJr$KGGf\ KsmŎ<60B_S zH*83: $Y$9zU #iC3588.{&R b&Eؐ?$+suG/ Vsw=gӂȝVz8@`" jKT?!żkS ť5:ZzIW!2Vs1;_ȋ="{yԮ l&=N{Voſ#a<*j=$wcpsוBGUf!R Qy|/UZլ`*غ&K v!a&">(H̦{]ϙֆi3\kSrɪ͍lF(U>śK6/0;op̿`ܲg ܢ\)?L/9\I7wv,g9p Բ{G2]t[`%1RF#~a!:+.,&\' RK"IΝ8R,43@pC[Cʂ_ko'Rd [ce BVga5nl6۬TOxkmp^d`Y9 "3nA҇\sfcYa. #4D0# x)փ̜2Uh&ApGH ً(MϢ/}NMUapD;4Zkg9Oz- F:"sƊ߻["85И+לCq.| 6l1W_*P+"'5<3iVXW.ܶ /}^Ֆutd8"3} e6*!AmS)ߨARwHƒI*=Zy#~=t:핍`.B:Z薲::>t`始ùt Εk)PcM8תݣ)ꍚ* FҾ"qCü]uH05\oUOTt#rqe%3h+&e/-n4Y-sݷfAQV7]_Md)wiw3*׊+Q/hg!J?\BB/R++e©rJkxop/}얥џ`k/q7Vkgv/N@_Z"xM*VF0fvicQ/d16ED窽~TU~ڵ9 zxBWU!U=d)%"7k!h=o"púD#q(e!3łEϞ%77ɲuGٲUJi߮IZ&ڠUF+/)j6Oі[Qݎ.ir&.+ң=ɿp_/LUu7E51ZDKW4>3̐3߲S*;Uw2gw"NYiYYcH Q42d,UնZ"U 2ةN@$ņTDIʃw=7r[൤gHOr\-CT"|mB6 ޒZ(qKpBmہ%wS.R LN4M{)и&Ob\s|fv+6x[ij1"#1_fڇҁ ެ Tqx@L9 :7gGzhvm\+!wJmcn'U{#q&q@wpt),ϓX qLG'ԖqضSi׌2c\%Ä 3JTeQ->_?V|lFg{"9?ht,΢ [s4 RbmAe ;DK܉OVf;QDJK^;S8c ۏ`e$_]^Ds @Ij]]ʠ~@^q2BłuHOFKѴ&E{^TLc۰|#?d+$N$?h|̄yQOu*}`j5gA~1%#%R4JW=4$NފX1QAbE͛;_ q蛮٩g̮9^6߾_Y=xڃ{:Yc:}zh.Tb(961rv`ܘQDvUz-|PёVBkbJ3<8%s|9dF5B:vU~Y?RV210-^\"~x~1{m*@gi6)3H-]_x_"d_^a_ίm4\NVmH Dә@MVIC.XעxPS{4\KDt8i`+5Xʌc11-%;kK ? t׶+1^^ٖ$og0ֳ4֝.KEpԘ>xhuȬYKEȞ3&I|4h|F?M*ecA W||v@1w :3x +W&ᏂfG֢\]$ 6EВW #dkD,< $ۚJ)5c|#_޻%}Re_IPyD/! ;PSIEd-51˪Eܬڵ+LhQ,cN"+VɑJggz[Ikroh$ lE# :k o6O  7). 0Ue(F :^M*nwC!+s Y)j_(8oEʬ(:1׈JRoVDeCx} C܍!G ވ+%Zf7( z<f>9>%JͨwRew\B (|07GSE&{pir6_7:r֭@aӇvpdudi{S,y82BHqJ Bٝ뚦nBq;;~rKl'SF韥qu4ӢlR )K >FV, y§<創9{w]=s 9s ߶!i}^W?xIll^$E~g}DτX8.Oڵ6 q2jCCm·˅XXpHcYKTdf/7"}N4ү)krX>fmжhh. xlN/VJ}TS,KB=4MW'W/sT)x32B|p:tCjP<;_̥QqQtduw45lflNW ><~>gxȠc 0vbȉ-HUX# gtc?.;>czUȎ@0CJy@{}*`?KQ[n~cK dxG~O:5kV\7*rϧfK,}OdH͔ l"ߟK0xT].N!􌋂7B+q(6 }PŜaM}ї$Yq)CQA]/{ ux"^ε,V|bͲ۾|m"AY->9 /X)b%8~ng!g$#tA9#xYAq:+*DOLa7PH#zT*F˙f?U_P/'j*cN"o}4'ݦVNfc߂4yœ%Xѭ,˂$N@ ewkhYk%S/2lmHfuh%/SJk1l! ܰNsD>|EGZI`^4 mMy}E`©4w9'd?I⃁67qvف[ިN@g? .GD?`3`^w9/jIE<[ӆh1-o&&RhJ%(|BjQ-%3x1K5hy$(Ua+j9]`c K )I3y{8ٺ@gdmG؂bd :ǧЊW)b|)KBj]Odznw&^/-kիH]|ճ1t< +,uFJ%a![،ꯃ\ T9O-Yv, :/, z2.є-&SJ15*J\J'gx(1M %cij%Xn2- жy혊̲4dՁfr4 B d*>O΢ɴ BM,%$ "0y'-2mɲeQ/95خ خcXbV&vGK\LyŒ(LDϣȻEе}t l"7NG^!,:]b\VYaKzHY7y=w*PsSaf#q03٫@eВ8Gs= RK[xO{HsMz~>*p]s۬?U>E ʽe<߼;a =UAzt#c8 $8M dt3\o):rz.%[Wh-b1]K?I:~]i> Hפ wABS4e&%sUXā Hw0!=DMNuiU;1_$3+@a}O}~smWQ]۳O>Gk{G@|z- *>OL|^繒8OlE>Ԩe;RgK)4^*b;+ycU=Kkϛe{t>scڅ6v#LJמu.(O~>H0߆x8>;2 - .1ĭ B<4^+{k68) 3 Ql A@ٚB&K.2@ \b*mBYEdbLtc0fDv&R٢Ȅ4kBNՑQ.$86d]3hA6_OAheLy?iQzIJPi[rp$%3 Lb$)XN 0oG:14$D6k,jNnzK~ {;@'|oʈ GMD*jƀQ:x))>>3zDedb[pg0p&60MSw~9 A;LHxTu`✬tVRZPϗ?5%}oi"&F!\Yj3teEoZGjg㖚ù}a`׾cӵljtobT0MzBVcX}:1*.SgM1 \*ҋ2T'"-el띹SVڳ@z**Re<xZurͺv^`nJt$hsi(4Ol=DawPV Z]ll6 JRQ\ &@P'ziajD5B 7E!o)$QtcSNў2u菸 ~)K{x86PTAHxsK5n;4/LT>h7{15~-R! HRԕ5Y"l/=$ nU?HG,q^p%&UWjK&].oR+<o  X~0+t*m\5_TOxJ0.lP^l%/0bV $dC"(\ +,貶^H`pvo63ADpN^JG,"jT'k1OZBï(.љ1"SU򫇳rV p#%*֟"("),f&s Zq!65 U{&Ųt'RDiPZ}sLT?Gf<+ֹEUc݉LsNj7W;T樒;qti l u߃m9 C(SF;#?*] ޣ/lvmt52ۏ@ -U.+m R])SH7wUfY fST⏡ fTc)oQGqw%Tgo5#.u:˺Y\ LIMzȀWj.LJO/#ȋ̧!,u"I,YbᐨWV^%6L$2cm|aQɖ8!ek$'ORt\Z\qL5srّ8 l_"\#uAHr a3Y"ʻEf=O:z-9K}‚KА\! 3 _Q!-$_&s,s wxlռVs ͅF5q_Z@6rk3Qk\ kq=C=~ԭ#sxp,U]#dYC!鲌iٟ8AVב%d,qc$vEE;:P˺[/ibDcRGFgH~_Mn-P} LPʅt{fNg*E+BR+A.>4=-Zh ֥1$Թsb(T(p%i .i'sT1J ⹽ nSh`2?^8X/)Zz{J noc )$o^0a!G$C=;ͳ 9F\9ӃܲLu(Xwl3#5R~2SS\G,zrUix")bw()x DjzJEĞWGɹ1 32nh?|op?gb0q NgfS_TAӗ˞%^Xj{TV+`Ba4'\t?Z*JV? c>TW+>}R1,2:+xq:>MY 8U7̔%ҫ`%.Qx.x%D``/~0B ]\-gN[?y:g #S /vKȯ9*)Ԫf<}M8.tr\VaBikkT2#Հ/d,ty0BK}`p2#g 9UÈ'X& R^|ޔEk2kӚMhd.G-A~qLSQ^9fok-MZ8æ84znI/kRkQZ̍YxH[PK3-@1{4';OA|2MD҂2o hur ͽ--VaMdCXr)'.TT^pfOq ƔGf˼"ダcRY{]8MW,@ Fzܴ[ x&Qrl_8m3f\yg)sиb1W| E|?@ldh-; }ل=7#=R~څ2$Q'i oV ,VwLm-cSc0a^5LSn؃ ^]I0K(̅ wt)%LB)]c{~:z% 9psĜ@$\">o1+燠%o#Lï+ǧ:1-þ̯OSVH.<<:NwA\K8.'^Co2ĬF'p… m#(:{T[Da崔?W+Eq`i6vd-kpֆqhzvo@!Nuzq,Y)UY*KF=o g!Apgv1$BJp<|@;Ke:s A|S! @:1mmU{Ywi 9Q_S93Dг&zdw(gFHw)[T0{q֟a43&'׈-qGU\x'Y}ApQONX"h1^7 Xmk]d/9Iޡ&*oBݼJV7~Gƪ@Xg&UC X1Tә;p&K$kNHL65k۴BЩtT05,7L|R\; L-40dK>~=C;3^ -s HY"DT8A}'v׃ÜzW K(h:XiĎc^i2f"@ 0Q)Ł{n!ji&:&N|g0q{T OIwCtbfuMA 6zz5PLX0ʢF EAUTu|kp:y |*%@њMl\d(۷h?< *f,qx#MQ>B1|gL  YE])<,uvRH>js(NЩn|9UH& t>|fMK51' 1z~ 92Lq> N1#V4 UAq5Vb,!㛌6n z8/h]5-ŠQgՔEIb lH%2Fb+BT{6 ƹ[KTz-X<ʉɨd1~|]ȗ<6J$ƃ*>oy@ZJj"߆ְ?HdTpDwC#C Z%v.bFW\$B ^PWmyc' -t%X;lW7 /s^b\R4,ڥ4Ci 'Ɩ\,Z(U^G4&ii% <ڼȰE~qqpedsciBA31k䍔Yd44)ZjqS"'$Ŭ@yDF6?,"@PJ-[HώVH u,FjA:KD+s~N($uW~Hk Qg;I<+T+M 充fxN aIQ%^(%H/+ L砃> -lb Ogltl%ER(AVH =X3."\R uW5Oq>[,LSIv'e%vkX;y*η^88dp x$~M umjeCuMmSאxsO0!8z,bF phM(&p|ȢJ,J]n6j䜘bd3saJix$]O\c*R.jR-NxLe yE$|&(S/,X?Z*XW[&2< t!0-WU<@_Z̙"6 AW$<[K2% $%ɗaIM*W e |plϸu4.1xP@BZJڝwW3-M')!2}&v9F("gP?=_ٶpj>L3IJH2RN-*ݰ\'І ~:~cJ)yxF ۔RTvL BeLD :C~]ErΩ yE(.0a*)[_To۰9 J܃WZNwXx`(@LէR>u'^<۶5/GU{wp-L$) n' 01۫07w*+ƒ@ic'=YQX9c %UݞSN'cXW' 1uԘ8^q}1Eɋ"I%.4 0/kx=GvtyÅ)h6YK筰Pmdc05C&w ކU@s v1.ȍI=>BVpS*8^M2qJ٘-ϐ+#CWBR)m`U߫q͈ x9R5etF}x9ِT 5 jeTA= ዇E=<6}oT^FΓg*Ol ͝bSМ*NVO%=*66Db?T#&'b1^R\X>G#O{bɂC.@rr$"l3mN0? ) Wr,D,) jba[DQ1RF߄#b {s ]LCEb%1]ys/iJTwt6g~4ׁ(rBܡX]3H>r] 3y(4L}UWl,t4064Qϰ,CP< g:(a 6Df:5H P m 18].;E!O)B4CSBF:9¶дYKCE^a;ΚWr6Bu+:MzL./粐oɼgN|tSKQ2..)Y\(f&TF.|*;JpOA/k =.X& ËX鯬/=\r$SD5 Ōè%,d?j7 2Zvi86 Vˮ=Nf]0(Fp`4@yYi^ d̸`#;b~~g{*F#(R;ܳ'-K;*u;8r|"} xN0?ik#8\8cCԕq.|htҿ3kA-Jne#*qC;δj+}T0=@B2NJgtیɚmwҌȖcԷgh΢9s(SaVA6^r./dо4N:ߤ|):ek:L"l8f q:E)D\1-t5Iw?$dg>5uEMIџU4c,Ϡp + nSD* 8x_mk "m?AY[] !9J%#-* ,;y{godOU%e3cN&ٯJɢ|418jǬvgmi6_).& 覣Xn#:ۃKF":|y$x?׼ּoЈLF\QN&"Qg@2<|,PlƋL+Uck/Tq'pH=?~Cg-gƱ)NԢţ `YAOnPK_yz 4CXcpJbTN"( r LjDZc~N:+S\aft_w-r'zrbu!Z̯_EqwF>[库ь+zGj中kQږ;~k`sK..s9=7+y;&t1$>3{w5^cwIw5Πwd&%ك")hf)'ثɞuuD`i \12h*(=xa`e$]eQjF@k1gגIK{8?O1I^KGr '㽞iEtR) gӖY u7cf;Mq0ݎ)ЧE|\=G G;oaecSʺ^ذ.zەq'zLjK˴={eR szc*8[P_FgBe'?LѺ$ ̛Ei0׌=y_3˯`$?A⸩&ntd4 Δ~`ʋyG* %6ymhg.-. X%mc+Gcࣩ8nJx5-PZIyin"Qtz!|ȯRwW{/ z||HWy%Wkb7He(PP|B2\7a WD|l!}xP],۶j5,-JmJb,cNg)W%TOhVAîѶ$ i >~|=2oakf;$Iw}%8#K?p{G AGʇ8 !e)nЮ6q\ph([WvB pQq"z$}l ^̝\g;C(h:,%:oBя5Lxb 8Vׇ ?ߎ ̏.8aȕ_F:)*ThԑeW+O,PpZLʹZXk.ln6'/nl7TQuDtLyhb?fh!y˺=j6V4 C$"h':l_2_m㕭|ձY2;y(d9 ч9Z5t,>_々 HY\3w={s7Kfzr?xeߣ,{^_.97sd,iwlo͙uRg;TH}6JDv1_rd~m2'fIJY& T^>RICTh >`:><i/4 8xpOke@u'Kln̽KYn$qO N2[dBkͭzX~=j4u]鼒rF K(^~5N'T;wS)1az;7%1 @{d+/ $ʻ}edK$ Br5g~$ൾu^kj\x'A}j3*_kt#.=2wDVq2Y6Ӝfjљg|k1IkAi%*M3psePa/sN'ߚxfP>93e˳G2drV"DPi ?^/H8UP~8U݁OSt;/}sQ eו,w QR' X6OHoy–m "5KT?:yJxCNI`{Q.7Cr #x/u*vhud́Q ~wqIdr4H( /en| }*A4!يwf"3n %TZpa28Rm%$Vh[ oU#+אy\y@ vURT霓2wTU{u1s`"&cnt6̀|f v1W08:4|u;'/oe g|)y|+/7/۴e~$ٸ9<.[:,~tIz㛗lx}xiɿƒm_ݧ>[Osx>:}‘Kn~R1/-,-Wz=e9/W}~|sHǿ4so`oWLwkȮ_}Go^ϱK oe>7}s}S>>/D>?p`醿_]<=Õxl|Ӄ+985o|7󮋿s\&y_¯F,Ug2sp#=lmoƉcyrskKGZonܲiU__r78Uˎ[C'^츩I뿮?昿:tCמ18vk}GƲe͵xm'/ٰ|ڿ~GL?kk?Ï98\{kVZs?;|UN:o ߩzxђ N :XwMZS;^nXqJ>/VJN8jWqyckӣ[{ts7n:'gr74^w~ՙY{zGGm9dǭ;u1GY7]{F/+\qܪ+V-{?~G6<?OzTa?c{FXV4?dىc_#Wp5bǝCk]so^Gl/'v\Nѵ+_ߍ7Z\GnɧɒdbzTyt%uMϸ(n1'qa,b #Kxdxyy&>\|xUFV׈׊#{ܑM-b#A!#I֑Pu$k)yFL翯ԝ.+xi?]~X,^#/ c:W+gűy?<9|b~ӖuZqxӁʘ>eʖǣnj^i6 1qQ\'}3*wڒi)nẘk8u4p[,캲?!> s\ן|l'x^x ^{^Wx ^ӸF&fovw❸ w]{^A>^cOI| 6GY||>/KF^yM o;.??"Ts/8S,Δ*Wax$FeKN4*׈׊׉׋77z|;|O“<Os&܌[ps5;-S<oH ⢸$.癖iZRt}Υ2^sc٣2c??LͲxjѸ W1LrnĿ( epmƝVƟٓ_Gx=GȽL sʽL ?X)S2濩Mq o6-,"ŭ8f|\DM&~o)(.WRUפ,<.`5 \]WqY^<tYxs}gc=>?OU=#;<㯌?Q?))=gsF(އ/yY j57oCȻXSg_pm6e(?=:^)<^#^+^'^/ ƿ'x y&f8yM6q(ı .Kbי"5r:~ >t5M&p]ݔj?++~5纺Kܔjv>gjX)<(;בjvLW˸3t5wύgzn&LW7s3E͸Gq+8+%mb1%L<הP6Rugpk8ulâmw`HFL< 6~\W~n-7g|/ċb/rījzoěo܉w.܍w{^AC0>cy\I| ,{ψ!R_| ͙ < ģh7Un7Un/׋77|]|d)SŹm~f9SwA6{~3c屿Lc~y<[f͙LXdϊ_Aǜuo ۼ§D6ӽto3ۜ^\6gm/wύ\6!ߎxڒ)ޯ3>vKxy|Z[l-8[qI6 103-\b]99-q ǸWܒi]ӆxQ¶vsyw9lלkc>_yOIoOsfڋ}ůF^.~C-COğ?j?!R_| 3LxGQ8-<nm edk;R#_7rd)Sŧ&#[idB)S<ה)U₸(.sw3-jL3~R^|O cLxρ7۲§m1ݒiT>rxIJ+ےiwwύ_!]y]F|*4j>;JFi(-5HiT}o"RQ4JFgGҨ(uUF3uz>㴑 V1٧4S~嬸s8o|A\7~G>ş?.Bx8LQz8JGgGgG3U^hyVN^AQ|<_,'O">U쯞F9Qёf5j>;:2)7>b#EL'gvO˙ZuL-ZfjPrZώ/ 糣4sTp4ꄣf1xk|h ƹѕeF3Grw72Mώώώώntθ:Sݭi}fss[3]Q܊cNo# .K|V5w3S[V5qs8fu4!?x^x^Wx^^ux=ހ?i>7x ފx;qƻ<{^AC0>$WOo)|?#~3x|K2k:o[{{~G>ş?}.Bx@)ot5Wax$?c9WY-^#^+^'^/ ވ uIŧO摼5<")oLyf[&o5Sj5y֑nӞ+ Oot5c+1_޺\.-K̻.5_ޚj1lYl5<^%^->& f*<(;?בjv}?˸3t5wύg#LWs>{1QccؒT81Nu,S||\I6 1O ⢸$Neq>SE̔̔̔x11^tfc999f^!| |§=gsF](އ/yY j57oCOğ?s_>p1>pW?̋FV׈׊׉׋77zxw1111111111mgpx1mgx1nm[81kLmmƸ11kƸ1k\mm\ʸx)cJ;o*UqƭҎ[_;qViǭҎ[ו7nv\W޸Uqkܬvb/W0eϊk8yWx!y\wMȢmw`ו}xCgYx6<շ]w{}?vO|/ċb/rījOF&fovw❸ w]y|'>WW>'<'ſ?%~{#~F,>gy^ %#/_W&~]M[wϼ_tlqgGr/17o;>|v|߻q7nb[{V(޸q7nb<]ݦũ:_ib8m>;\.Y7n}v6[7n}vN1w[7|W~qb:VSq:NQ)8E2R8p\5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5E (j@QPԀ5vL 9A?'s~NN 9A?'s~N 9A?'23#pq5 #]Wq} q!>ӳg9G|kc=>?{G?/‹/ «F~x3ނmx;ށ;N܅.w[|ދ>‡|<.'<'ſ?%~ڻ#~F,>gy^ %#/_W&~]M[XSg/_smP因q6N 8A'F 81FVN^AQkmq6N 8A'L '#~'ēmPcqA\9y}oBUPߛeUTqB}o*NP 8A'UTqºUn2A'LP *7A&T|2k"(n1'gR C0v}A\ =v b p Z5tky/"8&qLfZ,ogLWx!^%x)^{x%^W5xgF&o[6x'xu|3>#;Inmz$6ɭMZϝZ2_TQTQTQTQTQܶd5n2cmfےi`gzYx+*k:o⣮ygY|w]|/go9WZ\y6Sd6MVld¶@ L&Ʉmr`m:TvmֆYڶ2ߖv>X?C!!!!?s?s?s?s?s?~ˡC?oP!TB:T}˄u[&-r!G?!GrԡC?C&TBP!TBP!TB:C:C:C:C:C:C:C:CP7TyP!TBP!TBP!TB;TBP!TBP!TBMwS?C?ɇa|I>&~\+k߈?y?y^W%|_W5|7-|=w=|O?#yϼ_PQ0Wax$接`GOT5=kR;z ֤ N̫d>rd)SŹ+X*pwkRwWpO+8S N)pwU*_!S¿Zfq٣PQX.L2̙W\ ~PQ43swW43ŠūīŹ+X*pw+SL3PW,+tT `GOA\P.T]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wWE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wWԬY+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+rwE"wW]+YO/qw%%'1JNb,9$ƒz]I%'1.9$ƒKNb,וXR+9DJv(,e)n<.`-l{vq;gij-01Mab"~8"8"+'W$NHb䊄*&T1 ULt%'W$NHsd L{๮9ϫ͵1qrE+'W$NH\؇pn pn pn pn pn}}}}}} MhBE*XHs'W$NH\8"qrE+'W$NH\YJ\8"qrE+'W$NH\8"{PDe+'W$NH\ر8"c1c1qrEbb䊄L\8"'W$NH8 8"'W$v,&v,&v,&v,&a&aBW0 gՄ3Lj&t5 p gp gbJ[L\ط8"o1qrEbb䊄cLsؽƄ&IyYEo&NHj䊄&NHj䊄&NHb$:0'W$NH\ ߘՄoL\ ]MDŽ&c){!<7t5oGЇՄ&t5 ]MLjBWՄ&tu SKV|Uwu\uJ}o*ӽsթL!>?/‹/ «ѳ}݌xގwNwn߃}x?>O-~RSm{/_×,~_5u7o{>~)~_bo9rJN)Sј;5u |V;euu))֩ # FgSgSgSFTϦtKN铜r>)Sz#x)S@~NoNiN釜Z)OrN!+eUΩy vl욲JWYgHىe!e!e!e'uu uuuuZRv"kYgH9sV9sgUV+[)(sPe+e+e+eg92UT9S캲;3Qg|&5eUWYիUV*zUNm-)))))))));ֲS[Nm-;ֲXY}>VV+)[#([#([#([#([#([#([#([#([#([#([#(gJxޏ!|G}+|£~-~RS=v{/xԋ}ůF^.~C-?ďş?&\K~qR:@:@:@:@ʙ.q-[#(;ǵlײ5rO,>E|8Ne eީlJYlJYlJYlJYlJYlJl\siΥ)[(;5~~ZQz?ʙeQ^S:P\S箩5~~C˺>ʺ>ʺ>N);ײs\q-;ǵL-1WL-8_o^;iKGq+8Qmb ⢸$Nۍb 0_K杦i㴕i+456M((G= nMQIN['N:mt:uiә</ "/K2c+*k]y^7~zތxގwNwn {^A|GW>'Ŀ?))Ӹg9| ݋}ůF^.~C-?ďc?K<3Ӵ+0<iӼִui^kں45msךNjO6m>8MӦiڴ99/s_#GbqA\Z۴iklZt`ٕC9iWxz^0_ӜT+ִ4՚6˛6Δ*cQٳШLx7=۴ik.]N[Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш Ш WWUv WU*NUUSUEUũTUq8U8U8UlV4z*vTTTTTTTiTUgEՎU;vTjUUUZ}N᪝U;v W1V0v WUv WՠjPU5TU UUAUՠv W)\SjpN᪙c̱jX5sWTTTTTTTTTTTTTTTTTTTTTTUݫz*z*z*z*z*z*v W)\SjXwjXYQSQMQSjpNU]%E܇/ o~~XU?)\U?ұ*ұ*ұJyJyJyJyJyJyJyJyJyJyJyJyJyJXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVJR^+R^+R^+R^+R^+R^+R^+R^+R^+RҨF4*Qt7Wo܅1_ٮbd;_/ڞ[k9x!|vۗ4׼;̨홶q`d;S3gYx6]>>OzF^ | ? C~vgmvGe59sv{y xaya{ٳ؈:vWƟש.rx.gc8cF?Le׉f,f&<7X'3Y#FZٻu>#q߃^|_6 o[[w{ ~湾iϙerOGV*[9̽ :ïp3~覛G7nFL{3r{FndYnX1cČ֙b-gZ=Cg<2_gyn$̬̿gcǘя1cF?Ƭ<Տ1+gYgfy|ƚxN{Ee#k)O|柉pY\gyp\e| fy'㩘<5 555皥z f1]z<-;5nWΈOf<ϙwήXyYz>+gYy>`V_Y{VYy>+gy-`Q:j\Gq5y^:juԸLyRCjkFkGzײΙP5]5]5]5ޣ{xQ=jԻFkHq 5Ɓ8QQQ5uԸQ:j\Gq5udrM&drb(vQT'j5]5]FjHq#5nFkFkejejFkFkFkƇhu!5>ƇhuVhuVx7Rkpg^5{kHq#5nƍQ9ndJ 1GsTzgsfs˲w_ƶv]ŃfwdɜsN[sTzFt١0gœ sY> o;=C0>zm?{<9܋/fl| ;==? Yn\4휇csTzJQ,sTz.7v|9g9g9gv9GsTzJQ9*=Gz\9ssYgϘex\72G72Ǎq#sTzJQ9*=G<_F U (x]q84~vպ99ݼ9ݼ9ݼ9ݼ9ݼ9ݼjjjjj9ݼjjjjjjڼ*|W؇/y_7-;}N5yyuy,Cr~5'㩘?*RW/<횧]~~kiޜ}aI/X-/,Y#g!ӟ35|o.dʓadQ26. q3L,<9s<+ Y9 4g,М @s8@shY9 qOý}W5|z㟌y/ϙiN.p ؂؂j؂:gtA;-Z9 4g,М@shYXG/МLsr =OtA]? ,Pj2wY6 ju.o\_s}uչ:Wuճ͜|ֹ:W\_s}uZTOuququU*Ww.딪:X|`u>:X|`u>:X*QuJT]%n ֭y:OX Yݐ Y0iꆬn4 Yݐ nA4A4A4ᤸNk8)ᤸMn8)ᤸNk8)ᤸMÌaF0iW,7+ jp \o g5q7p[ o g5֐ ܐ ޯa{C7pC7pZIk g5dlC6dlC6dlC6bf1 YLÿؐ ې,c;؆ X8iې Yڐ Y+6]6]6]6]6]6dikG<^̟5`4eiS6q7qS5)?t)3M3K7\iNS6jS6g3lrM4OiϦlϦlϦl&m&mۦl4m6m6m6eiS6eiS6gSf6il6il6il6il6il6UJ*MҦI6gӼi4n4M&MۤMۤMT2)c2)c2)c2)c2ɝ6&wڤM)WԵ)K#M󑦌mئm|͕ٔĻF`qqI>Y./f2֌̉Źf./f9`Q:"o,f?'فgzmFɳ܌6px'Knw~|tC0>yOW>{Ee#krO<3O2_Z{,'e9sn<'L-ZZ2('E}/EH?I?確oE֧O-Eh\rE2?,_Tt.RE*-ߢ-RiٵԒ--\mmQіmoYjQі*}\eSEm-̖oEmQEmQEmQEmoooooQEmooooooZfa-ے-E][[[[[[[[[[[Y&'?/<{-ܢ-ڢ-~?вբ-ڢ-|,e2 k8ؖfKmZj-Z*?-ܢ-Jۢ-JRoϷ8ؖnq-Yݒ-|Zj>-5OKͧm֖ms9Z6W6Gk9Z7h9Zwm6nsm:l[np676Gk6}n6}n9Zm6GkvxN8 s ́*@bˁs/N8rˁ>>>@]w;P8rɁ3'NȖ@lb6H#pW Thj_UνUUνJ@PPPPhcHaz?*CߤC3!ʊѐ iΐ iPP i!&&ʜNPP iPWPWPWPWPWPWPWPWPWPWPWPWɐ iѐ iѐ u ͌: PPPPtiHPPPPPIIIjHfFCJ5TCJ5TCJ5TC+C+C+C+C7TCJ5TC ֐j ֐j u ͌fFC3.hHjC3!R!R=C{  Un )fPvr;TJÊ;<+㌟ΊkP!wP{; v='e>;g{~zm7yx o܉w.܍Ļn=x/އ+‡#ޞ;AuLxcG4ęc3,9:u7s7YoWfvf::]%9&@BNcD B("0Ʊ8['QYGcqyB>)O]=#usy|Q?_{xMZwxÇyxuӫ^t:~oM!_' $k.uM؛:Cn2澷Ot%z{SoodM؛5ܴXutcuao찷G:YaoYfvqT{;aoG3;JuqTގ3 g:JuՎv;{;ގvt]jvt]jGW;aovaovێv{;zێv,xgi;K;8SaoQRG:ގv8*aov8*aovaoG{;ގv{;JuaovqTT:Aq~B;;ܱ8*qTTQR]ֻzjUL;V]ͮfq׮Nw.^ww.]κΝu?ΝuB^wwuz׹]ʻye]k^tz]uM׺k]ڵ.ZvK^t/ZvNV]Ӯi|Ye]˺#kuڵ:ZvNV]Ӯikuڵ::udj9C׻>ϰt#:GukڵvZv]^w;]z%JY9sd]Ⱥ^wz ޵z m;΋uzGt;^}wZ-t;kеZzwbWc>ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=dO'{:ɞNt=d߻b:w;wThOkf[[T^^d}{WL߻bw;wOw;wO?}^{*O߻b;wIJe?}d_':o}Y}^g[P#B}G֨}^[~}+wt|ѡc}+wd@_}V}TUkV}^[ X:K,tK,h쀥X:`逥X:`逥X:`逥X:`@o,tK,tK,tK,tK,tK,tK,tK,tK,tK,@oz;`逥X:`逥X:`逥X:`逥X:`逥X:`逥X:`逥X:`逥X:`逥X:`逥X:`逥k#GΏ:k#,y3 _|J>gnyN>/_/ʗe[:ҥ#]:ҥ#]:bwD#xG7熮>7t>7t ]wnsCם`sC; ]wnhԡvoh=wW K_)%#뿾O_~@~}hw+ ]YnrCWЕ冮,7te+ n0C n0Ю.C 2О}CI;$ЮXCy;P?ۡCP?Ca y;~C; t0\`1t5!4гc1t5䆞)CWz t0NC ;5冮)7z ]Mn6t5ceCW:b6t5fCWv@zV0ahgеv :.1щHQ x5}C =vcz^2ڍe9>}ψ!]#n9>tCׅz]npC{KtUCV ]nhW~W~lcخ;]wplcz;8ޱa>LMW*[;rұ-޷p캔VKǮqlԱu\米->yl˱#~>yZ\s=w|Od CXޒj,L\<939w Z6~{[r)Wr-7򎼖[{''=}Aa|T~1G>k[߻///'eS毘6?#gɯy/a~M?;xI-/l~O͇}pv@8c ]:+߱Sv;߱T>8vgO==O}|)>>vc{ʱ]G{گ:nyG uEKp]cW;_889c{-vlwc=Ou?:̿f?G+O]"%r]"%r]"'9q;Ρ'v=s\Nzb;9Ρ'v=s\Nzb?;"O(wr[ &&#]=>~ACQcniȮ'~cyE"S3Bv"r&nyQFwS-RFޑr+wy}A|D>*?}Yqy?aKI|+~?O_u˳0h|O~_OCK_6'柚;8sb;9Ρ'{bFإQ'vi9q&.-':s N\:,ON\:Ğ'4;' N\f'^_īx}BOhvj'{MV?loNΡ'^9c'v=qΡ'^9ī;׉\X}o'G>ۉCO^m_< 8ٿ^;ʿqaOi:qęgNi H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ H0 a@€ $ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! C$ I0$aH! GqoĽFqoĽFqoĽFqoĽFqoĽFqoĽFqoĽFqoĽFqoĽFqoĽFqoĽFqoĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnĺFnDFlDZ."EL1-bZĴi"EL1-bZĴi"EL1-bZĴi"EL1-bZĴi"EL1-bZĴi"EL1-bZĴZ.-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|-[ķo"E|"kZ."kZ."aDˆ #$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 c$I0&aL˜1 oy-o]y ߲᭻~_'?^k~||||||p~o{WoqWoqWO0Ozjyz4}?$X>yzkͯooooo/~?u˟{p_ʿ7@~У}H~-uMt|Ǯɾ#Þ֖{TfL沐乜ȩɹ[^Z6啟m!r%7򎼖[{'=}A|}>kqy _O_1?m~F~-Ϛ_s毛_0ooh/d~'柚v*OW)I+I)S]ZUԪ7~n o1;)Nwz$ $$$<$T$xmny|([zX>">k[3?n{_o|En)WO_u˳0h[;{?4de_1Sg1+-k{~VT[1bl؊c+V[1bl؊c+V[1bl؊c+V[1bl؊c+V[1bl؊c+V[1bl؊c+V>=Ycmۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[mۊo+Vx[m+gp*gp*|򲲓dE+2Wd>'9ωz<#;wN9sϝ ?w6gΝ ?w6sgϝ?w|/_*{s6y}}>>tn󽜇[>$?,?"?{-U=w#͇M{3@r$#[rL\ld+/6nIT +wʝG+?)O!|D>*[[Ϲ̏yIgW95A~>5~;|po1n=Hz6mZv8ֹΩunsjxs?Is?ɞs?w835ܹs-;|jo>#~ns?Wɹs%8;;;;;;PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhB &PhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJ)RhJfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFfQhFShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9ShN9BwSn 9xnsǹq8w{eoA /\ y /7p5 /7?ZM7bpr{a̋f]{}CQck-]_Փ}G9;9٭} HF2GL\<939w Z6+?B.Jny-r'OI3/?%ʇ|LJ#Qgz3?n{_Oh|-_6?ez[5?'_7`E7=ww{?4deͯbp~n^8?x{9y8usS^oͿbw_5z[~nMo; /p~y{Qkͯ3o2[滼]C ?]4/x93xZ ^K™tf~K{W_w0pf™ g/pf9 / ^8'xpkh]օkh]օkhմiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeM˚5-kZִiYӲeMˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhвeCˆ -Z6lhҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--[ZliҲeK˖--/Zyra\>}~?tXzu &o1g/W]pMKd/\¥+_B+P]r ttrgd(G2%O=c&2<,d)+yk'r*gr.YFz%r)Wr#k;yW~R'OCa|Tg~ϛ __O/˧W6?#gɯy/a~M-m]|IHXD{j//;/]?/]?/]?/]?/5_7LtK]~%.oxsͨ_uy5.ox~fޱ&o1l^O\ҧ .ﹷ:0tK>YpWk?6%.]Z{^}F]:ʿqp5.]5.]5>ǝs4ww|9;Gqh>}]+Y8`/_//GO/ɗ}Wz 䐯:?/Aãퟕ5߰]non{s=})߸68Ͻ?wsJ+ vNqsZWEyZWp3Wwe~=r3Wz~o>suכ6\iV_=^i=^w\yww\|ȍ#}{s~)|P>G31Y|W=)O[&Q|W,_{8 seO}c_o!E|z+ ^ՍW7~_[^' $*.7v{eW_1ʧɮ\-W<\W?5cW[Wre+_QWTBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZ҅.t -]hBKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZҥ.tK-]jRKZɕNtr+\J'W:ɕNtr+\J'W:ɕNtr+\J'WzÕp+=\JWzÕp+=\JWzÕp+=\JWzÕp+=\JWzÕp+=\JWzÕp+=\JWzÕp+=\JWzÕp+=\JWzÕp+=\JWzҮvk]+Z3p5ַmok}[Zַmok}[Zַmok}[ۚkuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo{k[Zֺֽuo5 \3p5 \kZKZҵnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7Zҍnt-hFK7ZҍncPwԝ}KÎw->i~{u3?$?G}~|s۸w=<{yۣ]Ʌ\ʵ;nN#pOr|@~Z>(Ggl?k~c>᫞Oɧ[?1_/{Wz}lΝ}+Wk>̿%G}y8{1;q\nwpw^#_r8uNw\Ϋ<\?ΫYwq cPwǠ8u1;Aq cPwԵ_u82|\__{Tny[>4H~-Gcc>Zϯkk=sG kw䵯ʝG+?>~)|P>$GgyϚ7?>)O[Qg_W:ܾ!Ak+W__;zX[^' $=k=k=k=k=k)=?z~Xcz~׮ntz~F?8_z~z~z-ϷzVϷzo|oyVϷ<|oy-Ϸz[=[=[oy[oy[=VϷz-Ϸ&$u  &M"ACe懃xC=/O>??????????????y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^y %p^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yeq^yWp^bUbUbUbUbU>bUbUbUbU=?{~*V+TVV8bO`Ū`TWSçbO>;|*+++++vTX!X!X!X!X!X!SçbO]=wwwz*++N8]=z*vTVVVVVSă*vTSbbbbbbbbbb?O~<y*N$8 z+譠 z+X-X-X-X-X-}cMƚ zo{ޠ7A zo.^L zo{ޠ7AUK_~p{GG?//mBJ~~~O}@KL+^sU]:m&m[l҇~Þqx;}ՄNkC,銮>#=3u9c o}l`7ؾ o}l`J+7Vo`97>' 7A o~ 7vu\2.ӿu*~sz78yKWtKWq^3jgf̪Umjgf*ΫH̪UWq^3󪝙U;38Z-r6RFV vfVvoWvUWq^yUWq^3jgf̪U;38jgf̪U;3vfV̬*߮*߮ڙY3jgfU;3vfV̬ڙY3jgf̪U;3vfV̬ڙY3*ΫvfV̬ڙY3*Ϋ8ڙY3jgf̪UWq^yjajaWyxWyx*'r*'ڙYU;3vfVUWq^yUUU;38*Ϋ8*?6RFHUj#5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y 5p^y uq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^yuq^y 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7py 7pyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qyM7qy-py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py -py oZWWֺu[늷o+zֺ3~}.w?0~u]oq~Ē['ZWϭu ןǮ|~~~ :-hVV]:m&m[Ivh>zOt&tJg.\Y] }߻GzUgO+ZW-oq~k]ֺu[늷oq~[ZWx[xk]ֺu[늷o+ZWx[o+z\[%2[WZWxk]ֺu[mqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqymqywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpywpy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy]wqy݇>Czhw [[{׷Aw??}\GOI< ]XzhCڅ.-hV mivifL'tJg;tAtEtCK鑞\?)w>ГzhC;>'Oџ??GꡝWzhCw]>tw~Cwz"+mnv[=ʇ+zSϵ=\ +Wbzɞ&{FzFzFzFzFzFzFzFzFzYYYޞ2{YY顴gm՞YYYYYYYYYYYYޞޞYYYYYޞn{{{n{{{{{Fzޞz{FzFzFzFz{{{{agmgmgmgmgmgmgmgmgmgmgmgmgm>{{{{>>>>#{>x>>>>>>>>>>>>>>>>>>>>>>>>>>>c{{c{{>z>z{{{>n{{{]'?j|ۗ_ۗsߺ2 @y?<Пt恶<ЖxF~`c8>؁<@gz@O=y'䁞<Гz@O=y!4䁆<А@C18cp`<А@Ch y!4䁆<А@Ch y!4䁆<xghMx 4&<3<#?;v4xy <Є@h<#?3w;w`73w߁;~s#gw?z//+_I WWz_oi|VEw-f۾x}6y;}}'}n|/}}ĿcS3O}?A__{~oU5u M-hWkNI[Ol҇~۞qxC:]!ǑC\Y/i81^{sKw@yMFs~l]?9ƣ7?J>r"#-ȉ܏|#'r?9ȧ >z%g|~</{_/2#a=Ư2~k_k:WҞ~C-W^\gE c5OyuG#'>9G߻꿢/W 'D~$IGD~$qG'| q¡롼򟡼!!롼롼!롼r롼롼롼롼롹?4P^?Cy=Cy=Cy=Cy=Cy=Cy=Cy=Cy=Cy=C~(z(fЌ롼롼롼롼롼Csph P^P^͠롼롼롼롼롼롼롼!·롼롼롼롼롼롼!J(t!J_/ 0B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>B#>Bc?Fc?WKWW:K;_E_M_C_K_G_O@?ot_>ߥooGwx;|w^>W+?@?H??׳륏/J9 n____ߠߤߢhS5:m&m[6.}H{^7>SƁqH'DS'3;WK2NƩxKw@ьRk=oO?0u%_ub#G??F)Sx>y 5>O^?C֕3y_0E_2~Fcψy>~%7[>~|zyG+7]7_? /].Ec\uOwKS'_J/W1u>#.EtcG}FcG9cg<1}FcgČ5":9c3vV猝0?.:9cgy5vX[[[[[${ H@=d${ H@=d${ H@=d̲, ${`=d̲@W H@=0H@=d${ H@=d${ H@=d${ H@=d${`Fft`F=03:d${ H@=d${ H@=쁹H@ft H@=d${ >0H@=d${ H@=d${ H@=d${ H@=d${ H@=d${ p@=d${ H@=d${ H@=d${ H@=dxW H@=fd${ H@=d${ H@/d8^ H@=d9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^Br/x! 9^B7q/3q/3q/393q/392223q/3q/3<2222223q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3>02>0222222222222222222n0q/3222s|bOLLLLLLLLLLӉ{{{{{{{{{{6q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3q/3q/31;&Ľ\|^f^f{{{{{{{HG=d${$#IHG=d${$#IHG=d${$#I,̲HGfY$#I,${d~E=d${$#3+d${$#IHG=d${$#IHG=d${$#IHG=d${$#IHGftdFGft$#3:2#IHG=d${$#IHG=d${$#ˑd${dFG=d${$#IHG=2#>d${$#IHG=d${$#IHG=d${$#IHG=d${$#IHG=d${$#IHG=${$#IHG=d${$#IHG=d${$#IHG=d${$#IwE=`d${$#nIHG=d${$#IHG=d${"IE=d${$#IdJd)ϙJ)ϙJdJ)ϙJdrdJdJdJ)JdJdJdJdJdJ))J)dJdJdJdJdJdJdJdJdJ)7J)JdJ9>5ǧ}*٧}*٧}*٧}*٧}*٧TO%TO%TO%TO%TO%\JdJdJdJdJdJdJdJ15/}j.L%TO%TO%TO%TOq>S>TO%TO%TO%T?OO|=}vw˕w=#WO?>H?5q4O?B+o??F?N?A?I?E?M?C?K?G?O@H_K~/BJFNAIE-Z5Z ڤ-zK۴Cmҁ+/tB;ΕƮqj1~fќ?/p_:~1_mOj{b?;ٞ<~rI땟s鯸/5~5axd'Ó&\:~`|mOa{b{؞H'=$Ϲ{_0>_ēK_/wxk'w_bk'Hs:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s:s3s:s:?s:s:s:s4s4s:s:s:s:w2ݝ {ՅUR2rk}o^vRwwqor迦o}+I;]oor=^^>z~ӏc]O?B+o; 8$4 ,Sg_пE?oyE~/y͗BJFNAIE-߭j\uڠMڢ~bvh>>6GCGƏ}80ĕxjxfzxIcWVƉ85o3ќIa|6h}2;~x??f0IaS_b3g}S~zwVyj<5swul_|:6/>y7河/}q穙;g_q;[y[iwc + q/.|Jg-ق-g-JI ',4'^x{'^X \X \X \X \X \x{+VVVVVVb+b+ba%p+^X \X \X \X \X \X \X \X \X \X \x`) ^ + mF mS Oy/....|JJJg-|lZG 3ha,̔JJg-| + ',..TpRI + + + + +K/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/qK/q籞ɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱwyɱɱɱqɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱ1OXOXOXOyBb'zrb=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c=9֓c.ɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱɱ1Njzrb=9恱ɱsXOXOXOXOXOXOXOgzr'zr'zr'zr'zr'zrWc=9֓c=9֓c=9֓c=9֓c=9֓c=9֓WJX+a?VJX+VJX[+a?VlVl?JX+a?VJX+a?VÊWVJX+^+^+^Vb?VJX+a?VJX+3w?VJX+a?VJX+a?̦y2VLY+a?VJX+sa?V +a?VJX+a?}ywqqqDHDHDH'$ͤy&ZXkkmbM6&fZXkkmbM5ZXkkmbM6&ZXkkm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"5Rm"&R.5Rm"&Rm"&Rm"5R3.5Rm"5Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm" 6j6j6j)OHyBRTHyBMDMDMDMDMDMDMDMDMDMDMDMDMDMDMDMDMDʅRm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"&Rm"x6TH_M<0&Rm"&Rj6j6j6j6j6j6j6THTHTHTHTHTHjMDMDMDMDMDMFa?l6Fa6F>ca?l6Æmنm 7a?l6Fa?l6F6Fa+6b+6b+6ÆWl6Fa?l6Facn6Fa?l6Fa?lٴ16f٘)a?l6Fac.l6F|?l6Fa?l=w?{2^s4}鯹 W_w7_E_M_C_뿾o0M7_oxonponpofvv{Yo/%_'^1q I)iYӿI~+?O@HD *:&}@KLFAEoivh>N\O+fߡw,4veeS﹥;zϼ&9{ w\r^.{|uW݅O 2?m_3g]y^cFExo]vExo]vExo 2>{z/Ce ^z{x/ =s/ ὧ|^K{ix/ \b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\b%\%E.3?zowt]}/}!#WO?7 +6Q.%~Яҿ_ߠoD˴57UZuڠMڢM;K={~Ͼw:3׿C,銮>#=~z W>sO=ԳO=eO=YsO=MsO=A}SwOzS=TO~'?ՓOy'?~'<|_p} ק~ +|!?Ր<S 3y[;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;鶓n;NNNNNNNNNNΌItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItItIItItItK=KtKtKtKtKtKtKtKtKtKtKtKtK9n{sm/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/m/mt;Hn                  ?Ht;Ht;Ht;Ht;Ht;Ht;Ht;Ht;Ht;Ht;Hwnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvnvn>pnvnvnvnG.qnGvnGvnGvnGvnGvnGvnGvnGvnGvnGvnGvnGvnGs(ݎQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQG_?\W.%ѮR2rkzovx&מ=&ߢo\w-.ܹ5owMY̬yv5C#^}JB?F?N?A?I?E?M?C?Ks/_}~~_/ *:&}@KLo|Ϫqi6i+ivC[3U/7N\Ogߡw,4veeS>WgϿoO?0u,a]:~1z޳ǯ?aO?ϜG =s3^y83{=oysy$3<ϜL"?s3y0$3>{ۛgoҩ.}RًXu|mS^45~5g|ug쾌J=s*3ކg_\f y'wry'wry'7'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒf0'8a 3NqŒ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNsœ09'9a sNs‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a NXp‚',8a Nxz{I '^trB{R'''u}E'gwϻMkNN>9}ŗ?H?t)'ttZ~3O >933O >933O >933ON!=933O >93Nc:y=8q89?O>y]O>9?OֺOֺOֺO>9Od&.s~p˼O>9?O>yOO>9 ГtN9yO|9yɗSO|9!}wpN8?9SON>9zO9yn}qN[9Y>>8'㜼s>ٻg'a{>igq~٧ܜ{Figi{ٳ*gl=rٙgl}gɞ{vgOksٻ6gڜksg$|Fgڜ=rFg$|FgYvegYveg鞽SsFg{Fg{F ݞ<)7fYj=r4(g{Fggܞ{Fg{g~g~~v*٩gҞq{v*ygܞ>{(gĞ{Fv}n?+ߺ2WV^hwϋe\+K_E_M_C_3~OmߡKBJ>}}z;q}w .~W>;|~w/}k9 /// |~~~~YՙqcrxgZ,MWVVV{zcel` >} ac{d5xؤYA @07`7Vuw'NgeU9yy2s⍸ķxa;ޅw=x=gGQ/ŏQ-ŏxħi|O>|_W5}7?Nq3P8]{c`1&?]{c~p Wv?2i>-ov?Ӳ- l{UpӞKs+t\gԜ抧=4W<}.".aitm?GD9][bc7Uӵ%t:v'iw>-;S_D3zZU=-SVUOeuOUӪiU.}][w=zU^ {\JZ>sRe3x+},:܋ ހyoxoͭv<0i˻n #< ')-OI|OK+k|u2q$S=?m3uf^ϣzo l uݵ뮪^w=ں3uf י:'\p>9z=|\KpuNJu8*z=nz=nC|o]m;GPϸ~L]mC^,,3䙳lJ;]~?5c (c/㫁u ܆v ?Ngd3ra+9k876wNTۉ:;̷gMjT=DxRēj&T3IgO'XQ'q'*DMx3&XY%&-sbebebebebeC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 dC>ِO6 }w6Ά|!L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>'Sd*L哩|2OT>SdjNة|2OT>'Sd*l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|)l'ɦ|6ΦٔO6C>pkǿ{ _slJ;]~?5c (c/㫁܆vY̱+tpk.[pkx$lUPfK~_olk<|7ߋ,yf.b#,q^I~pDHaZSZ>!$^d%/~/y>㵟 x-t?;V_/*~ o.~?w'SG`'}ş ހpoxoķxa {^ϧ_ zPa#GGĿ?G?.~B|i|FIϋO_/o?ψ' T WƘ_5|m͖\q[]C<#z<|{[s8wř'3ۚ{-\<⑸ŕ͋".Ua햿 y>|{[X |,!|{[qQmM*|{[sx÷5Vook%UX^Vj{yQ<DZ6-a ~NfnYi<)| q'kyNhy55-|SV;pg8kv{<G8y[.".j^bs䜰j]1|j+lh0 W6\ DŽN+5q 19D!bsC"19D!bsC"19D!bsC"19D!by19D!bs̻9Df\"19D!bsC"19DZ"19D!bsC"19D!bsC"19D!bsC"19D!bsC"19D!bsC"19D!bsC"19D!bll19D!bsC"19D!bsC"19D!bsC"19D!bsC"19D!b,19D!bsC"19D!bsC"19D!bsC"19D!bsC"19D!bsC"19D!#19D!bsdň9D!bsC$OF!bsC"19D!bsC"5bsC"19D!bsC̡̡2X94C94C94dsh0<` ` ` ` ` ` ` ٬̡̡̡̡̡̡̡̡̡̡̡̡̡rECh ` ` ` ` ` ` ` ` s̡̡̡̡̡̡̡̡̡̡a4C94C94Ci0sh ` ` ` ̡̡̡̡̡!f1sCb39!f1sCb39!f1sCb39!f1sCb.f1sCbw1s͸9!f1sCb39!f1s͵9!f1sCb39!f1sCb39!f1sCb39!f1sCb39!f1sCb39!f1sCb39!f1sCb b f1sCb39!f1sCb39!f1sCb39!f1sCb39!f1sCbY(f1sCb39!f1sCb39!f1sCb39!f1sCb39!f1sCb39!f1sC,!f1sCbˊ1sCb3XCb39!f1sCb392jb39!f1sCb394C94C94e&sh2&sh2&sh`MdMy̡̡̡̡̡̡Y94C94C94C94C94C94C94C94C94C94C94C94C94C94劦\є+̡̡̡̡̡̡̡̡l94C94C94C94C94C94C94C94C94C94CLi2&sh2&sh29dM4#̡̡̡y94C94C94C94C94C94C'$x<'9۸&42ak=[4;pg8a+s_<8q>>5q)6z>[_<SfkO`[V氕9l 9/>7i dٲ|jl5_/[͗m6eqvc5ԯAZ<gqUxpϳͯVqm3z?~l 0^ŏş/r1^e>秽Z>ms+!cl!/+U~oGx ?u4}k}p/ W܇x#x+ކxa»Q-?,~D|q|>)gω&~7Yxݧ=#7SfP5#1{ lawmv Wܥ%wř'ލ{Gə6{mj6g%mMKk΅qOi>m WlP}Mk<ᾦ5xiQжp_ӚCBh)FߊgWlTm6vjMݦڶdjےZmKm-նڶTۖjRm[AKm-ն%'䄖jRm[mKm-նڶTۖjRm[mKm-նڶTۖjRm[mKm-նڶTۖjRm[mr ac|w^;W5ߏ`}[\x!~DGܫ>!$^bĖe>ɧms3Y- {YKe ~_o7[m~G5c g^͵p/ W܇x#x&x.{~>U?,~DRrL|\ |RS-'ϊ?/>%~A"k:o:&->-^ψ' T_|o/e ` ` va\~vg(BGi?yE/Kl)6iu!vf;3k~A|-_me{ýx= kWF܏܊ix.{}#^u9OiyOsx _W}0q5  ׯl m܁;C/g(b PfhaK5rxrC a.ׯ ;3kMx a;?;?;?̄C w3#!{/`39xX\/ϫgg39!0^ $^].K\O?-\gskt|2f|5S;@/_ůM~Cq ?eZ:܋?*ވM|;ށ;.{>|g>"1%~>_ėU|6,~[|Z.>#7Sf}>SWGcaEhƷ]3[r%>Woxm3VfX1q3clƹL]ؾ/>O|x683uP\GR<W s>ռx;.?clgv64sASW?&>.mp4SW:z6\iٌ3?SWψW q⌊?Z*Ψ3~ 3eF& gdpF&Yg53a?(+;埝Ng̳JN~i}NfPvZW|dg\ۼu*ވbķxaӻ߅w=xQy0/~?~_᜺>vSwSwSwǎsQ;cG}p88XꨏXa1;,㜺㜺JvSwSwSwSwSwSwSw3j~_ůM~COu ?k^ WF܏Vuv!'9{|Ő[vb#,q^sA~/ďE/r)^skWweNvn3b_{hW7w"~~_ &~ !Opٻ_po}7~ ~Pa#GcOOZ?h9)~Vy) e|_ 3335#1wa0[[smv8ݮ*zݮ$:ݮ@ٽ\bl1[yw>gAwԘQO<Đvg W}vnWv\-Ɖo0w7n~X3`Oxb`n{Yۚì=~G=S_xէė/.˵?W>նYk:܋ ހpoxo[6xCx]x7ރC9G8>X<'9u+xU'M|;ށ;]x7ރ: |?$~XQ="1OjyJ4>Ysŧ/2u|?xn֙*0 OPs9s9s9s92;qTsΛ\7'S͹.oysțb~"on劼-+涔ⱸ_ vT9O}xQ.セ>.BmtGW".] g; ,8K]ptyЅڻm.8]p7r{#7rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#gY4rE#0r#%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gY2r%#gȹA]GW1<*AWzWyUUUt]|Sk)[sV-߃~x^XKۏŕal>g -ZޏY kX=[zflٚ35gkV̂5gkfs5kV֬15kfzͼX3/Xٱj5wz_\5gk:לu9\sֹsY皳ε3W5:~ow=>?5c _}k\{g7>\q?[6xCxt$»בO|^!Gďz#_ãZ'>O g9|O "k:o'->-^?Ox3rZ}cL09K],uzښ5ikR׬g<yYg"9K]L5gk%~zښįKsܷk[qm1}#Vx,'5pk^\oV֯vdUm> gk_jklÙZ}&[ǞLv3לɮYU[s5jkVՆ| wM]uל᮹K¬9]s wZ8=;=9;!Pc?ğOnyJ|{w囧95 –p-^{z\pWF܏܊ix>]x7ރl?dG('ls4-|aOÓ_jsk6qkxmx;pg8a^j^Vtk~A|=_i7\k}p/^+x*ވb[ŷxCxĻn99?dG('<'9 Gl9 lVlawN.pFFFFj^ZC?jZwk`\ 0<Iˑpw;sxqWq?f/o6_wƻn~|ća#((ú|gg_2bo7/8 Lqc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc/;ˎc_Wk.ux=*x3#G;ķx;Ck%a|cx͟|J]'I| 3l}ܮ{sڟSZ^__ė,~E*N{| ?&m&}5{͋z^^z ~<7fTvCz5G#{9>_ >d#Z(OOÓi|6'Y-y</׾*߉i:Q˟ |+^E< {f \p/^+\_[V~ CN {^׃a#GG1<8ֵ?)~ gsl+ůU-V;5?u_l3 -S W]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEW]ѿ+wEOӿ>޲Oӿ>O7Cӿ>O~ާ`̓|HƐ}w٧}f_ݿ}?d#평{g|mISZ~/;5{='[kx^5:7ڲu_wUVϪY?gUUVϪY?gUUVϪY?gUUVϪY?gUUVϪY?gUUVϪY?gUUVϪY?gUUVϪY?gUUY~ֹuss?=sumnނb0 t?@3 t /׼K|7c<?*>Q< <}?O}c5OO +|_—ۿ*;5}h?y&+ NpY󦺏~^x1}S}lC=x?>mky?')-O3ZN⳵qob7* E|IWU-VĿ6kRnRnb7*lM|+^ǿf:`7<7<7<77<7<7<7<7<77<7<7<7<7<77<7;~|!+@FR8Http.rCzxh4qʑ-YR5XQSRɖIdIﲄNY9Vڵk[ko[:ߢ<-*Oߢ<-|Ӣ-:9ߢ<-:Ӣ<-*Oߢ-:ߢ-:ߢ:-:Ԣ-SߢFQ-:Jբ-:ߢ-Uozբ^-:ߢ-X:֢-:R`;C ,~gnuL{#x.pctv;C^tv'i`g?pq;m v;ݟpv+0ņo-2⻸;:{˜e2w鶻].s~9˜aX].s~9+R`;].s~9+8^aWqkbn#[ c G.%vBx}5O8r3L㌑Ycἑq| I=>g\IFx#*"*"*"*"*U[EU[EU[EU[CwhKX Vq#{Hcs~``K"*"*"*:u`T*U``````ԭ"*"*R``WmU}FYQVmUeFYTmv(6ʪjt6jTm4U5FMNmTSF5QMmTAFkS mA]6ڠ6h mA]6zmvkFk h6ڠ6h6zmvh6zmvmvh6zmvh6ڠ6M Yp.0fp'x7>#qA!<8Sx٦q,9=hn׳ݮg]v+v v=zln]in]iL]iL~g;n~gvn3v=hL3v]ouv3vՓv=hgnzzޮ{&@gGѡztjHҡt!jHYJҡt!jH{ޡt$*IJҡtXu$*I\PO:ԓyau!;:TuCPg:ԙuC;*L;rCtVgVgrCtȗ!_:K|:/VgWYYYAquCtȗ!_:dJL:::+]kdJA.]kt킮]е vA.]kt킮]/]kt킮]е vAt킮]5] k vA.]kt킮]5]kt킮]е vA _A+`A.,,fA.fA+կ _A+,`A.]kD ԺE(EyWE(E,Z-E(E,`QVE,Z-S"XE(E,E(VE9XZ,`Q+`Q"XNQVEŢ|,Z-VEŢ^V͢hY͢bjhXZ,Z-YZ,fQ4Y͢^VZ,Z-bjhXZ,Z-ŷhXZ,oQ|))))))))))))))))))))))))))))))))))))))))[7KfI,oI,%}o͒Y7KfI,%}o͒Y7KfI,%}$%}oĴoĴo͒Y7KfI,%}oıo͒Y7KnI,%UҖ͒J[RiKfI-%}o͒Y7KfI,%U͒Y7KfI-%}oͲ,ʲ,ZYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVE,+˲,eYY,ʲ,ʲ,ʲ,ʲ,ʲ,fYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVeeYVVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVķ"oE|+[ߊVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪVŷ*UoU|[ߪ=G|;#{w lgu#{w=G|kbn#>>7`0pGqg8q7`݀=!ˁG93F.qǟx OYg> ǯ/8F}ǯc..%"]"%"]"%"]2KDDKDDKDd\tɸ....q]"%"]2Kuɸ.%"]2KDDKDDKDDKuɸ.%d\q]2Kuɸ.%^]%d\q]2Kuɸ.%d\q]2Kuɸ.%d\q]2K|d\q]2K  |_WU܎y܁ob wol[ wc;v`T{Cd݉%,;C].܋-<a_e7cmK^^:v/71L$8 q63Ff=F}m#''٧ا:0ņ3,9~W/w;:Feminv;wminym{vPvAKnv궃mj'Qv{o>j}nvnv{o>jFvGmێP}n{{nv{-Oiv7-nhvnvn[vn{mzjv{o{n{-[v+++++kOyz4{4{4{1{de5f5f5f챺챺챖챊챊챊챊쑃=V=x#F=x)O<=x)O<=x)O<=x)O<=x)O<=xcGOyzz.>ꢏ>ꢏ.>z>ꢏ.>ꢏ>ꢏ>z>ꢏ.>O>z>>zT>zSԟ>z>z~ߓ~uߓ~ꧯ=W=m=mm?ԯvU~ոRnoRno_5mU~ݶ_5W~w觚 m~ݶ_5o_5WUv0oܷv0ov@0ov0ov*0ov0ov@v@tQx0ov0ox@%x*v0tx@mv@|w@|w@]Pw@x*n; ; 9( e,tAsP ʂAY0( e,`P KҠ4( e,`P ʂAY0( ݥAY0. ʂAwi]te,te,`P ʂAY0( ݥAwi]C`H y 9$ d,C`S!Y0$ d,C4,CDaH ɂ!Y0Dsɂ!Y0),CBy 9)䐞;$ k=$ d,C";$ T!w!Zyz 2!zȻC޵Rk=]!!!yȻCy;]!ZyzXDEdXDaaaVEdXDEdXDEdX]auiX]aauiXDEdX Ȱ ˠauiX K"2. Ȱ Ȱ K"2. KҰ4. KҰ ˸a7,jҰ4,jҰ ݰ4,2nX]qҰq8. K8,Ұ4. KҰﰌq2&5oMķ&5oM|k2&5oM|k[q5ɸoM|k[q5oMķ&5Wq5Wq5ɸķ&5ɸd\Mj2&jbWq5WD&^5Wq5Wq5WɸHD&j"Rɸ vDDFDdDDFDdDDF(`GDdq#"2""#"2"FDdDDF( v`G(`GDdDDFDdDDFd܈;BP#;"F;BP#;B;BȈP#`G( v`GEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFEdTDFE."uH]WH]D"RuE."uH]WH]WH]D"RE."u]."uJu]+uuE."uH]DR]WJu]+uTWR]WluW]eJuu*WוR]WJu]+պTוj]]Ju]+uXוR]W ;p?fX1ڇHcj><38pq;m"0rrc&4W#pW]\}kc=ϗ e~?\n~đY:ƞy# Eg>a$xu9L7<{2Wc}Gc|<*O~: RԐrT*PO30r}}8&e7|<{2|1k#1Fp[[[[[{cpkk_|x1Sx9.9n6.$&q[[[z>^<1ю1=߃Au:s3qTg㷎pmd #'Ƴly.92c}Gc3Rg?$?{iY}\Ǎ o̙P&Ԅ uoBС&Ԅ 5aBС&Ժ jBP&t u`BС&ԁ jBP&ܫ jBP&T UnBС&dL|$_&2ɗILe/|$_&2ɗILe/|$_&2ɗILe/|$_&2ɗILe/|˔Z=elJŞ2OS8ǣuT|<|\<>Gp‘8edg<.qǿ^FbQ>xL. ⻸;:Fy7m6Nnl4i~Mk_45ͯi~Mk_״8ͯi~Mkl4y4͗iLe/| _f2×e/3| _f2×e/3| _f2×e/3| _f2×e/3| _f2˗Y^̺Y:vVgcgY:vcgYұt,_fY:v/t,;kұt쬜fuYq|fy7˻Yұt,;Kұt1>YxzLfYx}LԎɬcvLԎ1Q;cvLԎc<=&jDO1Q;&jd1Q;&ɬc|<&Dc"8ǻ9~eNDpNDpNDpNDp_s"8's9לΉDpNDpNDpNDpN89͉ΉΉSt"8O{V2OStݼ?y^zby=Ozy}|_/ٻ`.ٻ`. fٻ`.ٻ`.ٻ`.ٻ`.ٻ`. fٻ`.. `. fٻ`;.i"{\dFNc4ocἑq}")ixb>+5+^ W9BЄ+^ WkVwl_1WU_WE|՚nUWE|UWUUjUZUVUjUWիUjUWիUjUWE|UZ[UVիUR«n^ZӭZӭ*WUUUkUZUVU < <. s\ v.8ۻl:ۻl:ۻl:ۻζf6YkV%kV%k䚺w5srͪdͪd<\*Y*Y3׬J5pM]]3dߚyfɾ5X5׿fUfkV%kfUɚUɚf{޺n˻uso[\\\\wVVn[wn[wV޺UU:׭:׭:׭:׭:׭:׭:ݺU纹n˻usoݪs]ޭ˻uuu sC17T sCd7t  sC17t sC17DvC 17DvCd7t sC17t sC17qC7b?nL4H#;4.#2jH6#mFڌ6n#Fڍ0aHHHHHHHN#FJFJFJFFFF*F*F*FFFFcd.#]F5^#Ft1cH^#F3>#7o-#oyȠA#F 62bdȈQ#FFԍԍԍ32fdF9`䀑Fƍ7rA#2r!#6r#G12adȄI#F&L22e䨑F62md:\rQQ l^ƾ7F?þY~ƍ7-x+wd?/s7_:^o9~|ća|đc~qW>u)#g?~U=J?ƟO9/_o;=w?_7W<e'<6a7;E,aUU{b7>>v?-{=ĮሑQv=qo |1, l6gn,`KXvr{}~s9xgpqW\;xo!C#/n?I<[ȏngȸpk:o[v+(Svʔ2e],Svʑ!;.a#^qk ?Jx.pi$؝Bc(1b嘧?ÎڠA?'S|_-lv7^p%/e'<6܍؁,b X*RO{oq8ƣq{Pv7#%M.=;6sUNqF>ɾ)5kF>þ}=ʦ7eSK)ط`ɎݹM`˅2C_LJ }9"r8ӔP!t`ovtfwCG.y,;nbzq!}<{id0^^\(xQo70;1mζH;v`X²`^gl:82r'(;yqŷ !w"/KCij|^W{Ӣ~ZEPOiQ?-Eub:i1]Ha/8:iQ'-E3h,ng;M#a~ӊEZH+i"8f s{8h_3pIY~F#7o[Vͧ`Ɏk[c5.ˮnW5}/އso=~#| }Oi3سA >C?gs/+5|'3snǷp512ʮp?A{Py7#%bXG&F2eq^`}5Skk5-̖}; [*7oaʾ};/:]~nWx~72ÕĿh.]b.^YgD|_zLٍm >jfv}EP?Uɧ#M񡮾=fwށoġv=FbO-Ȩ jF;jPc3zP"7T65ھB͉ l؎X"pq?/#8Gqr#uZNki-O8j6~FX/GRKZWʚe͊B]Rf_gEݚݿs=9<^7`܏ssss~y;ށw|\wwW7:^^M=̙h1y >#|ywç#quܫ)>?sKGſy;݁\~ _ lsvewU܃]Uu{ܟ^ccbq=ĮሑQv=ǃFI({=Þeg.2/~>^c^g:]\\\\w=th'Be쏲?8rv}UNW#ڟd_Amo_g|zN׭g}zN׭gEvnu~7U6%]Ans=tpu*^8NWߜazt,\,;6/n~i426Yy7f;f;YYYYY`cֿca>G|;Gq;KY ,cSB5|>EW6gm;E,aّr{}<[#XCF$q\z/ߊO<::::::::ӯ1zxxИ}1;BcdئJ5XȔ`ˑ1k1k11fB} g&[!yq_yOtw{cٍ?O~_7[?/W#ǿ?٧//?U| _q9nv;v`X²;Y*.wr/V{{512ʮp?A{X?ތď=H}쏱?ξëbģ~Of} x=ϰc_xr<@9CmwdyQU1^=PCV|'\\ !oF<^턝a_s ̲s&ʎPW==xu5pqEa_!0V{n_8 Wr v vq|-#n>da|w~Q?>Ow=|18?cY %|_W5|؊mζݎX":+X=:?#X82r'(ož!|q3n"wOi>v?-Cec~e?{9>F&Si {9p39Kl_wa_`^c^goD~߸ ܌ďn$^զ 2Gc}9;绱m !?Wa*eodĖ}x|F(C{+q<6odR|/P[yjW|+/V^{rn !ҽ[-jV^u5~j[B]#ѯPWC֫[-uu5>ek|Fpq!x/އnA>~o=O8{~3Y%|_W5|؊m۱ X]I|qq?!28ϷwPwFmkgۼ:&CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$CB?$/!!! ȸD%2.qK臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~HDMHDMH臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~HT~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~HD5KDMKDeK臄~H臄~H臄~H臄~H臄~H臄~H臄~H臄~HTDULTDULDUL臄~H臄~H臄~H臄~H臄~H臄~HT΄~Hτ~H臄~H臄~HD]MD]M臄~HՄ~H臄~H臄~H臄~!C?d 2C~!C?dT 2C~!C?d Q2C~Ȩf,eTj2C~!C?d 2C~!C?d 2C~!C?d 2CF"C?d 2C~!C?d 2C~2C~!C?d 2C~kY2C~!C?ddJFddJFd臌L!C?d 2 cg 13C<!cg 2C~3x^~~x=ހ\Co[V o;N"~w}M|1#F\!O2/\!#V.?Oy~_-?+ ǿ?"^—*v|ۜm7;E,a_eom=ĮሑQv=ǃFI({=Þeg.?GnGp nŨؔa_(c쏳/gر&\"AIl d&ɜ{+_o{c.)H:WFn^iuxy!!9~`Wʋb2T_ݘ ZW'n o]zܕ_>~0>[a?~̯<cx9{eW5iߺoěV{0+ؿf3}B3:Wd|veWnI`]WwKwFcguՕRVWJY])+euՕRVWJY])+euՕRVWJY])+eu5RVWJY])knguՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+dzRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJY])+euՕRVWJ9])+tӕrRNWJ9YӕrRNWJ9])+tӕrRNtӕrRNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+tӕrflNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+tӕrRNWJ9])+ti s)x-~ڧ9<^7ufovĸd)t| wckmSd^k&z5kmSdELid^k֦vey$~)>> ϸc?ƟO93_7[?/W{<ͮǼe'<6gn,`KXr7b7`oo|wgo G1~84r}'LG,{m

      P+j[Ѿo:[>ȷ>9q|ȓϰ s/ GyI4G"? ^*k>fo3۷ۼe[ۼefL$нI`z$rkfyͼζ0cCL=ζ0cH\l 3v祯.|`X7x97Mx3ނm}Nv菁_ܘomG>~‡;I| v# ß9 % # </8C]susa Gq̑qpg3 69\|=\q7".7Anw?ǜO $jװMff7Ļľ} VmwW"sk3ǵ`>و #bs00agWeQ~f/:gsy׳ofoy;/_P~u:^ &[ms>8;Gُ_O>?ŸO9 _-?+ ǿ?W"_^— ʞfϰgsgypŧ\`^c^goD;%/pkݸv̰/cqHWFbرlu&~FMٷoe5uf&qmȗng_M/;V<.p'6+1vnDƧrSf{s&՛NuBI]-]8IBzζbYrv2333WnSfp*333ӷ;7n}ٽ흼dOdOdOdOdOdOdOdOdOdOdOdOdOdOdOdOdw].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w].q ~?w`>+0 fVXa`fV fv-xt';C(ԉo?4Wg typB{B^t=z 1z 1w=00NB2rWU@z k^z@oz ۀw]nT@y @@?|gP/}J^U_uM.}?9Я~?o@?Ub}@ T|Dl:J* _yPZ oot+pUNU~]U+; :0Sz'PkXX`=JG?u4 5}<[d5;n t@'t2)@@@M!auRݔ6u5] PR]SN: t(: z lWs5jft>-/~=A6uc5{wF=pG= @z,:@Oz"Г =@zг<~.z!Ћ^ ڻrrWU@z k^z@oz [ۀ@ @ z>:|f!]=8<j5Ч_<K@_W׀7 =(O~k(~3o _=VR<c|Ǡ|Z:( PW /;2JGVoR:80yր={X~@@'Bd&hݍQj9g!YvE(][Z^d_ Rzԅ6^5YCOUJPւ}\" Je\ Eݔ~&Y,tstZ:( PW @;({ƧTaJ ׂ̒%K^ }CFPgS@'B@Nt7Fײ'q5JW}h藌ou(:@z oPzԅfk keXUª;=.C2 I1:J?e X pF UwVAAXuaKUw,y,y,y,y,y,N]!p SWBJo:;; tл5z><c|Ǡ|Z:( PW /;lUN0!pv SKWBa[[[UwV]8#!pUwVAXua[UwVAAXuaUwVAXu42.B42 ª; 9 YUY,ea-ª[UYUnV"EXu`EXu`EXuRUnV"EU8aՅ@HV"jlZ[-V`E"jlZ[-ª[-b`E"XlV"EXu.A`E"Xl,[-b`E"XlV"EXuna-ª[UnV"E"Xr,\U p?HV"EXua-ª g"EXua-%a-ª[U.ARU.AnV]8nV"EXu٩r7S<91yN>D^OEn"o#/q[ ?WB' { OTu"홗5rKV^5A^ xWA^6*+w|%kq{#O^Rc<ύE}-ei\ yXXySnj<ki7lW!Oe$'W1]{yq/_C˵qA%nq;??v5?tLs>vxFy֏x(yZ>ie9yϘs_"'EO~#VQ~FLg"O0z_7#{clCF Q#OGϗȳ~~~+3=\LKll;V-~"uenKqZ.M܄2oV o(_-gqYڣCPƮe$%i.MLw_iL N`ZZ+83m^;ZB:a瓙4<"Z{MRv:Eh\fv*@4,BHl ; L!]y\HU1ʤV&'Mgz,0 /q nUYmͣ%=4_*D2Qn1I22)hk'5M $Tn6&)5Ԭrw2ziϦW'Q LB}Ou_Fe!~dm>ߝacvǤtalf&Qڨi_K{p]@{ac-Y54Y>{>&2o6J-fL}`L慕'etڊ2X6A+T njx7<)w<+qL4bWͥ-w&FZ٨Re I-с#fF0T p-i8 emQL'IAv`;h<4_ ,Bi 06`<^"jW-4nos<-dG3^[FV)O,͞'73YJy Q'0 o䚨3Aem[MΧX~mddk53!Jt.7h-oVqwx21=pV㝗C-@ 9x'{PC6R`g3OVZ[n:rk¿!2utH#`g7>pЦ{ȝycqAZZ;0WN(t ?,_F cv7\+IV@ (DéP]9?0NکڹVLƝtΩ$$$j[=mLuz#iMlcL7k-6ev tB+QLCn:Xo2muj 9PKk.2m΂ًk5Λ8ef#C:=O;dt<+6y4}Llkz֜ysLo^0q^Ιs3q'utP%LPQRǡw=T Ew3GLFkzcV'd;[~RHy=&BiQ\ORgE&>Ye:IJ"/t9J{;Lw3Z\WH):Ǵ;e$ Š#aTw N' ʒѮ13=fT Vב饆(k̜*$7Dڮd{G)tOxVJ>*]IR}IHf*rh-^Sv6ePvCY"CW2.ͱF/_@4ᘹ<ږt Y),mL,B(qOdr{wjRGJLro[jI;HnRT/:~翵Zf\Mfj&քk6Q?ԛ"hh抜mך9AjZ 㡮8jIڮSKk  6"'m>Z !H~=,ᷧ%crfռ~]kmN]./.%>)(,>oVicn9-w{~2PS0 _ժ\ѤaJxwuC?Jw] ɜ©pU\5WÍFrn,7ϭí˭ǭmmmmmB766㶧DF&Ö3 qa.q\uJ;r;q;sprN3[!jf91jna }Z-sK}}~tܑ}YQI܅ܵǽΝ}}ǝȋ1Ľ}]]}] pOp.}sǍ>Vsn- s\{S/ekLsP;\(9xpkէAe%]Vqrsqprs_rw O??*Gp?ŏy~ ?Ǐ7777~~7kM--mm D~+? o!>G:owwwwwww&1 ~&ww3?{| _ν}/K}}~ͷq>;|wI~ɧ{.>gnC#~9s|/=|/WsWGGGG''''ggggWWWW ɯS~-?ggWW77wwOO//oo__??NAIEPMC BP-#(a0F+     ¦f–V6¶va0I,LBP0"BP/4;; ; ;  B,D` Sitawa0S%s=y|EX , { %^>¾Ra?ZMh:LRB2B\ 9!/WX! +CCÄÅ##ccSSӄӅ33ss KK˄˅++kk~nnnnnnn^V w w      sqsopospo OO j)iaV3³s ‹K+«k›[;»{‡G'§g—W7·wO/¯oŸ_"' $ʢ"&!JkHq8Z#ljuu ōčMZqSq3qsq qKq+qkqq[q;q{q8Q$N1(bH Nŝĝ]]FIlbLĩ4q8C)gsĹ%>-׊bQ|F|V|N|^|A|Q|I|Y|E|U|M|]|C|S|K|[|G|W|O|_@PHXDTL\BRJZFVN^AQIYEUM]CSK$^$Q$YR$U$]2$"UIR4B)FKc8i76666jMͤͥ--mm Di4Y"haJ!yD:4xdGi'igiiWKh|b%MIӥݥLi4[#͕IiPZ$)-H{I{KHJK$[jRBr6]ꐒ2SJI]RZHr)+夼Tz^i'NNNNNNNNΐΔΒΖΑΕΓΗ........$WQIYEUM]CSZ%%-#+'/= =(=$=,="=*=&=.=!=) H5ZiP*JHJIK/H/J/I/KHJIKoHoJoIoKHJIKHJIKHJIK_H_J_I_KHJIK?H?J?I?KHJIKHJɜ˂,ʒ,ˊʚˆL*ZG#QhyʾRe?VZPMiW:LTRJV2J\*9%WY)+CCÔÕ##ccSSӔӕ33ss KK˔˕++kk~UnTnRnVnQnUnSnWPTV)w)w+(*)+(*)+(*)+O(O*j)ieVT3ʳs ʋK+ʫkʛ[;ʻ{ʇG'ʧgʗW7ʷwʏO/ʯoʟ_*򪠊ʪꪡNSG1Xu: `P7P7T7R7V7QkM--խԭmm Du:YԠj!5F:^mPwPwTwRwVwQwUwS&Y1R u:KQ{j@].RTKԽԽ}}ե~q5:jڮvIuک.5fnuUsj^-=jBSWGGGGǨǪǩǫ''''ggggWWWWרתש׫ ިޤެޢުަޮޡީRRVQUSWPTRVQUSWPTSu:gg՗ԗWW77շԷwwՏԏOO//կԯoo՟ԟ__??տ4N5A5I5ES5M5C#ZVh#(m6FkhjikhjikhڦfږV6ڶvm6IMZP3"ZV5h;h;j;i;khjiZ֬EfiSitmwm6Shs=y|E[-i{j%^>ھRm?ZMk:LRZ2Z\j9-W[i+CCôõ##ccSSӴӵ33ss KK˴˵++kk~nnnnnnnViwiwkhjikhjikhjikOppjOj7ܝܣSmcam6]ggǵWW״׵77wwO{Oϴϵ//oo__ߴߵ??tNuAuIuEWuMuC'z^#(}>FfV6v}>IOzP7#z^7;;;;zެGnSit}w}>Ss=y|E_/{%^>R}?[Mo;LSz3z\9=W_+CC##ccSS33ss KK++kk~oooooooWwwOOj)i}Vԋ3s K+9kܹWܕi[;ܙ{]G'gW7wO/o_g`dȆbfaʨ6jHc1c5uu MZcSc3csc cKc+ckcc[c;c{c1јdL6#hFΨ7]]݌Fh6F̰4c1Øi2fsd_GlJ$AFIIeHI &IHH%+HYI'A`r9F'G#Qhr 9G''Idr 9FN'g3Ylr9G' Ebr \F.'W+Ujr \G'Mfr Fn'w;*rC%Ay )|N _-|O~ ?+N *J*JR*0w,}NZJƳ+HdJ.ag.UK֬(6$jc=v:UKIs<R yhN:oˬ۬˄Div^!1ЁĈ9eV*1G2B }٪LW VOKZA2=L%% :GđLFT7eNz0}w!^fTJ9$ӞutN'qe/%Iz2SP i&b>kϮll?k3|6CHE'ݮgpsg QHBW.39e'C֓a^ Jy2dd* _Ɯk-q'Ll-5{haSgSʂ7 p4o4Hd].0Z` 9uNyERV+>Wxc\ 7ߕeVf#B:9%P?ALMLC1`Zi= 6bڄi3QLcZ^ڀ ߀ ۀ ۀ ۀ ۀ ۀ 1i2yNG&3zq܈܈܈܈܈fl6!vb7!vb7Eř p7!p7!p7Ť޾4"6G݌nFfoFfoFfoini"~E(G?Qď"~E(G?Qď!~ cCTfoK=֠3SMcC[n![n譈m06 |7"|# A1b<x @ A;rn'd;:2RN_V,p#B6$Jc2cCN-Wl$0嫖2y}K3W, ]G3OeKwة6p+b%5L |uY|fz;;@)-)XcE"ӛ#zl>L1x6|tʹS΍lrk+G34Bgvh"6pZ<)0ط#Gqw'Z2AJ&T!Gкi`RYҜg%Qݦl)7R_PTщ";d5,G_3 R!*rث iޓ!Ch'N F;Av1 bh'N;; w[o!ÄȠUd\l5<3e5xXLUifINl. ٭Ie"ҙ\#-[i^uh*񱋚8}Zڭt@iIЂ1y@j/(8ȱfٜ_g_3Z p[ Ym`RªK*{a/FzMHv;TT, 2.S8VuZ;ϰԕ2f>/>1frMw,=A)7ڷrRnܐ9.-#{f+\ea#gь0~љ͍e |v>\&LrP/C+]J43|5j순cu4U+J3F[9kIRqz[fư0םrI&Peۖ$(cZcZcZcZcZcZcZcZcZcZcZcZcZcZcZcZcZcZ3\E(BE֌ ~#AAAAAAYδ;wnlN4&K%Tw n!(IU\y]Vx}z9]ZPQ٘{F } XR̷zH%HI PawwL5a 산gRE Iq^GFl4܎LKVMdV( *rNiҰ6V6(䄓*%dCb0$֙ CJ<45 邰"fq4"QrlP1Odžb7]D3LU1L̪Ll*g+S-O h%d,2!bhW֛@ō"7L(2qč"7L(2qč"*njCY11njCyP6 U݆ R[m#;,GRXR.+_$S}^5VK8Yfw{Yljuf@Дhѕ~}T.4T?hXRQ<ӓCv|ge }Dz>+-|tqIK@suwiv6AodU+_eᮼ:*V |BM/+]Uꏯg}6I_⊹4VV՟Nw|Mv|; u_W?^\sC1\} W7'}~"MG,&9LTܴ7jOWܴʛsM޴`"D#F! BA0a"1mŴP?Y=F! աu(po,Trԡu~Q:KXwB3pg,;c! XwB_3P=׷v[22% AÃ0a 1<cxn(+a|{ AߞYF| ,o,o,o,o,oÍp]]CrSenJ d6}[n*samzrzeHGzf:[odԄd gd:4*2B78^gtEVfwB>Ak`Q+dK;J|$<-Sv  gH.59BP*sU9ںUhTCnX+1#8IDȖ`. 4*LyU3I_$'t&L5_Ӛ^Z†Ь.zmP'ĊeFM26dlY(NA 5:m2ð$eqĽ +A*$^i"D+aޫ*zz7u{Ei2]@fr?2vЙAk=6}^uR']$ctVP**,\dfU\)J y+P:z t g!yz8,:Y2tV'v@ uv-SjmK`so߁ N5+Y t8LrZLͲ}@e&X1+3Que[jLRHΎ UU켟魬I32Y)et{&^Z [U|ҫS 2_=@/}>L8 9g >i_ :iwzNTL޻Z ^CInePT 5jp wgS ^U7bL'4zS-Sލj].MW>oz6-@T#IRWKC$o\UAl!FK>LGIQZgM6 Ww>;`t5tt N{8]rag 0cr݂_J!rMLJFA!~ U 1"ewwave1٤ˊӜg%rf(K.0hxiOvGPEڨ1uyƨ:!+glIA+*d=.*P*ٲ+&j(Pq8G PE)^GALMLC1`Zi= 6bڄi3QLcZ^ڄM߄M߄M߄M߄M߄M߄M߄Mߌ͈ߌ͈ߌ͈QQR}7FQ(Ey(o卢Q7?1ď!~ cC?1ď!~ cC[o![o!~!~!挦£ID4.MKD4.MKD4.MKD4.MKD4.MKD4.MKD4.MKD4.MKD4.MKD4.foFfoFfoFfoFfoF|sD;7vnhƖvol6ol6ol6olƖvnh&ڹvnh&ڹvnh&ڹvo8oih1{&W9ԼaL#aZi{I (1L=c۠iSS"RPJ@) 6bڄ)K6L J Zk,A%Q DY(Ke ,AEuD](0Q&D|M7D|M7D|M7-c?a!"RPJB)B(E!"RPJB-Q aBÈFpؘK=L0JF)(Ea"R-ckK絈<GA}DPH{n)3AԡfP3u:LJRԡ$u(IJR:CԡNP'u:įEXE/z!>{K׮q 8߀o7 ~7 ~7 p-F&0u0msd8aّP0F?V+Vc*j$cx~eW^9ȅ˒Ȁ퀯K5+s2#_yxzdgxAl֝Z֝zl֝Z֝%ˬ>dS2s_9Ç^0g.2u1t']p]]dAX7RÕLҲ5!Y {mZu2/(s<  > |) JY*_ʂ/!R*sboD_\,b>^Y+}ޯٚfa hyiSaL#y_Ȧ4.L6bڄi3QLcz˹@< ?sssssssssVpppppppppppppppp2?!@@@@@@@@@ ca_LJ!.G#?^^^^^Vq"8Ep<pppppppppppppppp˪GzīGzīGzʪ/x1000000000000q O,>p O,>p O,>p O,>p O,>pm M,6pm MfV˚l& Af_'IoE{b'Xkbᮉ&XkbᮉLiiMچgV$Q7pm Q,.pm M,6pĊ6K O,?p O,?p O,?pĊ5H$u(TgPU 7O,<,BP A-jk3+ N|/M15I'8WF ucڀi#MۗOgeiآg^鳟&,JihKO)yz1R=\SҷXҠYII6f*X D !C6 @,s2 ZF7aW+J[b%3i y4bjDx&K0P_fze !TB‘pgi3B8F #iia#~ÈF0?a#~#AGBUJ? UO*eH.Yp5 *uP{%Tΰc1V vmgɵ %ʮ2$ȞLyQ.zK|5*`d~&㷡#+s0r#6rW䍩TꏩTR1MppppZToɻ;;ۇA)JՈQ=:NJJdR5FF& ekBٚP& [ђ[Gy?cvg2iol4)"r;bQ4F(Q=x{D#⠢8*rA|cC?1ď!~ cC[St:L!ϴ؉D;-6L3Iv$yfiSv.m9VHх9&6>%0V |մ֔L9yZ[B 6uWQޖPgzlTkgb$5ԑ^'II>krVq 1]JN{ңiSS\*SılGӺ%CBoƴUmq7WT7]D<.1L-/-+xuBg&\)} q3OQ1qfS!s(= a?ل/)cEmIz"`r>7ز籬&7`]g\Ng*h9j _Kb)>k)Pmq DpT3Mq^g>cZhڄi3QLт#hIu_u_uQH,[T y'0״**))쉦LG*]f[=+ Mȥ ؟u붽 `g$ JT3!}kWiU "8H~-nk*R|Dp>"8@4͡e_7 TF#7|x)5!j[d zoҼxBOX9dj`zi';5q*C| L޿OSrvL_r)*پЙ!6H}yL3v,]C WwYe/=/n;|>We-|>}|ED¿>[+ZW%*V}ۯ]Q/n(>lo/T5 QȡVϛ66/:~Ι;w$d"*U4Hť"uߵJRkQZnըEQM^(.q-?g <9gyγY$qAIgSٖ1;`̷eUVZ:nr55)E2qaYF]2*l=[c,Y6۔\brFO*p-_R$ϳ LkN P\2ц<RkKj[*$#6߲ _yX` ~Z=cu0ڵ~}zm(c*n^(RSa*C|U0 6ۗ6?_ko>K>yYR*`XܚL(/50ϳleۨ . pUx! ڡ`n, IXcl6̪lr3*>ҿ)l!31ʼTZ t\?y8WlgLDe~o*!o[[΢N ]mxwy=S]w! O=c|O5Ck547"l\,{*L@XmStͬJ{ Nc55Ԥ)իϫx[QPFuPoe5Ԉ:Lz?=Vy,2lfڶڶ !0*`&ՁuD'G\d.H_^W\^1I5$->PAL lgC}~6Qo%A]Y|<~U^}kY\Z,M_Qa{E+m[h lvMvVS̞ +VT+Bv {S'$< lI$:TIj~U Ѥ0H ToSeʂ"* *EOüu:%UG]ઊUUF]otIiטh5=f> 7 Jxu}A3 :h2𓳑H嫎&UG5ՅՑrdr|QAv*l<ÖQVYĝ4Kӥv.?[ as5EۼhҼYhѤȅ&/,ci ̞qJ6dR$8)ZNgx Ȃ" UD* j'K' ' ncXpRo‚a͡,܃ޅ3k瘯 hĬ S>O;I҈ސ 5E8$'W ߄qD{YHVbM{S0Z?vN ߝec|X'P%q"Ҳ3gWNpUhjEj{1G"MUv;&H/"-'B#Mv`hGR%@'͒z*#e%$PΑ bZVZC6fyLeȇ|l;YP 9:Xkac/m?wLq=d,{?OKGyorZ8CF:_-%2Ф*h:c - EOhGiBwdzAVȍѦ8ƺWl1T7ZΫ\$9#W=Aκ5r6D81RN)9E8y#C}?D,ST}{;I?*-*^ [GAMX8#9b393)sqsd1]QQ.r渐9.`89f1Ǐv9*489Na#a1cT6?c$I7YV# HHYj})q'nOFFw{a Ո=ou? MA!6zOv 5QRD/ 5'i/R%F:@"M:t,J:p#H'IzѶެ?Kϫ@ҷһDҟ3Z#dKgIY|>KZgIYҥ|t=%_" B#ϏNNHr2t$82t tSj,.k$^l-ϼ ?5Z̊{bv 4xANڧ  =bk=|i~C:j2jf iʘs;OK@O@l?x\.*hA6ȍlW[)C3ï,v =VMPThij.̅j:O-WC[_Vvh{fzR=^TjzG}>Q;XDL{m"*3#ΩRЁ+HO'=(HUOSi"tO#I%ߓSDžW cs}ٞ" ]Iz3IUQœ)kH%]>U#4TCr|Bf Gv0cqn ÐPqSFI"56uxCSKIQ<ثbo~ ~)߈߁}#?1[7jImw@VmKd; c#4MR4FJyvPbB_NGo\WI]sz(=Mԧ ]ku>G_WKF}^@v~ݤ_wOWzs u "2]z/d\,W!ߵПMr+9:9Gy֟P,xSy/!eBYm6LQ#hY7.;k0noq]~W!)-]NINJo;p:ݤA#Dm-6yƒ@: lGɌU[Ŕz5\V$5EMW'SUbL]VյjZ֫ j_=3jzUZj\}(t{>zz'P_#_v8JHzWHH;Gu_>LF& OrO#8J?6UàA%8}=7Š&A &>ο`N93u0kē&PA]y9uW汖bzBo<)OpHo?]23 :PPL wdN9T}oH&ٺRVA9q$$]SmW:;]d_]9{;k3nPjJ K1ѩ1rHj|j$RSԱc!bw{CX4>:;歚b˰_}%˱O&dE)ݫ{tUн WA*^j^٭{5潆нzKCi^ ݫ{1DCj^rнWCj^ ݫ{5t/Q I ݫ{5tнz3{21iwj'r S-jz7w<a @_Pm_ztz tO@NJ涯Pn K\}_^G S$}.һI7Gz_`[R{HWCz,ib />M!1g;Cmc[s[#mͶl;l|A&LiLr&4+|M& V5 s4Gn~} oGM@̣ilڝo}َdZڳښl5omo5˲-w#繁mo53֠OGͬO-u3ߦ~55{G΃zfk cwS8)UAvތG'_6淸sְE-a?6[ F1bs8:45- F^Lر>3bB#\ d$elA\eCO 4lY<[1,Da+])%2JFKF`KXlfi%j6e#H" 1[ew`s?6]Vl1D@/͕fl.67[>۠-"QlIO@?Ŗ-6O͓6lr*W*)ĈIUH" &+1S9qUEavzΪ>1T_t(%HD UCAF j z@wh!ş?+ $($09N'%$2{%DDg3g5azR˺d) Hcw6xg9 wx; [so /d"pl}&QGc+G:E:"=x~-.3mR8'?V$'`+r29E?Ɩ抳l%f)UYJU*P#[ʖ_a+Eke38݇Q#bE;-18'%> 86!OcSv݄<-N N [\^4glqy [E:,<7gd=KYRֳ_wg l)Y[9?+a+nl Ys&d9 Y΄*VŒR%D*2HRU \;U9- Au6s&RʙSUw73rlfQN6sQ}rT?x?qvej`32jlfZF QC| lf]FOsOQjX5Vj:^sZ-UKԟF)Cr8KI1j65y̌wwJ6yK$J%,NSNKYgXX#s魘SJ`ff.Y<{(fp#9W`^(?sYͼbD.N\+1̹ ?7jsVsޭл/C*ACZ kB>a- ZӅ YwmOc@`p?^)F_>9`S;7ƮޢO>.SvWZgOl 8o)y;6W뛘p^sm_xvaw*Z|xevYkWx-aY޲3i[hwD-֠]#ija.LwksV44clGkNܮ'B!=&aszƯ75>~=|=R J7=TZTEaQ'ͅm9bk5I뚠uM1RSa?&`gG9ҖfiiKiiiiKhi3EZ2ZNa%co9rhL6asiKTӖЖfhK5miVԷTC 61-a60FbK߰%]lI$hRlEi*TIPOy^iZ*MibKYZRڢRZRڟbڙZږZڐ mHmHmHJ6$Ii7\Z8mEV"%bЀ>2&d`pUN7K~x+,>>rPn2RM妔rܤ)7ʍKQn2,妈Z)dx`#=JOQzM)(JOSYV8;QrSD)ܔRnEPn|q(+RJ)e~T%SJ)ĔRbJ)1iJLQb\JL?瓥Qn(7ERM)妔rSJ)$(7 Mrc(=qJO)=ғ$)=IJOiDz22JOғQz(= JOQz߉.v}=YR'OB~'J_0 67qY\Iٮ+lk;Wm5*Lnf)o檆_jlm9Mն}CȔ`5i\ֶn+Y[msKh]FWe5Fk)75i"):6:̉; l&ZֶvPC^ ~n'T$R)RWd"cfZDokkZ3CHYJBفZ3GٙZ'Ԛ8rAYeewˮԗ8ʩ/,?}9zc\-H]?1RHX`Qfw3,mwG,up:8GRw.RGL$D]1zcJzߥ:Fgųv]1=kW{^2v; ;;;Sdߛp#$-@/FI%w51Dc4܉!88FkDJdh+vX,F`֣;`6;`;4IWiƾE*Ѷtc[D ӍoL7ƻŴ6j{elNu,QӃpkS{ u+Te:Hvإ.;:w1ދʏ=ګ=ZӴ]] iFV|_^PgzAuԋf~]"kaSRM˹b&&H!nrCN໒w?|Zt3E Fm.1;sv <ٷZc=4xf32 2"ː!e)])e"JHטB.] )*Q]n,0(لq/rd6sdȑy#Q˜/`4?a>&O׳4<3zt*Ej tn4F_;ʮR+ujkmhU|H bSVZkgmbvmOy*Xʚӷa,o5c$ǥEQ~b#?ǥv+ l.k.hRb꯺U=kpu Re#kEv5+ETIZL$.W` lih asN=a#&0+#1@t߬~ _{c5Y{E^s߻jM< l+9rrZ\d5Y{E^sלChXI lmNmN6'IIhsLd5õڟ &6F؟b%UWchJi蹔Vȏ'YXcsҴ9kEltdlN6'IIFV`3 5dnش(90ƬW;}(߂߾ PKzXeofj}Ƚ%r]´NX+*Epo\?ȯGk%T>kh Zm_7W$yfeؾkza {Tz1IBYJyV4 q'N4E2MZex>_2首 M Sb_Y:|fA+o3W_x-i~S4w^J%kY 6Vw~[; Hit8/OW2RQq+@-|JbA aTg?-6}){GXGH( YRKlH_0gFf|v涶oZT4 {,ɿȌmsZfc5D4Ғgf{owl6r3bJC5){4eX'[ L (_ArojQ8syˡ,cGY4h{58iZw:]gϜϥ||':a͗mغN4_{ܻ\X"iig]X(yM{%Յ2W75<; M{O5JNzj^h|J$=%h΁:Q.ǫx^ԡIE?tF=#yV^Lz l1lIU5^@z H +.F}*%}ȗds1qڎ yHȅz,Ĩ g(Nշ6oK6OM25YR~No%lw궸sq[|YF 遽Z^/[m!\z}ѶLA d)*G&N11JA"21QHL4b"BL||1t~u̹b04_/ WkbscKbm;o&:2B6ѩuOab^ayqECCkྐ_Yo 7bnτЊFr db> x>z]eg0_A< Lߡ/{0ׂvd=C#hS3cr^ z~KK?bo?|c-[ݔ?*Collabtive-2.0/include/font/helvetica.php000066400000000000000000000050171237252063700205170ustar00rootroot0000000000000032,'FontBBox'=>'[-166 -225 1000 931]','ItalicAngle'=>0,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513); $cw=array(0=>500,1=>500,2=>500,3=>500,4=>500,5=>500,6=>500,7=>500,8=>500,9=>500,10=>500,11=>500,12=>500,13=>500,14=>500,15=>500,16=>500,17=>500,18=>500,19=>500,20=>500,21=>500,22=>500,23=>500,24=>500,25=>500,26=>500,27=>500,28=>500,29=>500,30=>500,31=>500,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>278,92=>278,93=>277,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,127=>500,128=>655,129=>500,130=>222,131=>278,132=>333,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>250,140=>1000,141=>500,142=>611,143=>500,144=>500,145=>222,146=>221,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>500,155=>250,156=>938,157=>500,158=>500,159=>667,160=>278,161=>278,162=>556,163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>448,172=>584,173=>333,174=>737,175=>333,176=>606,177=>584,178=>350,179=>350,180=>333,181=>556,182=>537,183=>278,184=>333,185=>350,186=>365,187=>448,188=>869,189=>869,190=>879,191=>556,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>666,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>896,231=>500,232=>556,233=>556,234=>556,235=>556,236=>251,237=>251,238=>251,239=>251,240=>556,241=>556,242=>556,243=>556,244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,253=>500,254=>555,255=>500); // --- EOF --- Collabtive-2.0/include/font/helveticab.php000066400000000000000000000050241237252063700206570ustar00rootroot0000000000000032,'FontBBox'=>'[-170 -228 1003 962]','ItalicAngle'=>0,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535); $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>333,34=>474,35=>556,36=>556,37=>889,38=>722,39=>238,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>333,59=>333,60=>584,61=>584,62=>584,63=>611,64=>975,65=>722,66=>722,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>556,75=>722,76=>611,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>333,92=>278,93=>333,94=>584,95=>556,96=>333,97=>556,98=>611,99=>556,100=>611,101=>556,102=>333,103=>611,104=>611,105=>278,106=>278,107=>556,108=>278,109=>889,110=>611,111=>611,112=>611,113=>611,114=>389,115=>556,116=>333,117=>611,118=>556,119=>778,120=>556,121=>556,122=>500,123=>389,124=>280,125=>389,126=>584,127=>350,128=>556,129=>350,130=>278,131=>556,132=>500,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>278,146=>278,147=>500,148=>500,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>556,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>280,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>611,182=>556,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>556,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>611,241=>611,242=>611,243=>611,244=>611,245=>611,246=>611,247=>584,248=>611,249=>611,250=>611,251=>611,252=>611,253=>556,254=>611,255=>556); // --- EOF --- Collabtive-2.0/include/font/helveticabi.php000066400000000000000000000050351237252063700210320ustar00rootroot0000000000000096,'FontBBox'=>'[-174 -228 1114 962]','ItalicAngle'=>-12,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535); $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>333,34=>474,35=>556,36=>556,37=>889,38=>722,39=>238,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>333,59=>333,60=>584,61=>584,62=>584,63=>611,64=>975,65=>722,66=>722,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>556,75=>722,76=>611,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>333,92=>278,93=>333,94=>584,95=>556,96=>333,97=>556,98=>611,99=>556,100=>611,101=>556,102=>333,103=>611,104=>611,105=>278,106=>278,107=>556,108=>278,109=>889,110=>611,111=>611,112=>611,113=>611,114=>389,115=>556,116=>333,117=>611,118=>556,119=>778,120=>556,121=>556,122=>500,123=>389,124=>280,125=>389,126=>584,127=>350,128=>556,129=>350,130=>278,131=>556,132=>500,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>278,146=>278,147=>500,148=>500,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>556,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>280,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>611,182=>556,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>556,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>611,241=>611,242=>611,243=>611,244=>611,245=>611,246=>611,247=>584,248=>611,249=>611,250=>611,251=>611,252=>611,253=>556,254=>611,255=>556); // --- EOF --- Collabtive-2.0/include/font/helveticai.php000066400000000000000000000050301237252063700206630ustar00rootroot0000000000000096,'FontBBox'=>'[-170 -225 1116 931]','ItalicAngle'=>-12,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513); $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>278,92=>278,93=>278,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,127=>350,128=>556,129=>350,130=>222,131=>556,132=>333,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>222,146=>222,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>500,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>556,182=>537,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>500,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>556,241=>556,242=>556,243=>556,244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,253=>500,254=>556,255=>500); // --- EOF --- Collabtive-2.0/include/htmlcolors.php000066400000000000000000000126001237252063700177670ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : Array of WEB safe colors // //============================================================+ /** * @file * Array of WEB safe colors * @author Nicola Asuni * @package com.tecnick.tcpdf * @since 2.9.000 (2008-03-26) */ /** * Array of WEB safe colors */ $webcolor = array ( 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'aqua' => '00ffff', 'aquamarine' => '7fffd4', 'azure' => 'f0ffff', 'beige' => 'f5f5dc', 'bisque' => 'ffe4c4', 'black' => '000000', 'blanchedalmond' => 'ffebcd', 'blue' => '0000ff', 'blueviolet' => '8a2be2', 'brown' => 'a52a2a', 'burlywood' => 'deb887', 'cadetblue' => '5f9ea0', 'chartreuse' => '7fff00', 'chocolate' => 'd2691e', 'coral' => 'ff7f50', 'cornflowerblue' => '6495ed', 'cornsilk' => 'fff8dc', 'crimson' => 'dc143c', 'cyan' => '00ffff', 'darkblue' => '00008b', 'darkcyan' => '008b8b', 'darkgoldenrod' => 'b8860b', 'dkgray' => 'a9a9a9', 'darkgray' => 'a9a9a9', 'darkgrey' => 'a9a9a9', 'darkgreen' => '006400', 'darkkhaki' => 'bdb76b', 'darkmagenta' => '8b008b', 'darkolivegreen' => '556b2f', 'darkorange' => 'ff8c00', 'darkorchid' => '9932cc', 'darkred' => '8b0000', 'darksalmon' => 'e9967a', 'darkseagreen' => '8fbc8f', 'darkslateblue' => '483d8b', 'darkslategray' => '2f4f4f', 'darkslategrey' => '2f4f4f', 'darkturquoise' => '00ced1', 'darkviolet' => '9400d3', 'deeppink' => 'ff1493', 'deepskyblue' => '00bfff', 'dimgray' => '696969', 'dimgrey' => '696969', 'dodgerblue' => '1e90ff', 'firebrick' => 'b22222', 'floralwhite' => 'fffaf0', 'forestgreen' => '228b22', 'fuchsia' => 'ff00ff', 'gainsboro' => 'dcdcdc', 'ghostwhite' => 'f8f8ff', 'gold' => 'ffd700', 'goldenrod' => 'daa520', 'gray' => '808080', 'grey' => '808080', 'green' => '008000', 'greenyellow' => 'adff2f', 'honeydew' => 'f0fff0', 'hotpink' => 'ff69b4', 'indianred' => 'cd5c5c', 'indigo' => '4b0082', 'ivory' => 'fffff0', 'khaki' => 'f0e68c', 'lavender' => 'e6e6fa', 'lavenderblush' => 'fff0f5', 'lawngreen' => '7cfc00', 'lemonchiffon' => 'fffacd', 'lightblue' => 'add8e6', 'lightcoral' => 'f08080', 'lightcyan' => 'e0ffff', 'lightgoldenrodyellow' => 'fafad2', 'ltgray' => 'd3d3d3', 'lightgray' => 'd3d3d3', 'lightgrey' => 'd3d3d3', 'lightgreen' => '90ee90', 'lightpink' => 'ffb6c1', 'lightsalmon' => 'ffa07a', 'lightseagreen' => '20b2aa', 'lightskyblue' => '87cefa', 'lightslategray' => '778899', 'lightslategrey' => '778899', 'lightsteelblue' => 'b0c4de', 'lightyellow' => 'ffffe0', 'lime' => '00ff00', 'limegreen' => '32cd32', 'linen' => 'faf0e6', 'magenta' => 'ff00ff', 'maroon' => '800000', 'mediumaquamarine' => '66cdaa', 'mediumblue' => '0000cd', 'mediumorchid' => 'ba55d3', 'mediumpurple' => '9370d8', 'mediumseagreen' => '3cb371', 'mediumslateblue' => '7b68ee', 'mediumspringgreen' => '00fa9a', 'mediumturquoise' => '48d1cc', 'mediumvioletred' => 'c71585', 'midnightblue' => '191970', 'mintcream' => 'f5fffa', 'mistyrose' => 'ffe4e1', 'moccasin' => 'ffe4b5', 'navajowhite' => 'ffdead', 'navy' => '000080', 'oldlace' => 'fdf5e6', 'olive' => '808000', 'olivedrab' => '6b8e23', 'orange' => 'ffa500', 'orangered' => 'ff4500', 'orchid' => 'da70d6', 'palegoldenrod' => 'eee8aa', 'palegreen' => '98fb98', 'paleturquoise' => 'afeeee', 'palevioletred' => 'd87093', 'papayawhip' => 'ffefd5', 'peachpuff' => 'ffdab9', 'peru' => 'cd853f', 'pink' => 'ffc0cb', 'plum' => 'dda0dd', 'powderblue' => 'b0e0e6', 'purple' => '800080', 'red' => 'ff0000', 'rosybrown' => 'bc8f8f', 'royalblue' => '4169e1', 'saddlebrown' => '8b4513', 'salmon' => 'fa8072', 'sandybrown' => 'f4a460', 'seagreen' => '2e8b57', 'seashell' => 'fff5ee', 'sienna' => 'a0522d', 'silver' => 'c0c0c0', 'skyblue' => '87ceeb', 'slateblue' => '6a5acd', 'slategray' => '708090', 'slategrey' => '708090', 'snow' => 'fffafa', 'springgreen' => '00ff7f', 'steelblue' => '4682b4', 'tan' => 'd2b48c', 'teal' => '008080', 'thistle' => 'd8bfd8', 'tomato' => 'ff6347', 'turquoise' => '40e0d0', 'violet' => 'ee82ee', 'wheat' => 'f5deb3', 'white' => 'ffffff', 'whitesmoke' => 'f5f5f5', 'yellow' => 'ffff00', 'yellowgreen' => '9acd32' ); //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/000077500000000000000000000000001237252063700165145ustar00rootroot00000000000000Collabtive-2.0/include/include/barcodes/000077500000000000000000000000001237252063700202765ustar00rootroot00000000000000Collabtive-2.0/include/include/barcodes/datamatrix.php000066400000000000000000001216521237252063700231540ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // DESCRIPTION : // // Class to create DataMatrix ECC 200 barcode arrays for TCPDF class. // DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code. //============================================================+ /** * @file * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class. * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code. * * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.004 */ // custom definitions if (!defined('DATAMATRIXDEFS')) { /** * Indicate that definitions for this class are set */ define('DATAMATRIXDEFS', true); // ----------------------------------------------------- } // end of custom definitions // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# /** * ASCII encoding: ASCII character 0 to 127 (1 byte per CW) */ define('ENC_ASCII', 0); /** * C40 encoding: Upper-case alphanumeric (3/2 bytes per CW) */ define('ENC_C40', 1); /** * TEXT encoding: Lower-case alphanumeric (3/2 bytes per CW) */ define('ENC_TXT', 2); /** * X12 encoding: ANSI X12 (3/2 byte per CW) */ define('ENC_X12', 3); /** * EDIFACT encoding: ASCII character 32 to 94 (4/3 bytes per CW) */ define('ENC_EDF', 4); /** * BASE 256 encoding: ASCII character 0 to 255 (1 byte per CW) */ define('ENC_BASE256', 5); /** * ASCII extended encoding: ASCII character 128 to 255 (1/2 byte per CW) */ define('ENC_ASCII_EXT', 6); /** * ASCII number encoding: ASCII digits (2 bytes per CW) */ define('ENC_ASCII_NUM', 7); /** * @class Datamatrix * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class. * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code. * * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.004 */ class Datamatrix { /** * Barcode array to be returned which is readable by TCPDF. * @protected */ protected $barcode_array = array(); /** * Store last used encoding for data codewords. * @protected */ protected $last_enc = ENC_ASCII; /** * Table of Data Matrix ECC 200 Symbol Attributes:

        *
      • total matrix rows (including finder pattern)
      • *
      • total matrix cols (including finder pattern)
      • *
      • total matrix rows (without finder pattern)
      • *
      • total matrix cols (without finder pattern)
      • *
      • region data rows (with finder pattern)
      • *
      • region data col (with finder pattern)
      • *
      • region data rows (without finder pattern)
      • *
      • region data col (without finder pattern)
      • *
      • horizontal regions
      • *
      • vertical regions
      • *
      • regions
      • *
      • data codewords
      • *
      • error codewords
      • *
      • blocks
      • *
      • data codewords per block
      • *
      • error codewords per block
      • *
      * @protected */ protected $symbattr = array( // square form --------------------------------------------------------------------------------------- array(0x00a,0x00a,0x008,0x008,0x00a,0x00a,0x008,0x008,0x001,0x001,0x001,0x003,0x005,0x001,0x003,0x005), // 10x10 array(0x00c,0x00c,0x00a,0x00a,0x00c,0x00c,0x00a,0x00a,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007), // 12x12 array(0x00e,0x00e,0x00c,0x00c,0x00e,0x00e,0x00c,0x00c,0x001,0x001,0x001,0x008,0x00a,0x001,0x008,0x00a), // 14x14 array(0x010,0x010,0x00e,0x00e,0x010,0x010,0x00e,0x00e,0x001,0x001,0x001,0x00c,0x00c,0x001,0x00c,0x00c), // 16x16 array(0x012,0x012,0x010,0x010,0x012,0x012,0x010,0x010,0x001,0x001,0x001,0x012,0x00e,0x001,0x012,0x00e), // 18x18 array(0x014,0x014,0x012,0x012,0x014,0x014,0x012,0x012,0x001,0x001,0x001,0x016,0x012,0x001,0x016,0x012), // 20x20 array(0x016,0x016,0x014,0x014,0x016,0x016,0x014,0x014,0x001,0x001,0x001,0x01e,0x014,0x001,0x01e,0x014), // 22x22 array(0x018,0x018,0x016,0x016,0x018,0x018,0x016,0x016,0x001,0x001,0x001,0x024,0x018,0x001,0x024,0x018), // 24x24 array(0x01a,0x01a,0x018,0x018,0x01a,0x01a,0x018,0x018,0x001,0x001,0x001,0x02c,0x01c,0x001,0x02c,0x01c), // 26x26 array(0x020,0x020,0x01c,0x01c,0x010,0x010,0x00e,0x00e,0x002,0x002,0x004,0x03e,0x024,0x001,0x03e,0x024), // 32x32 array(0x024,0x024,0x020,0x020,0x012,0x012,0x010,0x010,0x002,0x002,0x004,0x056,0x02a,0x001,0x056,0x02a), // 36x36 array(0x028,0x028,0x024,0x024,0x014,0x014,0x012,0x012,0x002,0x002,0x004,0x072,0x030,0x001,0x072,0x030), // 40x40 array(0x02c,0x02c,0x028,0x028,0x016,0x016,0x014,0x014,0x002,0x002,0x004,0x090,0x038,0x001,0x090,0x038), // 44x44 array(0x030,0x030,0x02c,0x02c,0x018,0x018,0x016,0x016,0x002,0x002,0x004,0x0ae,0x044,0x001,0x0ae,0x044), // 48x48 array(0x034,0x034,0x030,0x030,0x01a,0x01a,0x018,0x018,0x002,0x002,0x004,0x0cc,0x054,0x002,0x066,0x02a), // 52x52 array(0x040,0x040,0x038,0x038,0x010,0x010,0x00e,0x00e,0x004,0x004,0x010,0x118,0x070,0x002,0x08c,0x038), // 64x64 array(0x048,0x048,0x040,0x040,0x012,0x012,0x010,0x010,0x004,0x004,0x010,0x170,0x090,0x004,0x05c,0x024), // 72x72 array(0x050,0x050,0x048,0x048,0x014,0x014,0x012,0x012,0x004,0x004,0x010,0x1c8,0x0c0,0x004,0x072,0x030), // 80x80 array(0x058,0x058,0x050,0x050,0x016,0x016,0x014,0x014,0x004,0x004,0x010,0x240,0x0e0,0x004,0x090,0x038), // 88x88 array(0x060,0x060,0x058,0x058,0x018,0x018,0x016,0x016,0x004,0x004,0x010,0x2b8,0x110,0x004,0x0ae,0x044), // 96x96 array(0x068,0x068,0x060,0x060,0x01a,0x01a,0x018,0x018,0x004,0x004,0x010,0x330,0x150,0x006,0x088,0x038), // 104x104 array(0x078,0x078,0x06c,0x06c,0x014,0x014,0x012,0x012,0x006,0x006,0x024,0x41a,0x198,0x006,0x0af,0x044), // 120x120 array(0x084,0x084,0x078,0x078,0x016,0x016,0x014,0x014,0x006,0x006,0x024,0x518,0x1f0,0x008,0x0a3,0x03e), // 132x132 array(0x090,0x090,0x084,0x084,0x018,0x018,0x016,0x016,0x006,0x006,0x024,0x616,0x26c,0x00a,0x09c,0x03e), // 144x144 // rectangular form (currently unused) --------------------------------------------------------------------------- array(0x008,0x012,0x006,0x010,0x008,0x012,0x006,0x010,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007), // 8x18 array(0x008,0x020,0x006,0x01c,0x008,0x010,0x006,0x00e,0x001,0x002,0x002,0x00a,0x00b,0x001,0x00a,0x00b), // 8x32 array(0x00c,0x01a,0x00a,0x018,0x00c,0x01a,0x00a,0x018,0x001,0x001,0x001,0x010,0x00e,0x001,0x010,0x00e), // 12x26 array(0x00c,0x024,0x00a,0x020,0x00c,0x012,0x00a,0x010,0x001,0x002,0x002,0x00c,0x012,0x001,0x00c,0x012), // 12x36 array(0x010,0x024,0x00e,0x020,0x010,0x012,0x00e,0x010,0x001,0x002,0x002,0x020,0x018,0x001,0x020,0x018), // 16x36 array(0x010,0x030,0x00e,0x02c,0x010,0x018,0x00e,0x016,0x001,0x002,0x002,0x031,0x01c,0x001,0x031,0x01c) // 16x48 ); /** * Map encodation modes whit character sets. * @protected */ protected $chset_id = array(ENC_C40 => 'C40', ENC_TXT => 'TXT', ENC_X12 =>'X12'); /** * Basic set of characters for each encodation mode. * @protected */ protected $chset = array( 'C40' => array( // Basic set for C40 ---------------------------------------------------------------------------- 'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, // 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13, // 0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d, // 0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27),// 'TXT' => array( // Basic set for TEXT --------------------------------------------------------------------------- 'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, // 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x61=>0x0e,0x62=>0x0f,0x63=>0x10,0x64=>0x11,0x65=>0x12,0x66=>0x13, // 0x67=>0x14,0x68=>0x15,0x69=>0x16,0x6a=>0x17,0x6b=>0x18,0x6c=>0x19,0x6d=>0x1a,0x6e=>0x1b,0x6f=>0x1c,0x70=>0x1d, // 0x71=>0x1e,0x72=>0x1f,0x73=>0x20,0x74=>0x21,0x75=>0x22,0x76=>0x23,0x77=>0x24,0x78=>0x25,0x79=>0x26,0x7a=>0x27),// 'SH1' => array( // Shift 1 set ---------------------------------------------------------------------------------- 0x00=>0x00,0x01=>0x01,0x02=>0x02,0x03=>0x03,0x04=>0x04,0x05=>0x05,0x06=>0x06,0x07=>0x07,0x08=>0x08,0x09=>0x09, // 0x0a=>0x0a,0x0b=>0x0b,0x0c=>0x0c,0x0d=>0x0d,0x0e=>0x0e,0x0f=>0x0f,0x10=>0x10,0x11=>0x11,0x12=>0x12,0x13=>0x13, // 0x14=>0x14,0x15=>0x15,0x16=>0x16,0x17=>0x17,0x18=>0x18,0x19=>0x19,0x1a=>0x1a,0x1b=>0x1b,0x1c=>0x1c,0x1d=>0x1d, // 0x1e=>0x1e,0x1f=>0x1f), // 'SH2' => array( // Shift 2 set ---------------------------------------------------------------------------------- 0x21=>0x00,0x22=>0x01,0x23=>0x02,0x24=>0x03,0x25=>0x04,0x26=>0x05,0x27=>0x06,0x28=>0x07,0x29=>0x08,0x2a=>0x09, // 0x2b=>0x0a,0x2c=>0x0b,0x2d=>0x0c,0x2e=>0x0d,0x2f=>0x0e,0x3a=>0x0f,0x3b=>0x10,0x3c=>0x11,0x3d=>0x12,0x3e=>0x13, // 0x3f=>0x14,0x40=>0x15,0x5b=>0x16,0x5c=>0x17,0x5d=>0x18,0x5e=>0x19,0x5f=>0x1a,'F1'=>0x1b,'US'=>0x1e), // 'S3C' => array( // Shift 3 set for C40 -------------------------------------------------------------------------- 0x60=>0x00,0x61=>0x01,0x62=>0x02,0x63=>0x03,0x64=>0x04,0x65=>0x05,0x66=>0x06,0x67=>0x07,0x68=>0x08,0x69=>0x09, // 0x6a=>0x0a,0x6b=>0x0b,0x6c=>0x0c,0x6d=>0x0d,0x6e=>0x0e,0x6f=>0x0f,0x70=>0x10,0x71=>0x11,0x72=>0x12,0x73=>0x13, // 0x74=>0x14,0x75=>0x15,0x76=>0x16,0x77=>0x17,0x78=>0x18,0x79=>0x19,0x7a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d, // 0x7e=>0x1e,0x7f=>0x1f), 'S3T' => array( // Shift 3 set for TEXT ------------------------------------------------------------------------- 0x60=>0x00,0x41=>0x01,0x42=>0x02,0x43=>0x03,0x44=>0x04,0x45=>0x05,0x46=>0x06,0x47=>0x07,0x48=>0x08,0x49=>0x09, // 0x4a=>0x0a,0x4b=>0x0b,0x4c=>0x0c,0x4d=>0x0d,0x4e=>0x0e,0x4f=>0x0f,0x50=>0x10,0x51=>0x11,0x52=>0x12,0x53=>0x13, // 0x54=>0x14,0x55=>0x15,0x56=>0x16,0x57=>0x17,0x58=>0x18,0x59=>0x19,0x5a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d, // 0x7e=>0x1e,0x7f=>0x1f), // 'X12' => array( // Set for X12 ---------------------------------------------------------------------------------- 0x0d=>0x00,0x2a=>0x01,0x3e=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, // 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13, // 0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d, // 0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27) // ); // ----------------------------------------------------------------------------- /** * This is the class constructor. * Creates a datamatrix object * @param $code (string) Code to represent using Datamatrix. * @public */ public function __construct($code) { $barcode_array = array(); if ((is_null($code)) OR ($code == '\0') OR ($code == '')) { return false; } // get data codewords $cw = $this->getHighLevelEncoding($code); // number of data codewords $nd = count($cw); // check size if ($nd > 1558) { return false; } // get minimum required matrix size. foreach ($this->symbattr as $params) { if ($params[11] >= $nd) { break; } } if ($params[11] < $nd) { // too much data return false; } elseif ($params[11] > $nd) { // add padding if ($this->last_enc == ENC_EDF) { // switch to ASCII encoding $cw[] = 124; ++$nd; } elseif (($this->last_enc != ENC_ASCII) AND ($this->last_enc != ENC_BASE256)) { // switch to ASCII encoding $cw[] = 254; ++$nd; } if ($params[11] > $nd) { // add first pad $cw[] = 129; ++$nd; // add remaining pads for ($i = $nd; $i < $params[11]; ++$i) { $cw[] = $this->get253StateCodeword(129, $i); } } } // add error correction codewords $cw = $this->getErrorCorrection($cw, $params[13], $params[14], $params[15]); // initialize empty arrays $grid = array_fill(0, ($params[2] * $params[3]), 0); // get placement map $places = $this->getPlacementMap($params[2], $params[3]); // fill the grid with data $grid = array(); $i = 0; // region data row max index $rdri = ($params[4] - 1); // region data column max index $rdci = ($params[5] - 1); // for each vertical region for ($vr = 0; $vr < $params[9]; ++$vr) { // for each row on region for ($r = 0; $r < $params[4]; ++$r) { // get row $row = (($vr * $params[4]) + $r); // for each horizontal region for ($hr = 0; $hr < $params[8]; ++$hr) { // for each column on region for ($c = 0; $c < $params[5]; ++$c) { // get column $col = (($hr * $params[5]) + $c); // braw bits by case if ($r == 0) { // top finder pattern if ($c % 2) { $grid[$row][$col] = 0; } else { $grid[$row][$col] = 1; } } elseif ($r == $rdri) { // bottom finder pattern $grid[$row][$col] = 1; } elseif ($c == 0) { // left finder pattern $grid[$row][$col] = 1; } elseif ($c == $rdci) { // right finder pattern if ($r % 2) { $grid[$row][$col] = 1; } else { $grid[$row][$col] = 0; } } else { // data bit if ($places[$i] < 2) { $grid[$row][$col] = $places[$i]; } else { // codeword ID $cw_id = (floor($places[$i] / 10) - 1); // codeword BIT mask $cw_bit = pow(2, (8 - ($places[$i] % 10))); $grid[$row][$col] = (($cw[$cw_id] & $cw_bit) == 0) ? 0 : 1; } ++$i; } } } } } $this->barcode_array['num_rows'] = $params[0]; $this->barcode_array['num_cols'] = $params[1]; $this->barcode_array['bcode'] = $grid; } /** * Returns a barcode array which is readable by TCPDF * @return array barcode array readable by TCPDF; * @public */ public function getBarcodeArray() { return $this->barcode_array; } /** * Product of two numbers in a Power-of-Two Galois Field * @param $a (int) first number to multiply. * @param $b (int) second number to multiply. * @param $log (array) Log table. * @param $alog (array) Anti-Log table. * @param $gf (array) Number of Factors of the Reed-Solomon polynomial. * @return int product * @protected */ protected function getGFProduct($a, $b, $log, $alog, $gf) { if (($a == 0) OR ($b == 0)) { return 0; } return ($alog[($log[$a] + $log[$b]) % ($gf - 1)]); } /** * Add error correction codewords to data codewords array (ANNEX E). * @param $wd (array) Array of datacodewords. * @param $nb (int) Number of blocks. * @param $nd (int) Number of data codewords per block. * @param $nc (int) Number of correction codewords per block. * @param $gf (int) numner of fields on log/antilog table (power of 2). * @param $pp (int) The value of its prime modulus polynomial (301 for ECC200). * @return array data codewords + error codewords * @protected */ protected function getErrorCorrection($wd, $nb, $nd, $nc, $gf=256, $pp=301) { // generate the log ($log) and antilog ($alog) tables $log[0] = 0; $alog[0] = 1; for ($i = 1; $i < $gf; ++$i) { $alog[$i] = ($alog[($i - 1)] * 2); if ($alog[$i] >= $gf) { $alog[$i] ^= $pp; } $log[$alog[$i]] = $i; } ksort($log); // generate the polynomial coefficients (c) $c = array_fill(0, ($nc + 1), 0); $c[0] = 1; for ($i = 1; $i <= $nc; ++$i) { $c[$i] = $c[($i-1)]; for ($j = ($i - 1); $j >= 1; --$j) { $c[$j] = $c[($j - 1)] ^ $this->getGFProduct($c[$j], $alog[$i], $log, $alog, $gf); } $c[0] = $this->getGFProduct($c[0], $alog[$i], $log, $alog, $gf); } ksort($c); // total number of data codewords $num_wd = ($nb * $nd); // total number of error codewords $num_we = ($nb * $nc); // for each block for ($b = 0; $b < $nb; ++$b) { // create interleaved data block $block = array(); for ($n = $b; $n < $num_wd; $n += $nb) { $block[] = $wd[$n]; } // initialize error codewords $we = array_fill(0, ($nc + 1), 0); // calculate error correction codewords for this block for ($i = 0; $i < $nd; ++$i) { $k = ($we[0] ^ $block[$i]); for ($j = 0; $j < $nc; ++$j) { $we[$j] = ($we[($j + 1)] ^ $this->getGFProduct($k, $c[($nc - $j - 1)], $log, $alog, $gf)); } } // add error codewords at the end of data codewords $j = 0; for ($i = $b; $i < $num_we; $i += $nb) { $wd[($num_wd + $i)] = $we[$j]; ++$j; } } // reorder codewords ksort($wd); return $wd; } /** * Return the 253-state codeword * @param $cwpad (int) Pad codeword. * @param $cwpos (int) Number of data codewords from the beginning of encoded data. * @return pad codeword * @protected */ protected function get253StateCodeword($cwpad, $cwpos) { $pad = ($cwpad + (((149 * $cwpos) % 253) + 1)); if ($pad > 254) { $pad -= 254; } return $pad; } /** * Return the 255-state codeword * @param $cwpad (int) Pad codeword. * @param $cwpos (int) Number of data codewords from the beginning of encoded data. * @return pad codeword * @protected */ protected function get255StateCodeword($cwpad, $cwpos) { $pad = ($cwpad + (((149 * $cwpos) % 255) + 1)); if ($pad > 255) { $pad -= 256; } return $pad; } /** * Returns true if the char belongs to the selected mode * @param $chr (int) Character (byte) to check. * @param $mode (int) Current encoding mode. * @return boolean true if the char is of the selected mode. * @protected */ protected function isCharMode($chr, $mode) { $status = false; switch ($mode) { case ENC_ASCII: { // ASCII character 0 to 127 $status = (($chr >= 0) AND ($chr <= 127)); break; } case ENC_C40: { // Upper-case alphanumeric $status = (($chr == 32) OR (($chr >= 48) AND ($chr <= 57)) OR (($chr >= 65) AND ($chr <= 90))); break; } case ENC_TXT: { // Lower-case alphanumeric $status = (($chr == 32) OR (($chr >= 48) AND ($chr <= 57)) OR (($chr >= 97) AND ($chr <= 122))); break; } case ENC_X12: { // ANSI X12 $status = (($chr == 13) OR ($chr == 42) OR ($chr == 62)); break; } case ENC_EDF: { // ASCII character 32 to 94 $status = (($chr >= 32) AND ($chr <= 94)); break; } case ENC_BASE256: { // Function character (FNC1, Structured Append, Reader Program, or Code Page) $status = (($chr == 232) OR ($chr == 233) OR ($chr == 234) OR ($chr == 241)); break; } case ENC_ASCII_EXT: { // ASCII character 128 to 255 $status = (($chr >= 128) AND ($chr <= 255)); break; } case ENC_ASCII_NUM: { // ASCII digits $status = (($chr >= 48) AND ($chr <= 57)); break; } } return $status; } /** * The look-ahead test scans the data to be encoded to find the best mode (Annex P - steps from J to S). * @param $data (string) data to encode * @param $pos (int) current position * @param $mode (int) current encoding mode * @return int encoding mode * @protected */ protected function lookAheadTest($data, $pos, $mode) { $data_length = strlen($data); if ($pos >= $data_length) { return $mode; } $charscount = 0; // count processed chars // STEP J if ($mode == ENC_ASCII) { $numch = array(0, 1, 1, 1, 1, 1.25); } else { $numch = array(1, 2, 2, 2, 2, 2.25); $numch[$mode] = 0; } while (true) { // STEP K if (($pos + $charscount) == $data_length) { if ($numch[ENC_ASCII] <= ceil(min($numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256]))) { return ENC_ASCII; } if ($numch[ENC_BASE256] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF]))) { return ENC_BASE256; } if ($numch[ENC_EDF] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_BASE256]))) { return ENC_EDF; } if ($numch[ENC_TXT] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256]))) { return ENC_TXT; } if ($numch[ENC_X12] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_EDF], $numch[ENC_BASE256]))) { return ENC_X12; } return ENC_C40; } // get char $chr = ord($data[$pos + $charscount]); $charscount++; // STEP L if ($this->isCharMode($chr, ENC_ASCII_NUM)) { $numch[ENC_ASCII] += (1 / 2); } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) { $numch[ENC_ASCII] = ceil($numch[ENC_ASCII]); $numch[ENC_ASCII] += 2; } else { $numch[ENC_ASCII] = ceil($numch[ENC_ASCII]); $numch[ENC_ASCII] += 1; } // STEP M if ($this->isCharMode($chr, ENC_C40)) { $numch[ENC_C40] += (2 / 3); } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) { $numch[ENC_C40] += (8 / 3); } else { $numch[ENC_C40] += (4 / 3); } // STEP N if ($this->isCharMode($chr, ENC_TXT)) { $numch[ENC_TXT] += (2 / 3); } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) { $numch[ENC_TXT] += (8 / 3); } else { $numch[ENC_TXT] += (4 / 3); } // STEP O if ($this->isCharMode($chr, ENC_X12) OR $this->isCharMode($chr, ENC_C40)) { $numch[ENC_X12] += (2 / 3); } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) { $numch[ENC_X12] += (13 / 3); } else { $numch[ENC_X12] += (10 / 3); } // STEP P if ($this->isCharMode($chr, ENC_EDF)) { $numch[ENC_EDF] += (3 / 4); } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) { $numch[ENC_EDF] += (17 / 4); } else { $numch[ENC_EDF] += (13 / 4); } // STEP Q if ($this->isCharMode($chr, ENC_BASE256)) { $numch[ENC_BASE256] += 4; } else { $numch[ENC_BASE256] += 1; } // STEP R if ($charscount >= 4) { if (($numch[ENC_ASCII] + 1) <= min($numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256])) { return ENC_ASCII; } if ((($numch[ENC_BASE256] + 1) <= $numch[ENC_ASCII]) OR (($numch[ENC_BASE256] + 1) < min($numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF]))) { return ENC_BASE256; } if (($numch[ENC_EDF] + 1) < min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_BASE256])) { return ENC_EDF; } if (($numch[ENC_TXT] + 1) < min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256])) { return ENC_TXT; } if (($numch[ENC_X12] + 1) < min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_EDF], $numch[ENC_BASE256])) { return ENC_X12; } if (($numch[ENC_C40] + 1) < min($numch[ENC_ASCII], $numch[ENC_TXT], $numch[ENC_EDF], $numch[ENC_BASE256])) { if ($numch[ENC_C40] < $numch[ENC_X12]) { return ENC_C40; } if ($numch[ENC_C40] == $numch[ENC_X12]) { $k = ($pos + $charscount + 1); while ($k < $data_length) { $tmpchr = ord($data{$k}); if ($this->isCharMode($tmpchr, ENC_X12)) { return ENC_X12; } elseif (!($this->isCharMode($tmpchr, ENC_X12) OR $this->isCharMode($tmpchr, ENC_C40))) { break; } ++$k; } return ENC_C40; } } } } // end of while } /** * Get the switching codeword to a new encoding mode (latch codeword) * @param $mode (int) New encoding mode. * @return (int) Switch codeword. * @protected */ protected function getSwitchEncodingCodeword($mode) { switch ($mode) { case ENC_ASCII: { // ASCII character 0 to 127 $cw = 254; break; } case ENC_C40: { // Upper-case alphanumeric $cw = 230; break; } case ENC_TXT: { // Lower-case alphanumeric $cw = 239; break; } case ENC_X12: { // ANSI X12 $cw = 238; break; } case ENC_EDF: { // ASCII character 32 to 94 $cw = 240; break; } case ENC_BASE256: { // Function character (FNC1, Structured Append, Reader Program, or Code Page) $cw = 231; break; } } return $cw; } /** * Choose the minimum matrix size and return the max number of data codewords. * @param $numcw (int) Number of current codewords. * @return number of data codewords in matrix * @protected */ protected function getMaxDataCodewords($numcw) { foreach ($this->symbattr as $key => $matrix) { if ($matrix[11] >= $numcw) { return $matrix[11]; } } return 0; } /** * Get high level encoding using the minimum symbol data characters for ECC 200 * @param $data (string) data to encode * @return array of codewords * @protected */ protected function getHighLevelEncoding($data) { // STEP A. Start in ASCII encodation. $enc = ENC_ASCII; // current encoding mode $pos = 0; // current position $cw = array(); // array of codewords to be returned $cw_num = 0; // number of data codewords $data_lenght = strlen($data); // number of chars while ($pos < $data_lenght) { switch ($enc) { case ENC_ASCII: { // STEP B. While in ASCII encodation if (($data_lenght > 1) AND ($pos < ($data_lenght - 1)) AND ($this->isCharMode(ord($data[$pos]), ENC_ASCII_NUM) AND $this->isCharMode(ord($data[$pos + 1]), ENC_ASCII_NUM))) { // 1. If the next data sequence is at least 2 consecutive digits, encode the next two digits as a double digit in ASCII mode. $cw[] = (intval(substr($data, $pos, 2)) + 130); ++$cw_num; $pos += 2; } else { // 2. If the look-ahead test (starting at step J) indicates another mode, switch to that mode. $newenc = $this->lookAheadTest($data, $pos, $enc); if ($newenc != $enc) { // switch to new encoding $enc = $newenc; $cw[] = $this->getSwitchEncodingCodeword($enc); ++$cw_num; } else { // get new byte $chr = ord($data[$pos]); ++$pos; if ($this->isCharMode($chr, ENC_ASCII_EXT)) { // 3. If the next data character is extended ASCII (greater than 127) encode it in ASCII mode first using the Upper Shift (value 235) character. $cw[] = 235; $cw[] = ($chr - 127); $cw_num += 2; } else { // 4. Otherwise process the next data character in ASCII encodation. $cw[] = ($chr + 1); ++$cw_num; } } } break; } case ENC_C40 : // Upper-case alphanumeric case ENC_TXT : // Lower-case alphanumeric case ENC_X12 : { // ANSI X12 $temp_cw = array(); $p = 0; $epos = $pos; // get charset ID $set_id = $this->chset_id[$enc]; // get basic charset for current encoding $charset = $this->chset[$set_id]; do { // 2. process the next character in C40 encodation. $chr = ord($data[$epos]); ++$epos; // check for extended character if ($chr & 0x80) { if ($enc == ENC_X12) { return false; } $chr = ($chr & 0x7f); $temp_cw[] = 1; // shift 2 $temp_cw[] = 30; // upper shift $p += 2; } if (isset($charset[$chr])) { $temp_cw[] = $charset[$chr]; ++$p; } else { if (isset($this->chset['SH1'][$chr])) { $temp_cw[] = 0; // shift 1 $shiftset = $this->chset['SH1']; } elseif (isset($chr, $this->chset['SH2'][$chr])) { $temp_cw[] = 1; // shift 2 $shiftset = $this->chset['SH2']; } elseif (($enc == ENC_C40) AND isset($this->chset['S3C'][$chr])) { $temp_cw[] = 2; // shift 3 $shiftset = $this->chset['S3C']; } elseif (($enc == ENC_TXT) AND isset($this->chset['S3T'][$chr])) { $temp_cw[] = 2; // shift 3 $shiftset = $this->chset['S3T']; } else { return false; } $temp_cw[] = $shiftset[$chr]; $p += 2; } if ($p >= 3) { $c1 = array_shift($temp_cw); $c2 = array_shift($temp_cw); $c3 = array_shift($temp_cw); $p -= 3; $tmp = ((1600 * $c1) + (40 * $c2) + $c3 + 1); $cw[] = ($tmp >> 8); $cw[] = ($tmp % 256); $cw_num += 2; $pos = $epos; // 1. If the C40 encoding is at the point of starting a new double symbol character and if the look-ahead test (starting at step J) indicates another mode, switch to that mode. $newenc = $this->lookAheadTest($data, $pos, $enc); if ($newenc != $enc) { $enc = $newenc; $cw[] = $this->getSwitchEncodingCodeword($enc); ++$cw_num; $pos -= $p; $p = 0; break; } } } while (($p > 0) AND ($epos < $data_lenght)); // process last data (if any) if ($p > 0) { // get remaining number of data symbols $cwr = ($this->getMaxDataCodewords($cw_num + 2) - $cw_num); if (($cwr == 1) AND ($p == 1)) { // d. If one symbol character remains and one C40 value (data character) remains to be encoded $c1 = array_shift($temp_cw); --$p; $cw[] = ($c1 + 1); ++$cw_num; } elseif (($cwr == 2) AND ($p == 1)) { // c. If two symbol characters remain and only one C40 value (data character) remains to be encoded $c1 = array_shift($temp_cw); --$p; $cw[] = 254; $cw[] = ($c1 + 1); $cw_num += 2; } elseif (($cwr == 2) AND ($p == 2)) { // b. If two symbol characters remain and two C40 values remain to be encoded $c1 = array_shift($temp_cw); $c2 = array_shift($temp_cw); $p -= 2; $tmp = ((1600 * $c1) + (40 * $c2) + 1); $cw[] = ($tmp >> 8); $cw[] = ($tmp % 256); $cw_num += 2; } else { // switch to ASCII encoding if ($enc != ENC_ASCII) { $enc = ENC_ASCII; $cw[] = $this->getSwitchEncodingCodeword($enc); ++$cw_num; } } } break; } case ENC_EDF: { // F. While in EDIFACT (EDF) encodation // initialize temporary array with 0 lenght $temp_cw = array(); $epos = $pos; $field_lenght = 0; $newenc = $enc; do { // 2. process the next character in EDIFACT encodation. $chr = ord($data[$epos]); if ($this->isCharMode($chr, ENC_EDF)) { ++$epos; $temp_cw[] = $chr; ++$field_lenght; } if (($field_lenght == 4) OR ($epos == $data_lenght) OR !$this->isCharMode($chr, ENC_EDF)) { if ($field_lenght < 4) { // set unlatch character $temp_cw[] = 0x1f; ++$field_lenght; // fill empty characters for ($i = $field_lenght; $i < 4; ++$i) { $temp_cw[] = 0; } $enc = ENC_ASCII; } // encodes four data characters in three codewords $tcw = (($temp_cw[0] & 0x3F) << 2) + (($temp_cw[1] & 0x30) >> 4); if ($tcw > 0) { $cw[] = $tcw; $cw_num++; } $tcw= (($temp_cw[1] & 0x0F) << 4) + (($temp_cw[2] & 0x3C) >> 2); if ($tcw > 0) { $cw[] = $tcw; $cw_num++; } $tcw = (($temp_cw[2] & 0x03) << 6) + ($temp_cw[3] & 0x3F); if ($tcw > 0) { $cw[] = $tcw; $cw_num++; } $temp_cw = array(); $pos = $epos; $field_lenght = 0; if ($enc == ENC_ASCII) { break; // exit from EDIFACT mode } } } while ($epos < $data_lenght); break; } case ENC_BASE256: { // G. While in Base 256 (B256) encodation // initialize temporary array with 0 lenght $temp_cw = array(); $field_lenght = 0; while (($pos < $data_lenght) AND ($field_lenght <= 1555)) { $newenc = $this->lookAheadTest($data, $pos, $enc); if ($newenc != $enc) { // 1. If the look-ahead test (starting at step J) indicates another mode, switch to that mode. $enc = $newenc; $cw[] = $this->getSwitchEncodingCodeword($enc); ++$cw_num; break; // exit from B256 mode } else { // 2. Otherwise, process the next character in Base 256 encodation. $chr = ord($data[$pos]); ++$pos; $temp_cw[] = $chr; ++$field_lenght; } } // set field lenght if ($field_lenght <= 249) { $cw[] = $field_lenght; ++$cw_num; } else { $cw[] = (floor($field_lenght / 250) + 249); $cw[] = ($field_lenght % 250); $cw_num += 2; } if (!empty($temp_cw)) { // add B256 field foreach ($temp_cw as $p => $cht) { $cw[] = $this->get255StateCodeword($chr, ($cw_num + $p)); } } break; } } // end of switch enc } // end of while // set last used encoding $this->last_enc = $enc; return $cw; } /** * Places "chr+bit" with appropriate wrapping within array[]. * (Annex F - ECC 200 symbol character placement) * @param $marr (array) Array of symbols. * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @param $row (int) Row number. * @param $col (int) Column number. * @param $chr (int) Char byte. * @param $bit (int) Bit. * @return array * @protected */ protected function placeModule($marr, $nrow, $ncol, $row, $col, $chr, $bit) { if ($row < 0) { $row += $nrow; $col += (4 - (($nrow + 4) % 8)); } if ($col < 0) { $col += $ncol; $row += (4 - (($ncol + 4) % 8)); } $marr[(($row * $ncol) + $col)] = ((10 * $chr) + $bit); return $marr; } /** * Places the 8 bits of a utah-shaped symbol character. * (Annex F - ECC 200 symbol character placement) * @param $marr (array) Array of symbols. * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @param $row (int) Row number. * @param $col (int) Column number. * @param $chr (int) Char byte. * @return array * @protected */ protected function placeUtah($marr, $nrow, $ncol, $row, $col, $chr) { $marr = $this->placeModule($marr, $nrow, $ncol, $row-2, $col-2, $chr, 1); $marr = $this->placeModule($marr, $nrow, $ncol, $row-2, $col-1, $chr, 2); $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col-2, $chr, 3); $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col-1, $chr, 4); $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col, $chr, 5); $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col-2, $chr, 6); $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col-1, $chr, 7); $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col, $chr, 8); return $marr; } /** * Places the 8 bits of the first special corner case. * (Annex F - ECC 200 symbol character placement) * @param $marr (array) Array of symbols. * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @param $chr (int) Char byte. * @return array * @protected */ protected function placeCornerA($marr, $nrow, $ncol, $chr) { $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 1); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 1, $chr, 2); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 2, $chr, 3); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5); $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 6); $marr = $this->placeModule($marr, $nrow, $ncol, 2, $ncol-1, $chr, 7); $marr = $this->placeModule($marr, $nrow, $ncol, 3, $ncol-1, $chr, 8); return $marr; } /** * Places the 8 bits of the second special corner case. * (Annex F - ECC 200 symbol character placement) * @param $marr (array) Array of symbols. * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @param $chr (int) Char byte. * @return array * @protected */ protected function placeCornerB($marr, $nrow, $ncol, $chr) { $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-3, 0, $chr, 1); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-2, 0, $chr, 2); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 3); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-4, $chr, 4); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-3, $chr, 5); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 6); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 7); $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 8); return $marr; } /** * Places the 8 bits of the third special corner case. * (Annex F - ECC 200 symbol character placement) * @param $marr (array) Array of symbols. * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @param $chr (int) Char byte. * @return array * @protected */ protected function placeCornerC($marr, $nrow, $ncol, $chr) { $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-3, 0, $chr, 1); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-2, 0, $chr, 2); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 3); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5); $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 6); $marr = $this->placeModule($marr, $nrow, $ncol, 2, $ncol-1, $chr, 7); $marr = $this->placeModule($marr, $nrow, $ncol, 3, $ncol-1, $chr, 8); return $marr; } /** * Places the 8 bits of the fourth special corner case. * (Annex F - ECC 200 symbol character placement) * @param $marr (array) Array of symbols. * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @param $chr (int) Char byte. * @return array * @protected */ protected function placeCornerD($marr, $nrow, $ncol, $chr) { $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 1); $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, $ncol-1, $chr, 2); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-3, $chr, 3); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4); $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5); $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-3, $chr, 6); $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-2, $chr, 7); $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 8); return $marr; } /** * Build a placement map. * (Annex F - ECC 200 symbol character placement) * @param $nrow (int) Number of rows. * @param $ncol (int) Number of columns. * @return array * @protected */ protected function getPlacementMap($nrow, $ncol) { // initialize array with zeros $marr = array_fill(0, ($nrow * $ncol), 0); // set starting values $chr = 1; $row = 4; $col = 0; do { // repeatedly first check for one of the special corner cases, then if (($row == $nrow) AND ($col == 0)) { $marr = $this->placeCornerA($marr, $nrow, $ncol, $chr); ++$chr; } if (($row == ($nrow - 2)) AND ($col == 0) AND ($ncol % 4)) { $marr = $this->placeCornerB($marr, $nrow, $ncol, $chr); ++$chr; } if (($row == ($nrow - 2)) AND ($col == 0) AND (($ncol % 8) == 4)) { $marr = $this->placeCornerC($marr, $nrow, $ncol, $chr); ++$chr; } if (($row == ($nrow + 4)) AND ($col == 2) AND (!($ncol % 8))) { $marr = $this->placeCornerD($marr, $nrow, $ncol, $chr); ++$chr; } // sweep upward diagonally, inserting successive characters, do { if (($row < $nrow) AND ($col >= 0) AND (!$marr[(($row * $ncol) + $col)])) { $marr = $this->placeUtah($marr, $nrow, $ncol, $row, $col, $chr); ++$chr; } $row -= 2; $col += 2; } while (($row >= 0) AND ($col < $ncol)); ++$row; $col += 3; // & then sweep downward diagonally, inserting successive characters,... do { if (($row >= 0) AND ($col < $ncol) AND (!$marr[(($row * $ncol) + $col)])) { $marr = $this->placeUtah($marr, $nrow, $ncol, $row, $col, $chr); ++$chr; } $row += 2; $col -= 2; } while (($row < $nrow) AND ($col >= 0)); $row += 3; ++$col; // ... until the entire array is scanned } while (($row < $nrow) OR ($col < $ncol)); // lastly, if the lower righthand corner is untouched, fill in fixed pattern if (!$marr[(($nrow * $ncol) - 1)]) { $marr[(($nrow * $ncol) - 1)] = 1; $marr[(($nrow * $ncol) - $ncol - 2)] = 1; } return $marr; } } // end DataMatrix class //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/barcodes/pdf417.php000066400000000000000000001506601237252063700220240ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // DESCRIPTION : // // Class to create PDF417 barcode arrays for TCPDF class. // PDF417 (ISO/IEC 15438:2006) is a 2-dimensional stacked bar code created by Symbol Technologies in 1991. // It is one of the most popular 2D codes because of its ability to be read with slightly modified handheld laser or linear CCD scanners. // TECHNICAL DATA / FEATURES OF PDF417: // Encodable Character Set: All 128 ASCII Characters (including extended) // Code Type: Continuous, Multi-Row // Symbol Height: 3 - 90 Rows // Symbol Width: 90X - 583X // Bidirectional Decoding: Yes // Error Correction Characters: 2 - 512 // Maximum Data Characters: 1850 text, 2710 digits, 1108 bytes // //============================================================+ /** * @file * Class to create PDF417 barcode arrays for TCPDF class. * PDF417 (ISO/IEC 15438:2006) is a 2-dimensional stacked bar code created by Symbol Technologies in 1991. * (requires PHP bcmath extension) * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.003 */ // definitions if (!defined('PDF417DEFS')) { /** * Indicate that definitions for this class are set */ define('PDF417DEFS', true); // ----------------------------------------------------- /** * Row height respect X dimension of single module */ define('ROWHEIGHT', 4); /** * Horizontal quiet zone in modules */ define('QUIETH', 2); /** * Vertical quiet zone in modules */ define('QUIETV', 2); } // end of definitions // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# /** * @class PDF417 * Class to create PDF417 barcode arrays for TCPDF class. * PDF417 (ISO/IEC 15438:2006) is a 2-dimensional stacked bar code created by Symbol Technologies in 1991. * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.003 */ class PDF417 { /** * Barcode array to be returned which is readable by TCPDF. * @protected */ protected $barcode_array = array(); /** * Start pattern. * @protected */ protected $start_pattern = '11111111010101000'; /** * Stop pattern. * @protected */ protected $stop_pattern = '111111101000101001'; /** * Array of text Compaction Sub-Modes (values 0xFB - 0xFF are used for submode changers). * @protected */ protected $textsubmodes = array( array(0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x20,0xFD,0xFE,0xFF), // Alpha array(0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x20,0xFD,0xFE,0xFF), // Lower array(0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x26,0x0d,0x09,0x2c,0x3a,0x23,0x2d,0x2e,0x24,0x2f,0x2b,0x25,0x2a,0x3d,0x5e,0xFB,0x20,0xFD,0xFE,0xFF), // Mixed array(0x3b,0x3c,0x3e,0x40,0x5b,0x5c,0x5d,0x5f,0x60,0x7e,0x21,0x0d,0x09,0x2c,0x3a,0x0a,0x2d,0x2e,0x24,0x2f,0x22,0x7c,0x2a,0x28,0x29,0x3f,0x7b,0x7d,0x27,0xFF) // Puntuaction ); /** * Array of switching codes for Text Compaction Sub-Modes. * @protected */ protected $textlatch = array( '01' => array(27), '02' => array(28), '03' => array(28,25), // '10' => array(28,28), '12' => array(28), '13' => array(28,25), // '20' => array(28), '21' => array(27), '23' => array(25), // '30' => array(29), '31' => array(29,27), '32' => array(29,28) // ); /** * Clusters of codewords (0, 3, 6)
      * Values are hex equivalents of binary representation of bars (1 = bar, 0 = space).
      * The codewords numbered from 900 to 928 have special meaning, some enable to switch between modes in order to optimise the code:
        *
      • 900 : Switch to "Text" mode
      • *
      • 901 : Switch to "Byte" mode
      • *
      • 902 : Switch to "Numeric" mode
      • *
      • 903 - 912 : Reserved
      • *
      • 913 : Switch to "Octet" only for the next codeword
      • *
      • 914 - 920 : Reserved
      • *
      • 921 : Initialization
      • *
      • 922 : Terminator codeword for Macro PDF control block
      • *
      • 923 : Sequence tag to identify the beginning of optional fields in the Macro PDF control block
      • *
      • 924 : Switch to "Byte" mode (If the total number of byte is multiple of 6)
      • *
      • 925 : Identifier for a user defined Extended Channel Interpretation (ECI)
      • *
      • 926 : Identifier for a general purpose ECI format
      • *
      • 927 : Identifier for an ECI of a character set or code page
      • *
      • 928 : Macro marker codeword to indicate the beginning of a Macro PDF Control Block
      • *
      * @protected */ protected $clusters = array( array( // cluster 0 ----------------------------------------------------------------------- 0x1d5c0,0x1eaf0,0x1f57c,0x1d4e0,0x1ea78,0x1f53e,0x1a8c0,0x1d470,0x1a860,0x15040, // 10 0x1a830,0x15020,0x1adc0,0x1d6f0,0x1eb7c,0x1ace0,0x1d678,0x1eb3e,0x158c0,0x1ac70, // 20 0x15860,0x15dc0,0x1aef0,0x1d77c,0x15ce0,0x1ae78,0x1d73e,0x15c70,0x1ae3c,0x15ef0, // 30 0x1af7c,0x15e78,0x1af3e,0x15f7c,0x1f5fa,0x1d2e0,0x1e978,0x1f4be,0x1a4c0,0x1d270, // 40 0x1e93c,0x1a460,0x1d238,0x14840,0x1a430,0x1d21c,0x14820,0x1a418,0x14810,0x1a6e0, // 50 0x1d378,0x1e9be,0x14cc0,0x1a670,0x1d33c,0x14c60,0x1a638,0x1d31e,0x14c30,0x1a61c, // 60 0x14ee0,0x1a778,0x1d3be,0x14e70,0x1a73c,0x14e38,0x1a71e,0x14f78,0x1a7be,0x14f3c, // 70 0x14f1e,0x1a2c0,0x1d170,0x1e8bc,0x1a260,0x1d138,0x1e89e,0x14440,0x1a230,0x1d11c, // 80 0x14420,0x1a218,0x14410,0x14408,0x146c0,0x1a370,0x1d1bc,0x14660,0x1a338,0x1d19e, // 90 0x14630,0x1a31c,0x14618,0x1460c,0x14770,0x1a3bc,0x14738,0x1a39e,0x1471c,0x147bc, // 100 0x1a160,0x1d0b8,0x1e85e,0x14240,0x1a130,0x1d09c,0x14220,0x1a118,0x1d08e,0x14210, // 110 0x1a10c,0x14208,0x1a106,0x14360,0x1a1b8,0x1d0de,0x14330,0x1a19c,0x14318,0x1a18e, // 120 0x1430c,0x14306,0x1a1de,0x1438e,0x14140,0x1a0b0,0x1d05c,0x14120,0x1a098,0x1d04e, // 130 0x14110,0x1a08c,0x14108,0x1a086,0x14104,0x141b0,0x14198,0x1418c,0x140a0,0x1d02e, // 140 0x1a04c,0x1a046,0x14082,0x1cae0,0x1e578,0x1f2be,0x194c0,0x1ca70,0x1e53c,0x19460, // 150 0x1ca38,0x1e51e,0x12840,0x19430,0x12820,0x196e0,0x1cb78,0x1e5be,0x12cc0,0x19670, // 160 0x1cb3c,0x12c60,0x19638,0x12c30,0x12c18,0x12ee0,0x19778,0x1cbbe,0x12e70,0x1973c, // 170 0x12e38,0x12e1c,0x12f78,0x197be,0x12f3c,0x12fbe,0x1dac0,0x1ed70,0x1f6bc,0x1da60, // 180 0x1ed38,0x1f69e,0x1b440,0x1da30,0x1ed1c,0x1b420,0x1da18,0x1ed0e,0x1b410,0x1da0c, // 190 0x192c0,0x1c970,0x1e4bc,0x1b6c0,0x19260,0x1c938,0x1e49e,0x1b660,0x1db38,0x1ed9e, // 200 0x16c40,0x12420,0x19218,0x1c90e,0x16c20,0x1b618,0x16c10,0x126c0,0x19370,0x1c9bc, // 210 0x16ec0,0x12660,0x19338,0x1c99e,0x16e60,0x1b738,0x1db9e,0x16e30,0x12618,0x16e18, // 220 0x12770,0x193bc,0x16f70,0x12738,0x1939e,0x16f38,0x1b79e,0x16f1c,0x127bc,0x16fbc, // 230 0x1279e,0x16f9e,0x1d960,0x1ecb8,0x1f65e,0x1b240,0x1d930,0x1ec9c,0x1b220,0x1d918, // 240 0x1ec8e,0x1b210,0x1d90c,0x1b208,0x1b204,0x19160,0x1c8b8,0x1e45e,0x1b360,0x19130, // 250 0x1c89c,0x16640,0x12220,0x1d99c,0x1c88e,0x16620,0x12210,0x1910c,0x16610,0x1b30c, // 260 0x19106,0x12204,0x12360,0x191b8,0x1c8de,0x16760,0x12330,0x1919c,0x16730,0x1b39c, // 270 0x1918e,0x16718,0x1230c,0x12306,0x123b8,0x191de,0x167b8,0x1239c,0x1679c,0x1238e, // 280 0x1678e,0x167de,0x1b140,0x1d8b0,0x1ec5c,0x1b120,0x1d898,0x1ec4e,0x1b110,0x1d88c, // 290 0x1b108,0x1d886,0x1b104,0x1b102,0x12140,0x190b0,0x1c85c,0x16340,0x12120,0x19098, // 300 0x1c84e,0x16320,0x1b198,0x1d8ce,0x16310,0x12108,0x19086,0x16308,0x1b186,0x16304, // 310 0x121b0,0x190dc,0x163b0,0x12198,0x190ce,0x16398,0x1b1ce,0x1638c,0x12186,0x16386, // 320 0x163dc,0x163ce,0x1b0a0,0x1d858,0x1ec2e,0x1b090,0x1d84c,0x1b088,0x1d846,0x1b084, // 330 0x1b082,0x120a0,0x19058,0x1c82e,0x161a0,0x12090,0x1904c,0x16190,0x1b0cc,0x19046, // 340 0x16188,0x12084,0x16184,0x12082,0x120d8,0x161d8,0x161cc,0x161c6,0x1d82c,0x1d826, // 350 0x1b042,0x1902c,0x12048,0x160c8,0x160c4,0x160c2,0x18ac0,0x1c570,0x1e2bc,0x18a60, // 360 0x1c538,0x11440,0x18a30,0x1c51c,0x11420,0x18a18,0x11410,0x11408,0x116c0,0x18b70, // 370 0x1c5bc,0x11660,0x18b38,0x1c59e,0x11630,0x18b1c,0x11618,0x1160c,0x11770,0x18bbc, // 380 0x11738,0x18b9e,0x1171c,0x117bc,0x1179e,0x1cd60,0x1e6b8,0x1f35e,0x19a40,0x1cd30, // 390 0x1e69c,0x19a20,0x1cd18,0x1e68e,0x19a10,0x1cd0c,0x19a08,0x1cd06,0x18960,0x1c4b8, // 400 0x1e25e,0x19b60,0x18930,0x1c49c,0x13640,0x11220,0x1cd9c,0x1c48e,0x13620,0x19b18, // 410 0x1890c,0x13610,0x11208,0x13608,0x11360,0x189b8,0x1c4de,0x13760,0x11330,0x1cdde, // 420 0x13730,0x19b9c,0x1898e,0x13718,0x1130c,0x1370c,0x113b8,0x189de,0x137b8,0x1139c, // 430 0x1379c,0x1138e,0x113de,0x137de,0x1dd40,0x1eeb0,0x1f75c,0x1dd20,0x1ee98,0x1f74e, // 440 0x1dd10,0x1ee8c,0x1dd08,0x1ee86,0x1dd04,0x19940,0x1ccb0,0x1e65c,0x1bb40,0x19920, // 450 0x1eedc,0x1e64e,0x1bb20,0x1dd98,0x1eece,0x1bb10,0x19908,0x1cc86,0x1bb08,0x1dd86, // 460 0x19902,0x11140,0x188b0,0x1c45c,0x13340,0x11120,0x18898,0x1c44e,0x17740,0x13320, // 470 0x19998,0x1ccce,0x17720,0x1bb98,0x1ddce,0x18886,0x17710,0x13308,0x19986,0x17708, // 480 0x11102,0x111b0,0x188dc,0x133b0,0x11198,0x188ce,0x177b0,0x13398,0x199ce,0x17798, // 490 0x1bbce,0x11186,0x13386,0x111dc,0x133dc,0x111ce,0x177dc,0x133ce,0x1dca0,0x1ee58, // 500 0x1f72e,0x1dc90,0x1ee4c,0x1dc88,0x1ee46,0x1dc84,0x1dc82,0x198a0,0x1cc58,0x1e62e, // 510 0x1b9a0,0x19890,0x1ee6e,0x1b990,0x1dccc,0x1cc46,0x1b988,0x19884,0x1b984,0x19882, // 520 0x1b982,0x110a0,0x18858,0x1c42e,0x131a0,0x11090,0x1884c,0x173a0,0x13190,0x198cc, // 530 0x18846,0x17390,0x1b9cc,0x11084,0x17388,0x13184,0x11082,0x13182,0x110d8,0x1886e, // 540 0x131d8,0x110cc,0x173d8,0x131cc,0x110c6,0x173cc,0x131c6,0x110ee,0x173ee,0x1dc50, // 550 0x1ee2c,0x1dc48,0x1ee26,0x1dc44,0x1dc42,0x19850,0x1cc2c,0x1b8d0,0x19848,0x1cc26, // 560 0x1b8c8,0x1dc66,0x1b8c4,0x19842,0x1b8c2,0x11050,0x1882c,0x130d0,0x11048,0x18826, // 570 0x171d0,0x130c8,0x19866,0x171c8,0x1b8e6,0x11042,0x171c4,0x130c2,0x171c2,0x130ec, // 580 0x171ec,0x171e6,0x1ee16,0x1dc22,0x1cc16,0x19824,0x19822,0x11028,0x13068,0x170e8, // 590 0x11022,0x13062,0x18560,0x10a40,0x18530,0x10a20,0x18518,0x1c28e,0x10a10,0x1850c, // 600 0x10a08,0x18506,0x10b60,0x185b8,0x1c2de,0x10b30,0x1859c,0x10b18,0x1858e,0x10b0c, // 610 0x10b06,0x10bb8,0x185de,0x10b9c,0x10b8e,0x10bde,0x18d40,0x1c6b0,0x1e35c,0x18d20, // 620 0x1c698,0x18d10,0x1c68c,0x18d08,0x1c686,0x18d04,0x10940,0x184b0,0x1c25c,0x11b40, // 630 0x10920,0x1c6dc,0x1c24e,0x11b20,0x18d98,0x1c6ce,0x11b10,0x10908,0x18486,0x11b08, // 640 0x18d86,0x10902,0x109b0,0x184dc,0x11bb0,0x10998,0x184ce,0x11b98,0x18dce,0x11b8c, // 650 0x10986,0x109dc,0x11bdc,0x109ce,0x11bce,0x1cea0,0x1e758,0x1f3ae,0x1ce90,0x1e74c, // 660 0x1ce88,0x1e746,0x1ce84,0x1ce82,0x18ca0,0x1c658,0x19da0,0x18c90,0x1c64c,0x19d90, // 670 0x1cecc,0x1c646,0x19d88,0x18c84,0x19d84,0x18c82,0x19d82,0x108a0,0x18458,0x119a0, // 680 0x10890,0x1c66e,0x13ba0,0x11990,0x18ccc,0x18446,0x13b90,0x19dcc,0x10884,0x13b88, // 690 0x11984,0x10882,0x11982,0x108d8,0x1846e,0x119d8,0x108cc,0x13bd8,0x119cc,0x108c6, // 700 0x13bcc,0x119c6,0x108ee,0x119ee,0x13bee,0x1ef50,0x1f7ac,0x1ef48,0x1f7a6,0x1ef44, // 710 0x1ef42,0x1ce50,0x1e72c,0x1ded0,0x1ef6c,0x1e726,0x1dec8,0x1ef66,0x1dec4,0x1ce42, // 720 0x1dec2,0x18c50,0x1c62c,0x19cd0,0x18c48,0x1c626,0x1bdd0,0x19cc8,0x1ce66,0x1bdc8, // 730 0x1dee6,0x18c42,0x1bdc4,0x19cc2,0x1bdc2,0x10850,0x1842c,0x118d0,0x10848,0x18426, // 740 0x139d0,0x118c8,0x18c66,0x17bd0,0x139c8,0x19ce6,0x10842,0x17bc8,0x1bde6,0x118c2, // 750 0x17bc4,0x1086c,0x118ec,0x10866,0x139ec,0x118e6,0x17bec,0x139e6,0x17be6,0x1ef28, // 760 0x1f796,0x1ef24,0x1ef22,0x1ce28,0x1e716,0x1de68,0x1ef36,0x1de64,0x1ce22,0x1de62, // 770 0x18c28,0x1c616,0x19c68,0x18c24,0x1bce8,0x19c64,0x18c22,0x1bce4,0x19c62,0x1bce2, // 780 0x10828,0x18416,0x11868,0x18c36,0x138e8,0x11864,0x10822,0x179e8,0x138e4,0x11862, // 790 0x179e4,0x138e2,0x179e2,0x11876,0x179f6,0x1ef12,0x1de34,0x1de32,0x19c34,0x1bc74, // 800 0x1bc72,0x11834,0x13874,0x178f4,0x178f2,0x10540,0x10520,0x18298,0x10510,0x10508, // 810 0x10504,0x105b0,0x10598,0x1058c,0x10586,0x105dc,0x105ce,0x186a0,0x18690,0x1c34c, // 820 0x18688,0x1c346,0x18684,0x18682,0x104a0,0x18258,0x10da0,0x186d8,0x1824c,0x10d90, // 830 0x186cc,0x10d88,0x186c6,0x10d84,0x10482,0x10d82,0x104d8,0x1826e,0x10dd8,0x186ee, // 840 0x10dcc,0x104c6,0x10dc6,0x104ee,0x10dee,0x1c750,0x1c748,0x1c744,0x1c742,0x18650, // 850 0x18ed0,0x1c76c,0x1c326,0x18ec8,0x1c766,0x18ec4,0x18642,0x18ec2,0x10450,0x10cd0, // 860 0x10448,0x18226,0x11dd0,0x10cc8,0x10444,0x11dc8,0x10cc4,0x10442,0x11dc4,0x10cc2, // 870 0x1046c,0x10cec,0x10466,0x11dec,0x10ce6,0x11de6,0x1e7a8,0x1e7a4,0x1e7a2,0x1c728, // 880 0x1cf68,0x1e7b6,0x1cf64,0x1c722,0x1cf62,0x18628,0x1c316,0x18e68,0x1c736,0x19ee8, // 890 0x18e64,0x18622,0x19ee4,0x18e62,0x19ee2,0x10428,0x18216,0x10c68,0x18636,0x11ce8, // 900 0x10c64,0x10422,0x13de8,0x11ce4,0x10c62,0x13de4,0x11ce2,0x10436,0x10c76,0x11cf6, // 910 0x13df6,0x1f7d4,0x1f7d2,0x1e794,0x1efb4,0x1e792,0x1efb2,0x1c714,0x1cf34,0x1c712, // 920 0x1df74,0x1cf32,0x1df72,0x18614,0x18e34,0x18612,0x19e74,0x18e32,0x1bef4), // 929 array( // cluster 3 ----------------------------------------------------------------------- 0x1f560,0x1fab8,0x1ea40,0x1f530,0x1fa9c,0x1ea20,0x1f518,0x1fa8e,0x1ea10,0x1f50c, // 10 0x1ea08,0x1f506,0x1ea04,0x1eb60,0x1f5b8,0x1fade,0x1d640,0x1eb30,0x1f59c,0x1d620, // 20 0x1eb18,0x1f58e,0x1d610,0x1eb0c,0x1d608,0x1eb06,0x1d604,0x1d760,0x1ebb8,0x1f5de, // 30 0x1ae40,0x1d730,0x1eb9c,0x1ae20,0x1d718,0x1eb8e,0x1ae10,0x1d70c,0x1ae08,0x1d706, // 40 0x1ae04,0x1af60,0x1d7b8,0x1ebde,0x15e40,0x1af30,0x1d79c,0x15e20,0x1af18,0x1d78e, // 50 0x15e10,0x1af0c,0x15e08,0x1af06,0x15f60,0x1afb8,0x1d7de,0x15f30,0x1af9c,0x15f18, // 60 0x1af8e,0x15f0c,0x15fb8,0x1afde,0x15f9c,0x15f8e,0x1e940,0x1f4b0,0x1fa5c,0x1e920, // 70 0x1f498,0x1fa4e,0x1e910,0x1f48c,0x1e908,0x1f486,0x1e904,0x1e902,0x1d340,0x1e9b0, // 80 0x1f4dc,0x1d320,0x1e998,0x1f4ce,0x1d310,0x1e98c,0x1d308,0x1e986,0x1d304,0x1d302, // 90 0x1a740,0x1d3b0,0x1e9dc,0x1a720,0x1d398,0x1e9ce,0x1a710,0x1d38c,0x1a708,0x1d386, // 100 0x1a704,0x1a702,0x14f40,0x1a7b0,0x1d3dc,0x14f20,0x1a798,0x1d3ce,0x14f10,0x1a78c, // 110 0x14f08,0x1a786,0x14f04,0x14fb0,0x1a7dc,0x14f98,0x1a7ce,0x14f8c,0x14f86,0x14fdc, // 120 0x14fce,0x1e8a0,0x1f458,0x1fa2e,0x1e890,0x1f44c,0x1e888,0x1f446,0x1e884,0x1e882, // 130 0x1d1a0,0x1e8d8,0x1f46e,0x1d190,0x1e8cc,0x1d188,0x1e8c6,0x1d184,0x1d182,0x1a3a0, // 140 0x1d1d8,0x1e8ee,0x1a390,0x1d1cc,0x1a388,0x1d1c6,0x1a384,0x1a382,0x147a0,0x1a3d8, // 150 0x1d1ee,0x14790,0x1a3cc,0x14788,0x1a3c6,0x14784,0x14782,0x147d8,0x1a3ee,0x147cc, // 160 0x147c6,0x147ee,0x1e850,0x1f42c,0x1e848,0x1f426,0x1e844,0x1e842,0x1d0d0,0x1e86c, // 170 0x1d0c8,0x1e866,0x1d0c4,0x1d0c2,0x1a1d0,0x1d0ec,0x1a1c8,0x1d0e6,0x1a1c4,0x1a1c2, // 180 0x143d0,0x1a1ec,0x143c8,0x1a1e6,0x143c4,0x143c2,0x143ec,0x143e6,0x1e828,0x1f416, // 190 0x1e824,0x1e822,0x1d068,0x1e836,0x1d064,0x1d062,0x1a0e8,0x1d076,0x1a0e4,0x1a0e2, // 200 0x141e8,0x1a0f6,0x141e4,0x141e2,0x1e814,0x1e812,0x1d034,0x1d032,0x1a074,0x1a072, // 210 0x1e540,0x1f2b0,0x1f95c,0x1e520,0x1f298,0x1f94e,0x1e510,0x1f28c,0x1e508,0x1f286, // 220 0x1e504,0x1e502,0x1cb40,0x1e5b0,0x1f2dc,0x1cb20,0x1e598,0x1f2ce,0x1cb10,0x1e58c, // 230 0x1cb08,0x1e586,0x1cb04,0x1cb02,0x19740,0x1cbb0,0x1e5dc,0x19720,0x1cb98,0x1e5ce, // 240 0x19710,0x1cb8c,0x19708,0x1cb86,0x19704,0x19702,0x12f40,0x197b0,0x1cbdc,0x12f20, // 250 0x19798,0x1cbce,0x12f10,0x1978c,0x12f08,0x19786,0x12f04,0x12fb0,0x197dc,0x12f98, // 260 0x197ce,0x12f8c,0x12f86,0x12fdc,0x12fce,0x1f6a0,0x1fb58,0x16bf0,0x1f690,0x1fb4c, // 270 0x169f8,0x1f688,0x1fb46,0x168fc,0x1f684,0x1f682,0x1e4a0,0x1f258,0x1f92e,0x1eda0, // 280 0x1e490,0x1fb6e,0x1ed90,0x1f6cc,0x1f246,0x1ed88,0x1e484,0x1ed84,0x1e482,0x1ed82, // 290 0x1c9a0,0x1e4d8,0x1f26e,0x1dba0,0x1c990,0x1e4cc,0x1db90,0x1edcc,0x1e4c6,0x1db88, // 300 0x1c984,0x1db84,0x1c982,0x1db82,0x193a0,0x1c9d8,0x1e4ee,0x1b7a0,0x19390,0x1c9cc, // 310 0x1b790,0x1dbcc,0x1c9c6,0x1b788,0x19384,0x1b784,0x19382,0x1b782,0x127a0,0x193d8, // 320 0x1c9ee,0x16fa0,0x12790,0x193cc,0x16f90,0x1b7cc,0x193c6,0x16f88,0x12784,0x16f84, // 330 0x12782,0x127d8,0x193ee,0x16fd8,0x127cc,0x16fcc,0x127c6,0x16fc6,0x127ee,0x1f650, // 340 0x1fb2c,0x165f8,0x1f648,0x1fb26,0x164fc,0x1f644,0x1647e,0x1f642,0x1e450,0x1f22c, // 350 0x1ecd0,0x1e448,0x1f226,0x1ecc8,0x1f666,0x1ecc4,0x1e442,0x1ecc2,0x1c8d0,0x1e46c, // 360 0x1d9d0,0x1c8c8,0x1e466,0x1d9c8,0x1ece6,0x1d9c4,0x1c8c2,0x1d9c2,0x191d0,0x1c8ec, // 370 0x1b3d0,0x191c8,0x1c8e6,0x1b3c8,0x1d9e6,0x1b3c4,0x191c2,0x1b3c2,0x123d0,0x191ec, // 380 0x167d0,0x123c8,0x191e6,0x167c8,0x1b3e6,0x167c4,0x123c2,0x167c2,0x123ec,0x167ec, // 390 0x123e6,0x167e6,0x1f628,0x1fb16,0x162fc,0x1f624,0x1627e,0x1f622,0x1e428,0x1f216, // 400 0x1ec68,0x1f636,0x1ec64,0x1e422,0x1ec62,0x1c868,0x1e436,0x1d8e8,0x1c864,0x1d8e4, // 410 0x1c862,0x1d8e2,0x190e8,0x1c876,0x1b1e8,0x1d8f6,0x1b1e4,0x190e2,0x1b1e2,0x121e8, // 420 0x190f6,0x163e8,0x121e4,0x163e4,0x121e2,0x163e2,0x121f6,0x163f6,0x1f614,0x1617e, // 430 0x1f612,0x1e414,0x1ec34,0x1e412,0x1ec32,0x1c834,0x1d874,0x1c832,0x1d872,0x19074, // 440 0x1b0f4,0x19072,0x1b0f2,0x120f4,0x161f4,0x120f2,0x161f2,0x1f60a,0x1e40a,0x1ec1a, // 450 0x1c81a,0x1d83a,0x1903a,0x1b07a,0x1e2a0,0x1f158,0x1f8ae,0x1e290,0x1f14c,0x1e288, // 460 0x1f146,0x1e284,0x1e282,0x1c5a0,0x1e2d8,0x1f16e,0x1c590,0x1e2cc,0x1c588,0x1e2c6, // 470 0x1c584,0x1c582,0x18ba0,0x1c5d8,0x1e2ee,0x18b90,0x1c5cc,0x18b88,0x1c5c6,0x18b84, // 480 0x18b82,0x117a0,0x18bd8,0x1c5ee,0x11790,0x18bcc,0x11788,0x18bc6,0x11784,0x11782, // 490 0x117d8,0x18bee,0x117cc,0x117c6,0x117ee,0x1f350,0x1f9ac,0x135f8,0x1f348,0x1f9a6, // 500 0x134fc,0x1f344,0x1347e,0x1f342,0x1e250,0x1f12c,0x1e6d0,0x1e248,0x1f126,0x1e6c8, // 510 0x1f366,0x1e6c4,0x1e242,0x1e6c2,0x1c4d0,0x1e26c,0x1cdd0,0x1c4c8,0x1e266,0x1cdc8, // 520 0x1e6e6,0x1cdc4,0x1c4c2,0x1cdc2,0x189d0,0x1c4ec,0x19bd0,0x189c8,0x1c4e6,0x19bc8, // 530 0x1cde6,0x19bc4,0x189c2,0x19bc2,0x113d0,0x189ec,0x137d0,0x113c8,0x189e6,0x137c8, // 540 0x19be6,0x137c4,0x113c2,0x137c2,0x113ec,0x137ec,0x113e6,0x137e6,0x1fba8,0x175f0, // 550 0x1bafc,0x1fba4,0x174f8,0x1ba7e,0x1fba2,0x1747c,0x1743e,0x1f328,0x1f996,0x132fc, // 560 0x1f768,0x1fbb6,0x176fc,0x1327e,0x1f764,0x1f322,0x1767e,0x1f762,0x1e228,0x1f116, // 570 0x1e668,0x1e224,0x1eee8,0x1f776,0x1e222,0x1eee4,0x1e662,0x1eee2,0x1c468,0x1e236, // 580 0x1cce8,0x1c464,0x1dde8,0x1cce4,0x1c462,0x1dde4,0x1cce2,0x1dde2,0x188e8,0x1c476, // 590 0x199e8,0x188e4,0x1bbe8,0x199e4,0x188e2,0x1bbe4,0x199e2,0x1bbe2,0x111e8,0x188f6, // 600 0x133e8,0x111e4,0x177e8,0x133e4,0x111e2,0x177e4,0x133e2,0x177e2,0x111f6,0x133f6, // 610 0x1fb94,0x172f8,0x1b97e,0x1fb92,0x1727c,0x1723e,0x1f314,0x1317e,0x1f734,0x1f312, // 620 0x1737e,0x1f732,0x1e214,0x1e634,0x1e212,0x1ee74,0x1e632,0x1ee72,0x1c434,0x1cc74, // 630 0x1c432,0x1dcf4,0x1cc72,0x1dcf2,0x18874,0x198f4,0x18872,0x1b9f4,0x198f2,0x1b9f2, // 640 0x110f4,0x131f4,0x110f2,0x173f4,0x131f2,0x173f2,0x1fb8a,0x1717c,0x1713e,0x1f30a, // 650 0x1f71a,0x1e20a,0x1e61a,0x1ee3a,0x1c41a,0x1cc3a,0x1dc7a,0x1883a,0x1987a,0x1b8fa, // 660 0x1107a,0x130fa,0x171fa,0x170be,0x1e150,0x1f0ac,0x1e148,0x1f0a6,0x1e144,0x1e142, // 670 0x1c2d0,0x1e16c,0x1c2c8,0x1e166,0x1c2c4,0x1c2c2,0x185d0,0x1c2ec,0x185c8,0x1c2e6, // 680 0x185c4,0x185c2,0x10bd0,0x185ec,0x10bc8,0x185e6,0x10bc4,0x10bc2,0x10bec,0x10be6, // 690 0x1f1a8,0x1f8d6,0x11afc,0x1f1a4,0x11a7e,0x1f1a2,0x1e128,0x1f096,0x1e368,0x1e124, // 700 0x1e364,0x1e122,0x1e362,0x1c268,0x1e136,0x1c6e8,0x1c264,0x1c6e4,0x1c262,0x1c6e2, // 710 0x184e8,0x1c276,0x18de8,0x184e4,0x18de4,0x184e2,0x18de2,0x109e8,0x184f6,0x11be8, // 720 0x109e4,0x11be4,0x109e2,0x11be2,0x109f6,0x11bf6,0x1f9d4,0x13af8,0x19d7e,0x1f9d2, // 730 0x13a7c,0x13a3e,0x1f194,0x1197e,0x1f3b4,0x1f192,0x13b7e,0x1f3b2,0x1e114,0x1e334, // 740 0x1e112,0x1e774,0x1e332,0x1e772,0x1c234,0x1c674,0x1c232,0x1cef4,0x1c672,0x1cef2, // 750 0x18474,0x18cf4,0x18472,0x19df4,0x18cf2,0x19df2,0x108f4,0x119f4,0x108f2,0x13bf4, // 760 0x119f2,0x13bf2,0x17af0,0x1bd7c,0x17a78,0x1bd3e,0x17a3c,0x17a1e,0x1f9ca,0x1397c, // 770 0x1fbda,0x17b7c,0x1393e,0x17b3e,0x1f18a,0x1f39a,0x1f7ba,0x1e10a,0x1e31a,0x1e73a, // 780 0x1ef7a,0x1c21a,0x1c63a,0x1ce7a,0x1defa,0x1843a,0x18c7a,0x19cfa,0x1bdfa,0x1087a, // 790 0x118fa,0x139fa,0x17978,0x1bcbe,0x1793c,0x1791e,0x138be,0x179be,0x178bc,0x1789e, // 800 0x1785e,0x1e0a8,0x1e0a4,0x1e0a2,0x1c168,0x1e0b6,0x1c164,0x1c162,0x182e8,0x1c176, // 810 0x182e4,0x182e2,0x105e8,0x182f6,0x105e4,0x105e2,0x105f6,0x1f0d4,0x10d7e,0x1f0d2, // 820 0x1e094,0x1e1b4,0x1e092,0x1e1b2,0x1c134,0x1c374,0x1c132,0x1c372,0x18274,0x186f4, // 830 0x18272,0x186f2,0x104f4,0x10df4,0x104f2,0x10df2,0x1f8ea,0x11d7c,0x11d3e,0x1f0ca, // 840 0x1f1da,0x1e08a,0x1e19a,0x1e3ba,0x1c11a,0x1c33a,0x1c77a,0x1823a,0x1867a,0x18efa, // 850 0x1047a,0x10cfa,0x11dfa,0x13d78,0x19ebe,0x13d3c,0x13d1e,0x11cbe,0x13dbe,0x17d70, // 860 0x1bebc,0x17d38,0x1be9e,0x17d1c,0x17d0e,0x13cbc,0x17dbc,0x13c9e,0x17d9e,0x17cb8, // 870 0x1be5e,0x17c9c,0x17c8e,0x13c5e,0x17cde,0x17c5c,0x17c4e,0x17c2e,0x1c0b4,0x1c0b2, // 880 0x18174,0x18172,0x102f4,0x102f2,0x1e0da,0x1c09a,0x1c1ba,0x1813a,0x1837a,0x1027a, // 890 0x106fa,0x10ebe,0x11ebc,0x11e9e,0x13eb8,0x19f5e,0x13e9c,0x13e8e,0x11e5e,0x13ede, // 900 0x17eb0,0x1bf5c,0x17e98,0x1bf4e,0x17e8c,0x17e86,0x13e5c,0x17edc,0x13e4e,0x17ece, // 910 0x17e58,0x1bf2e,0x17e4c,0x17e46,0x13e2e,0x17e6e,0x17e2c,0x17e26,0x10f5e,0x11f5c, // 920 0x11f4e,0x13f58,0x19fae,0x13f4c,0x13f46,0x11f2e,0x13f6e,0x13f2c,0x13f26), // 929 array( // cluster 6 ----------------------------------------------------------------------- 0x1abe0,0x1d5f8,0x153c0,0x1a9f0,0x1d4fc,0x151e0,0x1a8f8,0x1d47e,0x150f0,0x1a87c, // 10 0x15078,0x1fad0,0x15be0,0x1adf8,0x1fac8,0x159f0,0x1acfc,0x1fac4,0x158f8,0x1ac7e, // 20 0x1fac2,0x1587c,0x1f5d0,0x1faec,0x15df8,0x1f5c8,0x1fae6,0x15cfc,0x1f5c4,0x15c7e, // 30 0x1f5c2,0x1ebd0,0x1f5ec,0x1ebc8,0x1f5e6,0x1ebc4,0x1ebc2,0x1d7d0,0x1ebec,0x1d7c8, // 40 0x1ebe6,0x1d7c4,0x1d7c2,0x1afd0,0x1d7ec,0x1afc8,0x1d7e6,0x1afc4,0x14bc0,0x1a5f0, // 50 0x1d2fc,0x149e0,0x1a4f8,0x1d27e,0x148f0,0x1a47c,0x14878,0x1a43e,0x1483c,0x1fa68, // 60 0x14df0,0x1a6fc,0x1fa64,0x14cf8,0x1a67e,0x1fa62,0x14c7c,0x14c3e,0x1f4e8,0x1fa76, // 70 0x14efc,0x1f4e4,0x14e7e,0x1f4e2,0x1e9e8,0x1f4f6,0x1e9e4,0x1e9e2,0x1d3e8,0x1e9f6, // 80 0x1d3e4,0x1d3e2,0x1a7e8,0x1d3f6,0x1a7e4,0x1a7e2,0x145e0,0x1a2f8,0x1d17e,0x144f0, // 90 0x1a27c,0x14478,0x1a23e,0x1443c,0x1441e,0x1fa34,0x146f8,0x1a37e,0x1fa32,0x1467c, // 100 0x1463e,0x1f474,0x1477e,0x1f472,0x1e8f4,0x1e8f2,0x1d1f4,0x1d1f2,0x1a3f4,0x1a3f2, // 110 0x142f0,0x1a17c,0x14278,0x1a13e,0x1423c,0x1421e,0x1fa1a,0x1437c,0x1433e,0x1f43a, // 120 0x1e87a,0x1d0fa,0x14178,0x1a0be,0x1413c,0x1411e,0x141be,0x140bc,0x1409e,0x12bc0, // 130 0x195f0,0x1cafc,0x129e0,0x194f8,0x1ca7e,0x128f0,0x1947c,0x12878,0x1943e,0x1283c, // 140 0x1f968,0x12df0,0x196fc,0x1f964,0x12cf8,0x1967e,0x1f962,0x12c7c,0x12c3e,0x1f2e8, // 150 0x1f976,0x12efc,0x1f2e4,0x12e7e,0x1f2e2,0x1e5e8,0x1f2f6,0x1e5e4,0x1e5e2,0x1cbe8, // 160 0x1e5f6,0x1cbe4,0x1cbe2,0x197e8,0x1cbf6,0x197e4,0x197e2,0x1b5e0,0x1daf8,0x1ed7e, // 170 0x169c0,0x1b4f0,0x1da7c,0x168e0,0x1b478,0x1da3e,0x16870,0x1b43c,0x16838,0x1b41e, // 180 0x1681c,0x125e0,0x192f8,0x1c97e,0x16de0,0x124f0,0x1927c,0x16cf0,0x1b67c,0x1923e, // 190 0x16c78,0x1243c,0x16c3c,0x1241e,0x16c1e,0x1f934,0x126f8,0x1937e,0x1fb74,0x1f932, // 200 0x16ef8,0x1267c,0x1fb72,0x16e7c,0x1263e,0x16e3e,0x1f274,0x1277e,0x1f6f4,0x1f272, // 210 0x16f7e,0x1f6f2,0x1e4f4,0x1edf4,0x1e4f2,0x1edf2,0x1c9f4,0x1dbf4,0x1c9f2,0x1dbf2, // 220 0x193f4,0x193f2,0x165c0,0x1b2f0,0x1d97c,0x164e0,0x1b278,0x1d93e,0x16470,0x1b23c, // 230 0x16438,0x1b21e,0x1641c,0x1640e,0x122f0,0x1917c,0x166f0,0x12278,0x1913e,0x16678, // 240 0x1b33e,0x1663c,0x1221e,0x1661e,0x1f91a,0x1237c,0x1fb3a,0x1677c,0x1233e,0x1673e, // 250 0x1f23a,0x1f67a,0x1e47a,0x1ecfa,0x1c8fa,0x1d9fa,0x191fa,0x162e0,0x1b178,0x1d8be, // 260 0x16270,0x1b13c,0x16238,0x1b11e,0x1621c,0x1620e,0x12178,0x190be,0x16378,0x1213c, // 270 0x1633c,0x1211e,0x1631e,0x121be,0x163be,0x16170,0x1b0bc,0x16138,0x1b09e,0x1611c, // 280 0x1610e,0x120bc,0x161bc,0x1209e,0x1619e,0x160b8,0x1b05e,0x1609c,0x1608e,0x1205e, // 290 0x160de,0x1605c,0x1604e,0x115e0,0x18af8,0x1c57e,0x114f0,0x18a7c,0x11478,0x18a3e, // 300 0x1143c,0x1141e,0x1f8b4,0x116f8,0x18b7e,0x1f8b2,0x1167c,0x1163e,0x1f174,0x1177e, // 310 0x1f172,0x1e2f4,0x1e2f2,0x1c5f4,0x1c5f2,0x18bf4,0x18bf2,0x135c0,0x19af0,0x1cd7c, // 320 0x134e0,0x19a78,0x1cd3e,0x13470,0x19a3c,0x13438,0x19a1e,0x1341c,0x1340e,0x112f0, // 330 0x1897c,0x136f0,0x11278,0x1893e,0x13678,0x19b3e,0x1363c,0x1121e,0x1361e,0x1f89a, // 340 0x1137c,0x1f9ba,0x1377c,0x1133e,0x1373e,0x1f13a,0x1f37a,0x1e27a,0x1e6fa,0x1c4fa, // 350 0x1cdfa,0x189fa,0x1bae0,0x1dd78,0x1eebe,0x174c0,0x1ba70,0x1dd3c,0x17460,0x1ba38, // 360 0x1dd1e,0x17430,0x1ba1c,0x17418,0x1ba0e,0x1740c,0x132e0,0x19978,0x1ccbe,0x176e0, // 370 0x13270,0x1993c,0x17670,0x1bb3c,0x1991e,0x17638,0x1321c,0x1761c,0x1320e,0x1760e, // 380 0x11178,0x188be,0x13378,0x1113c,0x17778,0x1333c,0x1111e,0x1773c,0x1331e,0x1771e, // 390 0x111be,0x133be,0x177be,0x172c0,0x1b970,0x1dcbc,0x17260,0x1b938,0x1dc9e,0x17230, // 400 0x1b91c,0x17218,0x1b90e,0x1720c,0x17206,0x13170,0x198bc,0x17370,0x13138,0x1989e, // 410 0x17338,0x1b99e,0x1731c,0x1310e,0x1730e,0x110bc,0x131bc,0x1109e,0x173bc,0x1319e, // 420 0x1739e,0x17160,0x1b8b8,0x1dc5e,0x17130,0x1b89c,0x17118,0x1b88e,0x1710c,0x17106, // 430 0x130b8,0x1985e,0x171b8,0x1309c,0x1719c,0x1308e,0x1718e,0x1105e,0x130de,0x171de, // 440 0x170b0,0x1b85c,0x17098,0x1b84e,0x1708c,0x17086,0x1305c,0x170dc,0x1304e,0x170ce, // 450 0x17058,0x1b82e,0x1704c,0x17046,0x1302e,0x1706e,0x1702c,0x17026,0x10af0,0x1857c, // 460 0x10a78,0x1853e,0x10a3c,0x10a1e,0x10b7c,0x10b3e,0x1f0ba,0x1e17a,0x1c2fa,0x185fa, // 470 0x11ae0,0x18d78,0x1c6be,0x11a70,0x18d3c,0x11a38,0x18d1e,0x11a1c,0x11a0e,0x10978, // 480 0x184be,0x11b78,0x1093c,0x11b3c,0x1091e,0x11b1e,0x109be,0x11bbe,0x13ac0,0x19d70, // 490 0x1cebc,0x13a60,0x19d38,0x1ce9e,0x13a30,0x19d1c,0x13a18,0x19d0e,0x13a0c,0x13a06, // 500 0x11970,0x18cbc,0x13b70,0x11938,0x18c9e,0x13b38,0x1191c,0x13b1c,0x1190e,0x13b0e, // 510 0x108bc,0x119bc,0x1089e,0x13bbc,0x1199e,0x13b9e,0x1bd60,0x1deb8,0x1ef5e,0x17a40, // 520 0x1bd30,0x1de9c,0x17a20,0x1bd18,0x1de8e,0x17a10,0x1bd0c,0x17a08,0x1bd06,0x17a04, // 530 0x13960,0x19cb8,0x1ce5e,0x17b60,0x13930,0x19c9c,0x17b30,0x1bd9c,0x19c8e,0x17b18, // 540 0x1390c,0x17b0c,0x13906,0x17b06,0x118b8,0x18c5e,0x139b8,0x1189c,0x17bb8,0x1399c, // 550 0x1188e,0x17b9c,0x1398e,0x17b8e,0x1085e,0x118de,0x139de,0x17bde,0x17940,0x1bcb0, // 560 0x1de5c,0x17920,0x1bc98,0x1de4e,0x17910,0x1bc8c,0x17908,0x1bc86,0x17904,0x17902, // 570 0x138b0,0x19c5c,0x179b0,0x13898,0x19c4e,0x17998,0x1bcce,0x1798c,0x13886,0x17986, // 580 0x1185c,0x138dc,0x1184e,0x179dc,0x138ce,0x179ce,0x178a0,0x1bc58,0x1de2e,0x17890, // 590 0x1bc4c,0x17888,0x1bc46,0x17884,0x17882,0x13858,0x19c2e,0x178d8,0x1384c,0x178cc, // 600 0x13846,0x178c6,0x1182e,0x1386e,0x178ee,0x17850,0x1bc2c,0x17848,0x1bc26,0x17844, // 610 0x17842,0x1382c,0x1786c,0x13826,0x17866,0x17828,0x1bc16,0x17824,0x17822,0x13816, // 620 0x17836,0x10578,0x182be,0x1053c,0x1051e,0x105be,0x10d70,0x186bc,0x10d38,0x1869e, // 630 0x10d1c,0x10d0e,0x104bc,0x10dbc,0x1049e,0x10d9e,0x11d60,0x18eb8,0x1c75e,0x11d30, // 640 0x18e9c,0x11d18,0x18e8e,0x11d0c,0x11d06,0x10cb8,0x1865e,0x11db8,0x10c9c,0x11d9c, // 650 0x10c8e,0x11d8e,0x1045e,0x10cde,0x11dde,0x13d40,0x19eb0,0x1cf5c,0x13d20,0x19e98, // 660 0x1cf4e,0x13d10,0x19e8c,0x13d08,0x19e86,0x13d04,0x13d02,0x11cb0,0x18e5c,0x13db0, // 670 0x11c98,0x18e4e,0x13d98,0x19ece,0x13d8c,0x11c86,0x13d86,0x10c5c,0x11cdc,0x10c4e, // 680 0x13ddc,0x11cce,0x13dce,0x1bea0,0x1df58,0x1efae,0x1be90,0x1df4c,0x1be88,0x1df46, // 690 0x1be84,0x1be82,0x13ca0,0x19e58,0x1cf2e,0x17da0,0x13c90,0x19e4c,0x17d90,0x1becc, // 700 0x19e46,0x17d88,0x13c84,0x17d84,0x13c82,0x17d82,0x11c58,0x18e2e,0x13cd8,0x11c4c, // 710 0x17dd8,0x13ccc,0x11c46,0x17dcc,0x13cc6,0x17dc6,0x10c2e,0x11c6e,0x13cee,0x17dee, // 720 0x1be50,0x1df2c,0x1be48,0x1df26,0x1be44,0x1be42,0x13c50,0x19e2c,0x17cd0,0x13c48, // 730 0x19e26,0x17cc8,0x1be66,0x17cc4,0x13c42,0x17cc2,0x11c2c,0x13c6c,0x11c26,0x17cec, // 740 0x13c66,0x17ce6,0x1be28,0x1df16,0x1be24,0x1be22,0x13c28,0x19e16,0x17c68,0x13c24, // 750 0x17c64,0x13c22,0x17c62,0x11c16,0x13c36,0x17c76,0x1be14,0x1be12,0x13c14,0x17c34, // 760 0x13c12,0x17c32,0x102bc,0x1029e,0x106b8,0x1835e,0x1069c,0x1068e,0x1025e,0x106de, // 770 0x10eb0,0x1875c,0x10e98,0x1874e,0x10e8c,0x10e86,0x1065c,0x10edc,0x1064e,0x10ece, // 780 0x11ea0,0x18f58,0x1c7ae,0x11e90,0x18f4c,0x11e88,0x18f46,0x11e84,0x11e82,0x10e58, // 790 0x1872e,0x11ed8,0x18f6e,0x11ecc,0x10e46,0x11ec6,0x1062e,0x10e6e,0x11eee,0x19f50, // 800 0x1cfac,0x19f48,0x1cfa6,0x19f44,0x19f42,0x11e50,0x18f2c,0x13ed0,0x19f6c,0x18f26, // 810 0x13ec8,0x11e44,0x13ec4,0x11e42,0x13ec2,0x10e2c,0x11e6c,0x10e26,0x13eec,0x11e66, // 820 0x13ee6,0x1dfa8,0x1efd6,0x1dfa4,0x1dfa2,0x19f28,0x1cf96,0x1bf68,0x19f24,0x1bf64, // 830 0x19f22,0x1bf62,0x11e28,0x18f16,0x13e68,0x11e24,0x17ee8,0x13e64,0x11e22,0x17ee4, // 840 0x13e62,0x17ee2,0x10e16,0x11e36,0x13e76,0x17ef6,0x1df94,0x1df92,0x19f14,0x1bf34, // 850 0x19f12,0x1bf32,0x11e14,0x13e34,0x11e12,0x17e74,0x13e32,0x17e72,0x1df8a,0x19f0a, // 860 0x1bf1a,0x11e0a,0x13e1a,0x17e3a,0x1035c,0x1034e,0x10758,0x183ae,0x1074c,0x10746, // 870 0x1032e,0x1076e,0x10f50,0x187ac,0x10f48,0x187a6,0x10f44,0x10f42,0x1072c,0x10f6c, // 880 0x10726,0x10f66,0x18fa8,0x1c7d6,0x18fa4,0x18fa2,0x10f28,0x18796,0x11f68,0x18fb6, // 890 0x11f64,0x10f22,0x11f62,0x10716,0x10f36,0x11f76,0x1cfd4,0x1cfd2,0x18f94,0x19fb4, // 900 0x18f92,0x19fb2,0x10f14,0x11f34,0x10f12,0x13f74,0x11f32,0x13f72,0x1cfca,0x18f8a, // 910 0x19f9a,0x10f0a,0x11f1a,0x13f3a,0x103ac,0x103a6,0x107a8,0x183d6,0x107a4,0x107a2, // 920 0x10396,0x107b6,0x187d4,0x187d2,0x10794,0x10fb4,0x10792,0x10fb2,0x1c7ea) // 929 ); // end of $clusters array /** * Array of factors of the Reed-Solomon polynomial equations used for error correction; one sub array for each correction level (0-8). * @protected */ protected $rsfactors = array( array( // ECL 0 (2 factors) ------------------------------------------------------------------------------- 0x01b,0x395), // 2 array( // ECL 1 (4 factors) ------------------------------------------------------------------------------- 0x20a,0x238,0x2d3,0x329), // 4 array( // ECL 2 (8 factors) ------------------------------------------------------------------------------- 0x0ed,0x134,0x1b4,0x11c,0x286,0x28d,0x1ac,0x17b), // 8 array( // ECL 3 (16 factors) ------------------------------------------------------------------------------ 0x112,0x232,0x0e8,0x2f3,0x257,0x20c,0x321,0x084,0x127,0x074,0x1ba,0x1ac,0x127,0x02a,0x0b0,0x041),// 16 array( // ECL 4 (32 factors) ------------------------------------------------------------------------------ 0x169,0x23f,0x39a,0x20d,0x0b0,0x24a,0x280,0x141,0x218,0x2e6,0x2a5,0x2e6,0x2af,0x11c,0x0c1,0x205, // 16 0x111,0x1ee,0x107,0x093,0x251,0x320,0x23b,0x140,0x323,0x085,0x0e7,0x186,0x2ad,0x14a,0x03f,0x19a),// 32 array( // ECL 5 (64 factors) ------------------------------------------------------------------------------ 0x21b,0x1a6,0x006,0x05d,0x35e,0x303,0x1c5,0x06a,0x262,0x11f,0x06b,0x1f9,0x2dd,0x36d,0x17d,0x264, // 16 0x2d3,0x1dc,0x1ce,0x0ac,0x1ae,0x261,0x35a,0x336,0x21f,0x178,0x1ff,0x190,0x2a0,0x2fa,0x11b,0x0b8, // 32 0x1b8,0x023,0x207,0x01f,0x1cc,0x252,0x0e1,0x217,0x205,0x160,0x25d,0x09e,0x28b,0x0c9,0x1e8,0x1f6, // 48 0x288,0x2dd,0x2cd,0x053,0x194,0x061,0x118,0x303,0x348,0x275,0x004,0x17d,0x34b,0x26f,0x108,0x21f),// 64 array( // ECL 6 (128 factors) ----------------------------------------------------------------------------- 0x209,0x136,0x360,0x223,0x35a,0x244,0x128,0x17b,0x035,0x30b,0x381,0x1bc,0x190,0x39d,0x2ed,0x19f, // 16 0x336,0x05d,0x0d9,0x0d0,0x3a0,0x0f4,0x247,0x26c,0x0f6,0x094,0x1bf,0x277,0x124,0x38c,0x1ea,0x2c0, // 32 0x204,0x102,0x1c9,0x38b,0x252,0x2d3,0x2a2,0x124,0x110,0x060,0x2ac,0x1b0,0x2ae,0x25e,0x35c,0x239, // 48 0x0c1,0x0db,0x081,0x0ba,0x0ec,0x11f,0x0c0,0x307,0x116,0x0ad,0x028,0x17b,0x2c8,0x1cf,0x286,0x308, // 64 0x0ab,0x1eb,0x129,0x2fb,0x09c,0x2dc,0x05f,0x10e,0x1bf,0x05a,0x1fb,0x030,0x0e4,0x335,0x328,0x382, // 80 0x310,0x297,0x273,0x17a,0x17e,0x106,0x17c,0x25a,0x2f2,0x150,0x059,0x266,0x057,0x1b0,0x29e,0x268, // 96 0x09d,0x176,0x0f2,0x2d6,0x258,0x10d,0x177,0x382,0x34d,0x1c6,0x162,0x082,0x32e,0x24b,0x324,0x022, // 112 0x0d3,0x14a,0x21b,0x129,0x33b,0x361,0x025,0x205,0x342,0x13b,0x226,0x056,0x321,0x004,0x06c,0x21b),// 128 array( // ECL 7 (256 factors) ----------------------------------------------------------------------------- 0x20c,0x37e,0x04b,0x2fe,0x372,0x359,0x04a,0x0cc,0x052,0x24a,0x2c4,0x0fa,0x389,0x312,0x08a,0x2d0, // 16 0x35a,0x0c2,0x137,0x391,0x113,0x0be,0x177,0x352,0x1b6,0x2dd,0x0c2,0x118,0x0c9,0x118,0x33c,0x2f5, // 32 0x2c6,0x32e,0x397,0x059,0x044,0x239,0x00b,0x0cc,0x31c,0x25d,0x21c,0x391,0x321,0x2bc,0x31f,0x089, // 48 0x1b7,0x1a2,0x250,0x29c,0x161,0x35b,0x172,0x2b6,0x145,0x0f0,0x0d8,0x101,0x11c,0x225,0x0d1,0x374, // 64 0x13b,0x046,0x149,0x319,0x1ea,0x112,0x36d,0x0a2,0x2ed,0x32c,0x2ac,0x1cd,0x14e,0x178,0x351,0x209, // 80 0x133,0x123,0x323,0x2c8,0x013,0x166,0x18f,0x38c,0x067,0x1ff,0x033,0x008,0x205,0x0e1,0x121,0x1d6, // 96 0x27d,0x2db,0x042,0x0ff,0x395,0x10d,0x1cf,0x33e,0x2da,0x1b1,0x350,0x249,0x088,0x21a,0x38a,0x05a, // 112 0x002,0x122,0x2e7,0x0c7,0x28f,0x387,0x149,0x031,0x322,0x244,0x163,0x24c,0x0bc,0x1ce,0x00a,0x086, // 128 0x274,0x140,0x1df,0x082,0x2e3,0x047,0x107,0x13e,0x176,0x259,0x0c0,0x25d,0x08e,0x2a1,0x2af,0x0ea, // 144 0x2d2,0x180,0x0b1,0x2f0,0x25f,0x280,0x1c7,0x0c1,0x2b1,0x2c3,0x325,0x281,0x030,0x03c,0x2dc,0x26d, // 160 0x37f,0x220,0x105,0x354,0x28f,0x135,0x2b9,0x2f3,0x2f4,0x03c,0x0e7,0x305,0x1b2,0x1a5,0x2d6,0x210, // 176 0x1f7,0x076,0x031,0x31b,0x020,0x090,0x1f4,0x0ee,0x344,0x18a,0x118,0x236,0x13f,0x009,0x287,0x226, // 192 0x049,0x392,0x156,0x07e,0x020,0x2a9,0x14b,0x318,0x26c,0x03c,0x261,0x1b9,0x0b4,0x317,0x37d,0x2f2, // 208 0x25d,0x17f,0x0e4,0x2ed,0x2f8,0x0d5,0x036,0x129,0x086,0x036,0x342,0x12b,0x39a,0x0bf,0x38e,0x214, // 224 0x261,0x33d,0x0bd,0x014,0x0a7,0x01d,0x368,0x1c1,0x053,0x192,0x029,0x290,0x1f9,0x243,0x1e1,0x0ad, // 240 0x194,0x0fb,0x2b0,0x05f,0x1f1,0x22b,0x282,0x21f,0x133,0x09f,0x39c,0x22e,0x288,0x037,0x1f1,0x00a),// 256 array( // ECL 8 (512 factors) ----------------------------------------------------------------------------- 0x160,0x04d,0x175,0x1f8,0x023,0x257,0x1ac,0x0cf,0x199,0x23e,0x076,0x1f2,0x11d,0x17c,0x15e,0x1ec, // 16 0x0c5,0x109,0x398,0x09b,0x392,0x12b,0x0e5,0x283,0x126,0x367,0x132,0x058,0x057,0x0c1,0x160,0x30d, // 32 0x34e,0x04b,0x147,0x208,0x1b3,0x21f,0x0cb,0x29a,0x0f9,0x15a,0x30d,0x26d,0x280,0x10c,0x31a,0x216, // 48 0x21b,0x30d,0x198,0x186,0x284,0x066,0x1dc,0x1f3,0x122,0x278,0x221,0x025,0x35a,0x394,0x228,0x029, // 64 0x21e,0x121,0x07a,0x110,0x17f,0x320,0x1e5,0x062,0x2f0,0x1d8,0x2f9,0x06b,0x310,0x35c,0x292,0x2e5, // 80 0x122,0x0cc,0x2a9,0x197,0x357,0x055,0x063,0x03e,0x1e2,0x0b4,0x014,0x129,0x1c3,0x251,0x391,0x08e, // 96 0x328,0x2ac,0x11f,0x218,0x231,0x04c,0x28d,0x383,0x2d9,0x237,0x2e8,0x186,0x201,0x0c0,0x204,0x102, // 112 0x0f0,0x206,0x31a,0x18b,0x300,0x350,0x033,0x262,0x180,0x0a8,0x0be,0x33a,0x148,0x254,0x312,0x12f, // 128 0x23a,0x17d,0x19f,0x281,0x09c,0x0ed,0x097,0x1ad,0x213,0x0cf,0x2a4,0x2c6,0x059,0x0a8,0x130,0x192, // 144 0x028,0x2c4,0x23f,0x0a2,0x360,0x0e5,0x041,0x35d,0x349,0x200,0x0a4,0x1dd,0x0dd,0x05c,0x166,0x311, // 160 0x120,0x165,0x352,0x344,0x33b,0x2e0,0x2c3,0x05e,0x008,0x1ee,0x072,0x209,0x002,0x1f3,0x353,0x21f, // 176 0x098,0x2d9,0x303,0x05f,0x0f8,0x169,0x242,0x143,0x358,0x31d,0x121,0x033,0x2ac,0x1d2,0x215,0x334, // 192 0x29d,0x02d,0x386,0x1c4,0x0a7,0x156,0x0f4,0x0ad,0x023,0x1cf,0x28b,0x033,0x2bb,0x24f,0x1c4,0x242, // 208 0x025,0x07c,0x12a,0x14c,0x228,0x02b,0x1ab,0x077,0x296,0x309,0x1db,0x352,0x2fc,0x16c,0x242,0x38f, // 224 0x11b,0x2c7,0x1d8,0x1a4,0x0f5,0x120,0x252,0x18a,0x1ff,0x147,0x24d,0x309,0x2bb,0x2b0,0x02b,0x198, // 240 0x34a,0x17f,0x2d1,0x209,0x230,0x284,0x2ca,0x22f,0x03e,0x091,0x369,0x297,0x2c9,0x09f,0x2a0,0x2d9, // 256 0x270,0x03b,0x0c1,0x1a1,0x09e,0x0d1,0x233,0x234,0x157,0x2b5,0x06d,0x260,0x233,0x16d,0x0b5,0x304, // 272 0x2a5,0x136,0x0f8,0x161,0x2c4,0x19a,0x243,0x366,0x269,0x349,0x278,0x35c,0x121,0x218,0x023,0x309, // 288 0x26a,0x24a,0x1a8,0x341,0x04d,0x255,0x15a,0x10d,0x2f5,0x278,0x2b7,0x2ef,0x14b,0x0f7,0x0b8,0x02d, // 304 0x313,0x2a8,0x012,0x042,0x197,0x171,0x036,0x1ec,0x0e4,0x265,0x33e,0x39a,0x1b5,0x207,0x284,0x389, // 320 0x315,0x1a4,0x131,0x1b9,0x0cf,0x12c,0x37c,0x33b,0x08d,0x219,0x17d,0x296,0x201,0x038,0x0fc,0x155, // 336 0x0f2,0x31d,0x346,0x345,0x2d0,0x0e0,0x133,0x277,0x03d,0x057,0x230,0x136,0x2f4,0x299,0x18d,0x328, // 352 0x353,0x135,0x1d9,0x31b,0x17a,0x01f,0x287,0x393,0x1cb,0x326,0x24e,0x2db,0x1a9,0x0d8,0x224,0x0f9, // 368 0x141,0x371,0x2bb,0x217,0x2a1,0x30e,0x0d2,0x32f,0x389,0x12f,0x34b,0x39a,0x119,0x049,0x1d5,0x317, // 384 0x294,0x0a2,0x1f2,0x134,0x09b,0x1a6,0x38b,0x331,0x0bb,0x03e,0x010,0x1a9,0x217,0x150,0x11e,0x1b5, // 400 0x177,0x111,0x262,0x128,0x0b7,0x39b,0x074,0x29b,0x2ef,0x161,0x03e,0x16e,0x2b3,0x17b,0x2af,0x34a, // 416 0x025,0x165,0x2d0,0x2e6,0x14a,0x005,0x027,0x39b,0x137,0x1a8,0x0f2,0x2ed,0x141,0x036,0x29d,0x13c, // 432 0x156,0x12b,0x216,0x069,0x29b,0x1e8,0x280,0x2a0,0x240,0x21c,0x13c,0x1e6,0x2d1,0x262,0x02e,0x290, // 448 0x1bf,0x0ab,0x268,0x1d0,0x0be,0x213,0x129,0x141,0x2fa,0x2f0,0x215,0x0af,0x086,0x00e,0x17d,0x1b1, // 464 0x2cd,0x02d,0x06f,0x014,0x254,0x11c,0x2e0,0x08a,0x286,0x19b,0x36d,0x29d,0x08d,0x397,0x02d,0x30c, // 480 0x197,0x0a4,0x14c,0x383,0x0a5,0x2d6,0x258,0x145,0x1f2,0x28f,0x165,0x2f0,0x300,0x0df,0x351,0x287, // 496 0x03f,0x136,0x35f,0x0fb,0x16e,0x130,0x11a,0x2e2,0x2a3,0x19a,0x185,0x0f4,0x01f,0x079,0x12f,0x107) // 512 ); /** * This is the class constructor. * Creates a PDF417 object * @param $code (string) code to represent using PDF417 * @param $ecl (int) error correction level (0-8); default -1 = automatic correction level * @param $aspectratio (float) the width to height of the symbol (excluding quiet zones) * @param $macro (array) information for macro block * @public */ public function __construct($code, $ecl=-1, $aspectratio=2, $macro=array()) { $barcode_array = array(); if ((is_null($code)) OR ($code == '\0') OR ($code == '')) { return false; } // get the input sequence array $sequence = $this->getInputSequences($code); $codewords = array(); // array of code-words foreach($sequence as $seq) { $cw = $this->getCompaction($seq[0], $seq[1], true); $codewords = array_merge($codewords, $cw); } if ($codewords[0] == 900) { // Text Alpha is the default mode, so remove the first code array_shift($codewords); } // count number of codewords $numcw = count($codewords); if ($numcw > 925) { // reached maximum data codeword capacity return false; } // build macro control block codewords if (!empty($macro)) { $macrocw = array(); // beginning of macro control block $macrocw[] = 928; // segment index $cw = $this->getCompaction(902, sprintf('%05d', $macro['segment_index']), false); $macrocw = array_merge($macrocw, $cw); // file ID $cw = $this->getCompaction(900, $macro['file_id'], false); $macrocw = array_merge($macrocw, $cw); // optional fields $optmodes = array(900,902,902,900,900,902,902); $optsize = array(-1,2,4,-1,-1,-1,2); foreach ($optmodes as $k => $omode) { if (isset($macro['option_'.$k])) { $macrocw[] = 923; $macrocw[] = $k; if ($optsize[$k] == 2) { $macro['option_'.$k] = sprintf('%05d', $macro['option_'.$k]); } elseif ($optsize[$k] == 4) { $macro['option_'.$k] = sprintf('%010d', $macro['option_'.$k]); } $cw = $this->getCompaction($omode, $macro['option_'.$k], false); $macrocw = array_merge($macrocw, $cw); } } if ($macro['segment_index'] == ($macro['segment_total'] - 1)) { // end of control block $macrocw[] = 922; } // update total codewords $numcw += count($macrocw); } // set error correction level $ecl = $this->getErrorCorrectionLevel($ecl, $numcw); // number of codewords for error correction $errsize = (2 << $ecl); // calculate number of columns (number of codewords per row) and rows $nce = ($numcw + $errsize + 1); $cols = round((sqrt(4761 + (68 * $aspectratio * ROWHEIGHT * $nce)) - 69) / 34); // adjust cols if ($cols < 1) { $cols = 1; } elseif ($cols > 30) { $cols = 30; } $rows = ceil($nce / $cols); $size = ($cols * $rows); // adjust rows if (($rows < 3) OR ($rows > 90)) { if ($rows < 3) { $rows = 3; } elseif ($rows > 90) { $rows = 90; } $cols = ceil($size / $rows); $size = ($cols * $rows); } if ($size > 928) { // set dimensions to get maximum capacity if (abs($aspectratio - (17 * 29 / 32)) < abs($aspectratio - (17 * 16 / 58))) { $cols = 29; $rows = 32; } else { $cols = 16; $rows = 58; } $size = 928; } // calculate padding $pad = ($size - $nce); if ($pad > 0) { if (($size - $rows) == $nce) { --$rows; $size -= $rows; } else { // add pading $codewords = array_merge($codewords, array_fill(0, $pad, 900)); } } if (!empty($macro)) { // add macro section $codewords = array_merge($codewords, $macrocw); } // Symbol Lenght Descriptor (number of data codewords including Symbol Lenght Descriptor and pad codewords) $sld = $size - $errsize; // add symbol length description array_unshift($codewords, $sld); // calculate error correction $ecw = $this->getErrorCorrection($codewords, $ecl); // add error correction codewords $codewords = array_merge($codewords, $ecw); // add horizontal quiet zones to start and stop patterns $pstart = str_repeat('0', QUIETH).$this->start_pattern; $pstop = $this->stop_pattern.str_repeat('0', QUIETH); $barcode_array['num_rows'] = ($rows * ROWHEIGHT) + (2 * QUIETV); $barcode_array['num_cols'] = (($cols + 2) * 17) + 35 + (2 * QUIETH); $barcode_array['bcode'] = array(); // build rows for vertical quiet zone if (QUIETV > 0) { $empty_row = array_fill(0, $barcode_array['num_cols'], 0); for ($i = 0; $i < QUIETV; ++$i) { // add vertical quiet rows $barcode_array['bcode'][] = $empty_row; } } $k = 0; // codeword index $cid = 0; // initial cluster // for each row for ($r = 0; $r < $rows; ++$r) { // row start code $row = $pstart; switch ($cid) { case 0: { $L = ((30 * intval($r / 3)) + intval(($rows - 1) / 3)); break; } case 1: { $L = ((30 * intval($r / 3)) + ($ecl * 3) + (($rows - 1) % 3)); break; } case 2: { $L = ((30 * intval($r / 3)) + ($cols - 1)); break; } } // left row indicator $row .= sprintf('%17b', $this->clusters[$cid][$L]); // for each column for ($c = 0; $c < $cols; ++$c) { $row .= sprintf('%17b', $this->clusters[$cid][$codewords[$k]]); ++$k; } switch ($cid) { case 0: { $L = ((30 * intval($r / 3)) + ($cols - 1)); break; } case 1: { $L = ((30 * intval($r / 3)) + intval(($rows - 1) / 3)); break; } case 2: { $L = ((30 * intval($r / 3)) + ($ecl * 3) + (($rows - 1) % 3)); break; } } // right row indicator $row .= sprintf('%17b', $this->clusters[$cid][$L]); // row stop code $row .= $pstop; // convert the string to array $arow = preg_split('//', $row, -1, PREG_SPLIT_NO_EMPTY); // duplicate row to get the desired height for ($h = 0; $h < ROWHEIGHT; ++$h) { $barcode_array['bcode'][] = $arow; } ++$cid; if ($cid > 2) { $cid = 0; } } if (QUIETV > 0) { for ($i = 0; $i < QUIETV; ++$i) { // add vertical quiet rows $barcode_array['bcode'][] = $empty_row; } } $this->barcode_array = $barcode_array; } /** * Returns a barcode array which is readable by TCPDF * @return array barcode array readable by TCPDF; * @public */ public function getBarcodeArray() { return $this->barcode_array; } /** * Returns the error correction level (0-8) to be used * @param $ecl (int) error correction level * @param $numcw (int) number of data codewords * @return int error correction level * @protected */ protected function getErrorCorrectionLevel($ecl, $numcw) { // get maximum correction level $maxecl = 8; // starting error level $maxerrsize = (928 - $numcw); // available codewords for error while ($maxecl > 0) { $errsize = (2 << $ecl); if ($maxerrsize >= $errsize) { break; } --$maxecl; } // check for automatic levels if (($ecl < 0) OR ($ecl > 8)) { if ($numcw < 41) { $ecl = 2; } elseif ($numcw < 161) { $ecl = 3; } elseif ($numcw < 321) { $ecl = 4; } elseif ($numcw < 864) { $ecl = 5; } else { $ecl = $maxecl; } } if ($ecl > $maxecl) { $ecl = $maxecl; } return $ecl; } /** * Returns the error correction codewords * @param $cw (array) array of codewords including Symbol Lenght Descriptor and pad * @param $ecl (int) error correction level 0-8 * @return array of error correction codewords * @protected */ protected function getErrorCorrection($cw, $ecl) { // get error correction coefficients $ecc = $this->rsfactors[$ecl]; // number of error correction factors $eclsize = (2 << $ecl); // maximum index for $rsfactors[$ecl] $eclmaxid = ($eclsize - 1); // initialize array of error correction codewords $ecw = array_fill(0, $eclsize, 0); // for each data codeword foreach($cw as $k => $d) { $t1 = ($d + $ecw[$eclmaxid]) % 929; for ($j = $eclmaxid; $j > 0; --$j) { $t2 = ($t1 * $ecc[$j]) % 929; $t3 = 929 - $t2; $ecw[$j] = ($ecw[($j - 1)] + $t3) % 929; } $t2 = ($t1 * $ecc[0]) % 929; $t3 = 929 - $t2; $ecw[0] = $t3 % 929; } foreach($ecw as $j => $e) { if ($e != 0) { $ecw[$j] = 929 - $e; } } $ecw = array_reverse($ecw); return $ecw; } /** * Create array of sequences from input * @param $code (string) code * @return bidimensional array containing characters and classification * @protected */ protected function getInputSequences($code) { $sequence_array = array(); // array to be returned $numseq = array(); // get numeric sequences preg_match_all('/([0-9]{13,44})/', $code, $numseq, PREG_OFFSET_CAPTURE); $numseq[1][] = array('', strlen($code)); $offset = 0; foreach($numseq[1] as $seq) { $seqlen = strlen($seq[0]); if ($seq[1] > 0) { // extract text sequence before the number sequence $prevseq = substr($code, $offset, ($seq[1] - $offset)); $textseq = array(); // get text sequences preg_match_all('/([\x09\x0a\x0d\x20-\x7e]{5,})/', $prevseq, $textseq, PREG_OFFSET_CAPTURE); $textseq[1][] = array('', strlen($prevseq)); $txtoffset = 0; foreach($textseq[1] as $txtseq) { $txtseqlen = strlen($txtseq[0]); if ($txtseq[1] > 0) { // extract byte sequence before the text sequence $prevtxtseq = substr($prevseq, $txtoffset, ($txtseq[1] - $txtoffset)); if (strlen($prevtxtseq) > 0) { // add BYTE sequence if ((strlen($prevtxtseq) == 1) AND ((count($sequence_array) > 0) AND ($sequence_array[(count($sequence_array) - 1)][0] == 900))) { $sequence_array[] = array(913, $prevtxtseq); } elseif ((strlen($prevtxtseq) % 6) == 0) { $sequence_array[] = array(924, $prevtxtseq); } else { $sequence_array[] = array(901, $prevtxtseq); } } } if ($txtseqlen > 0) { // add numeric sequence $sequence_array[] = array(900, $txtseq[0]); } $txtoffset = $txtseq[1] + $txtseqlen; } } if ($seqlen > 0) { // add numeric sequence $sequence_array[] = array(902, $seq[0]); } $offset = $seq[1] + $seqlen; } return $sequence_array; } /** * Compact data by mode. * @param $mode (int) compaction mode number * @param $code (string) data to compact * @param $addmode (boolean) if true add the mode codeword at first position * @return array of codewords * @protected */ protected function getCompaction($mode, $code, $addmode=true) { $cw = array(); // array of codewords to return switch($mode) { case 900: { // Text Compaction mode latch $submode = 0; // default Alpha sub-mode $txtarr = array(); // array of characters and sub-mode switching characters $codelen = strlen($code); for ($i = 0; $i < $codelen; ++$i) { $chval = ord($code{$i}); if (($k = array_search($chval, $this->textsubmodes[$submode])) !== false) { // we are on the same sub-mode $txtarr[] = $k; } else { // the sub-mode is changed for ($s = 0; $s < 4; ++$s) { // search new sub-mode if (($s != $submode) AND (($k = array_search($chval, $this->textsubmodes[$s])) !== false)) { // $s is the new submode if (((($i + 1) == $codelen) OR ((($i + 1) < $codelen) AND (array_search(ord($code{($i + 1)}), $this->textsubmodes[$submode]) !== false))) AND (($s == 3) OR (($s == 0) AND ($submode == 1)))) { // shift (temporary change only for this char) if ($s == 3) { // shift to puntuaction $txtarr[] = 29; } else { // shift from lower to alpha $txtarr[] = 27; } } else { // latch $txtarr = array_merge($txtarr, $this->textlatch[''.$submode.$s]); // set new submode $submode = $s; } // add characted code to array $txtarr[] = $k; break; } } } } $txtarrlen = count($txtarr); if (($txtarrlen % 2) != 0) { // add padding $txtarr[] = 29; ++$txtarrlen; } // calculate codewords for ($i = 0; $i < $txtarrlen; $i += 2) { $cw[] = (30 * $txtarr[$i]) + $txtarr[($i + 1)]; } break; } case 901: case 924: { // Byte Compaction mode latch while (($codelen = strlen($code)) > 0) { if ($codelen > 6) { $rest = substr($code, 6); $code = substr($code, 0, 6); $sublen = 6; } else { $rest = ''; $sublen = strlen($code); } if ($sublen == 6) { $t = bcmul(''.ord($code{0}), '1099511627776'); $t = bcadd($t, bcmul(''.ord($code{1}), '4294967296')); $t = bcadd($t, bcmul(''.ord($code{2}), '16777216')); $t = bcadd($t, bcmul(''.ord($code{3}), '65536')); $t = bcadd($t, bcmul(''.ord($code{4}), '256')); $t = bcadd($t, ''.ord($code{5})); do { $d = bcmod($t, '900'); $t = bcdiv($t, '900'); array_unshift($cw, $d); } while ($t != '0'); } else { for ($i = 0; $i < $sublen; ++$i) { $cw[] = ord($code{$i}); } } $code = $rest; } break; } case 902: { // Numeric Compaction mode latch while (($codelen = strlen($code)) > 0) { if ($codelen > 44) { $rest = substr($code, 44); $code = substr($code, 0, 44); } else { $rest = ''; } $t = '1'.$code; do { $d = bcmod($t, '900'); $t = bcdiv($t, '900'); array_unshift($cw, $d); } while ($t != '0'); $code = $rest; } break; } case 913: { // Byte Compaction mode shift $cw[] = ord($code); break; } } if ($addmode) { // add the compaction mode codeword at the beginning array_unshift($cw, $mode); } return $cw; } } // end PDF417 class //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/barcodes/qrcode.php000066400000000000000000002343221237252063700222720ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // DESCRIPTION : // // Class to create QR-code arrays for TCPDF class. // QR Code symbol is a 2D barcode that can be scanned by // handy terminals such as a mobile phone with CCD. // The capacity of QR Code is up to 7000 digits or 4000 // characters, and has high robustness. // This class supports QR Code model 2, described in // JIS (Japanese Industrial Standards) X0510:2004 // or ISO/IEC 18004. // Currently the following features are not supported: // ECI and FNC1 mode, Micro QR Code, QR Code model 1, // Structured mode. // // This class is derived from the following projects: // --------------------------------------------------------- // "PHP QR Code encoder" // License: GNU-LGPLv3 // Copyright (C) 2010 by Dominik Dzienia // http://phpqrcode.sourceforge.net/ // https://sourceforge.net/projects/phpqrcode/ // // The "PHP QR Code encoder" is based on // "C libqrencode library" (ver. 3.1.1) // License: GNU-LGPL 2.1 // Copyright (C) 2006-2010 by Kentaro Fukuchi // http://megaui.net/fukuchi/works/qrencode/index.en.html // // Reed-Solomon code encoder is written by Phil Karn, KA9Q. // Copyright (C) 2002-2006 Phil Karn, KA9Q // // QR Code is registered trademark of DENSO WAVE INCORPORATED // http://www.denso-wave.com/qrcode/index-e.html // --------------------------------------------------------- //============================================================+ /** * @file * Class to create QR-code arrays for TCPDF class. * QR Code symbol is a 2D barcode that can be scanned by handy terminals such as a mobile phone with CCD. * The capacity of QR Code is up to 7000 digits or 4000 characters, and has high robustness. * This class supports QR Code model 2, described in JIS (Japanese Industrial Standards) X0510:2004 or ISO/IEC 18004. * Currently the following features are not supported: ECI and FNC1 mode, Micro QR Code, QR Code model 1, Structured mode. * * This class is derived from "PHP QR Code encoder" by Dominik Dzienia (http://phpqrcode.sourceforge.net/) based on "libqrencode C library 3.1.1." by Kentaro Fukuchi (http://megaui.net/fukuchi/works/qrencode/index.en.html), contains Reed-Solomon code written by Phil Karn, KA9Q. QR Code is registered trademark of DENSO WAVE INCORPORATED (http://www.denso-wave.com/qrcode/index-e.html). * Please read comments on this class source file for full copyright and license information. * * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.010 */ // definitions if (!defined('QRCODEDEFS')) { /** * Indicate that definitions for this class are set */ define('QRCODEDEFS', true); // ----------------------------------------------------- // Encoding modes (characters which can be encoded in QRcode) /** * Encoding mode */ define('QR_MODE_NL', -1); /** * Encoding mode numeric (0-9). 3 characters are encoded to 10bit length. In theory, 7089 characters or less can be stored in a QRcode. */ define('QR_MODE_NM', 0); /** * Encoding mode alphanumeric (0-9A-Z $%*+-./:) 45characters. 2 characters are encoded to 11bit length. In theory, 4296 characters or less can be stored in a QRcode. */ define('QR_MODE_AN', 1); /** * Encoding mode 8bit byte data. In theory, 2953 characters or less can be stored in a QRcode. */ define('QR_MODE_8B', 2); /** * Encoding mode KANJI. A KANJI character (multibyte character) is encoded to 13bit length. In theory, 1817 characters or less can be stored in a QRcode. */ define('QR_MODE_KJ', 3); /** * Encoding mode STRUCTURED (currently unsupported) */ define('QR_MODE_ST', 4); // ----------------------------------------------------- // Levels of error correction. // QRcode has a function of an error correcting for miss reading that white is black. // Error correcting is defined in 4 level as below. /** * Error correction level L : About 7% or less errors can be corrected. */ define('QR_ECLEVEL_L', 0); /** * Error correction level M : About 15% or less errors can be corrected. */ define('QR_ECLEVEL_M', 1); /** * Error correction level Q : About 25% or less errors can be corrected. */ define('QR_ECLEVEL_Q', 2); /** * Error correction level H : About 30% or less errors can be corrected. */ define('QR_ECLEVEL_H', 3); // ----------------------------------------------------- // Version. Size of QRcode is defined as version. // Version is from 1 to 40. // Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases. // So version 40 is 177*177 matrix. /** * Maximum QR Code version. */ define('QRSPEC_VERSION_MAX', 40); /** * Maximum matrix size for maximum version (version 40 is 177*177 matrix). */ define('QRSPEC_WIDTH_MAX', 177); // ----------------------------------------------------- /** * Matrix index to get width from $capacity array. */ define('QRCAP_WIDTH', 0); /** * Matrix index to get number of words from $capacity array. */ define('QRCAP_WORDS', 1); /** * Matrix index to get remainder from $capacity array. */ define('QRCAP_REMINDER', 2); /** * Matrix index to get error correction level from $capacity array. */ define('QRCAP_EC', 3); // ----------------------------------------------------- // Structure (currently usupported) /** * Number of header bits for structured mode */ define('STRUCTURE_HEADER_BITS', 20); /** * Max number of symbols for structured mode */ define('MAX_STRUCTURED_SYMBOLS', 16); // ----------------------------------------------------- // Masks /** * Down point base value for case 1 mask pattern (concatenation of same color in a line or a column) */ define('N1', 3); /** * Down point base value for case 2 mask pattern (module block of same color) */ define('N2', 3); /** * Down point base value for case 3 mask pattern (1:1:3:1:1(dark:bright:dark:bright:dark)pattern in a line or a column) */ define('N3', 40); /** * Down point base value for case 4 mask pattern (ration of dark modules in whole) */ define('N4', 10); // ----------------------------------------------------- // Optimization settings /** * if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code */ define('QR_FIND_BEST_MASK', true); /** * if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly */ define('QR_FIND_FROM_RANDOM', 2); /** * when QR_FIND_BEST_MASK === false */ define('QR_DEFAULT_MASK', 2); // ----------------------------------------------------- } // end of definitions // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*# // for compatibility with PHP4 if (!function_exists('str_split')) { /** * Convert a string to an array (needed for PHP4 compatibility) * @param $string (string) The input string. * @param $split_length (int) Maximum length of the chunk. * @return If the optional split_length parameter is specified, the returned array will be broken down into chunks with each being split_length in length, otherwise each chunk will be one character in length. FALSE is returned if split_length is less than 1. If the split_length length exceeds the length of string , the entire string is returned as the first (and only) array element. */ function str_split($string, $split_length=1) { if ((strlen($string) > $split_length) OR (!$split_length)) { do { $c = strlen($string); $parts[] = substr($string, 0, $split_length); $string = substr($string, $split_length); } while ($string !== false); } else { $parts = array($string); } return $parts; } } // ##################################################### /** * @class QRcode * Class to create QR-code arrays for TCPDF class. * QR Code symbol is a 2D barcode that can be scanned by handy terminals such as a mobile phone with CCD. * The capacity of QR Code is up to 7000 digits or 4000 characters, and has high robustness. * This class supports QR Code model 2, described in JIS (Japanese Industrial Standards) X0510:2004 or ISO/IEC 18004. * Currently the following features are not supported: ECI and FNC1 mode, Micro QR Code, QR Code model 1, Structured mode. * * This class is derived from "PHP QR Code encoder" by Dominik Dzienia (http://phpqrcode.sourceforge.net/) based on "libqrencode C library 3.1.1." by Kentaro Fukuchi (http://megaui.net/fukuchi/works/qrencode/index.en.html), contains Reed-Solomon code written by Phil Karn, KA9Q. QR Code is registered trademark of DENSO WAVE INCORPORATED (http://www.denso-wave.com/qrcode/index-e.html). * Please read comments on this class source file for full copyright and license information. * * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.010 */ class QRcode { /** * Barcode array to be returned which is readable by TCPDF. * @protected */ protected $barcode_array = array(); /** * QR code version. Size of QRcode is defined as version. Version is from 1 to 40. Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases. So version 40 is 177*177 matrix. * @protected */ protected $version = 0; /** * Levels of error correction. See definitions for possible values. * @protected */ protected $level = QR_ECLEVEL_L; /** * Encoding mode. * @protected */ protected $hint = QR_MODE_8B; /** * Boolean flag, if true the input string will be converted to uppercase. * @protected */ protected $casesensitive = true; /** * Structured QR code (not supported yet). * @protected */ protected $structured = 0; /** * Mask data. * @protected */ protected $data; // FrameFiller /** * Width. * @protected */ protected $width; /** * Frame. * @protected */ protected $frame; /** * X position of bit. * @protected */ protected $x; /** * Y position of bit. * @protected */ protected $y; /** * Direction. * @protected */ protected $dir; /** * Single bit value. * @protected */ protected $bit; // ---- QRrawcode ---- /** * Data code. * @protected */ protected $datacode = array(); /** * Error correction code. * @protected */ protected $ecccode = array(); /** * Blocks. * @protected */ protected $blocks; /** * Reed-Solomon blocks. * @protected */ protected $rsblocks = array(); //of RSblock /** * Counter. * @protected */ protected $count; /** * Data length. * @protected */ protected $dataLength; /** * Error correction length. * @protected */ protected $eccLength; /** * Value b1. * @protected */ protected $b1; // ---- QRmask ---- /** * Run length. * @protected */ protected $runLength = array(); // ---- QRsplit ---- /** * Input data string. * @protected */ protected $dataStr = ''; /** * Input items. * @protected */ protected $items; // Reed-Solomon items /** * Reed-Solomon items. * @protected */ protected $rsitems = array(); /** * Array of frames. * @protected */ protected $frames = array(); /** * Alphabet-numeric convesion table. * @protected */ protected $anTable = array( -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, // -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // ); /** * Array Table of the capacity of symbols. * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004. * @protected */ protected $capacity = array( array( 0, 0, 0, array( 0, 0, 0, 0)), // array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 array( 25, 44, 7, array( 10, 16, 22, 28)), // array( 29, 70, 7, array( 15, 26, 36, 44)), // array( 33, 100, 7, array( 20, 36, 52, 64)), // array( 37, 134, 7, array( 26, 48, 72, 88)), // 5 array( 41, 172, 7, array( 36, 64, 96, 112)), // array( 45, 196, 0, array( 40, 72, 108, 130)), // array( 49, 242, 0, array( 48, 88, 132, 156)), // array( 53, 292, 0, array( 60, 110, 160, 192)), // array( 57, 346, 0, array( 72, 130, 192, 224)), // 10 array( 61, 404, 0, array( 80, 150, 224, 264)), // array( 65, 466, 0, array( 96, 176, 260, 308)), // array( 69, 532, 0, array( 104, 198, 288, 352)), // array( 73, 581, 3, array( 120, 216, 320, 384)), // array( 77, 655, 3, array( 132, 240, 360, 432)), // 15 array( 81, 733, 3, array( 144, 280, 408, 480)), // array( 85, 815, 3, array( 168, 308, 448, 532)), // array( 89, 901, 3, array( 180, 338, 504, 588)), // array( 93, 991, 3, array( 196, 364, 546, 650)), // array( 97, 1085, 3, array( 224, 416, 600, 700)), // 20 array(101, 1156, 4, array( 224, 442, 644, 750)), // array(105, 1258, 4, array( 252, 476, 690, 816)), // array(109, 1364, 4, array( 270, 504, 750, 900)), // array(113, 1474, 4, array( 300, 560, 810, 960)), // array(117, 1588, 4, array( 312, 588, 870, 1050)), // 25 array(121, 1706, 4, array( 336, 644, 952, 1110)), // array(125, 1828, 4, array( 360, 700, 1020, 1200)), // array(129, 1921, 3, array( 390, 728, 1050, 1260)), // array(133, 2051, 3, array( 420, 784, 1140, 1350)), // array(137, 2185, 3, array( 450, 812, 1200, 1440)), // 30 array(141, 2323, 3, array( 480, 868, 1290, 1530)), // array(145, 2465, 3, array( 510, 924, 1350, 1620)), // array(149, 2611, 3, array( 540, 980, 1440, 1710)), // array(153, 2761, 3, array( 570, 1036, 1530, 1800)), // array(157, 2876, 0, array( 570, 1064, 1590, 1890)), // 35 array(161, 3034, 0, array( 600, 1120, 1680, 1980)), // array(165, 3196, 0, array( 630, 1204, 1770, 2100)), // array(169, 3362, 0, array( 660, 1260, 1860, 2220)), // array(173, 3532, 0, array( 720, 1316, 1950, 2310)), // array(177, 3706, 0, array( 750, 1372, 2040, 2430)) // 40 ); /** * Array Length indicator. * @protected */ protected $lengthTableBits = array( array(10, 12, 14), array( 9, 11, 13), array( 8, 16, 16), array( 8, 10, 12) ); /** * Array Table of the error correction code (Reed-Solomon block). * See Table 12-16 (pp.30-36), JIS X0510:2004. * @protected */ protected $eccTable = array( array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), // array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), // array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), // array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), // array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), // array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), // array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), // array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), // 10 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), // array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), // array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), // array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), // array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), // 15 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), // array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), // array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), // array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), // array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), // 20 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), // array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), // array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), // array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), // array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), // 25 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), // array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), // array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), // array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), // array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), // 30 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), // array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), // array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), // array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), // array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), // 35 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), // array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), // array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), // array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), // array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)) // 40 ); /** * Array Positions of alignment patterns. * This array includes only the second and the third position of the alignment patterns. Rest of them can be calculated from the distance between them. * See Table 1 in Appendix E (pp.71) of JIS X0510:2004. * @protected */ protected $alignmentPattern = array( array( 0, 0), array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), // 11-15 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), // 16-20 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), // 21-25 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), // 26-30 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), // 31-35 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58) // 35-40 ); /** * Array Version information pattern (BCH coded). * See Table 1 in Appendix D (pp.68) of JIS X0510:2004. * size: [QRSPEC_VERSION_MAX - 6] * @protected */ protected $versionPattern = array( 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, // 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, // 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, // 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, // 0x27541, 0x28c69 ); /** * Array Format information * @protected */ protected $formatInfo = array( array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), // array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), // array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), // array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) // ); // ------------------------------------------------- // ------------------------------------------------- /** * This is the class constructor. * Creates a QRcode object * @param $code (string) code to represent using QRcode * @param $eclevel (string) error level:
      • L : About 7% or less errors can be corrected.
      • M : About 15% or less errors can be corrected.
      • Q : About 25% or less errors can be corrected.
      • H : About 30% or less errors can be corrected.
      * @public * @since 1.0.000 */ public function __construct($code, $eclevel = 'L') { $barcode_array = array(); if ((is_null($code)) OR ($code == '\0') OR ($code == '')) { return false; } // set error correction level $this->level = array_search($eclevel, array('L', 'M', 'Q', 'H')); if ($this->level === false) { $this->level = QR_ECLEVEL_L; } if (($this->hint != QR_MODE_8B) AND ($this->hint != QR_MODE_KJ)) { return false; } if (($this->version < 0) OR ($this->version > QRSPEC_VERSION_MAX)) { return false; } $this->items = array(); $this->encodeString($code); if (is_null($this->data)) { return false; } $qrTab = $this->binarize($this->data); $size = count($qrTab); $barcode_array['num_rows'] = $size; $barcode_array['num_cols'] = $size; $barcode_array['bcode'] = array(); foreach ($qrTab as $line) { $arrAdd = array(); foreach (str_split($line) as $char) { $arrAdd[] = ($char=='1')?1:0; } $barcode_array['bcode'][] = $arrAdd; } $this->barcode_array = $barcode_array; } /** * Returns a barcode array which is readable by TCPDF * @return array barcode array readable by TCPDF; * @public */ public function getBarcodeArray() { return $this->barcode_array; } /** * Convert the frame in binary form * @param $frame (array) array to binarize * @return array frame in binary form */ protected function binarize($frame) { $len = count($frame); // the frame is square (width = height) foreach ($frame as &$frameLine) { for ($i=0; $i<$len; $i++) { $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0'; } } return $frame; } /** * Encode the input string to QR code * @param $string (string) input string to encode */ protected function encodeString($string) { $this->dataStr = $string; if (!$this->casesensitive) { $this->toUpper(); } $ret = $this->splitString(); if ($ret < 0) { return NULL; } $this->encodeMask(-1); } /** * Encode mask * @param $mask (int) masking mode */ protected function encodeMask($mask) { $spec = array(0, 0, 0, 0, 0); $this->datacode = $this->getByteStream($this->items); if (is_null($this->datacode)) { return NULL; } $spec = $this->getEccSpec($this->version, $this->level, $spec); $this->b1 = $this->rsBlockNum1($spec); $this->dataLength = $this->rsDataLength($spec); $this->eccLength = $this->rsEccLength($spec); $this->ecccode = array_fill(0, $this->eccLength, 0); $this->blocks = $this->rsBlockNum($spec); $ret = $this->init($spec); if ($ret < 0) { return NULL; } $this->count = 0; $this->width = $this->getWidth($this->version); $this->frame = $this->newFrame($this->version); $this->x = $this->width - 1; $this->y = $this->width - 1; $this->dir = -1; $this->bit = -1; // inteleaved data and ecc codes for ($i=0; $i < ($this->dataLength + $this->eccLength); $i++) { $code = $this->getCode(); $bit = 0x80; for ($j=0; $j<8; $j++) { $addr = $this->getNextPosition(); $this->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); $bit = $bit >> 1; } } // remainder bits $j = $this->getRemainder($this->version); for ($i=0; $i<$j; $i++) { $addr = $this->getNextPosition(); $this->setFrameAt($addr, 0x02); } // masking $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); if ($mask < 0) { if (QR_FIND_BEST_MASK) { $masked = $this->mask($this->width, $this->frame, $this->level); } else { $masked = $this->makeMask($this->width, $this->frame, (intval(QR_DEFAULT_MASK) % 8), $this->level); } } else { $masked = $this->makeMask($this->width, $this->frame, $mask, $this->level); } if ($masked == NULL) { return NULL; } $this->data = $masked; } // - - - - - - - - - - - - - - - - - - - - - - - - - // FrameFiller /** * Set frame value at specified position * @param $at (array) x,y position * @param $val (int) value of the character to set */ protected function setFrameAt($at, $val) { $this->frame[$at['y']][$at['x']] = chr($val); } /** * Get frame value at specified position * @param $at (array) x,y position * @return value at specified position */ protected function getFrameAt($at) { return ord($this->frame[$at['y']][$at['x']]); } /** * Return the next frame position * @return array of x,y coordinates */ protected function getNextPosition() { do { if ($this->bit == -1) { $this->bit = 0; return array('x'=>$this->x, 'y'=>$this->y); } $x = $this->x; $y = $this->y; $w = $this->width; if ($this->bit == 0) { $x--; $this->bit++; } else { $x++; $y += $this->dir; $this->bit--; } if ($this->dir < 0) { if ($y < 0) { $y = 0; $x -= 2; $this->dir = 1; if ($x == 6) { $x--; $y = 9; } } } else { if ($y == $w) { $y = $w - 1; $x -= 2; $this->dir = -1; if ($x == 6) { $x--; $y -= 8; } } } if (($x < 0) OR ($y < 0)) { return NULL; } $this->x = $x; $this->y = $y; } while(ord($this->frame[$y][$x]) & 0x80); return array('x'=>$x, 'y'=>$y); } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRrawcode /** * Initialize code. * @param $spec (array) array of ECC specification * @return 0 in case of success, -1 in case of error */ protected function init($spec) { $dl = $this->rsDataCodes1($spec); $el = $this->rsEccCodes1($spec); $rs = $this->init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); $blockNo = 0; $dataPos = 0; $eccPos = 0; $endfor = $this->rsBlockNum1($spec); for ($i=0; $i < $endfor; ++$i) { $ecc = array_slice($this->ecccode, $eccPos); $this->rsblocks[$blockNo] = array(); $this->rsblocks[$blockNo]['dataLength'] = $dl; $this->rsblocks[$blockNo]['data'] = array_slice($this->datacode, $dataPos); $this->rsblocks[$blockNo]['eccLength'] = $el; $ecc = $this->encode_rs_char($rs, $this->rsblocks[$blockNo]['data'], $ecc); $this->rsblocks[$blockNo]['ecc'] = $ecc; $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } if ($this->rsBlockNum2($spec) == 0) { return 0; } $dl = $this->rsDataCodes2($spec); $el = $this->rsEccCodes2($spec); $rs = $this->init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); if ($rs == NULL) { return -1; } $endfor = $this->rsBlockNum2($spec); for ($i=0; $i < $endfor; ++$i) { $ecc = array_slice($this->ecccode, $eccPos); $this->rsblocks[$blockNo] = array(); $this->rsblocks[$blockNo]['dataLength'] = $dl; $this->rsblocks[$blockNo]['data'] = array_slice($this->datacode, $dataPos); $this->rsblocks[$blockNo]['eccLength'] = $el; $ecc = $this->encode_rs_char($rs, $this->rsblocks[$blockNo]['data'], $ecc); $this->rsblocks[$blockNo]['ecc'] = $ecc; $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } return 0; } /** * Return Reed-Solomon block code. * @return array rsblocks */ protected function getCode() { if ($this->count < $this->dataLength) { $row = $this->count % $this->blocks; $col = $this->count / $this->blocks; if ($col >= $this->rsblocks[0]['dataLength']) { $row += $this->b1; } $ret = $this->rsblocks[$row]['data'][$col]; } elseif ($this->count < $this->dataLength + $this->eccLength) { $row = ($this->count - $this->dataLength) % $this->blocks; $col = ($this->count - $this->dataLength) / $this->blocks; $ret = $this->rsblocks[$row]['ecc'][$col]; } else { return 0; } $this->count++; return $ret; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRmask /** * Write Format Information on frame and returns the number of black bits * @param $width (int) frame width * @param $frame (array) frame * @param $mask (array) masking mode * @param $level (int) error correction level * @return int blacks */ protected function writeFormatInformation($width, &$frame, $mask, $level) { $blacks = 0; $format = $this->getFormatInfo($mask, $level); for ($i=0; $i<8; ++$i) { if ($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[8][$width - 1 - $i] = chr($v); if ($i < 6) { $frame[$i][8] = chr($v); } else { $frame[$i + 1][8] = chr($v); } $format = $format >> 1; } for ($i=0; $i<7; ++$i) { if ($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[$width - 7 + $i][8] = chr($v); if ($i == 0) { $frame[8][7] = chr($v); } else { $frame[8][6 - $i] = chr($v); } $format = $format >> 1; } return $blacks; } /** * mask0 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask0($x, $y) { return ($x + $y) & 1; } /** * mask1 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask1($x, $y) { return ($y & 1); } /** * mask2 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask2($x, $y) { return ($x % 3); } /** * mask3 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask3($x, $y) { return ($x + $y) % 3; } /** * mask4 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask4($x, $y) { return (((int)($y / 2)) + ((int)($x / 3))) & 1; } /** * mask5 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask5($x, $y) { return (($x * $y) & 1) + ($x * $y) % 3; } /** * mask6 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask6($x, $y) { return ((($x * $y) & 1) + ($x * $y) % 3) & 1; } /** * mask7 * @param $x (int) X position * @param $y (int) Y position * @return int mask */ protected function mask7($x, $y) { return ((($x * $y) % 3) + (($x + $y) & 1)) & 1; } /** * Return bitmask * @param $maskNo (int) mask number * @param $width (int) width * @param $frame (array) frame * @return array bitmask */ protected function generateMaskNo($maskNo, $width, $frame) { $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for ($y=0; $y<$width; ++$y) { for ($x=0; $x<$width; ++$x) { if (ord($frame[$y][$x]) & 0x80) { $bitMask[$y][$x] = 0; } else { $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); $bitMask[$y][$x] = ($maskFunc == 0)?1:0; } } } return $bitMask; } /** * makeMaskNo * @param $maskNo (int) * @param $width (int) * @param $s (int) * @param $d (int) * @param $maskGenOnly (boolean) * @return int b */ protected function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly=false) { $b = 0; $bitMask = array(); $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); if ($maskGenOnly) { return; } $d = $s; for ($y=0; $y<$width; ++$y) { for ($x=0; $x<$width; ++$x) { if ($bitMask[$y][$x] == 1) { $d[$y][$x] = chr(ord($s[$y][$x]) ^ ((int)($bitMask[$y][$x]))); } $b += (int)(ord($d[$y][$x]) & 1); } } return $b; } /** * makeMask * @param $width (int) * @param $frame (array) * @param $maskNo (int) * @param $level (int) * @return array mask */ protected function makeMask($width, $frame, $maskNo, $level) { $masked = array_fill(0, $width, str_repeat("\0", $width)); $this->makeMaskNo($maskNo, $width, $frame, $masked); $this->writeFormatInformation($width, $masked, $maskNo, $level); return $masked; } /** * calcN1N3 * @param $length (int) * @return int demerit */ protected function calcN1N3($length) { $demerit = 0; for ($i=0; $i<$length; ++$i) { if ($this->runLength[$i] >= 5) { $demerit += (N1 + ($this->runLength[$i] - 5)); } if ($i & 1) { if (($i >= 3) AND ($i < ($length-2)) AND ($this->runLength[$i] % 3 == 0)) { $fact = (int)($this->runLength[$i] / 3); if (($this->runLength[$i-2] == $fact) AND ($this->runLength[$i-1] == $fact) AND ($this->runLength[$i+1] == $fact) AND ($this->runLength[$i+2] == $fact)) { if (($this->runLength[$i-3] < 0) OR ($this->runLength[$i-3] >= (4 * $fact))) { $demerit += N3; } elseif ((($i+3) >= $length) OR ($this->runLength[$i+3] >= (4 * $fact))) { $demerit += N3; } } } } } return $demerit; } /** * evaluateSymbol * @param $width (int) * @param $frame (array) * @return int demerit */ protected function evaluateSymbol($width, $frame) { $head = 0; $demerit = 0; for ($y=0; $y<$width; ++$y) { $head = 0; $this->runLength[0] = 1; $frameY = $frame[$y]; if ($y > 0) { $frameYM = $frame[$y-1]; } for ($x=0; $x<$width; ++$x) { if (($x > 0) AND ($y > 0)) { $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); if (($b22 | ($w22 ^ 1)) & 1) { $demerit += N2; } } if (($x == 0) AND (ord($frameY[$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } elseif ($x > 0) { if ((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } for ($x=0; $x<$width; ++$x) { $head = 0; $this->runLength[0] = 1; for ($y=0; $y<$width; ++$y) { if (($y == 0) AND (ord($frame[$y][$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } elseif ($y > 0) { if ((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } return $demerit; } /** * mask * @param $width (int) * @param $frame (array) * @param $level (int) * @return array best mask */ protected function mask($width, $frame, $level) { $minDemerit = PHP_INT_MAX; $bestMaskNum = 0; $bestMask = array(); $checked_masks = array(0, 1, 2, 3, 4, 5, 6, 7); if (QR_FIND_FROM_RANDOM !== false) { $howManuOut = 8 - (QR_FIND_FROM_RANDOM % 9); for ($i = 0; $i < $howManuOut; ++$i) { $remPos = rand (0, count($checked_masks)-1); unset($checked_masks[$remPos]); $checked_masks = array_values($checked_masks); } } $bestMask = $frame; foreach ($checked_masks as $i) { $mask = array_fill(0, $width, str_repeat("\0", $width)); $demerit = 0; $blacks = 0; $blacks = $this->makeMaskNo($i, $width, $frame, $mask); $blacks += $this->writeFormatInformation($width, $mask, $i, $level); $blacks = (int)(100 * $blacks / ($width * $width)); $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); $demerit += $this->evaluateSymbol($width, $mask); if ($demerit < $minDemerit) { $minDemerit = $demerit; $bestMask = $mask; $bestMaskNum = $i; } } return $bestMask; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRsplit /** * Return true if the character at specified position is a number * @param $str (string) string * @param $pos (int) characted position * @return boolean true of false */ protected function isdigitat($str, $pos) { if ($pos >= strlen($str)) { return false; } return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); } /** * Return true if the character at specified position is an alphanumeric character * @param $str (string) string * @param $pos (int) characted position * @return boolean true of false */ protected function isalnumat($str, $pos) { if ($pos >= strlen($str)) { return false; } return ($this->lookAnTable(ord($str[$pos])) >= 0); } /** * identifyMode * @param $pos (int) * @return int mode */ protected function identifyMode($pos) { if ($pos >= strlen($this->dataStr)) { return QR_MODE_NL; } $c = $this->dataStr[$pos]; if ($this->isdigitat($this->dataStr, $pos)) { return QR_MODE_NM; } elseif ($this->isalnumat($this->dataStr, $pos)) { return QR_MODE_AN; } elseif ($this->hint == QR_MODE_KJ) { if ($pos+1 < strlen($this->dataStr)) { $d = $this->dataStr[$pos+1]; $word = (ord($c) << 8) | ord($d); if (($word >= 0x8140 && $word <= 0x9ffc) OR ($word >= 0xe040 && $word <= 0xebbf)) { return QR_MODE_KJ; } } } return QR_MODE_8B; } /** * eatNum * @return int run */ protected function eatNum() { $ln = $this->lengthIndicator(QR_MODE_NM, $this->version); $p = 0; while($this->isdigitat($this->dataStr, $p)) { $p++; } $run = $p; $mode = $this->identifyMode($p); if ($mode == QR_MODE_8B) { $dif = $this->estimateBitsModeNum($run) + 4 + $ln + $this->estimateBitsMode8(1) // + 4 + l8 - $this->estimateBitsMode8($run + 1); // - 4 - l8 if ($dif > 0) { return $this->eat8(); } } if ($mode == QR_MODE_AN) { $dif = $this->estimateBitsModeNum($run) + 4 + $ln + $this->estimateBitsModeAn(1) // + 4 + la - $this->estimateBitsModeAn($run + 1);// - 4 - la if ($dif > 0) { return $this->eatAn(); } } $this->items = $this->appendNewInputItem($this->items, QR_MODE_NM, $run, str_split($this->dataStr)); return $run; } /** * eatAn * @return int run */ protected function eatAn() { $la = $this->lengthIndicator(QR_MODE_AN, $this->version); $ln = $this->lengthIndicator(QR_MODE_NM, $this->version); $p =1 ; while($this->isalnumat($this->dataStr, $p)) { if ($this->isdigitat($this->dataStr, $p)) { $q = $p; while($this->isdigitat($this->dataStr, $q)) { $q++; } $dif = $this->estimateBitsModeAn($p) // + 4 + la + $this->estimateBitsModeNum($q - $p) + 4 + $ln - $this->estimateBitsModeAn($q); // - 4 - la if ($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; if (!$this->isalnumat($this->dataStr, $p)) { $dif = $this->estimateBitsModeAn($run) + 4 + $la + $this->estimateBitsMode8(1) // + 4 + l8 - $this->estimateBitsMode8($run + 1); // - 4 - l8 if ($dif > 0) { return $this->eat8(); } } $this->items = $this->appendNewInputItem($this->items, QR_MODE_AN, $run, str_split($this->dataStr)); return $run; } /** * eatKanji * @return int run */ protected function eatKanji() { $p = 0; while($this->identifyMode($p) == QR_MODE_KJ) { $p += 2; } $this->items = $this->appendNewInputItem($this->items, QR_MODE_KJ, $p, str_split($this->dataStr)); return $run; } /** * eat8 * @return int run */ protected function eat8() { $la = $this->lengthIndicator(QR_MODE_AN, $this->version); $ln = $this->lengthIndicator(QR_MODE_NM, $this->version); $p = 1; $dataStrLen = strlen($this->dataStr); while($p < $dataStrLen) { $mode = $this->identifyMode($p); if ($mode == QR_MODE_KJ) { break; } if ($mode == QR_MODE_NM) { $q = $p; while($this->isdigitat($this->dataStr, $q)) { $q++; } $dif = $this->estimateBitsMode8($p) // + 4 + l8 + $this->estimateBitsModeNum($q - $p) + 4 + $ln - $this->estimateBitsMode8($q); // - 4 - l8 if ($dif < 0) { break; } else { $p = $q; } } elseif ($mode == QR_MODE_AN) { $q = $p; while($this->isalnumat($this->dataStr, $q)) { $q++; } $dif = $this->estimateBitsMode8($p) // + 4 + l8 + $this->estimateBitsModeAn($q - $p) + 4 + $la - $this->estimateBitsMode8($q); // - 4 - l8 if ($dif < 0) { break; } else { $p = $q; } } else { $p++; } } $run = $p; $this->items = $this->appendNewInputItem($this->items, QR_MODE_8B, $run, str_split($this->dataStr)); return $run; } /** * splitString * @return (int) */ protected function splitString() { while (strlen($this->dataStr) > 0) { $mode = $this->identifyMode(0); switch ($mode) { case QR_MODE_NM: { $length = $this->eatNum(); break; } case QR_MODE_AN: { $length = $this->eatAn(); break; } case QR_MODE_KJ: { if ($hint == QR_MODE_KJ) { $length = $this->eatKanji(); } else { $length = $this->eat8(); } break; } default: { $length = $this->eat8(); break; } } if ($length == 0) { return 0; } if ($length < 0) { return -1; } $this->dataStr = substr($this->dataStr, $length); } return 0; } /** * toUpper */ protected function toUpper() { $stringLen = strlen($this->dataStr); $p = 0; while ($p < $stringLen) { $mode = $this->identifyMode(substr($this->dataStr, $p), $this->hint); if ($mode == QR_MODE_KJ) { $p += 2; } else { if ((ord($this->dataStr[$p]) >= ord('a')) AND (ord($this->dataStr[$p]) <= ord('z'))) { $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); } $p++; } } return $this->dataStr; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRinputItem /** * newInputItem * @param $mode (int) * @param $size (int) * @param $data (array) * @param $bstream (array) * @return array input item */ protected function newInputItem($mode, $size, $data, $bstream=null) { $setData = array_slice($data, 0, $size); if (count($setData) < $size) { $setData = array_merge($setData, array_fill(0, ($size - count($setData)), 0)); } if (!$this->check($mode, $size, $setData)) { return NULL; } $inputitem = array(); $inputitem['mode'] = $mode; $inputitem['size'] = $size; $inputitem['data'] = $setData; $inputitem['bstream'] = $bstream; return $inputitem; } /** * encodeModeNum * @param $inputitem (array) * @param $version (int) * @return array input item */ protected function encodeModeNum($inputitem, $version) { $words = (int)($inputitem['size'] / 3); $inputitem['bstream'] = array(); $val = 0x1; $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, $val); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_NM, $version), $inputitem['size']); for ($i=0; $i < $words; ++$i) { $val = (ord($inputitem['data'][$i*3 ]) - ord('0')) * 100; $val += (ord($inputitem['data'][$i*3+1]) - ord('0')) * 10; $val += (ord($inputitem['data'][$i*3+2]) - ord('0')); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 10, $val); } if ($inputitem['size'] - $words * 3 == 1) { $val = ord($inputitem['data'][$words*3]) - ord('0'); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, $val); } elseif (($inputitem['size'] - ($words * 3)) == 2) { $val = (ord($inputitem['data'][$words*3 ]) - ord('0')) * 10; $val += (ord($inputitem['data'][$words*3+1]) - ord('0')); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 7, $val); } return $inputitem; } /** * encodeModeAn * @param $inputitem (array) * @param $version (int) * @return array input item */ protected function encodeModeAn($inputitem, $version) { $words = (int)($inputitem['size'] / 2); $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x02); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_AN, $version), $inputitem['size']); for ($i=0; $i < $words; ++$i) { $val = (int)($this->lookAnTable(ord($inputitem['data'][$i*2])) * 45); $val += (int)($this->lookAnTable(ord($inputitem['data'][($i*2)+1]))); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 11, $val); } if ($inputitem['size'] & 1) { $val = $this->lookAnTable(ord($inputitem['data'][($words * 2)])); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 6, $val); } return $inputitem; } /** * encodeMode8 * @param $inputitem (array) * @param $version (int) * @return array input item */ protected function encodeMode8($inputitem, $version) { $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x4); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_8B, $version), $inputitem['size']); for ($i=0; $i < $inputitem['size']; ++$i) { $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 8, ord($inputitem['data'][$i])); } return $inputitem; } /** * encodeModeKanji * @param $inputitem (array) * @param $version (int) * @return array input item */ protected function encodeModeKanji($inputitem, $version) { $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x8); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], $this->lengthIndicator(QR_MODE_KJ, $version), (int)($inputitem['size'] / 2)); for ($i=0; $i<$inputitem['size']; $i+=2) { $val = (ord($inputitem['data'][$i]) << 8) | ord($inputitem['data'][$i+1]); if ($val <= 0x9ffc) { $val -= 0x8140; } else { $val -= 0xc140; } $h = ($val >> 8) * 0xc0; $val = ($val & 0xff) + $h; $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 13, $val); } return $inputitem; } /** * encodeModeStructure * @param $inputitem (array) * @return array input item */ protected function encodeModeStructure($inputitem) { $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, 0x03); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, ord($inputitem['data'][1]) - 1); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 4, ord($inputitem['data'][0]) - 1); $inputitem['bstream'] = $this->appendNum($inputitem['bstream'], 8, ord($inputitem['data'][2])); return $inputitem; } /** * encodeBitStream * @param $inputitem (array) * @param $version (int) * @return array input item */ protected function encodeBitStream($inputitem, $version) { $inputitem['bstream'] = array(); $words = $this->maximumWords($inputitem['mode'], $version); if ($inputitem['size'] > $words) { $st1 = $this->newInputItem($inputitem['mode'], $words, $inputitem['data']); $st2 = $this->newInputItem($inputitem['mode'], $inputitem['size'] - $words, array_slice($inputitem['data'], $words)); $st1 = $this->encodeBitStream($st1, $version); $st2 = $this->encodeBitStream($st2, $version); $inputitem['bstream'] = array(); $inputitem['bstream'] = $this->appendBitstream($inputitem['bstream'], $st1['bstream']); $inputitem['bstream'] = $this->appendBitstream($inputitem['bstream'], $st2['bstream']); } else { switch($inputitem['mode']) { case QR_MODE_NM: { $inputitem = $this->encodeModeNum($inputitem, $version); break; } case QR_MODE_AN: { $inputitem = $this->encodeModeAn($inputitem, $version); break; } case QR_MODE_8B: { $inputitem = $this->encodeMode8($inputitem, $version); break; } case QR_MODE_KJ: { $inputitem = $this->encodeModeKanji($inputitem, $version); break; } case QR_MODE_ST: { $inputitem = $this->encodeModeStructure($inputitem); break; } default: { break; } } } return $inputitem; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRinput /** * Append data to an input object. * The data is copied and appended to the input object. * @param $items (arrray) input items * @param $mode (int) encoding mode. * @param $size (int) size of data (byte). * @param $data (array) array of input data. * @return items * */ protected function appendNewInputItem($items, $mode, $size, $data) { $newitem = $this->newInputItem($mode, $size, $data); if (!empty($newitem)) { $items[] = $newitem; } return $items; } /** * insertStructuredAppendHeader * @param $items (array) * @param $size (int) * @param $index (int) * @param $parity (int) * @return array items */ protected function insertStructuredAppendHeader($items, $size, $index, $parity) { if ($size > MAX_STRUCTURED_SYMBOLS) { return -1; } if (($index <= 0) OR ($index > MAX_STRUCTURED_SYMBOLS)) { return -1; } $buf = array($size, $index, $parity); $entry = $this->newInputItem(QR_MODE_ST, 3, buf); array_unshift($items, $entry); return $items; } /** * calcParity * @param $items (array) * @return int parity */ protected function calcParity($items) { $parity = 0; foreach ($items as $item) { if ($item['mode'] != QR_MODE_ST) { for ($i=$item['size']-1; $i>=0; --$i) { $parity ^= $item['data'][$i]; } } } return $parity; } /** * checkModeNum * @param $size (int) * @param $data (array) * @return boolean true or false */ protected function checkModeNum($size, $data) { for ($i=0; $i<$size; ++$i) { if ((ord($data[$i]) < ord('0')) OR (ord($data[$i]) > ord('9'))){ return false; } } return true; } /** * Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19). * @param $c (int) character value * @return value */ protected function lookAnTable($c) { return (($c > 127)?-1:$this->anTable[$c]); } /** * checkModeAn * @param $size (int) * @param $data (array) * @return boolean true or false */ protected function checkModeAn($size, $data) { for ($i=0; $i<$size; ++$i) { if ($this->lookAnTable(ord($data[$i])) == -1) { return false; } } return true; } /** * estimateBitsModeNum * @param $size (int) * @return int number of bits */ protected function estimateBitsModeNum($size) { $w = (int)($size / 3); $bits = ($w * 10); switch($size - ($w * 3)) { case 1: { $bits += 4; break; } case 2: { $bits += 7; break; } } return $bits; } /** * estimateBitsModeAn * @param $size (int) * @return int number of bits */ protected function estimateBitsModeAn($size) { $bits = (int)($size * 5.5); // (size / 2 ) * 11 if ($size & 1) { $bits += 6; } return $bits; } /** * estimateBitsMode8 * @param $size (int) * @return int number of bits */ protected function estimateBitsMode8($size) { return (int)($size * 8); } /** * estimateBitsModeKanji * @param $size (int) * @return int number of bits */ protected function estimateBitsModeKanji($size) { return (int)($size * 6.5); // (size / 2 ) * 13 } /** * checkModeKanji * @param $size (int) * @param $data (array) * @return boolean true or false */ protected function checkModeKanji($size, $data) { if ($size & 1) { return false; } for ($i=0; $i<$size; $i+=2) { $val = (ord($data[$i]) << 8) | ord($data[$i+1]); if (($val < 0x8140) OR (($val > 0x9ffc) AND ($val < 0xe040)) OR ($val > 0xebbf)) { return false; } } return true; } /** * Validate the input data. * @param $mode (int) encoding mode. * @param $size (int) size of data (byte). * @param $data (array) data to validate * @return boolean true in case of valid data, false otherwise */ protected function check($mode, $size, $data) { if ($size <= 0) { return false; } switch($mode) { case QR_MODE_NM: { return $this->checkModeNum($size, $data); } case QR_MODE_AN: { return $this->checkModeAn($size, $data); } case QR_MODE_KJ: { return $this->checkModeKanji($size, $data); } case QR_MODE_8B: { return true; } case QR_MODE_ST: { return true; } default: { break; } } return false; } /** * estimateBitStreamSize * @param $items (array) * @param $version (int) * @return int bits */ protected function estimateBitStreamSize($items, $version) { $bits = 0; if ($version == 0) { $version = 1; } foreach ($items as $item) { switch($item['mode']) { case QR_MODE_NM: { $bits = $this->estimateBitsModeNum($item['size']); break; } case QR_MODE_AN: { $bits = $this->estimateBitsModeAn($item['size']); break; } case QR_MODE_8B: { $bits = $this->estimateBitsMode8($item['size']); break; } case QR_MODE_KJ: { $bits = $this->estimateBitsModeKanji($item['size']); break; } case QR_MODE_ST: { return STRUCTURE_HEADER_BITS; } default: { return 0; } } $l = $this->lengthIndicator($item['mode'], $version); $m = 1 << $l; $num = (int)(($item['size'] + $m - 1) / $m); $bits += $num * (4 + $l); } return $bits; } /** * estimateVersion * @param $items (array) * @return int version */ protected function estimateVersion($items) { $version = 0; $prev = 0; do { $prev = $version; $bits = $this->estimateBitStreamSize($items, $prev); $version = $this->getMinimumVersion((int)(($bits + 7) / 8), $this->level); if ($version < 0) { return -1; } } while ($version > $prev); return $version; } /** * lengthOfCode * @param $mode (int) * @param $version (int) * @param $bits (int) * @return int size */ protected function lengthOfCode($mode, $version, $bits) { $payload = $bits - 4 - $this->lengthIndicator($mode, $version); switch($mode) { case QR_MODE_NM: { $chunks = (int)($payload / 10); $remain = $payload - $chunks * 10; $size = $chunks * 3; if ($remain >= 7) { $size += 2; } elseif ($remain >= 4) { $size += 1; } break; } case QR_MODE_AN: { $chunks = (int)($payload / 11); $remain = $payload - $chunks * 11; $size = $chunks * 2; if ($remain >= 6) { ++$size; } break; } case QR_MODE_8B: { $size = (int)($payload / 8); break; } case QR_MODE_KJ: { $size = (int)(($payload / 13) * 2); break; } case QR_MODE_ST: { $size = (int)($payload / 8); break; } default: { $size = 0; break; } } $maxsize = $this->maximumWords($mode, $version); if ($size < 0) { $size = 0; } if ($size > $maxsize) { $size = $maxsize; } return $size; } /** * createBitStream * @param $items (array) * @return array of items and total bits */ protected function createBitStream($items) { $total = 0; foreach ($items as $key => $item) { $items[$key] = $this->encodeBitStream($item, $this->version); $bits = count($items[$key]['bstream']); $total += $bits; } return array($items, $total); } /** * convertData * @param $items (array) * @return array items */ protected function convertData($items) { $ver = $this->estimateVersion($items); if ($ver > $this->version) { $this->version = $ver; } while (true) { $cbs = $this->createBitStream($items); $items = $cbs[0]; $bits = $cbs[1]; if ($bits < 0) { return -1; } $ver = $this->getMinimumVersion((int)(($bits + 7) / 8), $this->level); if ($ver < 0) { return -1; } elseif ($ver > $this->version) { $this->version = $ver; } else { break; } } return $items; } /** * Append Padding Bit to bitstream * @param $bstream (array) * @return array bitstream */ protected function appendPaddingBit($bstream) { if (is_null($bstream)) { return null; } $bits = count($bstream); $maxwords = $this->getDataLength($this->version, $this->level); $maxbits = $maxwords * 8; if ($maxbits == $bits) { return $bstream; } if ($maxbits - $bits < 5) { return $this->appendNum($bstream, $maxbits - $bits, 0); } $bits += 4; $words = (int)(($bits + 7) / 8); $padding = array(); $padding = $this->appendNum($padding, $words * 8 - $bits + 4, 0); $padlen = $maxwords - $words; if ($padlen > 0) { $padbuf = array(); for ($i=0; $i<$padlen; ++$i) { $padbuf[$i] = ($i&1)?0x11:0xec; } $padding = $this->appendBytes($padding, $padlen, $padbuf); } return $this->appendBitstream($bstream, $padding); } /** * mergeBitStream * @param $items (array) items * @return array bitstream */ protected function mergeBitStream($items) { $items = $this->convertData($items); if (!is_array($items)) { return null; } $bstream = array(); foreach ($items as $item) { $bstream = $this->appendBitstream($bstream, $item['bstream']); } return $bstream; } /** * Returns a stream of bits. * @param $items (int) * @return array padded merged byte stream */ protected function getBitStream($items) { $bstream = $this->mergeBitStream($items); return $this->appendPaddingBit($bstream); } /** * Pack all bit streams padding bits into a byte array. * @param $items (int) * @return array padded merged byte stream */ protected function getByteStream($items) { $bstream = $this->getBitStream($items); return $this->bitstreamToByte($bstream); } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRbitstream /** * Return an array with zeros * @param $setLength (int) array size * @return array */ protected function allocate($setLength) { return array_fill(0, $setLength, 0); } /** * Return new bitstream from number * @param $bits (int) number of bits * @param $num (int) number * @return array bitstream */ protected function newFromNum($bits, $num) { $bstream = $this->allocate($bits); $mask = 1 << ($bits - 1); for ($i=0; $i<$bits; ++$i) { if ($num & $mask) { $bstream[$i] = 1; } else { $bstream[$i] = 0; } $mask = $mask >> 1; } return $bstream; } /** * Return new bitstream from bytes * @param $size (int) size * @param $data (array) bytes * @return array bitstream */ protected function newFromBytes($size, $data) { $bstream = $this->allocate($size * 8); $p=0; for ($i=0; $i<$size; ++$i) { $mask = 0x80; for ($j=0; $j<8; ++$j) { if ($data[$i] & $mask) { $bstream[$p] = 1; } else { $bstream[$p] = 0; } $p++; $mask = $mask >> 1; } } return $bstream; } /** * Append one bitstream to another * @param $bitstream (array) original bitstream * @param $append (array) bitstream to append * @return array bitstream */ protected function appendBitstream($bitstream, $append) { if ((!is_array($append)) OR (count($append) == 0)) { return $bitstream; } if (count($bitstream) == 0) { return $append; } return array_values(array_merge($bitstream, $append)); } /** * Append one bitstream created from number to another * @param $bitstream (array) original bitstream * @param $bits (int) number of bits * @param $num (int) number * @return array bitstream */ protected function appendNum($bitstream, $bits, $num) { if ($bits == 0) { return 0; } $b = $this->newFromNum($bits, $num); return $this->appendBitstream($bitstream, $b); } /** * Append one bitstream created from bytes to another * @param $bitstream (array) original bitstream * @param $size (int) size * @param $data (array) bytes * @return array bitstream */ protected function appendBytes($bitstream, $size, $data) { if ($size == 0) { return 0; } $b = $this->newFromBytes($size, $data); return $this->appendBitstream($bitstream, $b); } /** * Convert bitstream to bytes * @param $bstream (array) original bitstream * @return array of bytes */ protected function bitstreamToByte($bstream) { if (is_null($bstream)) { return null; } $size = count($bstream); if ($size == 0) { return array(); } $data = array_fill(0, (int)(($size + 7) / 8), 0); $bytes = (int)($size / 8); $p = 0; for ($i=0; $i<$bytes; $i++) { $v = 0; for ($j=0; $j<8; $j++) { $v = $v << 1; $v |= $bstream[$p]; $p++; } $data[$i] = $v; } if ($size & 7) { $v = 0; for ($j=0; $j<($size & 7); $j++) { $v = $v << 1; $v |= $bstream[$p]; $p++; } $data[$bytes] = $v; } return $data; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRspec /** * Replace a value on the array at the specified position * @param $srctab (array) * @param $x (int) X position * @param $y (int) Y position * @param $repl (string) value to replace * @param $replLen (int) length of the repl string * @return array srctab */ protected function qrstrset($srctab, $x, $y, $repl, $replLen=false) { $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl)); return $srctab; } /** * Return maximum data code length (bytes) for the version. * @param $version (int) version * @param $level (int) error correction level * @return int maximum size (bytes) */ protected function getDataLength($version, $level) { return $this->capacity[$version][QRCAP_WORDS] - $this->capacity[$version][QRCAP_EC][$level]; } /** * Return maximum error correction code length (bytes) for the version. * @param $version (int) version * @param $level (int) error correction level * @return int ECC size (bytes) */ protected function getECCLength($version, $level){ return $this->capacity[$version][QRCAP_EC][$level]; } /** * Return the width of the symbol for the version. * @param $version (int) version * @return int width */ protected function getWidth($version) { return $this->capacity[$version][QRCAP_WIDTH]; } /** * Return the numer of remainder bits. * @param $version (int) version * @return int number of remainder bits */ protected function getRemainder($version) { return $this->capacity[$version][QRCAP_REMINDER]; } /** * Return a version number that satisfies the input code length. * @param $size (int) input code length (bytes) * @param $level (int) error correction level * @return int version number */ protected function getMinimumVersion($size, $level) { for ($i = 1; $i <= QRSPEC_VERSION_MAX; ++$i) { $words = ($this->capacity[$i][QRCAP_WORDS] - $this->capacity[$i][QRCAP_EC][$level]); if ($words >= $size) { return $i; } } // the size of input data is greater than QR capacity, try to lover the error correction mode return -1; } /** * Return the size of length indicator for the mode and version. * @param $mode (int) encoding mode * @param $version (int) version * @return int the size of the appropriate length indicator (bits). */ protected function lengthIndicator($mode, $version) { if ($mode == QR_MODE_ST) { return 0; } if ($version <= 9) { $l = 0; } elseif ($version <= 26) { $l = 1; } else { $l = 2; } return $this->lengthTableBits[$mode][$l]; } /** * Return the maximum length for the mode and version. * @param $mode (int) encoding mode * @param $version (int) version * @return int the maximum length (bytes) */ protected function maximumWords($mode, $version) { if ($mode == QR_MODE_ST) { return 3; } if ($version <= 9) { $l = 0; } else if ($version <= 26) { $l = 1; } else { $l = 2; } $bits = $this->lengthTableBits[$mode][$l]; $words = (1 << $bits) - 1; if ($mode == QR_MODE_KJ) { $words *= 2; // the number of bytes is required } return $words; } /** * Return an array of ECC specification. * @param $version (int) version * @param $level (int) error correction level * @param $spec (array) an array of ECC specification contains as following: {# of type1 blocks, # of data code, # of ecc code, # of type2 blocks, # of data code} * @return array spec */ protected function getEccSpec($version, $level, $spec) { if (count($spec) < 5) { $spec = array(0, 0, 0, 0, 0); } $b1 = $this->eccTable[$version][$level][0]; $b2 = $this->eccTable[$version][$level][1]; $data = $this->getDataLength($version, $level); $ecc = $this->getECCLength($version, $level); if ($b2 == 0) { $spec[0] = $b1; $spec[1] = (int)($data / $b1); $spec[2] = (int)($ecc / $b1); $spec[3] = 0; $spec[4] = 0; } else { $spec[0] = $b1; $spec[1] = (int)($data / ($b1 + $b2)); $spec[2] = (int)($ecc / ($b1 + $b2)); $spec[3] = $b2; $spec[4] = $spec[1] + 1; } return $spec; } /** * Put an alignment marker. * @param $frame (array) frame * @param $ox (int) X center coordinate of the pattern * @param $oy (int) Y center coordinate of the pattern * @return array frame */ protected function putAlignmentMarker($frame, $ox, $oy) { $finder = array( "\xa1\xa1\xa1\xa1\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa0\xa1\xa0\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa1\xa1\xa1\xa1" ); $yStart = $oy - 2; $xStart = $ox - 2; for ($y=0; $y < 5; $y++) { $frame = $this->qrstrset($frame, $xStart, $yStart+$y, $finder[$y]); } return $frame; } /** * Put an alignment pattern. * @param $version (int) version * @param $frame (array) frame * @param $width (int) width * @return array frame */ protected function putAlignmentPattern($version, $frame, $width) { if ($version < 2) { return $frame; } $d = $this->alignmentPattern[$version][1] - $this->alignmentPattern[$version][0]; if ($d < 0) { $w = 2; } else { $w = (int)(($width - $this->alignmentPattern[$version][0]) / $d + 2); } if ($w * $w - 3 == 1) { $x = $this->alignmentPattern[$version][0]; $y = $this->alignmentPattern[$version][0]; $frame = $this->putAlignmentMarker($frame, $x, $y); return $frame; } $cx = $this->alignmentPattern[$version][0]; $wo = $w - 1; for ($x=1; $x < $wo; ++$x) { $frame = $this->putAlignmentMarker($frame, 6, $cx); $frame = $this->putAlignmentMarker($frame, $cx, 6); $cx += $d; } $cy = $this->alignmentPattern[$version][0]; for ($y=0; $y < $wo; ++$y) { $cx = $this->alignmentPattern[$version][0]; for ($x=0; $x < $wo; ++$x) { $frame = $this->putAlignmentMarker($frame, $cx, $cy); $cx += $d; } $cy += $d; } return $frame; } /** * Return BCH encoded version information pattern that is used for the symbol of version 7 or greater. Use lower 18 bits. * @param $version (int) version * @return BCH encoded version information pattern */ protected function getVersionPattern($version) { if (($version < 7) OR ($version > QRSPEC_VERSION_MAX)) { return 0; } return $this->versionPattern[($version - 7)]; } /** * Return BCH encoded format information pattern. * @param $mask (array) * @param $level (int) error correction level * @return BCH encoded format information pattern */ protected function getFormatInfo($mask, $level) { if (($mask < 0) OR ($mask > 7)) { return 0; } if (($level < 0) OR ($level > 3)) { return 0; } return $this->formatInfo[$level][$mask]; } /** * Put a finder pattern. * @param $frame (array) frame * @param $ox (int) X center coordinate of the pattern * @param $oy (int) Y center coordinate of the pattern * @return array frame */ protected function putFinderPattern($frame, $ox, $oy) { $finder = array( "\xc1\xc1\xc1\xc1\xc1\xc1\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" ); for ($y=0; $y < 7; $y++) { $frame = $this->qrstrset($frame, $ox, ($oy + $y), $finder[$y]); } return $frame; } /** * Return a copy of initialized frame. * @param $version (int) version * @return Array of unsigned char. */ protected function createFrame($version) { $width = $this->capacity[$version][QRCAP_WIDTH]; $frameLine = str_repeat ("\0", $width); $frame = array_fill(0, $width, $frameLine); // Finder pattern $frame = $this->putFinderPattern($frame, 0, 0); $frame = $this->putFinderPattern($frame, $width - 7, 0); $frame = $this->putFinderPattern($frame, 0, $width - 7); // Separator $yOffset = $width - 7; for ($y=0; $y < 7; ++$y) { $frame[$y][7] = "\xc0"; $frame[$y][$width - 8] = "\xc0"; $frame[$yOffset][7] = "\xc0"; ++$yOffset; } $setPattern = str_repeat("\xc0", 8); $frame = $this->qrstrset($frame, 0, 7, $setPattern); $frame = $this->qrstrset($frame, $width-8, 7, $setPattern); $frame = $this->qrstrset($frame, 0, $width - 8, $setPattern); // Format info $setPattern = str_repeat("\x84", 9); $frame = $this->qrstrset($frame, 0, 8, $setPattern); $frame = $this->qrstrset($frame, $width - 8, 8, $setPattern, 8); $yOffset = $width - 8; for ($y=0; $y < 8; ++$y,++$yOffset) { $frame[$y][8] = "\x84"; $frame[$yOffset][8] = "\x84"; } // Timing pattern $wo = $width - 15; for ($i=1; $i < $wo; ++$i) { $frame[6][7+$i] = chr(0x90 | ($i & 1)); $frame[7+$i][6] = chr(0x90 | ($i & 1)); } // Alignment pattern $frame = $this->putAlignmentPattern($version, $frame, $width); // Version information if ($version >= 7) { $vinf = $this->getVersionPattern($version); $v = $vinf; for ($x=0; $x<6; ++$x) { for ($y=0; $y<3; ++$y) { $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } $v = $vinf; for ($y=0; $y<6; ++$y) { for ($x=0; $x<3; ++$x) { $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1)); $v = $v >> 1; } } } // and a little bit... $frame[$width - 8][8] = "\x81"; return $frame; } /** * Set new frame for the specified version. * @param $version (int) version * @return Array of unsigned char. */ protected function newFrame($version) { if (($version < 1) OR ($version > QRSPEC_VERSION_MAX)) { return NULL; } if (!isset($this->frames[$version])) { $this->frames[$version] = $this->createFrame($version); } if (is_null($this->frames[$version])) { return NULL; } return $this->frames[$version]; } /** * Return block number 0 * @param $spec (array) * @return int value */ protected function rsBlockNum($spec) { return ($spec[0] + $spec[3]); } /** * Return block number 1 * @param $spec (array) * @return int value */ protected function rsBlockNum1($spec) { return $spec[0]; } /** * Return data codes 1 * @param $spec (array) * @return int value */ protected function rsDataCodes1($spec) { return $spec[1]; } /** * Return ecc codes 1 * @param $spec (array) * @return int value */ protected function rsEccCodes1($spec) { return $spec[2]; } /** * Return block number 2 * @param $spec (array) * @return int value */ protected function rsBlockNum2($spec) { return $spec[3]; } /** * Return data codes 2 * @param $spec (array) * @return int value */ protected function rsDataCodes2($spec) { return $spec[4]; } /** * Return ecc codes 2 * @param $spec (array) * @return int value */ protected function rsEccCodes2($spec) { return $spec[2]; } /** * Return data length * @param $spec (array) * @return int value */ protected function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } /** * Return ecc length * @param $spec (array) * @return int value */ protected function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRrs /** * Initialize a Reed-Solomon codec and add it to existing rsitems * @param $symsize (int) symbol size, bits * @param $gfpoly (int) Field generator polynomial coefficients * @param $fcr (int) first root of RS code generator polynomial, index form * @param $prim (int) primitive element to generate polynomial roots * @param $nroots (int) RS code generator polynomial degree (number of roots) * @param $pad (int) padding bytes at front of shortened block * @return array Array of RS values:
      • mm = Bits per symbol;
      • nn = Symbols per block;
      • alpha_to = log lookup table array;
      • index_of = Antilog lookup table array;
      • genpoly = Generator polynomial array;
      • nroots = Number of generator;
      • roots = number of parity symbols;
      • fcr = First consecutive root, index form;
      • prim = Primitive element, index form;
      • iprim = prim-th root of 1, index form;
      • pad = Padding bytes in shortened block;
      • gfpoly
      . */ protected function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { foreach ($this->rsitems as $rs) { if (($rs['pad'] != $pad) OR ($rs['nroots'] != $nroots) OR ($rs['mm'] != $symsize) OR ($rs['gfpoly'] != $gfpoly) OR ($rs['fcr'] != $fcr) OR ($rs['prim'] != $prim)) { continue; } return $rs; } $rs = $this->init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); array_unshift($this->rsitems, $rs); return $rs; } // - - - - - - - - - - - - - - - - - - - - - - - - - // QRrsItem /** * modnn * @param $rs (array) RS values * @param $x (int) X position * @return int X osition */ protected function modnn($rs, $x) { while ($x >= $rs['nn']) { $x -= $rs['nn']; $x = ($x >> $rs['mm']) + ($x & $rs['nn']); } return $x; } /** * Initialize a Reed-Solomon codec and returns an array of values. * @param $symsize (int) symbol size, bits * @param $gfpoly (int) Field generator polynomial coefficients * @param $fcr (int) first root of RS code generator polynomial, index form * @param $prim (int) primitive element to generate polynomial roots * @param $nroots (int) RS code generator polynomial degree (number of roots) * @param $pad (int) padding bytes at front of shortened block * @return array Array of RS values:
      • mm = Bits per symbol;
      • nn = Symbols per block;
      • alpha_to = log lookup table array;
      • index_of = Antilog lookup table array;
      • genpoly = Generator polynomial array;
      • nroots = Number of generator;
      • roots = number of parity symbols;
      • fcr = First consecutive root, index form;
      • prim = Primitive element, index form;
      • iprim = prim-th root of 1, index form;
      • pad = Padding bytes in shortened block;
      • gfpoly
      . */ protected function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) { // Based on Reed solomon encoder by Phil Karn, KA9Q (GNU-LGPLv2) $rs = null; // Check parameter ranges if (($symsize < 0) OR ($symsize > 8)) { return $rs; } if (($fcr < 0) OR ($fcr >= (1<<$symsize))) { return $rs; } if (($prim <= 0) OR ($prim >= (1<<$symsize))) { return $rs; } if (($nroots < 0) OR ($nroots >= (1<<$symsize))) { return $rs; } if (($pad < 0) OR ($pad >= ((1<<$symsize) -1 - $nroots))) { return $rs; } $rs = array(); $rs['mm'] = $symsize; $rs['nn'] = (1 << $symsize) - 1; $rs['pad'] = $pad; $rs['alpha_to'] = array_fill(0, ($rs['nn'] + 1), 0); $rs['index_of'] = array_fill(0, ($rs['nn'] + 1), 0); // PHP style macro replacement ;) $NN =& $rs['nn']; $A0 =& $NN; // Generate Galois field lookup tables $rs['index_of'][0] = $A0; // log(zero) = -inf $rs['alpha_to'][$A0] = 0; // alpha**-inf = 0 $sr = 1; for ($i=0; $i<$rs['nn']; ++$i) { $rs['index_of'][$sr] = $i; $rs['alpha_to'][$i] = $sr; $sr <<= 1; if ($sr & (1 << $symsize)) { $sr ^= $gfpoly; } $sr &= $rs['nn']; } if ($sr != 1) { // field generator polynomial is not primitive! return NULL; } // Form RS code generator polynomial from its roots $rs['genpoly'] = array_fill(0, ($nroots + 1), 0); $rs['fcr'] = $fcr; $rs['prim'] = $prim; $rs['nroots'] = $nroots; $rs['gfpoly'] = $gfpoly; // Find prim-th root of 1, used in decoding for ($iprim=1; ($iprim % $prim) != 0; $iprim += $rs['nn']) { ; // intentional empty-body loop! } $rs['iprim'] = (int)($iprim / $prim); $rs['genpoly'][0] = 1; for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { $rs['genpoly'][$i+1] = 1; // Multiply rs->genpoly[] by @**(root + x) for ($j = $i; $j > 0; --$j) { if ($rs['genpoly'][$j] != 0) { $rs['genpoly'][$j] = $rs['genpoly'][$j-1] ^ $rs['alpha_to'][$this->modnn($rs, $rs['index_of'][$rs['genpoly'][$j]] + $root)]; } else { $rs['genpoly'][$j] = $rs['genpoly'][$j-1]; } } // rs->genpoly[0] can never be zero $rs['genpoly'][0] = $rs['alpha_to'][$this->modnn($rs, $rs['index_of'][$rs['genpoly'][0]] + $root)]; } // convert rs->genpoly[] to index form for quicker encoding for ($i = 0; $i <= $nroots; ++$i) { $rs['genpoly'][$i] = $rs['index_of'][$rs['genpoly'][$i]]; } return $rs; } /** * Encode a Reed-Solomon codec and returns the parity array * @param $rs (array) RS values * @param $data (array) data * @param $parity (array) parity * @return parity array */ protected function encode_rs_char($rs, $data, $parity) { $MM =& $rs['mm']; // bits per symbol $NN =& $rs['nn']; // the total number of symbols in a RS block $ALPHA_TO =& $rs['alpha_to']; // the address of an array of NN elements to convert Galois field elements in index (log) form to polynomial form $INDEX_OF =& $rs['index_of']; // the address of an array of NN elements to convert Galois field elements in polynomial form to index (log) form $GENPOLY =& $rs['genpoly']; // an array of NROOTS+1 elements containing the generator polynomial in index form $NROOTS =& $rs['nroots']; // the number of roots in the RS code generator polynomial, which is the same as the number of parity symbols in a block $FCR =& $rs['fcr']; // first consecutive root, index form $PRIM =& $rs['prim']; // primitive element, index form $IPRIM =& $rs['iprim']; // prim-th root of 1, index form $PAD =& $rs['pad']; // the number of pad symbols in a block $A0 =& $NN; $parity = array_fill(0, $NROOTS, 0); for ($i=0; $i < ($NN - $NROOTS - $PAD); $i++) { $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; if ($feedback != $A0) { // feedback term is non-zero // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must // always be for the polynomials constructed by init_rs() $feedback = $this->modnn($rs, $NN - $GENPOLY[$NROOTS] + $feedback); for ($j=1; $j < $NROOTS; ++$j) { $parity[$j] ^= $ALPHA_TO[$this->modnn($rs, $feedback + $GENPOLY[($NROOTS - $j)])]; } } // Shift array_shift($parity); if ($feedback != $A0) { array_push($parity, $ALPHA_TO[$this->modnn($rs, $feedback + $GENPOLY[0])]); } else { array_push($parity, 0); } } return $parity; } } // end QRcode class //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/tcpdf_colors.php000066400000000000000000000336651237252063700217230ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : Array of WEB safe colors // //============================================================+ /** * @file * PHP color class for TCPDF * @author Nicola Asuni * @package com.tecnick.tcpdf */ /** * @class TCPDF_COLORS * PHP color class for TCPDF * @package com.tecnick.tcpdf * @version 1.0.000 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_COLORS { /** * Array of WEB safe colors * @public static */ public static $webcolor = array ( 'aliceblue' => 'f0f8ff', 'antiquewhite' => 'faebd7', 'aqua' => '00ffff', 'aquamarine' => '7fffd4', 'azure' => 'f0ffff', 'beige' => 'f5f5dc', 'bisque' => 'ffe4c4', 'black' => '000000', 'blanchedalmond' => 'ffebcd', 'blue' => '0000ff', 'blueviolet' => '8a2be2', 'brown' => 'a52a2a', 'burlywood' => 'deb887', 'cadetblue' => '5f9ea0', 'chartreuse' => '7fff00', 'chocolate' => 'd2691e', 'coral' => 'ff7f50', 'cornflowerblue' => '6495ed', 'cornsilk' => 'fff8dc', 'crimson' => 'dc143c', 'cyan' => '00ffff', 'darkblue' => '00008b', 'darkcyan' => '008b8b', 'darkgoldenrod' => 'b8860b', 'dkgray' => 'a9a9a9', 'darkgray' => 'a9a9a9', 'darkgrey' => 'a9a9a9', 'darkgreen' => '006400', 'darkkhaki' => 'bdb76b', 'darkmagenta' => '8b008b', 'darkolivegreen' => '556b2f', 'darkorange' => 'ff8c00', 'darkorchid' => '9932cc', 'darkred' => '8b0000', 'darksalmon' => 'e9967a', 'darkseagreen' => '8fbc8f', 'darkslateblue' => '483d8b', 'darkslategray' => '2f4f4f', 'darkslategrey' => '2f4f4f', 'darkturquoise' => '00ced1', 'darkviolet' => '9400d3', 'deeppink' => 'ff1493', 'deepskyblue' => '00bfff', 'dimgray' => '696969', 'dimgrey' => '696969', 'dodgerblue' => '1e90ff', 'firebrick' => 'b22222', 'floralwhite' => 'fffaf0', 'forestgreen' => '228b22', 'fuchsia' => 'ff00ff', 'gainsboro' => 'dcdcdc', 'ghostwhite' => 'f8f8ff', 'gold' => 'ffd700', 'goldenrod' => 'daa520', 'gray' => '808080', 'grey' => '808080', 'green' => '008000', 'greenyellow' => 'adff2f', 'honeydew' => 'f0fff0', 'hotpink' => 'ff69b4', 'indianred' => 'cd5c5c', 'indigo' => '4b0082', 'ivory' => 'fffff0', 'khaki' => 'f0e68c', 'lavender' => 'e6e6fa', 'lavenderblush' => 'fff0f5', 'lawngreen' => '7cfc00', 'lemonchiffon' => 'fffacd', 'lightblue' => 'add8e6', 'lightcoral' => 'f08080', 'lightcyan' => 'e0ffff', 'lightgoldenrodyellow' => 'fafad2', 'ltgray' => 'd3d3d3', 'lightgray' => 'd3d3d3', 'lightgrey' => 'd3d3d3', 'lightgreen' => '90ee90', 'lightpink' => 'ffb6c1', 'lightsalmon' => 'ffa07a', 'lightseagreen' => '20b2aa', 'lightskyblue' => '87cefa', 'lightslategray' => '778899', 'lightslategrey' => '778899', 'lightsteelblue' => 'b0c4de', 'lightyellow' => 'ffffe0', 'lime' => '00ff00', 'limegreen' => '32cd32', 'linen' => 'faf0e6', 'magenta' => 'ff00ff', 'maroon' => '800000', 'mediumaquamarine' => '66cdaa', 'mediumblue' => '0000cd', 'mediumorchid' => 'ba55d3', 'mediumpurple' => '9370d8', 'mediumseagreen' => '3cb371', 'mediumslateblue' => '7b68ee', 'mediumspringgreen' => '00fa9a', 'mediumturquoise' => '48d1cc', 'mediumvioletred' => 'c71585', 'midnightblue' => '191970', 'mintcream' => 'f5fffa', 'mistyrose' => 'ffe4e1', 'moccasin' => 'ffe4b5', 'navajowhite' => 'ffdead', 'navy' => '000080', 'oldlace' => 'fdf5e6', 'olive' => '808000', 'olivedrab' => '6b8e23', 'orange' => 'ffa500', 'orangered' => 'ff4500', 'orchid' => 'da70d6', 'palegoldenrod' => 'eee8aa', 'palegreen' => '98fb98', 'paleturquoise' => 'afeeee', 'palevioletred' => 'd87093', 'papayawhip' => 'ffefd5', 'peachpuff' => 'ffdab9', 'peru' => 'cd853f', 'pink' => 'ffc0cb', 'plum' => 'dda0dd', 'powderblue' => 'b0e0e6', 'purple' => '800080', 'red' => 'ff0000', 'rosybrown' => 'bc8f8f', 'royalblue' => '4169e1', 'saddlebrown' => '8b4513', 'salmon' => 'fa8072', 'sandybrown' => 'f4a460', 'seagreen' => '2e8b57', 'seashell' => 'fff5ee', 'sienna' => 'a0522d', 'silver' => 'c0c0c0', 'skyblue' => '87ceeb', 'slateblue' => '6a5acd', 'slategray' => '708090', 'slategrey' => '708090', 'snow' => 'fffafa', 'springgreen' => '00ff7f', 'steelblue' => '4682b4', 'tan' => 'd2b48c', 'teal' => '008080', 'thistle' => 'd8bfd8', 'tomato' => 'ff6347', 'turquoise' => '40e0d0', 'violet' => 'ee82ee', 'wheat' => 'f5deb3', 'white' => 'ffffff', 'whitesmoke' => 'f5f5f5', 'yellow' => 'ffff00', 'yellowgreen' => '9acd32' ); // end of web colors /** * Array of valid JavaScript color names * @public static */ public static $jscolor = array ('transparent', 'black', 'white', 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'dkGray', 'gray', 'ltGray'); /** * Array of Spot colors (C,M,Y,K,name) * Color keys must be in lowercase and without spaces. * As long as no open standard for spot colours exists, you have to buy a colour book by one of the colour manufacturers and insert the values and names of spot colours directly. * Common industry standard spot colors are: ANPA-COLOR, DIC, FOCOLTONE, GCMI, HKS, PANTONE, TOYO, TRUMATCH. * @public static */ public static $spotcolor = array ( // the following are just examples, fill the array with your own values 'mytcpdfblack' => array(0, 0, 0, 100, 'My TCPDF Black'), 'mytcpdfred' => array(30, 100, 90, 10, 'My TCPDF Red'), 'mytcpdfgreen' => array(100, 30, 100, 0, 'My TCPDF Green'), 'mytcpdfblue' => array(100, 60, 10, 5, 'My TCPDF Blue'), 'mytcpdfyellow' => array(0, 20, 100, 0, 'My TCPDF Yellow'), // ... ); // end of spot colors // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Return the Spot color array. * @param $name (string) Name of the spot color. * @param $spotc (array) Reference to an array of spot colors. * @return (array) Spot color array or false if not defined. * @since 5.9.125 (2011-10-03) * @public static */ public static function getSpotColor($name, &$spotc) { if (isset($spotc[$name])) { return $spotc[$name]; } $color = preg_replace('/[\s]*/', '', $name); // remove extra spaces $color = strtolower($color); if (isset(self::$spotcolor[$color])) { if (!isset($spotc[$name])) { $i = (1 + count($spotc)); $spotc[$name] = array('C' => self::$spotcolor[$color][0], 'M' => self::$spotcolor[$color][1], 'Y' => self::$spotcolor[$color][2], 'K' => self::$spotcolor[$color][3], 'name' => self::$spotcolor[$color][4], 'i' => $i); } return $spotc[self::$spotcolor[$color][4]]; } return false; } /** * Returns an array (RGB or CMYK) from an html color name, or a six-digit (i.e. #3FE5AA), or three-digit (i.e. #7FF) hexadecimal color, or a javascript color array, or javascript color name. * @param $hcolor (string) HTML color. * @param $spotc (array) Reference to an array of spot colors. * @param $defcol (array) Color to return in case of error. * @return array RGB or CMYK color, or false in case of error. * @public static */ public static function convertHTMLColorToDec($hcolor, &$spotc, $defcol=array('R'=>128,'G'=>128,'B'=>128)) { $color = preg_replace('/[\s]*/', '', $hcolor); // remove extra spaces $color = strtolower($color); // check for javascript color array syntax if (strpos($color, '[') !== false) { if (preg_match('/[\[][\"\'](t|g|rgb|cmyk)[\"\'][\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\]]/', $color, $m) > 0) { $returncolor = array(); switch ($m[1]) { case 'cmyk': { // RGB $returncolor['C'] = max(0, min(100, (floatval($m[2]) * 100))); $returncolor['M'] = max(0, min(100, (floatval($m[3]) * 100))); $returncolor['Y'] = max(0, min(100, (floatval($m[4]) * 100))); $returncolor['K'] = max(0, min(100, (floatval($m[5]) * 100))); break; } case 'rgb': { // RGB $returncolor['R'] = max(0, min(255, (floatval($m[2]) * 255))); $returncolor['G'] = max(0, min(255, (floatval($m[3]) * 255))); $returncolor['B'] = max(0, min(255, (floatval($m[4]) * 255))); break; } case 'g': { // grayscale $returncolor['G'] = max(0, min(255, (floatval($m[2]) * 255))); break; } case 't': default: { // transparent (empty array) break; } } return $returncolor; } } elseif (($dotpos = strpos($color, '.')) !== false) { // remove class parent (i.e.: color.red) $color = substr($color, ($dotpos + 1)); if ($color == 'transparent') { // transparent (empty array) return array(); } } if (strlen($color) == 0) { return $defcol; } // RGB ARRAY if (substr($color, 0, 3) == 'rgb') { $codes = substr($color, 4); $codes = str_replace(')', '', $codes); $returncolor = explode(',', $codes); foreach ($returncolor as $key => $val) { if (strpos($val, '%') > 0) { // percentage $returncolor[$key] = (255 * intval($val) / 100); } else { $returncolor[$key] = intval($val); } // normalize value $returncolor[$key] = max(0, min(255, $returncolor[$key])); } return $returncolor; } // CMYK ARRAY if (substr($color, 0, 4) == 'cmyk') { $codes = substr($color, 5); $codes = str_replace(')', '', $codes); $returncolor = explode(',', $codes); foreach ($returncolor as $key => $val) { if (strpos($val, '%') !== false) { // percentage $returncolor[$key] = (100 * intval($val) / 100); } else { $returncolor[$key] = intval($val); } // normalize value $returncolor[$key] = max(0, min(100, $returncolor[$key])); } return $returncolor; } if ($color{0} != '#') { // COLOR NAME if (isset(self::$webcolor[$color])) { // web color $color_code = self::$webcolor[$color]; } else { // spot color $returncolor = self::getSpotColor($color, $spotc); if ($returncolor === false) { $returncolor = $defcol; } return $returncolor; } } else { $color_code = substr($color, 1); } // HEXADECIMAL REPRESENTATION switch (strlen($color_code)) { case 3: { // 3-digit RGB hexadecimal representation $r = substr($color_code, 0, 1); $g = substr($color_code, 1, 1); $b = substr($color_code, 2, 1); $returncolor = array(); $returncolor['R'] = max(0, min(255, hexdec($r.$r))); $returncolor['G'] = max(0, min(255, hexdec($g.$g))); $returncolor['B'] = max(0, min(255, hexdec($b.$b))); break; } case 6: { // 6-digit RGB hexadecimal representation $returncolor = array(); $returncolor['R'] = max(0, min(255, hexdec(substr($color_code, 0, 2)))); $returncolor['G'] = max(0, min(255, hexdec(substr($color_code, 2, 2)))); $returncolor['B'] = max(0, min(255, hexdec(substr($color_code, 4, 2)))); break; } case 8: { // 8-digit CMYK hexadecimal representation $returncolor = array(); $returncolor['C'] = max(0, min(100, round(hexdec(substr($color_code, 0, 2)) / 2.55))); $returncolor['M'] = max(0, min(100, round(hexdec(substr($color_code, 2, 2)) / 2.55))); $returncolor['Y'] = max(0, min(100, round(hexdec(substr($color_code, 4, 2)) / 2.55))); $returncolor['K'] = max(0, min(100, round(hexdec(substr($color_code, 6, 2)) / 2.55))); break; } default: { $returncolor = $defcol; break; } } return $returncolor; } /** * Convert a color array into a string representation. * @param $c (array) Array of colors. * @return (string) The color array representation. * @since 5.9.137 (2011-12-01) * @public static */ public static function getColorStringFromArray($c) { $c = array_values($c); $color = '['; switch (count($c)) { case 4: { // CMYK $color .= sprintf('%F %F %F %F', (max(0, min(100, floatval($c[0]))) / 100), (max(0, min(100, floatval($c[1]))) / 100), (max(0, min(100, floatval($c[2]))) / 100), (max(0, min(100, floatval($c[3]))) / 100)); break; } case 3: { // RGB $color .= sprintf('%F %F %F', (max(0, min(255, floatval($c[0]))) / 255), (max(0, min(255, floatval($c[1]))) / 255), (max(0, min(255, floatval($c[2]))) / 255)); break; } case 1: { // grayscale $color .= sprintf('%F', (max(0, min(255, floatval($c[0]))) / 255)); break; } } $color .= ']'; return $color; } /** * Convert color to javascript color. * @param $color (string) color name or "#RRGGBB" * @protected * @since 2.1.002 (2008-02-12) * @public static */ public static function _JScolor($color) { if (substr($color, 0, 1) == '#') { return sprintf("['RGB',%F,%F,%F]", (hexdec(substr($color, 1, 2)) / 255), (hexdec(substr($color, 3, 2)) / 255), (hexdec(substr($color, 5, 2)) / 255)); } if (!in_array($color, self::$jscolor)) { // default transparent color $color = $jscolor[0]; } return 'color.'.$color; } } // --- END OF CLASS --- //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/tcpdf_filters.php000066400000000000000000000335751237252063700220720ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters). // //============================================================+ /** * @file * This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters).
      * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.000 */ /** * @class TCPDF_FILTERS * This is a PHP class for decoding common PDF filters (PDF 32000-2008 - 7.4 Filters).
      * @package com.tecnick.tcpdf * @brief This is a PHP class for decoding common PDF filters. * @version 1.0.000 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_FILTERS { /** * Define a list of available filter decoders. * @private static */ private static $available_filters = array('ASCIIHexDecode', 'ASCII85Decode', 'LZWDecode', 'FlateDecode', 'RunLengthDecode'); // ----------------------------------------------------------------------------- /** * Get a list of available decoding filters. * @return (array) Array of available filter decoders. * @since 1.0.000 (2011-05-23) * @public static */ public static function getAvailableFilters() { return self::$available_filters; } /** * Decode data using the specified filter type. * @param $filter (string) Filter name. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilter($filter, $data) { switch ($filter) { case 'ASCIIHexDecode': { return self::decodeFilterASCIIHexDecode($data); break; } case 'ASCII85Decode': { return self::decodeFilterASCII85Decode($data); break; } case 'LZWDecode': { return self::decodeFilterLZWDecode($data); break; } case 'FlateDecode': { return self::decodeFilterFlateDecode($data); break; } case 'RunLengthDecode': { return self::decodeFilterRunLengthDecode($data); break; } case 'CCITTFaxDecode': { return self::decodeFilterCCITTFaxDecode($data); break; } case 'JBIG2Decode': { return self::decodeFilterJBIG2Decode($data); break; } case 'DCTDecode': { return self::decodeFilterDCTDecode($data); break; } case 'JPXDecode': { return self::decodeFilterJPXDecode($data); break; } case 'Crypt': { return self::decodeFilterCrypt($data); break; } default: { return self::decodeFilterStandard($data); break; } } } // --- FILTERS (PDF 32000-2008 - 7.4 Filters) ------------------------------ /** * Standard * Default decoding filter (leaves data unchanged). * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterStandard($data) { return $data; } /** * ASCIIHexDecode * Decodes data encoded in an ASCII hexadecimal representation, reproducing the original binary data. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterASCIIHexDecode($data) { // intialize string to return $decoded = ''; // all white-space characters shall be ignored $data = preg_replace('/[\s]/', '', $data); // check for EOD character: GREATER-THAN SIGN (3Eh) $eod = strpos($data, '>'); if ($eod !== false) { // remove EOD and extra data (if any) $data = substr($data, 0, $eod); $eod = true; } // get data length $data_length = strlen($data); if (($data_length % 2) != 0) { // odd number of hexadecimal digits if ($eod) { // EOD shall behave as if a 0 (zero) followed the last digit $data = substr($data, 0, -1).'0'.substr($data, -1); } else { self::Error('decodeASCIIHex: invalid code'); } } // check for invalid characters if (preg_match('/[^a-fA-F\d]/', $data) > 0) { self::Error('decodeASCIIHex: invalid code'); } // get one byte of binary data for each pair of ASCII hexadecimal digits $decoded = pack('H*', $data); return $decoded; } /** * ASCII85Decode * Decodes data encoded in an ASCII base-85 representation, reproducing the original binary data. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterASCII85Decode($data) { // intialize string to return $decoded = ''; // all white-space characters shall be ignored $data = preg_replace('/[\s]/', '', $data); // remove start sequence 2-character sequence <~ (3Ch)(7Eh) if (strpos($data, '<~') !== false) { // remove EOD and extra data (if any) $data = substr($data, 2); } // check for EOD: 2-character sequence ~> (7Eh)(3Eh) $eod = strpos($data, '~>'); if ($eod !== false) { // remove EOD and extra data (if any) $data = substr($data, 0, $eod); } // data length $data_length = strlen($data); // check for invalid characters if (preg_match('/[^\x21-\x75,\x74]/', $data) > 0) { self::Error('decodeASCII85: invalid code'); } // z sequence $zseq = chr(0).chr(0).chr(0).chr(0); // position inside a group of 4 bytes (0-3) $group_pos = 0; $tuple = 0; $pow85 = array((85*85*85*85), (85*85*85), (85*85), 85, 1); $last_pos = ($data_length - 1); // for each byte for ($i = 0; $i < $data_length; ++$i) { // get char value $char = ord($data[$i]); if ($char == 122) { // 'z' if ($group_pos == 0) { $decoded .= $zseq; } else { self::Error('decodeASCII85: invalid code'); } } else { // the value represented by a group of 5 characters should never be greater than 2^32 - 1 $tuple += (($char - 33) * $pow85[$group_pos]); if ($group_pos == 4) { $decoded .= chr($tuple >> 24).chr($tuple >> 16).chr($tuple >> 8).chr($tuple); $tuple = 0; $group_pos = 0; } else { ++$group_pos; } } } if ($group_pos > 1) { $tuple += $pow85[($group_pos - 1)]; } // last tuple (if any) switch ($group_pos) { case 4: { $decoded .= chr($tuple >> 24).chr($tuple >> 16).chr($tuple >> 8); break; } case 3: { $decoded .= chr($tuple >> 24).chr($tuple >> 16); break; } case 2: { $decoded .= chr($tuple >> 24); break; } case 1: { self::Error('decodeASCII85: invalid code'); break; } } return $decoded; } /** * LZWDecode * Decompresses data encoded using the LZW (Lempel-Ziv-Welch) adaptive compression method, reproducing the original text or binary data. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterLZWDecode($data) { // intialize string to return $decoded = ''; // data length $data_length = strlen($data); // convert string to binary string $bitstring = ''; for ($i = 0; $i < $data_length; ++$i) { $bitstring .= sprintf('%08b', ord($data{$i})); } // get the number of bits $data_length = strlen($bitstring); // initialize code length in bits $bitlen = 9; // initialize dictionary index $dix = 258; // initialize the dictionary (with the first 256 entries). $dictionary = array(); for ($i = 0; $i < 256; ++$i) { $dictionary[$i] = chr($i); } // previous val $prev_index = 0; // while we encounter EOD marker (257), read code_length bits while (($data_length > 0) AND (($index = bindec(substr($bitstring, 0, $bitlen))) != 257)) { // remove read bits from string $bitstring = substr($bitstring, $bitlen); // update number of bits $data_length -= $bitlen; if ($index == 256) { // clear-table marker // reset code length in bits $bitlen = 9; // reset dictionary index $dix = 258; $prev_index = 256; // reset the dictionary (with the first 256 entries). $dictionary = array(); for ($i = 0; $i < 256; ++$i) { $dictionary[$i] = chr($i); } } elseif ($prev_index == 256) { // first entry $decoded .= $dictionary[$index]; $prev_index = $index; } else { // check if index exist in the dictionary if ($index < $dix) { // index exist on dictionary $decoded .= $dictionary[$index]; $dic_val = $dictionary[$prev_index].$dictionary[$index]{0}; // store current index $prev_index = $index; } else { // index do not exist on dictionary $dic_val = $dictionary[$prev_index].$dictionary[$prev_index]{0}; $decoded .= $dic_val; } // update dictionary $dictionary[$dix] = $dic_val; ++$dix; // change bit length by case if ($dix == 2047) { $bitlen = 12; } elseif ($dix == 1023) { $bitlen = 11; } elseif ($dix == 511) { $bitlen = 10; } } } return $decoded; } /** * FlateDecode * Decompresses data encoded using the zlib/deflate compression method, reproducing the original text or binary data. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterFlateDecode($data) { // intialize string to return $decoded = gzuncompress($data); if ($decoded === false) { self::Error('decodeFlate: invalid code'); } return $decoded; } /** * RunLengthDecode * Decompresses data encoded using a byte-oriented run-length encoding algorithm. * @param $data (string) Data to decode. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterRunLengthDecode($data) { // intialize string to return $decoded = ''; // data length $data_length = strlen($data); $i = 0; while($i < $data_length) { // get current byte value $byte = ord($data{$i}); if ($byte == 128) { // a length value of 128 denote EOD break; } elseif ($byte < 128) { // if the length byte is in the range 0 to 127 // the following length + 1 (1 to 128) bytes shall be copied literally during decompression $decoded .= substr($data, ($i + 1), ($byte + 1)); // move to next block $i += ($byte + 2); } else { // if length is in the range 129 to 255, // the following single byte shall be copied 257 - length (2 to 128) times during decompression $decoded .= str_repeat($data{($i + 1)}, (257 - $byte)); // move to next block $i += 2; } } return $decoded; } /** * CCITTFaxDecode (NOT IMPLEMETED) * Decompresses data encoded using the CCITT facsimile standard, reproducing the original data (typically monochrome image data at 1 bit per pixel). * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterCCITTFaxDecode($data) { return $data; } /** * JBIG2Decode (NOT IMPLEMETED) * Decompresses data encoded using the JBIG2 standard, reproducing the original monochrome (1 bit per pixel) image data (or an approximation of that data). * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterJBIG2Decode($data) { return $data; } /** * DCTDecode (NOT IMPLEMETED) * Decompresses data encoded using a DCT (discrete cosine transform) technique based on the JPEG standard, reproducing image sample data that approximates the original data. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterDCTDecode($data) { return $data; } /** * JPXDecode (NOT IMPLEMETED) * Decompresses data encoded using the wavelet-based JPEG2000 standard, reproducing the original image data. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterJPXDecode($data) { return $data; } /** * Crypt (NOT IMPLEMETED) * Decrypts data encrypted by a security handler, reproducing the data as it was before encryption. * @param $data (string) Data to decode. * @return Decoded data string. * @since 1.0.000 (2011-05-23) * @public static */ public static function decodeFilterCrypt($data) { return $data; } // --- END FILTERS SECTION ------------------------------------------------- /** * This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. * @param $msg (string) The error message * @since 1.0.000 (2011-05-23) * @public static */ public static function Error($msg) { // exit program and print error die('TCPDF_FILTERS ERROR: '.$msg); } } // END OF TCPDF_FILTERS CLASS //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/tcpdf_font_data.php000066400000000000000000011441201237252063700223470ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : Unicode data and encoding maps for TCPDF. // //============================================================+ /** * @file * Unicode data and encoding maps for TCPDF. * @author Nicola Asuni * @package com.tecnick.tcpdf */ /** * @class TCPDF_FONT_DATA * Unicode data and encoding maps for TCPDF. * @package com.tecnick.tcpdf * @version 1.0.001 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_FONT_DATA { /** * Unicode code for Left-to-Right Mark. * @public */ public static $uni_LRM = 8206; /** * Unicode code for Right-to-Left Mark. * @public */ public static $uni_RLM = 8207; /** * Unicode code for Left-to-Right Embedding. * @public */ public static $uni_LRE = 8234; /** * Unicode code for Right-to-Left Embedding. * @public */ public static $uni_RLE = 8235; /** * Unicode code for Pop Directional Format. * @public */ public static $uni_PDF = 8236; /** * Unicode code for Left-to-Right Override. * @public */ public static $uni_LRO = 8237; /** * Unicode code for Right-to-Left Override. * @public */ public static $uni_RLO = 8238; /** * Pattern to test RTL (Righ-To-Left) strings using regular expressions. * @public */ public static $uni_RE_PATTERN_RTL = "/( \xD6\xBE # R | \xD7[\x80\x83\x86\x90-\xAA\xB0-\xB4] # R | \xDF[\x80-\xAA\xB4\xB5\xBA] # R | \xE2\x80\x8F # R | \xEF\xAC[\x9D\x9F\xA0-\xA8\xAA-\xB6\xB8-\xBC\xBE] # R | \xEF\xAD[\x80\x81\x83\x84\x86-\x8F] # R | \xF0\x90\xA0[\x80-\x85\x88\x8A-\xB5\xB7\xB8\xBC\xBF] # R | \xF0\x90\xA4[\x80-\x99] # R | \xF0\x90\xA8[\x80\x90-\x93\x95-\x97\x99-\xB3] # R | \xF0\x90\xA9[\x80-\x87\x90-\x98] # R | \xE2\x80[\xAB\xAE] # RLE & RLO )/x"; /** * Pattern to test Arabic strings using regular expressions. Source: http://www.w3.org/International/questions/qa-forms-utf-8 * @public */ public static $uni_RE_PATTERN_ARABIC = "/( \xD8[\x80-\x83\x8B\x8D\x9B\x9E\x9F\xA1-\xBA] # AL | \xD9[\x80-\x8A\xAD-\xAF\xB1-\xBF] # AL | \xDA[\x80-\xBF] # AL | \xDB[\x80-\x95\x9D\xA5\xA6\xAE\xAF\xBA-\xBF] # AL | \xDC[\x80-\x8D\x90\x92-\xAF] # AL | \xDD[\x8D-\xAD] # AL | \xDE[\x80-\xA5\xB1] # AL | \xEF\xAD[\x90-\xBF] # AL | \xEF\xAE[\x80-\xB1] # AL | \xEF\xAF[\x93-\xBF] # AL | \xEF[\xB0-\xB3][\x80-\xBF] # AL | \xEF\xB4[\x80-\xBD] # AL | \xEF\xB5[\x90-\xBF] # AL | \xEF\xB6[\x80-\x8F\x92-\xBF] # AL | \xEF\xB7[\x80-\x87\xB0-\xBC] # AL | \xEF\xB9[\xB0-\xB4\xB6-\xBF] # AL | \xEF\xBA[\x80-\xBF] # AL | \xEF\xBB[\x80-\xBC] # AL | \xD9[\xA0-\xA9\xAB\xAC] # AN )/x"; /** * Array of Unicode types. * @public */ public static $uni_type = array( 0=>'BN', 1=>'BN', 2=>'BN', 3=>'BN', 4=>'BN', 5=>'BN', 6=>'BN', 7=>'BN', 8=>'BN', 9=>'S', 10=>'B', 11=>'S', 12=>'WS', 13=>'B', 14=>'BN', 15=>'BN', 16=>'BN', 17=>'BN', 18=>'BN', 19=>'BN', 20=>'BN', 21=>'BN', 22=>'BN', 23=>'BN', 24=>'BN', 25=>'BN', 26=>'BN', 27=>'BN', 28=>'B', 29=>'B', 30=>'B', 31=>'S', 32=>'WS', 33=>'ON', 34=>'ON', 35=>'ET', 36=>'ET', 37=>'ET', 38=>'ON', 39=>'ON', 40=>'ON', 41=>'ON', 42=>'ON', 43=>'ES', 44=>'CS', 45=>'ES', 46=>'CS', 47=>'CS', 48=>'EN', 49=>'EN', 50=>'EN', 51=>'EN', 52=>'EN', 53=>'EN', 54=>'EN', 55=>'EN', 56=>'EN', 57=>'EN', 58=>'CS', 59=>'ON', 60=>'ON', 61=>'ON', 62=>'ON', 63=>'ON', 64=>'ON', 65=>'L', 66=>'L', 67=>'L', 68=>'L', 69=>'L', 70=>'L', 71=>'L', 72=>'L', 73=>'L', 74=>'L', 75=>'L', 76=>'L', 77=>'L', 78=>'L', 79=>'L', 80=>'L', 81=>'L', 82=>'L', 83=>'L', 84=>'L', 85=>'L', 86=>'L', 87=>'L', 88=>'L', 89=>'L', 90=>'L', 91=>'ON', 92=>'ON', 93=>'ON', 94=>'ON', 95=>'ON', 96=>'ON', 97=>'L', 98=>'L', 99=>'L', 100=>'L', 101=>'L', 102=>'L', 103=>'L', 104=>'L', 105=>'L', 106=>'L', 107=>'L', 108=>'L', 109=>'L', 110=>'L', 111=>'L', 112=>'L', 113=>'L', 114=>'L', 115=>'L', 116=>'L', 117=>'L', 118=>'L', 119=>'L', 120=>'L', 121=>'L', 122=>'L', 123=>'ON', 124=>'ON', 125=>'ON', 126=>'ON', 127=>'BN', 128=>'BN', 129=>'BN', 130=>'BN', 131=>'BN', 132=>'BN', 133=>'B', 134=>'BN', 135=>'BN', 136=>'BN', 137=>'BN', 138=>'BN', 139=>'BN', 140=>'BN', 141=>'BN', 142=>'BN', 143=>'BN', 144=>'BN', 145=>'BN', 146=>'BN', 147=>'BN', 148=>'BN', 149=>'BN', 150=>'BN', 151=>'BN', 152=>'BN', 153=>'BN', 154=>'BN', 155=>'BN', 156=>'BN', 157=>'BN', 158=>'BN', 159=>'BN', 160=>'CS', 161=>'ON', 162=>'ET', 163=>'ET', 164=>'ET', 165=>'ET', 166=>'ON', 167=>'ON', 168=>'ON', 169=>'ON', 170=>'L', 171=>'ON', 172=>'ON', 173=>'BN', 174=>'ON', 175=>'ON', 176=>'ET', 177=>'ET', 178=>'EN', 179=>'EN', 180=>'ON', 181=>'L', 182=>'ON', 183=>'ON', 184=>'ON', 185=>'EN', 186=>'L', 187=>'ON', 188=>'ON', 189=>'ON', 190=>'ON', 191=>'ON', 192=>'L', 193=>'L', 194=>'L', 195=>'L', 196=>'L', 197=>'L', 198=>'L', 199=>'L', 200=>'L', 201=>'L', 202=>'L', 203=>'L', 204=>'L', 205=>'L', 206=>'L', 207=>'L', 208=>'L', 209=>'L', 210=>'L', 211=>'L', 212=>'L', 213=>'L', 214=>'L', 215=>'ON', 216=>'L', 217=>'L', 218=>'L', 219=>'L', 220=>'L', 221=>'L', 222=>'L', 223=>'L', 224=>'L', 225=>'L', 226=>'L', 227=>'L', 228=>'L', 229=>'L', 230=>'L', 231=>'L', 232=>'L', 233=>'L', 234=>'L', 235=>'L', 236=>'L', 237=>'L', 238=>'L', 239=>'L', 240=>'L', 241=>'L', 242=>'L', 243=>'L', 244=>'L', 245=>'L', 246=>'L', 247=>'ON', 248=>'L', 249=>'L', 250=>'L', 251=>'L', 252=>'L', 253=>'L', 254=>'L', 255=>'L', 256=>'L', 257=>'L', 258=>'L', 259=>'L', 260=>'L', 261=>'L', 262=>'L', 263=>'L', 264=>'L', 265=>'L', 266=>'L', 267=>'L', 268=>'L', 269=>'L', 270=>'L', 271=>'L', 272=>'L', 273=>'L', 274=>'L', 275=>'L', 276=>'L', 277=>'L', 278=>'L', 279=>'L', 280=>'L', 281=>'L', 282=>'L', 283=>'L', 284=>'L', 285=>'L', 286=>'L', 287=>'L', 288=>'L', 289=>'L', 290=>'L', 291=>'L', 292=>'L', 293=>'L', 294=>'L', 295=>'L', 296=>'L', 297=>'L', 298=>'L', 299=>'L', 300=>'L', 301=>'L', 302=>'L', 303=>'L', 304=>'L', 305=>'L', 306=>'L', 307=>'L', 308=>'L', 309=>'L', 310=>'L', 311=>'L', 312=>'L', 313=>'L', 314=>'L', 315=>'L', 316=>'L', 317=>'L', 318=>'L', 319=>'L', 320=>'L', 321=>'L', 322=>'L', 323=>'L', 324=>'L', 325=>'L', 326=>'L', 327=>'L', 328=>'L', 329=>'L', 330=>'L', 331=>'L', 332=>'L', 333=>'L', 334=>'L', 335=>'L', 336=>'L', 337=>'L', 338=>'L', 339=>'L', 340=>'L', 341=>'L', 342=>'L', 343=>'L', 344=>'L', 345=>'L', 346=>'L', 347=>'L', 348=>'L', 349=>'L', 350=>'L', 351=>'L', 352=>'L', 353=>'L', 354=>'L', 355=>'L', 356=>'L', 357=>'L', 358=>'L', 359=>'L', 360=>'L', 361=>'L', 362=>'L', 363=>'L', 364=>'L', 365=>'L', 366=>'L', 367=>'L', 368=>'L', 369=>'L', 370=>'L', 371=>'L', 372=>'L', 373=>'L', 374=>'L', 375=>'L', 376=>'L', 377=>'L', 378=>'L', 379=>'L', 380=>'L', 381=>'L', 382=>'L', 383=>'L', 384=>'L', 385=>'L', 386=>'L', 387=>'L', 388=>'L', 389=>'L', 390=>'L', 391=>'L', 392=>'L', 393=>'L', 394=>'L', 395=>'L', 396=>'L', 397=>'L', 398=>'L', 399=>'L', 400=>'L', 401=>'L', 402=>'L', 403=>'L', 404=>'L', 405=>'L', 406=>'L', 407=>'L', 408=>'L', 409=>'L', 410=>'L', 411=>'L', 412=>'L', 413=>'L', 414=>'L', 415=>'L', 416=>'L', 417=>'L', 418=>'L', 419=>'L', 420=>'L', 421=>'L', 422=>'L', 423=>'L', 424=>'L', 425=>'L', 426=>'L', 427=>'L', 428=>'L', 429=>'L', 430=>'L', 431=>'L', 432=>'L', 433=>'L', 434=>'L', 435=>'L', 436=>'L', 437=>'L', 438=>'L', 439=>'L', 440=>'L', 441=>'L', 442=>'L', 443=>'L', 444=>'L', 445=>'L', 446=>'L', 447=>'L', 448=>'L', 449=>'L', 450=>'L', 451=>'L', 452=>'L', 453=>'L', 454=>'L', 455=>'L', 456=>'L', 457=>'L', 458=>'L', 459=>'L', 460=>'L', 461=>'L', 462=>'L', 463=>'L', 464=>'L', 465=>'L', 466=>'L', 467=>'L', 468=>'L', 469=>'L', 470=>'L', 471=>'L', 472=>'L', 473=>'L', 474=>'L', 475=>'L', 476=>'L', 477=>'L', 478=>'L', 479=>'L', 480=>'L', 481=>'L', 482=>'L', 483=>'L', 484=>'L', 485=>'L', 486=>'L', 487=>'L', 488=>'L', 489=>'L', 490=>'L', 491=>'L', 492=>'L', 493=>'L', 494=>'L', 495=>'L', 496=>'L', 497=>'L', 498=>'L', 499=>'L', 500=>'L', 501=>'L', 502=>'L', 503=>'L', 504=>'L', 505=>'L', 506=>'L', 507=>'L', 508=>'L', 509=>'L', 510=>'L', 511=>'L', 512=>'L', 513=>'L', 514=>'L', 515=>'L', 516=>'L', 517=>'L', 518=>'L', 519=>'L', 520=>'L', 521=>'L', 522=>'L', 523=>'L', 524=>'L', 525=>'L', 526=>'L', 527=>'L', 528=>'L', 529=>'L', 530=>'L', 531=>'L', 532=>'L', 533=>'L', 534=>'L', 535=>'L', 536=>'L', 537=>'L', 538=>'L', 539=>'L', 540=>'L', 541=>'L', 542=>'L', 543=>'L', 544=>'L', 545=>'L', 546=>'L', 547=>'L', 548=>'L', 549=>'L', 550=>'L', 551=>'L', 552=>'L', 553=>'L', 554=>'L', 555=>'L', 556=>'L', 557=>'L', 558=>'L', 559=>'L', 560=>'L', 561=>'L', 562=>'L', 563=>'L', 564=>'L', 565=>'L', 566=>'L', 567=>'L', 568=>'L', 569=>'L', 570=>'L', 571=>'L', 572=>'L', 573=>'L', 574=>'L', 575=>'L', 576=>'L', 577=>'L', 578=>'L', 579=>'L', 580=>'L', 581=>'L', 582=>'L', 583=>'L', 584=>'L', 585=>'L', 586=>'L', 587=>'L', 588=>'L', 589=>'L', 590=>'L', 591=>'L', 592=>'L', 593=>'L', 594=>'L', 595=>'L', 596=>'L', 597=>'L', 598=>'L', 599=>'L', 600=>'L', 601=>'L', 602=>'L', 603=>'L', 604=>'L', 605=>'L', 606=>'L', 607=>'L', 608=>'L', 609=>'L', 610=>'L', 611=>'L', 612=>'L', 613=>'L', 614=>'L', 615=>'L', 616=>'L', 617=>'L', 618=>'L', 619=>'L', 620=>'L', 621=>'L', 622=>'L', 623=>'L', 624=>'L', 625=>'L', 626=>'L', 627=>'L', 628=>'L', 629=>'L', 630=>'L', 631=>'L', 632=>'L', 633=>'L', 634=>'L', 635=>'L', 636=>'L', 637=>'L', 638=>'L', 639=>'L', 640=>'L', 641=>'L', 642=>'L', 643=>'L', 644=>'L', 645=>'L', 646=>'L', 647=>'L', 648=>'L', 649=>'L', 650=>'L', 651=>'L', 652=>'L', 653=>'L', 654=>'L', 655=>'L', 656=>'L', 657=>'L', 658=>'L', 659=>'L', 660=>'L', 661=>'L', 662=>'L', 663=>'L', 664=>'L', 665=>'L', 666=>'L', 667=>'L', 668=>'L', 669=>'L', 670=>'L', 671=>'L', 672=>'L', 673=>'L', 674=>'L', 675=>'L', 676=>'L', 677=>'L', 678=>'L', 679=>'L', 680=>'L', 681=>'L', 682=>'L', 683=>'L', 684=>'L', 685=>'L', 686=>'L', 687=>'L', 688=>'L', 689=>'L', 690=>'L', 691=>'L', 692=>'L', 693=>'L', 694=>'L', 695=>'L', 696=>'L', 697=>'ON', 698=>'ON', 699=>'L', 700=>'L', 701=>'L', 702=>'L', 703=>'L', 704=>'L', 705=>'L', 706=>'ON', 707=>'ON', 708=>'ON', 709=>'ON', 710=>'ON', 711=>'ON', 712=>'ON', 713=>'ON', 714=>'ON', 715=>'ON', 716=>'ON', 717=>'ON', 718=>'ON', 719=>'ON', 720=>'L', 721=>'L', 722=>'ON', 723=>'ON', 724=>'ON', 725=>'ON', 726=>'ON', 727=>'ON', 728=>'ON', 729=>'ON', 730=>'ON', 731=>'ON', 732=>'ON', 733=>'ON', 734=>'ON', 735=>'ON', 736=>'L', 737=>'L', 738=>'L', 739=>'L', 740=>'L', 741=>'ON', 742=>'ON', 743=>'ON', 744=>'ON', 745=>'ON', 746=>'ON', 747=>'ON', 748=>'ON', 749=>'ON', 750=>'L', 751=>'ON', 752=>'ON', 753=>'ON', 754=>'ON', 755=>'ON', 756=>'ON', 757=>'ON', 758=>'ON', 759=>'ON', 760=>'ON', 761=>'ON', 762=>'ON', 763=>'ON', 764=>'ON', 765=>'ON', 766=>'ON', 767=>'ON', 768=>'NSM', 769=>'NSM', 770=>'NSM', 771=>'NSM', 772=>'NSM', 773=>'NSM', 774=>'NSM', 775=>'NSM', 776=>'NSM', 777=>'NSM', 778=>'NSM', 779=>'NSM', 780=>'NSM', 781=>'NSM', 782=>'NSM', 783=>'NSM', 784=>'NSM', 785=>'NSM', 786=>'NSM', 787=>'NSM', 788=>'NSM', 789=>'NSM', 790=>'NSM', 791=>'NSM', 792=>'NSM', 793=>'NSM', 794=>'NSM', 795=>'NSM', 796=>'NSM', 797=>'NSM', 798=>'NSM', 799=>'NSM', 800=>'NSM', 801=>'NSM', 802=>'NSM', 803=>'NSM', 804=>'NSM', 805=>'NSM', 806=>'NSM', 807=>'NSM', 808=>'NSM', 809=>'NSM', 810=>'NSM', 811=>'NSM', 812=>'NSM', 813=>'NSM', 814=>'NSM', 815=>'NSM', 816=>'NSM', 817=>'NSM', 818=>'NSM', 819=>'NSM', 820=>'NSM', 821=>'NSM', 822=>'NSM', 823=>'NSM', 824=>'NSM', 825=>'NSM', 826=>'NSM', 827=>'NSM', 828=>'NSM', 829=>'NSM', 830=>'NSM', 831=>'NSM', 832=>'NSM', 833=>'NSM', 834=>'NSM', 835=>'NSM', 836=>'NSM', 837=>'NSM', 838=>'NSM', 839=>'NSM', 840=>'NSM', 841=>'NSM', 842=>'NSM', 843=>'NSM', 844=>'NSM', 845=>'NSM', 846=>'NSM', 847=>'NSM', 848=>'NSM', 849=>'NSM', 850=>'NSM', 851=>'NSM', 852=>'NSM', 853=>'NSM', 854=>'NSM', 855=>'NSM', 856=>'NSM', 857=>'NSM', 858=>'NSM', 859=>'NSM', 860=>'NSM', 861=>'NSM', 862=>'NSM', 863=>'NSM', 864=>'NSM', 865=>'NSM', 866=>'NSM', 867=>'NSM', 868=>'NSM', 869=>'NSM', 870=>'NSM', 871=>'NSM', 872=>'NSM', 873=>'NSM', 874=>'NSM', 875=>'NSM', 876=>'NSM', 877=>'NSM', 878=>'NSM', 879=>'NSM', 884=>'ON', 885=>'ON', 890=>'L', 891=>'L', 892=>'L', 893=>'L', 894=>'ON', 900=>'ON', 901=>'ON', 902=>'L', 903=>'ON', 904=>'L', 905=>'L', 906=>'L', 908=>'L', 910=>'L', 911=>'L', 912=>'L', 913=>'L', 914=>'L', 915=>'L', 916=>'L', 917=>'L', 918=>'L', 919=>'L', 920=>'L', 921=>'L', 922=>'L', 923=>'L', 924=>'L', 925=>'L', 926=>'L', 927=>'L', 928=>'L', 929=>'L', 931=>'L', 932=>'L', 933=>'L', 934=>'L', 935=>'L', 936=>'L', 937=>'L', 938=>'L', 939=>'L', 940=>'L', 941=>'L', 942=>'L', 943=>'L', 944=>'L', 945=>'L', 946=>'L', 947=>'L', 948=>'L', 949=>'L', 950=>'L', 951=>'L', 952=>'L', 953=>'L', 954=>'L', 955=>'L', 956=>'L', 957=>'L', 958=>'L', 959=>'L', 960=>'L', 961=>'L', 962=>'L', 963=>'L', 964=>'L', 965=>'L', 966=>'L', 967=>'L', 968=>'L', 969=>'L', 970=>'L', 971=>'L', 972=>'L', 973=>'L', 974=>'L', 976=>'L', 977=>'L', 978=>'L', 979=>'L', 980=>'L', 981=>'L', 982=>'L', 983=>'L', 984=>'L', 985=>'L', 986=>'L', 987=>'L', 988=>'L', 989=>'L', 990=>'L', 991=>'L', 992=>'L', 993=>'L', 994=>'L', 995=>'L', 996=>'L', 997=>'L', 998=>'L', 999=>'L', 1000=>'L', 1001=>'L', 1002=>'L', 1003=>'L', 1004=>'L', 1005=>'L', 1006=>'L', 1007=>'L', 1008=>'L', 1009=>'L', 1010=>'L', 1011=>'L', 1012=>'L', 1013=>'L', 1014=>'ON', 1015=>'L', 1016=>'L', 1017=>'L', 1018=>'L', 1019=>'L', 1020=>'L', 1021=>'L', 1022=>'L', 1023=>'L', 1024=>'L', 1025=>'L', 1026=>'L', 1027=>'L', 1028=>'L', 1029=>'L', 1030=>'L', 1031=>'L', 1032=>'L', 1033=>'L', 1034=>'L', 1035=>'L', 1036=>'L', 1037=>'L', 1038=>'L', 1039=>'L', 1040=>'L', 1041=>'L', 1042=>'L', 1043=>'L', 1044=>'L', 1045=>'L', 1046=>'L', 1047=>'L', 1048=>'L', 1049=>'L', 1050=>'L', 1051=>'L', 1052=>'L', 1053=>'L', 1054=>'L', 1055=>'L', 1056=>'L', 1057=>'L', 1058=>'L', 1059=>'L', 1060=>'L', 1061=>'L', 1062=>'L', 1063=>'L', 1064=>'L', 1065=>'L', 1066=>'L', 1067=>'L', 1068=>'L', 1069=>'L', 1070=>'L', 1071=>'L', 1072=>'L', 1073=>'L', 1074=>'L', 1075=>'L', 1076=>'L', 1077=>'L', 1078=>'L', 1079=>'L', 1080=>'L', 1081=>'L', 1082=>'L', 1083=>'L', 1084=>'L', 1085=>'L', 1086=>'L', 1087=>'L', 1088=>'L', 1089=>'L', 1090=>'L', 1091=>'L', 1092=>'L', 1093=>'L', 1094=>'L', 1095=>'L', 1096=>'L', 1097=>'L', 1098=>'L', 1099=>'L', 1100=>'L', 1101=>'L', 1102=>'L', 1103=>'L', 1104=>'L', 1105=>'L', 1106=>'L', 1107=>'L', 1108=>'L', 1109=>'L', 1110=>'L', 1111=>'L', 1112=>'L', 1113=>'L', 1114=>'L', 1115=>'L', 1116=>'L', 1117=>'L', 1118=>'L', 1119=>'L', 1120=>'L', 1121=>'L', 1122=>'L', 1123=>'L', 1124=>'L', 1125=>'L', 1126=>'L', 1127=>'L', 1128=>'L', 1129=>'L', 1130=>'L', 1131=>'L', 1132=>'L', 1133=>'L', 1134=>'L', 1135=>'L', 1136=>'L', 1137=>'L', 1138=>'L', 1139=>'L', 1140=>'L', 1141=>'L', 1142=>'L', 1143=>'L', 1144=>'L', 1145=>'L', 1146=>'L', 1147=>'L', 1148=>'L', 1149=>'L', 1150=>'L', 1151=>'L', 1152=>'L', 1153=>'L', 1154=>'L', 1155=>'NSM', 1156=>'NSM', 1157=>'NSM', 1158=>'NSM', 1160=>'NSM', 1161=>'NSM', 1162=>'L', 1163=>'L', 1164=>'L', 1165=>'L', 1166=>'L', 1167=>'L', 1168=>'L', 1169=>'L', 1170=>'L', 1171=>'L', 1172=>'L', 1173=>'L', 1174=>'L', 1175=>'L', 1176=>'L', 1177=>'L', 1178=>'L', 1179=>'L', 1180=>'L', 1181=>'L', 1182=>'L', 1183=>'L', 1184=>'L', 1185=>'L', 1186=>'L', 1187=>'L', 1188=>'L', 1189=>'L', 1190=>'L', 1191=>'L', 1192=>'L', 1193=>'L', 1194=>'L', 1195=>'L', 1196=>'L', 1197=>'L', 1198=>'L', 1199=>'L', 1200=>'L', 1201=>'L', 1202=>'L', 1203=>'L', 1204=>'L', 1205=>'L', 1206=>'L', 1207=>'L', 1208=>'L', 1209=>'L', 1210=>'L', 1211=>'L', 1212=>'L', 1213=>'L', 1214=>'L', 1215=>'L', 1216=>'L', 1217=>'L', 1218=>'L', 1219=>'L', 1220=>'L', 1221=>'L', 1222=>'L', 1223=>'L', 1224=>'L', 1225=>'L', 1226=>'L', 1227=>'L', 1228=>'L', 1229=>'L', 1230=>'L', 1231=>'L', 1232=>'L', 1233=>'L', 1234=>'L', 1235=>'L', 1236=>'L', 1237=>'L', 1238=>'L', 1239=>'L', 1240=>'L', 1241=>'L', 1242=>'L', 1243=>'L', 1244=>'L', 1245=>'L', 1246=>'L', 1247=>'L', 1248=>'L', 1249=>'L', 1250=>'L', 1251=>'L', 1252=>'L', 1253=>'L', 1254=>'L', 1255=>'L', 1256=>'L', 1257=>'L', 1258=>'L', 1259=>'L', 1260=>'L', 1261=>'L', 1262=>'L', 1263=>'L', 1264=>'L', 1265=>'L', 1266=>'L', 1267=>'L', 1268=>'L', 1269=>'L', 1270=>'L', 1271=>'L', 1272=>'L', 1273=>'L', 1274=>'L', 1275=>'L', 1276=>'L', 1277=>'L', 1278=>'L', 1279=>'L', 1280=>'L', 1281=>'L', 1282=>'L', 1283=>'L', 1284=>'L', 1285=>'L', 1286=>'L', 1287=>'L', 1288=>'L', 1289=>'L', 1290=>'L', 1291=>'L', 1292=>'L', 1293=>'L', 1294=>'L', 1295=>'L', 1296=>'L', 1297=>'L', 1298=>'L', 1299=>'L', 1329=>'L', 1330=>'L', 1331=>'L', 1332=>'L', 1333=>'L', 1334=>'L', 1335=>'L', 1336=>'L', 1337=>'L', 1338=>'L', 1339=>'L', 1340=>'L', 1341=>'L', 1342=>'L', 1343=>'L', 1344=>'L', 1345=>'L', 1346=>'L', 1347=>'L', 1348=>'L', 1349=>'L', 1350=>'L', 1351=>'L', 1352=>'L', 1353=>'L', 1354=>'L', 1355=>'L', 1356=>'L', 1357=>'L', 1358=>'L', 1359=>'L', 1360=>'L', 1361=>'L', 1362=>'L', 1363=>'L', 1364=>'L', 1365=>'L', 1366=>'L', 1369=>'L', 1370=>'L', 1371=>'L', 1372=>'L', 1373=>'L', 1374=>'L', 1375=>'L', 1377=>'L', 1378=>'L', 1379=>'L', 1380=>'L', 1381=>'L', 1382=>'L', 1383=>'L', 1384=>'L', 1385=>'L', 1386=>'L', 1387=>'L', 1388=>'L', 1389=>'L', 1390=>'L', 1391=>'L', 1392=>'L', 1393=>'L', 1394=>'L', 1395=>'L', 1396=>'L', 1397=>'L', 1398=>'L', 1399=>'L', 1400=>'L', 1401=>'L', 1402=>'L', 1403=>'L', 1404=>'L', 1405=>'L', 1406=>'L', 1407=>'L', 1408=>'L', 1409=>'L', 1410=>'L', 1411=>'L', 1412=>'L', 1413=>'L', 1414=>'L', 1415=>'L', 1417=>'L', 1418=>'ON', 1425=>'NSM', 1426=>'NSM', 1427=>'NSM', 1428=>'NSM', 1429=>'NSM', 1430=>'NSM', 1431=>'NSM', 1432=>'NSM', 1433=>'NSM', 1434=>'NSM', 1435=>'NSM', 1436=>'NSM', 1437=>'NSM', 1438=>'NSM', 1439=>'NSM', 1440=>'NSM', 1441=>'NSM', 1442=>'NSM', 1443=>'NSM', 1444=>'NSM', 1445=>'NSM', 1446=>'NSM', 1447=>'NSM', 1448=>'NSM', 1449=>'NSM', 1450=>'NSM', 1451=>'NSM', 1452=>'NSM', 1453=>'NSM', 1454=>'NSM', 1455=>'NSM', 1456=>'NSM', 1457=>'NSM', 1458=>'NSM', 1459=>'NSM', 1460=>'NSM', 1461=>'NSM', 1462=>'NSM', 1463=>'NSM', 1464=>'NSM', 1465=>'NSM', 1466=>'NSM', 1467=>'NSM', 1468=>'NSM', 1469=>'NSM', 1470=>'R', 1471=>'NSM', 1472=>'R', 1473=>'NSM', 1474=>'NSM', 1475=>'R', 1476=>'NSM', 1477=>'NSM', 1478=>'R', 1479=>'NSM', 1488=>'R', 1489=>'R', 1490=>'R', 1491=>'R', 1492=>'R', 1493=>'R', 1494=>'R', 1495=>'R', 1496=>'R', 1497=>'R', 1498=>'R', 1499=>'R', 1500=>'R', 1501=>'R', 1502=>'R', 1503=>'R', 1504=>'R', 1505=>'R', 1506=>'R', 1507=>'R', 1508=>'R', 1509=>'R', 1510=>'R', 1511=>'R', 1512=>'R', 1513=>'R', 1514=>'R', 1520=>'R', 1521=>'R', 1522=>'R', 1523=>'R', 1524=>'R', 1536=>'AL', 1537=>'AL', 1538=>'AL', 1539=>'AL', 1547=>'AL', 1548=>'CS', 1549=>'AL', 1550=>'ON', 1551=>'ON', 1552=>'NSM', 1553=>'NSM', 1554=>'NSM', 1555=>'NSM', 1556=>'NSM', 1557=>'NSM', 1563=>'AL', 1566=>'AL', 1567=>'AL', 1569=>'AL', 1570=>'AL', 1571=>'AL', 1572=>'AL', 1573=>'AL', 1574=>'AL', 1575=>'AL', 1576=>'AL', 1577=>'AL', 1578=>'AL', 1579=>'AL', 1580=>'AL', 1581=>'AL', 1582=>'AL', 1583=>'AL', 1584=>'AL', 1585=>'AL', 1586=>'AL', 1587=>'AL', 1588=>'AL', 1589=>'AL', 1590=>'AL', 1591=>'AL', 1592=>'AL', 1593=>'AL', 1594=>'AL', 1600=>'AL', 1601=>'AL', 1602=>'AL', 1603=>'AL', 1604=>'AL', 1605=>'AL', 1606=>'AL', 1607=>'AL', 1608=>'AL', 1609=>'AL', 1610=>'AL', 1611=>'NSM', 1612=>'NSM', 1613=>'NSM', 1614=>'NSM', 1615=>'NSM', 1616=>'NSM', 1617=>'NSM', 1618=>'NSM', 1619=>'NSM', 1620=>'NSM', 1621=>'NSM', 1622=>'NSM', 1623=>'NSM', 1624=>'NSM', 1625=>'NSM', 1626=>'NSM', 1627=>'NSM', 1628=>'NSM', 1629=>'NSM', 1630=>'NSM', 1632=>'AN', 1633=>'AN', 1634=>'AN', 1635=>'AN', 1636=>'AN', 1637=>'AN', 1638=>'AN', 1639=>'AN', 1640=>'AN', 1641=>'AN', 1642=>'ET', 1643=>'AN', 1644=>'AN', 1645=>'AL', 1646=>'AL', 1647=>'AL', 1648=>'NSM', 1649=>'AL', 1650=>'AL', 1651=>'AL', 1652=>'AL', 1653=>'AL', 1654=>'AL', 1655=>'AL', 1656=>'AL', 1657=>'AL', 1658=>'AL', 1659=>'AL', 1660=>'AL', 1661=>'AL', 1662=>'AL', 1663=>'AL', 1664=>'AL', 1665=>'AL', 1666=>'AL', 1667=>'AL', 1668=>'AL', 1669=>'AL', 1670=>'AL', 1671=>'AL', 1672=>'AL', 1673=>'AL', 1674=>'AL', 1675=>'AL', 1676=>'AL', 1677=>'AL', 1678=>'AL', 1679=>'AL', 1680=>'AL', 1681=>'AL', 1682=>'AL', 1683=>'AL', 1684=>'AL', 1685=>'AL', 1686=>'AL', 1687=>'AL', 1688=>'AL', 1689=>'AL', 1690=>'AL', 1691=>'AL', 1692=>'AL', 1693=>'AL', 1694=>'AL', 1695=>'AL', 1696=>'AL', 1697=>'AL', 1698=>'AL', 1699=>'AL', 1700=>'AL', 1701=>'AL', 1702=>'AL', 1703=>'AL', 1704=>'AL', 1705=>'AL', 1706=>'AL', 1707=>'AL', 1708=>'AL', 1709=>'AL', 1710=>'AL', 1711=>'AL', 1712=>'AL', 1713=>'AL', 1714=>'AL', 1715=>'AL', 1716=>'AL', 1717=>'AL', 1718=>'AL', 1719=>'AL', 1720=>'AL', 1721=>'AL', 1722=>'AL', 1723=>'AL', 1724=>'AL', 1725=>'AL', 1726=>'AL', 1727=>'AL', 1728=>'AL', 1729=>'AL', 1730=>'AL', 1731=>'AL', 1732=>'AL', 1733=>'AL', 1734=>'AL', 1735=>'AL', 1736=>'AL', 1737=>'AL', 1738=>'AL', 1739=>'AL', 1740=>'AL', 1741=>'AL', 1742=>'AL', 1743=>'AL', 1744=>'AL', 1745=>'AL', 1746=>'AL', 1747=>'AL', 1748=>'AL', 1749=>'AL', 1750=>'NSM', 1751=>'NSM', 1752=>'NSM', 1753=>'NSM', 1754=>'NSM', 1755=>'NSM', 1756=>'NSM', 1757=>'AL', 1758=>'NSM', 1759=>'NSM', 1760=>'NSM', 1761=>'NSM', 1762=>'NSM', 1763=>'NSM', 1764=>'NSM', 1765=>'AL', 1766=>'AL', 1767=>'NSM', 1768=>'NSM', 1769=>'ON', 1770=>'NSM', 1771=>'NSM', 1772=>'NSM', 1773=>'NSM', 1774=>'AL', 1775=>'AL', 1776=>'EN', 1777=>'EN', 1778=>'EN', 1779=>'EN', 1780=>'EN', 1781=>'EN', 1782=>'EN', 1783=>'EN', 1784=>'EN', 1785=>'EN', 1786=>'AL', 1787=>'AL', 1788=>'AL', 1789=>'AL', 1790=>'AL', 1791=>'AL', 1792=>'AL', 1793=>'AL', 1794=>'AL', 1795=>'AL', 1796=>'AL', 1797=>'AL', 1798=>'AL', 1799=>'AL', 1800=>'AL', 1801=>'AL', 1802=>'AL', 1803=>'AL', 1804=>'AL', 1805=>'AL', 1807=>'BN', 1808=>'AL', 1809=>'NSM', 1810=>'AL', 1811=>'AL', 1812=>'AL', 1813=>'AL', 1814=>'AL', 1815=>'AL', 1816=>'AL', 1817=>'AL', 1818=>'AL', 1819=>'AL', 1820=>'AL', 1821=>'AL', 1822=>'AL', 1823=>'AL', 1824=>'AL', 1825=>'AL', 1826=>'AL', 1827=>'AL', 1828=>'AL', 1829=>'AL', 1830=>'AL', 1831=>'AL', 1832=>'AL', 1833=>'AL', 1834=>'AL', 1835=>'AL', 1836=>'AL', 1837=>'AL', 1838=>'AL', 1839=>'AL', 1840=>'NSM', 1841=>'NSM', 1842=>'NSM', 1843=>'NSM', 1844=>'NSM', 1845=>'NSM', 1846=>'NSM', 1847=>'NSM', 1848=>'NSM', 1849=>'NSM', 1850=>'NSM', 1851=>'NSM', 1852=>'NSM', 1853=>'NSM', 1854=>'NSM', 1855=>'NSM', 1856=>'NSM', 1857=>'NSM', 1858=>'NSM', 1859=>'NSM', 1860=>'NSM', 1861=>'NSM', 1862=>'NSM', 1863=>'NSM', 1864=>'NSM', 1865=>'NSM', 1866=>'NSM', 1869=>'AL', 1870=>'AL', 1871=>'AL', 1872=>'AL', 1873=>'AL', 1874=>'AL', 1875=>'AL', 1876=>'AL', 1877=>'AL', 1878=>'AL', 1879=>'AL', 1880=>'AL', 1881=>'AL', 1882=>'AL', 1883=>'AL', 1884=>'AL', 1885=>'AL', 1886=>'AL', 1887=>'AL', 1888=>'AL', 1889=>'AL', 1890=>'AL', 1891=>'AL', 1892=>'AL', 1893=>'AL', 1894=>'AL', 1895=>'AL', 1896=>'AL', 1897=>'AL', 1898=>'AL', 1899=>'AL', 1900=>'AL', 1901=>'AL', 1920=>'AL', 1921=>'AL', 1922=>'AL', 1923=>'AL', 1924=>'AL', 1925=>'AL', 1926=>'AL', 1927=>'AL', 1928=>'AL', 1929=>'AL', 1930=>'AL', 1931=>'AL', 1932=>'AL', 1933=>'AL', 1934=>'AL', 1935=>'AL', 1936=>'AL', 1937=>'AL', 1938=>'AL', 1939=>'AL', 1940=>'AL', 1941=>'AL', 1942=>'AL', 1943=>'AL', 1944=>'AL', 1945=>'AL', 1946=>'AL', 1947=>'AL', 1948=>'AL', 1949=>'AL', 1950=>'AL', 1951=>'AL', 1952=>'AL', 1953=>'AL', 1954=>'AL', 1955=>'AL', 1956=>'AL', 1957=>'AL', 1958=>'NSM', 1959=>'NSM', 1960=>'NSM', 1961=>'NSM', 1962=>'NSM', 1963=>'NSM', 1964=>'NSM', 1965=>'NSM', 1966=>'NSM', 1967=>'NSM', 1968=>'NSM', 1969=>'AL', 1984=>'R', 1985=>'R', 1986=>'R', 1987=>'R', 1988=>'R', 1989=>'R', 1990=>'R', 1991=>'R', 1992=>'R', 1993=>'R', 1994=>'R', 1995=>'R', 1996=>'R', 1997=>'R', 1998=>'R', 1999=>'R', 2000=>'R', 2001=>'R', 2002=>'R', 2003=>'R', 2004=>'R', 2005=>'R', 2006=>'R', 2007=>'R', 2008=>'R', 2009=>'R', 2010=>'R', 2011=>'R', 2012=>'R', 2013=>'R', 2014=>'R', 2015=>'R', 2016=>'R', 2017=>'R', 2018=>'R', 2019=>'R', 2020=>'R', 2021=>'R', 2022=>'R', 2023=>'R', 2024=>'R', 2025=>'R', 2026=>'R', 2027=>'NSM', 2028=>'NSM', 2029=>'NSM', 2030=>'NSM', 2031=>'NSM', 2032=>'NSM', 2033=>'NSM', 2034=>'NSM', 2035=>'NSM', 2036=>'R', 2037=>'R', 2038=>'ON', 2039=>'ON', 2040=>'ON', 2041=>'ON', 2042=>'R', 2305=>'NSM', 2306=>'NSM', 2307=>'L', 2308=>'L', 2309=>'L', 2310=>'L', 2311=>'L', 2312=>'L', 2313=>'L', 2314=>'L', 2315=>'L', 2316=>'L', 2317=>'L', 2318=>'L', 2319=>'L', 2320=>'L', 2321=>'L', 2322=>'L', 2323=>'L', 2324=>'L', 2325=>'L', 2326=>'L', 2327=>'L', 2328=>'L', 2329=>'L', 2330=>'L', 2331=>'L', 2332=>'L', 2333=>'L', 2334=>'L', 2335=>'L', 2336=>'L', 2337=>'L', 2338=>'L', 2339=>'L', 2340=>'L', 2341=>'L', 2342=>'L', 2343=>'L', 2344=>'L', 2345=>'L', 2346=>'L', 2347=>'L', 2348=>'L', 2349=>'L', 2350=>'L', 2351=>'L', 2352=>'L', 2353=>'L', 2354=>'L', 2355=>'L', 2356=>'L', 2357=>'L', 2358=>'L', 2359=>'L', 2360=>'L', 2361=>'L', 2364=>'NSM', 2365=>'L', 2366=>'L', 2367=>'L', 2368=>'L', 2369=>'NSM', 2370=>'NSM', 2371=>'NSM', 2372=>'NSM', 2373=>'NSM', 2374=>'NSM', 2375=>'NSM', 2376=>'NSM', 2377=>'L', 2378=>'L', 2379=>'L', 2380=>'L', 2381=>'NSM', 2384=>'L', 2385=>'NSM', 2386=>'NSM', 2387=>'NSM', 2388=>'NSM', 2392=>'L', 2393=>'L', 2394=>'L', 2395=>'L', 2396=>'L', 2397=>'L', 2398=>'L', 2399=>'L', 2400=>'L', 2401=>'L', 2402=>'NSM', 2403=>'NSM', 2404=>'L', 2405=>'L', 2406=>'L', 2407=>'L', 2408=>'L', 2409=>'L', 2410=>'L', 2411=>'L', 2412=>'L', 2413=>'L', 2414=>'L', 2415=>'L', 2416=>'L', 2427=>'L', 2428=>'L', 2429=>'L', 2430=>'L', 2431=>'L', 2433=>'NSM', 2434=>'L', 2435=>'L', 2437=>'L', 2438=>'L', 2439=>'L', 2440=>'L', 2441=>'L', 2442=>'L', 2443=>'L', 2444=>'L', 2447=>'L', 2448=>'L', 2451=>'L', 2452=>'L', 2453=>'L', 2454=>'L', 2455=>'L', 2456=>'L', 2457=>'L', 2458=>'L', 2459=>'L', 2460=>'L', 2461=>'L', 2462=>'L', 2463=>'L', 2464=>'L', 2465=>'L', 2466=>'L', 2467=>'L', 2468=>'L', 2469=>'L', 2470=>'L', 2471=>'L', 2472=>'L', 2474=>'L', 2475=>'L', 2476=>'L', 2477=>'L', 2478=>'L', 2479=>'L', 2480=>'L', 2482=>'L', 2486=>'L', 2487=>'L', 2488=>'L', 2489=>'L', 2492=>'NSM', 2493=>'L', 2494=>'L', 2495=>'L', 2496=>'L', 2497=>'NSM', 2498=>'NSM', 2499=>'NSM', 2500=>'NSM', 2503=>'L', 2504=>'L', 2507=>'L', 2508=>'L', 2509=>'NSM', 2510=>'L', 2519=>'L', 2524=>'L', 2525=>'L', 2527=>'L', 2528=>'L', 2529=>'L', 2530=>'NSM', 2531=>'NSM', 2534=>'L', 2535=>'L', 2536=>'L', 2537=>'L', 2538=>'L', 2539=>'L', 2540=>'L', 2541=>'L', 2542=>'L', 2543=>'L', 2544=>'L', 2545=>'L', 2546=>'ET', 2547=>'ET', 2548=>'L', 2549=>'L', 2550=>'L', 2551=>'L', 2552=>'L', 2553=>'L', 2554=>'L', 2561=>'NSM', 2562=>'NSM', 2563=>'L', 2565=>'L', 2566=>'L', 2567=>'L', 2568=>'L', 2569=>'L', 2570=>'L', 2575=>'L', 2576=>'L', 2579=>'L', 2580=>'L', 2581=>'L', 2582=>'L', 2583=>'L', 2584=>'L', 2585=>'L', 2586=>'L', 2587=>'L', 2588=>'L', 2589=>'L', 2590=>'L', 2591=>'L', 2592=>'L', 2593=>'L', 2594=>'L', 2595=>'L', 2596=>'L', 2597=>'L', 2598=>'L', 2599=>'L', 2600=>'L', 2602=>'L', 2603=>'L', 2604=>'L', 2605=>'L', 2606=>'L', 2607=>'L', 2608=>'L', 2610=>'L', 2611=>'L', 2613=>'L', 2614=>'L', 2616=>'L', 2617=>'L', 2620=>'NSM', 2622=>'L', 2623=>'L', 2624=>'L', 2625=>'NSM', 2626=>'NSM', 2631=>'NSM', 2632=>'NSM', 2635=>'NSM', 2636=>'NSM', 2637=>'NSM', 2649=>'L', 2650=>'L', 2651=>'L', 2652=>'L', 2654=>'L', 2662=>'L', 2663=>'L', 2664=>'L', 2665=>'L', 2666=>'L', 2667=>'L', 2668=>'L', 2669=>'L', 2670=>'L', 2671=>'L', 2672=>'NSM', 2673=>'NSM', 2674=>'L', 2675=>'L', 2676=>'L', 2689=>'NSM', 2690=>'NSM', 2691=>'L', 2693=>'L', 2694=>'L', 2695=>'L', 2696=>'L', 2697=>'L', 2698=>'L', 2699=>'L', 2700=>'L', 2701=>'L', 2703=>'L', 2704=>'L', 2705=>'L', 2707=>'L', 2708=>'L', 2709=>'L', 2710=>'L', 2711=>'L', 2712=>'L', 2713=>'L', 2714=>'L', 2715=>'L', 2716=>'L', 2717=>'L', 2718=>'L', 2719=>'L', 2720=>'L', 2721=>'L', 2722=>'L', 2723=>'L', 2724=>'L', 2725=>'L', 2726=>'L', 2727=>'L', 2728=>'L', 2730=>'L', 2731=>'L', 2732=>'L', 2733=>'L', 2734=>'L', 2735=>'L', 2736=>'L', 2738=>'L', 2739=>'L', 2741=>'L', 2742=>'L', 2743=>'L', 2744=>'L', 2745=>'L', 2748=>'NSM', 2749=>'L', 2750=>'L', 2751=>'L', 2752=>'L', 2753=>'NSM', 2754=>'NSM', 2755=>'NSM', 2756=>'NSM', 2757=>'NSM', 2759=>'NSM', 2760=>'NSM', 2761=>'L', 2763=>'L', 2764=>'L', 2765=>'NSM', 2768=>'L', 2784=>'L', 2785=>'L', 2786=>'NSM', 2787=>'NSM', 2790=>'L', 2791=>'L', 2792=>'L', 2793=>'L', 2794=>'L', 2795=>'L', 2796=>'L', 2797=>'L', 2798=>'L', 2799=>'L', 2801=>'ET', 2817=>'NSM', 2818=>'L', 2819=>'L', 2821=>'L', 2822=>'L', 2823=>'L', 2824=>'L', 2825=>'L', 2826=>'L', 2827=>'L', 2828=>'L', 2831=>'L', 2832=>'L', 2835=>'L', 2836=>'L', 2837=>'L', 2838=>'L', 2839=>'L', 2840=>'L', 2841=>'L', 2842=>'L', 2843=>'L', 2844=>'L', 2845=>'L', 2846=>'L', 2847=>'L', 2848=>'L', 2849=>'L', 2850=>'L', 2851=>'L', 2852=>'L', 2853=>'L', 2854=>'L', 2855=>'L', 2856=>'L', 2858=>'L', 2859=>'L', 2860=>'L', 2861=>'L', 2862=>'L', 2863=>'L', 2864=>'L', 2866=>'L', 2867=>'L', 2869=>'L', 2870=>'L', 2871=>'L', 2872=>'L', 2873=>'L', 2876=>'NSM', 2877=>'L', 2878=>'L', 2879=>'NSM', 2880=>'L', 2881=>'NSM', 2882=>'NSM', 2883=>'NSM', 2887=>'L', 2888=>'L', 2891=>'L', 2892=>'L', 2893=>'NSM', 2902=>'NSM', 2903=>'L', 2908=>'L', 2909=>'L', 2911=>'L', 2912=>'L', 2913=>'L', 2918=>'L', 2919=>'L', 2920=>'L', 2921=>'L', 2922=>'L', 2923=>'L', 2924=>'L', 2925=>'L', 2926=>'L', 2927=>'L', 2928=>'L', 2929=>'L', 2946=>'NSM', 2947=>'L', 2949=>'L', 2950=>'L', 2951=>'L', 2952=>'L', 2953=>'L', 2954=>'L', 2958=>'L', 2959=>'L', 2960=>'L', 2962=>'L', 2963=>'L', 2964=>'L', 2965=>'L', 2969=>'L', 2970=>'L', 2972=>'L', 2974=>'L', 2975=>'L', 2979=>'L', 2980=>'L', 2984=>'L', 2985=>'L', 2986=>'L', 2990=>'L', 2991=>'L', 2992=>'L', 2993=>'L', 2994=>'L', 2995=>'L', 2996=>'L', 2997=>'L', 2998=>'L', 2999=>'L', 3000=>'L', 3001=>'L', 3006=>'L', 3007=>'L', 3008=>'NSM', 3009=>'L', 3010=>'L', 3014=>'L', 3015=>'L', 3016=>'L', 3018=>'L', 3019=>'L', 3020=>'L', 3021=>'NSM', 3031=>'L', 3046=>'L', 3047=>'L', 3048=>'L', 3049=>'L', 3050=>'L', 3051=>'L', 3052=>'L', 3053=>'L', 3054=>'L', 3055=>'L', 3056=>'L', 3057=>'L', 3058=>'L', 3059=>'ON', 3060=>'ON', 3061=>'ON', 3062=>'ON', 3063=>'ON', 3064=>'ON', 3065=>'ET', 3066=>'ON', 3073=>'L', 3074=>'L', 3075=>'L', 3077=>'L', 3078=>'L', 3079=>'L', 3080=>'L', 3081=>'L', 3082=>'L', 3083=>'L', 3084=>'L', 3086=>'L', 3087=>'L', 3088=>'L', 3090=>'L', 3091=>'L', 3092=>'L', 3093=>'L', 3094=>'L', 3095=>'L', 3096=>'L', 3097=>'L', 3098=>'L', 3099=>'L', 3100=>'L', 3101=>'L', 3102=>'L', 3103=>'L', 3104=>'L', 3105=>'L', 3106=>'L', 3107=>'L', 3108=>'L', 3109=>'L', 3110=>'L', 3111=>'L', 3112=>'L', 3114=>'L', 3115=>'L', 3116=>'L', 3117=>'L', 3118=>'L', 3119=>'L', 3120=>'L', 3121=>'L', 3122=>'L', 3123=>'L', 3125=>'L', 3126=>'L', 3127=>'L', 3128=>'L', 3129=>'L', 3134=>'NSM', 3135=>'NSM', 3136=>'NSM', 3137=>'L', 3138=>'L', 3139=>'L', 3140=>'L', 3142=>'NSM', 3143=>'NSM', 3144=>'NSM', 3146=>'NSM', 3147=>'NSM', 3148=>'NSM', 3149=>'NSM', 3157=>'NSM', 3158=>'NSM', 3168=>'L', 3169=>'L', 3174=>'L', 3175=>'L', 3176=>'L', 3177=>'L', 3178=>'L', 3179=>'L', 3180=>'L', 3181=>'L', 3182=>'L', 3183=>'L', 3202=>'L', 3203=>'L', 3205=>'L', 3206=>'L', 3207=>'L', 3208=>'L', 3209=>'L', 3210=>'L', 3211=>'L', 3212=>'L', 3214=>'L', 3215=>'L', 3216=>'L', 3218=>'L', 3219=>'L', 3220=>'L', 3221=>'L', 3222=>'L', 3223=>'L', 3224=>'L', 3225=>'L', 3226=>'L', 3227=>'L', 3228=>'L', 3229=>'L', 3230=>'L', 3231=>'L', 3232=>'L', 3233=>'L', 3234=>'L', 3235=>'L', 3236=>'L', 3237=>'L', 3238=>'L', 3239=>'L', 3240=>'L', 3242=>'L', 3243=>'L', 3244=>'L', 3245=>'L', 3246=>'L', 3247=>'L', 3248=>'L', 3249=>'L', 3250=>'L', 3251=>'L', 3253=>'L', 3254=>'L', 3255=>'L', 3256=>'L', 3257=>'L', 3260=>'NSM', 3261=>'L', 3262=>'L', 3263=>'L', 3264=>'L', 3265=>'L', 3266=>'L', 3267=>'L', 3268=>'L', 3270=>'L', 3271=>'L', 3272=>'L', 3274=>'L', 3275=>'L', 3276=>'NSM', 3277=>'NSM', 3285=>'L', 3286=>'L', 3294=>'L', 3296=>'L', 3297=>'L', 3298=>'NSM', 3299=>'NSM', 3302=>'L', 3303=>'L', 3304=>'L', 3305=>'L', 3306=>'L', 3307=>'L', 3308=>'L', 3309=>'L', 3310=>'L', 3311=>'L', 3313=>'ON', 3314=>'ON', 3330=>'L', 3331=>'L', 3333=>'L', 3334=>'L', 3335=>'L', 3336=>'L', 3337=>'L', 3338=>'L', 3339=>'L', 3340=>'L', 3342=>'L', 3343=>'L', 3344=>'L', 3346=>'L', 3347=>'L', 3348=>'L', 3349=>'L', 3350=>'L', 3351=>'L', 3352=>'L', 3353=>'L', 3354=>'L', 3355=>'L', 3356=>'L', 3357=>'L', 3358=>'L', 3359=>'L', 3360=>'L', 3361=>'L', 3362=>'L', 3363=>'L', 3364=>'L', 3365=>'L', 3366=>'L', 3367=>'L', 3368=>'L', 3370=>'L', 3371=>'L', 3372=>'L', 3373=>'L', 3374=>'L', 3375=>'L', 3376=>'L', 3377=>'L', 3378=>'L', 3379=>'L', 3380=>'L', 3381=>'L', 3382=>'L', 3383=>'L', 3384=>'L', 3385=>'L', 3390=>'L', 3391=>'L', 3392=>'L', 3393=>'NSM', 3394=>'NSM', 3395=>'NSM', 3398=>'L', 3399=>'L', 3400=>'L', 3402=>'L', 3403=>'L', 3404=>'L', 3405=>'NSM', 3415=>'L', 3424=>'L', 3425=>'L', 3430=>'L', 3431=>'L', 3432=>'L', 3433=>'L', 3434=>'L', 3435=>'L', 3436=>'L', 3437=>'L', 3438=>'L', 3439=>'L', 3458=>'L', 3459=>'L', 3461=>'L', 3462=>'L', 3463=>'L', 3464=>'L', 3465=>'L', 3466=>'L', 3467=>'L', 3468=>'L', 3469=>'L', 3470=>'L', 3471=>'L', 3472=>'L', 3473=>'L', 3474=>'L', 3475=>'L', 3476=>'L', 3477=>'L', 3478=>'L', 3482=>'L', 3483=>'L', 3484=>'L', 3485=>'L', 3486=>'L', 3487=>'L', 3488=>'L', 3489=>'L', 3490=>'L', 3491=>'L', 3492=>'L', 3493=>'L', 3494=>'L', 3495=>'L', 3496=>'L', 3497=>'L', 3498=>'L', 3499=>'L', 3500=>'L', 3501=>'L', 3502=>'L', 3503=>'L', 3504=>'L', 3505=>'L', 3507=>'L', 3508=>'L', 3509=>'L', 3510=>'L', 3511=>'L', 3512=>'L', 3513=>'L', 3514=>'L', 3515=>'L', 3517=>'L', 3520=>'L', 3521=>'L', 3522=>'L', 3523=>'L', 3524=>'L', 3525=>'L', 3526=>'L', 3530=>'NSM', 3535=>'L', 3536=>'L', 3537=>'L', 3538=>'NSM', 3539=>'NSM', 3540=>'NSM', 3542=>'NSM', 3544=>'L', 3545=>'L', 3546=>'L', 3547=>'L', 3548=>'L', 3549=>'L', 3550=>'L', 3551=>'L', 3570=>'L', 3571=>'L', 3572=>'L', 3585=>'L', 3586=>'L', 3587=>'L', 3588=>'L', 3589=>'L', 3590=>'L', 3591=>'L', 3592=>'L', 3593=>'L', 3594=>'L', 3595=>'L', 3596=>'L', 3597=>'L', 3598=>'L', 3599=>'L', 3600=>'L', 3601=>'L', 3602=>'L', 3603=>'L', 3604=>'L', 3605=>'L', 3606=>'L', 3607=>'L', 3608=>'L', 3609=>'L', 3610=>'L', 3611=>'L', 3612=>'L', 3613=>'L', 3614=>'L', 3615=>'L', 3616=>'L', 3617=>'L', 3618=>'L', 3619=>'L', 3620=>'L', 3621=>'L', 3622=>'L', 3623=>'L', 3624=>'L', 3625=>'L', 3626=>'L', 3627=>'L', 3628=>'L', 3629=>'L', 3630=>'L', 3631=>'L', 3632=>'L', 3633=>'NSM', 3634=>'L', 3635=>'L', 3636=>'NSM', 3637=>'NSM', 3638=>'NSM', 3639=>'NSM', 3640=>'NSM', 3641=>'NSM', 3642=>'NSM', 3647=>'ET', 3648=>'L', 3649=>'L', 3650=>'L', 3651=>'L', 3652=>'L', 3653=>'L', 3654=>'L', 3655=>'NSM', 3656=>'NSM', 3657=>'NSM', 3658=>'NSM', 3659=>'NSM', 3660=>'NSM', 3661=>'NSM', 3662=>'NSM', 3663=>'L', 3664=>'L', 3665=>'L', 3666=>'L', 3667=>'L', 3668=>'L', 3669=>'L', 3670=>'L', 3671=>'L', 3672=>'L', 3673=>'L', 3674=>'L', 3675=>'L', 3713=>'L', 3714=>'L', 3716=>'L', 3719=>'L', 3720=>'L', 3722=>'L', 3725=>'L', 3732=>'L', 3733=>'L', 3734=>'L', 3735=>'L', 3737=>'L', 3738=>'L', 3739=>'L', 3740=>'L', 3741=>'L', 3742=>'L', 3743=>'L', 3745=>'L', 3746=>'L', 3747=>'L', 3749=>'L', 3751=>'L', 3754=>'L', 3755=>'L', 3757=>'L', 3758=>'L', 3759=>'L', 3760=>'L', 3761=>'NSM', 3762=>'L', 3763=>'L', 3764=>'NSM', 3765=>'NSM', 3766=>'NSM', 3767=>'NSM', 3768=>'NSM', 3769=>'NSM', 3771=>'NSM', 3772=>'NSM', 3773=>'L', 3776=>'L', 3777=>'L', 3778=>'L', 3779=>'L', 3780=>'L', 3782=>'L', 3784=>'NSM', 3785=>'NSM', 3786=>'NSM', 3787=>'NSM', 3788=>'NSM', 3789=>'NSM', 3792=>'L', 3793=>'L', 3794=>'L', 3795=>'L', 3796=>'L', 3797=>'L', 3798=>'L', 3799=>'L', 3800=>'L', 3801=>'L', 3804=>'L', 3805=>'L', 3840=>'L', 3841=>'L', 3842=>'L', 3843=>'L', 3844=>'L', 3845=>'L', 3846=>'L', 3847=>'L', 3848=>'L', 3849=>'L', 3850=>'L', 3851=>'L', 3852=>'L', 3853=>'L', 3854=>'L', 3855=>'L', 3856=>'L', 3857=>'L', 3858=>'L', 3859=>'L', 3860=>'L', 3861=>'L', 3862=>'L', 3863=>'L', 3864=>'NSM', 3865=>'NSM', 3866=>'L', 3867=>'L', 3868=>'L', 3869=>'L', 3870=>'L', 3871=>'L', 3872=>'L', 3873=>'L', 3874=>'L', 3875=>'L', 3876=>'L', 3877=>'L', 3878=>'L', 3879=>'L', 3880=>'L', 3881=>'L', 3882=>'L', 3883=>'L', 3884=>'L', 3885=>'L', 3886=>'L', 3887=>'L', 3888=>'L', 3889=>'L', 3890=>'L', 3891=>'L', 3892=>'L', 3893=>'NSM', 3894=>'L', 3895=>'NSM', 3896=>'L', 3897=>'NSM', 3898=>'ON', 3899=>'ON', 3900=>'ON', 3901=>'ON', 3902=>'L', 3903=>'L', 3904=>'L', 3905=>'L', 3906=>'L', 3907=>'L', 3908=>'L', 3909=>'L', 3910=>'L', 3911=>'L', 3913=>'L', 3914=>'L', 3915=>'L', 3916=>'L', 3917=>'L', 3918=>'L', 3919=>'L', 3920=>'L', 3921=>'L', 3922=>'L', 3923=>'L', 3924=>'L', 3925=>'L', 3926=>'L', 3927=>'L', 3928=>'L', 3929=>'L', 3930=>'L', 3931=>'L', 3932=>'L', 3933=>'L', 3934=>'L', 3935=>'L', 3936=>'L', 3937=>'L', 3938=>'L', 3939=>'L', 3940=>'L', 3941=>'L', 3942=>'L', 3943=>'L', 3944=>'L', 3945=>'L', 3946=>'L', 3953=>'NSM', 3954=>'NSM', 3955=>'NSM', 3956=>'NSM', 3957=>'NSM', 3958=>'NSM', 3959=>'NSM', 3960=>'NSM', 3961=>'NSM', 3962=>'NSM', 3963=>'NSM', 3964=>'NSM', 3965=>'NSM', 3966=>'NSM', 3967=>'L', 3968=>'NSM', 3969=>'NSM', 3970=>'NSM', 3971=>'NSM', 3972=>'NSM', 3973=>'L', 3974=>'NSM', 3975=>'NSM', 3976=>'L', 3977=>'L', 3978=>'L', 3979=>'L', 3984=>'NSM', 3985=>'NSM', 3986=>'NSM', 3987=>'NSM', 3988=>'NSM', 3989=>'NSM', 3990=>'NSM', 3991=>'NSM', 3993=>'NSM', 3994=>'NSM', 3995=>'NSM', 3996=>'NSM', 3997=>'NSM', 3998=>'NSM', 3999=>'NSM', 4000=>'NSM', 4001=>'NSM', 4002=>'NSM', 4003=>'NSM', 4004=>'NSM', 4005=>'NSM', 4006=>'NSM', 4007=>'NSM', 4008=>'NSM', 4009=>'NSM', 4010=>'NSM', 4011=>'NSM', 4012=>'NSM', 4013=>'NSM', 4014=>'NSM', 4015=>'NSM', 4016=>'NSM', 4017=>'NSM', 4018=>'NSM', 4019=>'NSM', 4020=>'NSM', 4021=>'NSM', 4022=>'NSM', 4023=>'NSM', 4024=>'NSM', 4025=>'NSM', 4026=>'NSM', 4027=>'NSM', 4028=>'NSM', 4030=>'L', 4031=>'L', 4032=>'L', 4033=>'L', 4034=>'L', 4035=>'L', 4036=>'L', 4037=>'L', 4038=>'NSM', 4039=>'L', 4040=>'L', 4041=>'L', 4042=>'L', 4043=>'L', 4044=>'L', 4047=>'L', 4048=>'L', 4049=>'L', 4096=>'L', 4097=>'L', 4098=>'L', 4099=>'L', 4100=>'L', 4101=>'L', 4102=>'L', 4103=>'L', 4104=>'L', 4105=>'L', 4106=>'L', 4107=>'L', 4108=>'L', 4109=>'L', 4110=>'L', 4111=>'L', 4112=>'L', 4113=>'L', 4114=>'L', 4115=>'L', 4116=>'L', 4117=>'L', 4118=>'L', 4119=>'L', 4120=>'L', 4121=>'L', 4122=>'L', 4123=>'L', 4124=>'L', 4125=>'L', 4126=>'L', 4127=>'L', 4128=>'L', 4129=>'L', 4131=>'L', 4132=>'L', 4133=>'L', 4134=>'L', 4135=>'L', 4137=>'L', 4138=>'L', 4140=>'L', 4141=>'NSM', 4142=>'NSM', 4143=>'NSM', 4144=>'NSM', 4145=>'L', 4146=>'NSM', 4150=>'NSM', 4151=>'NSM', 4152=>'L', 4153=>'NSM', 4160=>'L', 4161=>'L', 4162=>'L', 4163=>'L', 4164=>'L', 4165=>'L', 4166=>'L', 4167=>'L', 4168=>'L', 4169=>'L', 4170=>'L', 4171=>'L', 4172=>'L', 4173=>'L', 4174=>'L', 4175=>'L', 4176=>'L', 4177=>'L', 4178=>'L', 4179=>'L', 4180=>'L', 4181=>'L', 4182=>'L', 4183=>'L', 4184=>'NSM', 4185=>'NSM', 4256=>'L', 4257=>'L', 4258=>'L', 4259=>'L', 4260=>'L', 4261=>'L', 4262=>'L', 4263=>'L', 4264=>'L', 4265=>'L', 4266=>'L', 4267=>'L', 4268=>'L', 4269=>'L', 4270=>'L', 4271=>'L', 4272=>'L', 4273=>'L', 4274=>'L', 4275=>'L', 4276=>'L', 4277=>'L', 4278=>'L', 4279=>'L', 4280=>'L', 4281=>'L', 4282=>'L', 4283=>'L', 4284=>'L', 4285=>'L', 4286=>'L', 4287=>'L', 4288=>'L', 4289=>'L', 4290=>'L', 4291=>'L', 4292=>'L', 4293=>'L', 4304=>'L', 4305=>'L', 4306=>'L', 4307=>'L', 4308=>'L', 4309=>'L', 4310=>'L', 4311=>'L', 4312=>'L', 4313=>'L', 4314=>'L', 4315=>'L', 4316=>'L', 4317=>'L', 4318=>'L', 4319=>'L', 4320=>'L', 4321=>'L', 4322=>'L', 4323=>'L', 4324=>'L', 4325=>'L', 4326=>'L', 4327=>'L', 4328=>'L', 4329=>'L', 4330=>'L', 4331=>'L', 4332=>'L', 4333=>'L', 4334=>'L', 4335=>'L', 4336=>'L', 4337=>'L', 4338=>'L', 4339=>'L', 4340=>'L', 4341=>'L', 4342=>'L', 4343=>'L', 4344=>'L', 4345=>'L', 4346=>'L', 4347=>'L', 4348=>'L', 4352=>'L', 4353=>'L', 4354=>'L', 4355=>'L', 4356=>'L', 4357=>'L', 4358=>'L', 4359=>'L', 4360=>'L', 4361=>'L', 4362=>'L', 4363=>'L', 4364=>'L', 4365=>'L', 4366=>'L', 4367=>'L', 4368=>'L', 4369=>'L', 4370=>'L', 4371=>'L', 4372=>'L', 4373=>'L', 4374=>'L', 4375=>'L', 4376=>'L', 4377=>'L', 4378=>'L', 4379=>'L', 4380=>'L', 4381=>'L', 4382=>'L', 4383=>'L', 4384=>'L', 4385=>'L', 4386=>'L', 4387=>'L', 4388=>'L', 4389=>'L', 4390=>'L', 4391=>'L', 4392=>'L', 4393=>'L', 4394=>'L', 4395=>'L', 4396=>'L', 4397=>'L', 4398=>'L', 4399=>'L', 4400=>'L', 4401=>'L', 4402=>'L', 4403=>'L', 4404=>'L', 4405=>'L', 4406=>'L', 4407=>'L', 4408=>'L', 4409=>'L', 4410=>'L', 4411=>'L', 4412=>'L', 4413=>'L', 4414=>'L', 4415=>'L', 4416=>'L', 4417=>'L', 4418=>'L', 4419=>'L', 4420=>'L', 4421=>'L', 4422=>'L', 4423=>'L', 4424=>'L', 4425=>'L', 4426=>'L', 4427=>'L', 4428=>'L', 4429=>'L', 4430=>'L', 4431=>'L', 4432=>'L', 4433=>'L', 4434=>'L', 4435=>'L', 4436=>'L', 4437=>'L', 4438=>'L', 4439=>'L', 4440=>'L', 4441=>'L', 4447=>'L', 4448=>'L', 4449=>'L', 4450=>'L', 4451=>'L', 4452=>'L', 4453=>'L', 4454=>'L', 4455=>'L', 4456=>'L', 4457=>'L', 4458=>'L', 4459=>'L', 4460=>'L', 4461=>'L', 4462=>'L', 4463=>'L', 4464=>'L', 4465=>'L', 4466=>'L', 4467=>'L', 4468=>'L', 4469=>'L', 4470=>'L', 4471=>'L', 4472=>'L', 4473=>'L', 4474=>'L', 4475=>'L', 4476=>'L', 4477=>'L', 4478=>'L', 4479=>'L', 4480=>'L', 4481=>'L', 4482=>'L', 4483=>'L', 4484=>'L', 4485=>'L', 4486=>'L', 4487=>'L', 4488=>'L', 4489=>'L', 4490=>'L', 4491=>'L', 4492=>'L', 4493=>'L', 4494=>'L', 4495=>'L', 4496=>'L', 4497=>'L', 4498=>'L', 4499=>'L', 4500=>'L', 4501=>'L', 4502=>'L', 4503=>'L', 4504=>'L', 4505=>'L', 4506=>'L', 4507=>'L', 4508=>'L', 4509=>'L', 4510=>'L', 4511=>'L', 4512=>'L', 4513=>'L', 4514=>'L', 4520=>'L', 4521=>'L', 4522=>'L', 4523=>'L', 4524=>'L', 4525=>'L', 4526=>'L', 4527=>'L', 4528=>'L', 4529=>'L', 4530=>'L', 4531=>'L', 4532=>'L', 4533=>'L', 4534=>'L', 4535=>'L', 4536=>'L', 4537=>'L', 4538=>'L', 4539=>'L', 4540=>'L', 4541=>'L', 4542=>'L', 4543=>'L', 4544=>'L', 4545=>'L', 4546=>'L', 4547=>'L', 4548=>'L', 4549=>'L', 4550=>'L', 4551=>'L', 4552=>'L', 4553=>'L', 4554=>'L', 4555=>'L', 4556=>'L', 4557=>'L', 4558=>'L', 4559=>'L', 4560=>'L', 4561=>'L', 4562=>'L', 4563=>'L', 4564=>'L', 4565=>'L', 4566=>'L', 4567=>'L', 4568=>'L', 4569=>'L', 4570=>'L', 4571=>'L', 4572=>'L', 4573=>'L', 4574=>'L', 4575=>'L', 4576=>'L', 4577=>'L', 4578=>'L', 4579=>'L', 4580=>'L', 4581=>'L', 4582=>'L', 4583=>'L', 4584=>'L', 4585=>'L', 4586=>'L', 4587=>'L', 4588=>'L', 4589=>'L', 4590=>'L', 4591=>'L', 4592=>'L', 4593=>'L', 4594=>'L', 4595=>'L', 4596=>'L', 4597=>'L', 4598=>'L', 4599=>'L', 4600=>'L', 4601=>'L', 4608=>'L', 4609=>'L', 4610=>'L', 4611=>'L', 4612=>'L', 4613=>'L', 4614=>'L', 4615=>'L', 4616=>'L', 4617=>'L', 4618=>'L', 4619=>'L', 4620=>'L', 4621=>'L', 4622=>'L', 4623=>'L', 4624=>'L', 4625=>'L', 4626=>'L', 4627=>'L', 4628=>'L', 4629=>'L', 4630=>'L', 4631=>'L', 4632=>'L', 4633=>'L', 4634=>'L', 4635=>'L', 4636=>'L', 4637=>'L', 4638=>'L', 4639=>'L', 4640=>'L', 4641=>'L', 4642=>'L', 4643=>'L', 4644=>'L', 4645=>'L', 4646=>'L', 4647=>'L', 4648=>'L', 4649=>'L', 4650=>'L', 4651=>'L', 4652=>'L', 4653=>'L', 4654=>'L', 4655=>'L', 4656=>'L', 4657=>'L', 4658=>'L', 4659=>'L', 4660=>'L', 4661=>'L', 4662=>'L', 4663=>'L', 4664=>'L', 4665=>'L', 4666=>'L', 4667=>'L', 4668=>'L', 4669=>'L', 4670=>'L', 4671=>'L', 4672=>'L', 4673=>'L', 4674=>'L', 4675=>'L', 4676=>'L', 4677=>'L', 4678=>'L', 4679=>'L', 4680=>'L', 4682=>'L', 4683=>'L', 4684=>'L', 4685=>'L', 4688=>'L', 4689=>'L', 4690=>'L', 4691=>'L', 4692=>'L', 4693=>'L', 4694=>'L', 4696=>'L', 4698=>'L', 4699=>'L', 4700=>'L', 4701=>'L', 4704=>'L', 4705=>'L', 4706=>'L', 4707=>'L', 4708=>'L', 4709=>'L', 4710=>'L', 4711=>'L', 4712=>'L', 4713=>'L', 4714=>'L', 4715=>'L', 4716=>'L', 4717=>'L', 4718=>'L', 4719=>'L', 4720=>'L', 4721=>'L', 4722=>'L', 4723=>'L', 4724=>'L', 4725=>'L', 4726=>'L', 4727=>'L', 4728=>'L', 4729=>'L', 4730=>'L', 4731=>'L', 4732=>'L', 4733=>'L', 4734=>'L', 4735=>'L', 4736=>'L', 4737=>'L', 4738=>'L', 4739=>'L', 4740=>'L', 4741=>'L', 4742=>'L', 4743=>'L', 4744=>'L', 4746=>'L', 4747=>'L', 4748=>'L', 4749=>'L', 4752=>'L', 4753=>'L', 4754=>'L', 4755=>'L', 4756=>'L', 4757=>'L', 4758=>'L', 4759=>'L', 4760=>'L', 4761=>'L', 4762=>'L', 4763=>'L', 4764=>'L', 4765=>'L', 4766=>'L', 4767=>'L', 4768=>'L', 4769=>'L', 4770=>'L', 4771=>'L', 4772=>'L', 4773=>'L', 4774=>'L', 4775=>'L', 4776=>'L', 4777=>'L', 4778=>'L', 4779=>'L', 4780=>'L', 4781=>'L', 4782=>'L', 4783=>'L', 4784=>'L', 4786=>'L', 4787=>'L', 4788=>'L', 4789=>'L', 4792=>'L', 4793=>'L', 4794=>'L', 4795=>'L', 4796=>'L', 4797=>'L', 4798=>'L', 4800=>'L', 4802=>'L', 4803=>'L', 4804=>'L', 4805=>'L', 4808=>'L', 4809=>'L', 4810=>'L', 4811=>'L', 4812=>'L', 4813=>'L', 4814=>'L', 4815=>'L', 4816=>'L', 4817=>'L', 4818=>'L', 4819=>'L', 4820=>'L', 4821=>'L', 4822=>'L', 4824=>'L', 4825=>'L', 4826=>'L', 4827=>'L', 4828=>'L', 4829=>'L', 4830=>'L', 4831=>'L', 4832=>'L', 4833=>'L', 4834=>'L', 4835=>'L', 4836=>'L', 4837=>'L', 4838=>'L', 4839=>'L', 4840=>'L', 4841=>'L', 4842=>'L', 4843=>'L', 4844=>'L', 4845=>'L', 4846=>'L', 4847=>'L', 4848=>'L', 4849=>'L', 4850=>'L', 4851=>'L', 4852=>'L', 4853=>'L', 4854=>'L', 4855=>'L', 4856=>'L', 4857=>'L', 4858=>'L', 4859=>'L', 4860=>'L', 4861=>'L', 4862=>'L', 4863=>'L', 4864=>'L', 4865=>'L', 4866=>'L', 4867=>'L', 4868=>'L', 4869=>'L', 4870=>'L', 4871=>'L', 4872=>'L', 4873=>'L', 4874=>'L', 4875=>'L', 4876=>'L', 4877=>'L', 4878=>'L', 4879=>'L', 4880=>'L', 4882=>'L', 4883=>'L', 4884=>'L', 4885=>'L', 4888=>'L', 4889=>'L', 4890=>'L', 4891=>'L', 4892=>'L', 4893=>'L', 4894=>'L', 4895=>'L', 4896=>'L', 4897=>'L', 4898=>'L', 4899=>'L', 4900=>'L', 4901=>'L', 4902=>'L', 4903=>'L', 4904=>'L', 4905=>'L', 4906=>'L', 4907=>'L', 4908=>'L', 4909=>'L', 4910=>'L', 4911=>'L', 4912=>'L', 4913=>'L', 4914=>'L', 4915=>'L', 4916=>'L', 4917=>'L', 4918=>'L', 4919=>'L', 4920=>'L', 4921=>'L', 4922=>'L', 4923=>'L', 4924=>'L', 4925=>'L', 4926=>'L', 4927=>'L', 4928=>'L', 4929=>'L', 4930=>'L', 4931=>'L', 4932=>'L', 4933=>'L', 4934=>'L', 4935=>'L', 4936=>'L', 4937=>'L', 4938=>'L', 4939=>'L', 4940=>'L', 4941=>'L', 4942=>'L', 4943=>'L', 4944=>'L', 4945=>'L', 4946=>'L', 4947=>'L', 4948=>'L', 4949=>'L', 4950=>'L', 4951=>'L', 4952=>'L', 4953=>'L', 4954=>'L', 4959=>'NSM', 4960=>'L', 4961=>'L', 4962=>'L', 4963=>'L', 4964=>'L', 4965=>'L', 4966=>'L', 4967=>'L', 4968=>'L', 4969=>'L', 4970=>'L', 4971=>'L', 4972=>'L', 4973=>'L', 4974=>'L', 4975=>'L', 4976=>'L', 4977=>'L', 4978=>'L', 4979=>'L', 4980=>'L', 4981=>'L', 4982=>'L', 4983=>'L', 4984=>'L', 4985=>'L', 4986=>'L', 4987=>'L', 4988=>'L', 4992=>'L', 4993=>'L', 4994=>'L', 4995=>'L', 4996=>'L', 4997=>'L', 4998=>'L', 4999=>'L', 5000=>'L', 5001=>'L', 5002=>'L', 5003=>'L', 5004=>'L', 5005=>'L', 5006=>'L', 5007=>'L', 5008=>'ON', 5009=>'ON', 5010=>'ON', 5011=>'ON', 5012=>'ON', 5013=>'ON', 5014=>'ON', 5015=>'ON', 5016=>'ON', 5017=>'ON', 5024=>'L', 5025=>'L', 5026=>'L', 5027=>'L', 5028=>'L', 5029=>'L', 5030=>'L', 5031=>'L', 5032=>'L', 5033=>'L', 5034=>'L', 5035=>'L', 5036=>'L', 5037=>'L', 5038=>'L', 5039=>'L', 5040=>'L', 5041=>'L', 5042=>'L', 5043=>'L', 5044=>'L', 5045=>'L', 5046=>'L', 5047=>'L', 5048=>'L', 5049=>'L', 5050=>'L', 5051=>'L', 5052=>'L', 5053=>'L', 5054=>'L', 5055=>'L', 5056=>'L', 5057=>'L', 5058=>'L', 5059=>'L', 5060=>'L', 5061=>'L', 5062=>'L', 5063=>'L', 5064=>'L', 5065=>'L', 5066=>'L', 5067=>'L', 5068=>'L', 5069=>'L', 5070=>'L', 5071=>'L', 5072=>'L', 5073=>'L', 5074=>'L', 5075=>'L', 5076=>'L', 5077=>'L', 5078=>'L', 5079=>'L', 5080=>'L', 5081=>'L', 5082=>'L', 5083=>'L', 5084=>'L', 5085=>'L', 5086=>'L', 5087=>'L', 5088=>'L', 5089=>'L', 5090=>'L', 5091=>'L', 5092=>'L', 5093=>'L', 5094=>'L', 5095=>'L', 5096=>'L', 5097=>'L', 5098=>'L', 5099=>'L', 5100=>'L', 5101=>'L', 5102=>'L', 5103=>'L', 5104=>'L', 5105=>'L', 5106=>'L', 5107=>'L', 5108=>'L', 5121=>'L', 5122=>'L', 5123=>'L', 5124=>'L', 5125=>'L', 5126=>'L', 5127=>'L', 5128=>'L', 5129=>'L', 5130=>'L', 5131=>'L', 5132=>'L', 5133=>'L', 5134=>'L', 5135=>'L', 5136=>'L', 5137=>'L', 5138=>'L', 5139=>'L', 5140=>'L', 5141=>'L', 5142=>'L', 5143=>'L', 5144=>'L', 5145=>'L', 5146=>'L', 5147=>'L', 5148=>'L', 5149=>'L', 5150=>'L', 5151=>'L', 5152=>'L', 5153=>'L', 5154=>'L', 5155=>'L', 5156=>'L', 5157=>'L', 5158=>'L', 5159=>'L', 5160=>'L', 5161=>'L', 5162=>'L', 5163=>'L', 5164=>'L', 5165=>'L', 5166=>'L', 5167=>'L', 5168=>'L', 5169=>'L', 5170=>'L', 5171=>'L', 5172=>'L', 5173=>'L', 5174=>'L', 5175=>'L', 5176=>'L', 5177=>'L', 5178=>'L', 5179=>'L', 5180=>'L', 5181=>'L', 5182=>'L', 5183=>'L', 5184=>'L', 5185=>'L', 5186=>'L', 5187=>'L', 5188=>'L', 5189=>'L', 5190=>'L', 5191=>'L', 5192=>'L', 5193=>'L', 5194=>'L', 5195=>'L', 5196=>'L', 5197=>'L', 5198=>'L', 5199=>'L', 5200=>'L', 5201=>'L', 5202=>'L', 5203=>'L', 5204=>'L', 5205=>'L', 5206=>'L', 5207=>'L', 5208=>'L', 5209=>'L', 5210=>'L', 5211=>'L', 5212=>'L', 5213=>'L', 5214=>'L', 5215=>'L', 5216=>'L', 5217=>'L', 5218=>'L', 5219=>'L', 5220=>'L', 5221=>'L', 5222=>'L', 5223=>'L', 5224=>'L', 5225=>'L', 5226=>'L', 5227=>'L', 5228=>'L', 5229=>'L', 5230=>'L', 5231=>'L', 5232=>'L', 5233=>'L', 5234=>'L', 5235=>'L', 5236=>'L', 5237=>'L', 5238=>'L', 5239=>'L', 5240=>'L', 5241=>'L', 5242=>'L', 5243=>'L', 5244=>'L', 5245=>'L', 5246=>'L', 5247=>'L', 5248=>'L', 5249=>'L', 5250=>'L', 5251=>'L', 5252=>'L', 5253=>'L', 5254=>'L', 5255=>'L', 5256=>'L', 5257=>'L', 5258=>'L', 5259=>'L', 5260=>'L', 5261=>'L', 5262=>'L', 5263=>'L', 5264=>'L', 5265=>'L', 5266=>'L', 5267=>'L', 5268=>'L', 5269=>'L', 5270=>'L', 5271=>'L', 5272=>'L', 5273=>'L', 5274=>'L', 5275=>'L', 5276=>'L', 5277=>'L', 5278=>'L', 5279=>'L', 5280=>'L', 5281=>'L', 5282=>'L', 5283=>'L', 5284=>'L', 5285=>'L', 5286=>'L', 5287=>'L', 5288=>'L', 5289=>'L', 5290=>'L', 5291=>'L', 5292=>'L', 5293=>'L', 5294=>'L', 5295=>'L', 5296=>'L', 5297=>'L', 5298=>'L', 5299=>'L', 5300=>'L', 5301=>'L', 5302=>'L', 5303=>'L', 5304=>'L', 5305=>'L', 5306=>'L', 5307=>'L', 5308=>'L', 5309=>'L', 5310=>'L', 5311=>'L', 5312=>'L', 5313=>'L', 5314=>'L', 5315=>'L', 5316=>'L', 5317=>'L', 5318=>'L', 5319=>'L', 5320=>'L', 5321=>'L', 5322=>'L', 5323=>'L', 5324=>'L', 5325=>'L', 5326=>'L', 5327=>'L', 5328=>'L', 5329=>'L', 5330=>'L', 5331=>'L', 5332=>'L', 5333=>'L', 5334=>'L', 5335=>'L', 5336=>'L', 5337=>'L', 5338=>'L', 5339=>'L', 5340=>'L', 5341=>'L', 5342=>'L', 5343=>'L', 5344=>'L', 5345=>'L', 5346=>'L', 5347=>'L', 5348=>'L', 5349=>'L', 5350=>'L', 5351=>'L', 5352=>'L', 5353=>'L', 5354=>'L', 5355=>'L', 5356=>'L', 5357=>'L', 5358=>'L', 5359=>'L', 5360=>'L', 5361=>'L', 5362=>'L', 5363=>'L', 5364=>'L', 5365=>'L', 5366=>'L', 5367=>'L', 5368=>'L', 5369=>'L', 5370=>'L', 5371=>'L', 5372=>'L', 5373=>'L', 5374=>'L', 5375=>'L', 5376=>'L', 5377=>'L', 5378=>'L', 5379=>'L', 5380=>'L', 5381=>'L', 5382=>'L', 5383=>'L', 5384=>'L', 5385=>'L', 5386=>'L', 5387=>'L', 5388=>'L', 5389=>'L', 5390=>'L', 5391=>'L', 5392=>'L', 5393=>'L', 5394=>'L', 5395=>'L', 5396=>'L', 5397=>'L', 5398=>'L', 5399=>'L', 5400=>'L', 5401=>'L', 5402=>'L', 5403=>'L', 5404=>'L', 5405=>'L', 5406=>'L', 5407=>'L', 5408=>'L', 5409=>'L', 5410=>'L', 5411=>'L', 5412=>'L', 5413=>'L', 5414=>'L', 5415=>'L', 5416=>'L', 5417=>'L', 5418=>'L', 5419=>'L', 5420=>'L', 5421=>'L', 5422=>'L', 5423=>'L', 5424=>'L', 5425=>'L', 5426=>'L', 5427=>'L', 5428=>'L', 5429=>'L', 5430=>'L', 5431=>'L', 5432=>'L', 5433=>'L', 5434=>'L', 5435=>'L', 5436=>'L', 5437=>'L', 5438=>'L', 5439=>'L', 5440=>'L', 5441=>'L', 5442=>'L', 5443=>'L', 5444=>'L', 5445=>'L', 5446=>'L', 5447=>'L', 5448=>'L', 5449=>'L', 5450=>'L', 5451=>'L', 5452=>'L', 5453=>'L', 5454=>'L', 5455=>'L', 5456=>'L', 5457=>'L', 5458=>'L', 5459=>'L', 5460=>'L', 5461=>'L', 5462=>'L', 5463=>'L', 5464=>'L', 5465=>'L', 5466=>'L', 5467=>'L', 5468=>'L', 5469=>'L', 5470=>'L', 5471=>'L', 5472=>'L', 5473=>'L', 5474=>'L', 5475=>'L', 5476=>'L', 5477=>'L', 5478=>'L', 5479=>'L', 5480=>'L', 5481=>'L', 5482=>'L', 5483=>'L', 5484=>'L', 5485=>'L', 5486=>'L', 5487=>'L', 5488=>'L', 5489=>'L', 5490=>'L', 5491=>'L', 5492=>'L', 5493=>'L', 5494=>'L', 5495=>'L', 5496=>'L', 5497=>'L', 5498=>'L', 5499=>'L', 5500=>'L', 5501=>'L', 5502=>'L', 5503=>'L', 5504=>'L', 5505=>'L', 5506=>'L', 5507=>'L', 5508=>'L', 5509=>'L', 5510=>'L', 5511=>'L', 5512=>'L', 5513=>'L', 5514=>'L', 5515=>'L', 5516=>'L', 5517=>'L', 5518=>'L', 5519=>'L', 5520=>'L', 5521=>'L', 5522=>'L', 5523=>'L', 5524=>'L', 5525=>'L', 5526=>'L', 5527=>'L', 5528=>'L', 5529=>'L', 5530=>'L', 5531=>'L', 5532=>'L', 5533=>'L', 5534=>'L', 5535=>'L', 5536=>'L', 5537=>'L', 5538=>'L', 5539=>'L', 5540=>'L', 5541=>'L', 5542=>'L', 5543=>'L', 5544=>'L', 5545=>'L', 5546=>'L', 5547=>'L', 5548=>'L', 5549=>'L', 5550=>'L', 5551=>'L', 5552=>'L', 5553=>'L', 5554=>'L', 5555=>'L', 5556=>'L', 5557=>'L', 5558=>'L', 5559=>'L', 5560=>'L', 5561=>'L', 5562=>'L', 5563=>'L', 5564=>'L', 5565=>'L', 5566=>'L', 5567=>'L', 5568=>'L', 5569=>'L', 5570=>'L', 5571=>'L', 5572=>'L', 5573=>'L', 5574=>'L', 5575=>'L', 5576=>'L', 5577=>'L', 5578=>'L', 5579=>'L', 5580=>'L', 5581=>'L', 5582=>'L', 5583=>'L', 5584=>'L', 5585=>'L', 5586=>'L', 5587=>'L', 5588=>'L', 5589=>'L', 5590=>'L', 5591=>'L', 5592=>'L', 5593=>'L', 5594=>'L', 5595=>'L', 5596=>'L', 5597=>'L', 5598=>'L', 5599=>'L', 5600=>'L', 5601=>'L', 5602=>'L', 5603=>'L', 5604=>'L', 5605=>'L', 5606=>'L', 5607=>'L', 5608=>'L', 5609=>'L', 5610=>'L', 5611=>'L', 5612=>'L', 5613=>'L', 5614=>'L', 5615=>'L', 5616=>'L', 5617=>'L', 5618=>'L', 5619=>'L', 5620=>'L', 5621=>'L', 5622=>'L', 5623=>'L', 5624=>'L', 5625=>'L', 5626=>'L', 5627=>'L', 5628=>'L', 5629=>'L', 5630=>'L', 5631=>'L', 5632=>'L', 5633=>'L', 5634=>'L', 5635=>'L', 5636=>'L', 5637=>'L', 5638=>'L', 5639=>'L', 5640=>'L', 5641=>'L', 5642=>'L', 5643=>'L', 5644=>'L', 5645=>'L', 5646=>'L', 5647=>'L', 5648=>'L', 5649=>'L', 5650=>'L', 5651=>'L', 5652=>'L', 5653=>'L', 5654=>'L', 5655=>'L', 5656=>'L', 5657=>'L', 5658=>'L', 5659=>'L', 5660=>'L', 5661=>'L', 5662=>'L', 5663=>'L', 5664=>'L', 5665=>'L', 5666=>'L', 5667=>'L', 5668=>'L', 5669=>'L', 5670=>'L', 5671=>'L', 5672=>'L', 5673=>'L', 5674=>'L', 5675=>'L', 5676=>'L', 5677=>'L', 5678=>'L', 5679=>'L', 5680=>'L', 5681=>'L', 5682=>'L', 5683=>'L', 5684=>'L', 5685=>'L', 5686=>'L', 5687=>'L', 5688=>'L', 5689=>'L', 5690=>'L', 5691=>'L', 5692=>'L', 5693=>'L', 5694=>'L', 5695=>'L', 5696=>'L', 5697=>'L', 5698=>'L', 5699=>'L', 5700=>'L', 5701=>'L', 5702=>'L', 5703=>'L', 5704=>'L', 5705=>'L', 5706=>'L', 5707=>'L', 5708=>'L', 5709=>'L', 5710=>'L', 5711=>'L', 5712=>'L', 5713=>'L', 5714=>'L', 5715=>'L', 5716=>'L', 5717=>'L', 5718=>'L', 5719=>'L', 5720=>'L', 5721=>'L', 5722=>'L', 5723=>'L', 5724=>'L', 5725=>'L', 5726=>'L', 5727=>'L', 5728=>'L', 5729=>'L', 5730=>'L', 5731=>'L', 5732=>'L', 5733=>'L', 5734=>'L', 5735=>'L', 5736=>'L', 5737=>'L', 5738=>'L', 5739=>'L', 5740=>'L', 5741=>'L', 5742=>'L', 5743=>'L', 5744=>'L', 5745=>'L', 5746=>'L', 5747=>'L', 5748=>'L', 5749=>'L', 5750=>'L', 5760=>'WS', 5761=>'L', 5762=>'L', 5763=>'L', 5764=>'L', 5765=>'L', 5766=>'L', 5767=>'L', 5768=>'L', 5769=>'L', 5770=>'L', 5771=>'L', 5772=>'L', 5773=>'L', 5774=>'L', 5775=>'L', 5776=>'L', 5777=>'L', 5778=>'L', 5779=>'L', 5780=>'L', 5781=>'L', 5782=>'L', 5783=>'L', 5784=>'L', 5785=>'L', 5786=>'L', 5787=>'ON', 5788=>'ON', 5792=>'L', 5793=>'L', 5794=>'L', 5795=>'L', 5796=>'L', 5797=>'L', 5798=>'L', 5799=>'L', 5800=>'L', 5801=>'L', 5802=>'L', 5803=>'L', 5804=>'L', 5805=>'L', 5806=>'L', 5807=>'L', 5808=>'L', 5809=>'L', 5810=>'L', 5811=>'L', 5812=>'L', 5813=>'L', 5814=>'L', 5815=>'L', 5816=>'L', 5817=>'L', 5818=>'L', 5819=>'L', 5820=>'L', 5821=>'L', 5822=>'L', 5823=>'L', 5824=>'L', 5825=>'L', 5826=>'L', 5827=>'L', 5828=>'L', 5829=>'L', 5830=>'L', 5831=>'L', 5832=>'L', 5833=>'L', 5834=>'L', 5835=>'L', 5836=>'L', 5837=>'L', 5838=>'L', 5839=>'L', 5840=>'L', 5841=>'L', 5842=>'L', 5843=>'L', 5844=>'L', 5845=>'L', 5846=>'L', 5847=>'L', 5848=>'L', 5849=>'L', 5850=>'L', 5851=>'L', 5852=>'L', 5853=>'L', 5854=>'L', 5855=>'L', 5856=>'L', 5857=>'L', 5858=>'L', 5859=>'L', 5860=>'L', 5861=>'L', 5862=>'L', 5863=>'L', 5864=>'L', 5865=>'L', 5866=>'L', 5867=>'L', 5868=>'L', 5869=>'L', 5870=>'L', 5871=>'L', 5872=>'L', 5888=>'L', 5889=>'L', 5890=>'L', 5891=>'L', 5892=>'L', 5893=>'L', 5894=>'L', 5895=>'L', 5896=>'L', 5897=>'L', 5898=>'L', 5899=>'L', 5900=>'L', 5902=>'L', 5903=>'L', 5904=>'L', 5905=>'L', 5906=>'NSM', 5907=>'NSM', 5908=>'NSM', 5920=>'L', 5921=>'L', 5922=>'L', 5923=>'L', 5924=>'L', 5925=>'L', 5926=>'L', 5927=>'L', 5928=>'L', 5929=>'L', 5930=>'L', 5931=>'L', 5932=>'L', 5933=>'L', 5934=>'L', 5935=>'L', 5936=>'L', 5937=>'L', 5938=>'NSM', 5939=>'NSM', 5940=>'NSM', 5941=>'L', 5942=>'L', 5952=>'L', 5953=>'L', 5954=>'L', 5955=>'L', 5956=>'L', 5957=>'L', 5958=>'L', 5959=>'L', 5960=>'L', 5961=>'L', 5962=>'L', 5963=>'L', 5964=>'L', 5965=>'L', 5966=>'L', 5967=>'L', 5968=>'L', 5969=>'L', 5970=>'NSM', 5971=>'NSM', 5984=>'L', 5985=>'L', 5986=>'L', 5987=>'L', 5988=>'L', 5989=>'L', 5990=>'L', 5991=>'L', 5992=>'L', 5993=>'L', 5994=>'L', 5995=>'L', 5996=>'L', 5998=>'L', 5999=>'L', 6000=>'L', 6002=>'NSM', 6003=>'NSM', 6016=>'L', 6017=>'L', 6018=>'L', 6019=>'L', 6020=>'L', 6021=>'L', 6022=>'L', 6023=>'L', 6024=>'L', 6025=>'L', 6026=>'L', 6027=>'L', 6028=>'L', 6029=>'L', 6030=>'L', 6031=>'L', 6032=>'L', 6033=>'L', 6034=>'L', 6035=>'L', 6036=>'L', 6037=>'L', 6038=>'L', 6039=>'L', 6040=>'L', 6041=>'L', 6042=>'L', 6043=>'L', 6044=>'L', 6045=>'L', 6046=>'L', 6047=>'L', 6048=>'L', 6049=>'L', 6050=>'L', 6051=>'L', 6052=>'L', 6053=>'L', 6054=>'L', 6055=>'L', 6056=>'L', 6057=>'L', 6058=>'L', 6059=>'L', 6060=>'L', 6061=>'L', 6062=>'L', 6063=>'L', 6064=>'L', 6065=>'L', 6066=>'L', 6067=>'L', 6068=>'L', 6069=>'L', 6070=>'L', 6071=>'NSM', 6072=>'NSM', 6073=>'NSM', 6074=>'NSM', 6075=>'NSM', 6076=>'NSM', 6077=>'NSM', 6078=>'L', 6079=>'L', 6080=>'L', 6081=>'L', 6082=>'L', 6083=>'L', 6084=>'L', 6085=>'L', 6086=>'NSM', 6087=>'L', 6088=>'L', 6089=>'NSM', 6090=>'NSM', 6091=>'NSM', 6092=>'NSM', 6093=>'NSM', 6094=>'NSM', 6095=>'NSM', 6096=>'NSM', 6097=>'NSM', 6098=>'NSM', 6099=>'NSM', 6100=>'L', 6101=>'L', 6102=>'L', 6103=>'L', 6104=>'L', 6105=>'L', 6106=>'L', 6107=>'ET', 6108=>'L', 6109=>'NSM', 6112=>'L', 6113=>'L', 6114=>'L', 6115=>'L', 6116=>'L', 6117=>'L', 6118=>'L', 6119=>'L', 6120=>'L', 6121=>'L', 6128=>'ON', 6129=>'ON', 6130=>'ON', 6131=>'ON', 6132=>'ON', 6133=>'ON', 6134=>'ON', 6135=>'ON', 6136=>'ON', 6137=>'ON', 6144=>'ON', 6145=>'ON', 6146=>'ON', 6147=>'ON', 6148=>'ON', 6149=>'ON', 6150=>'ON', 6151=>'ON', 6152=>'ON', 6153=>'ON', 6154=>'ON', 6155=>'NSM', 6156=>'NSM', 6157=>'NSM', 6158=>'WS', 6160=>'L', 6161=>'L', 6162=>'L', 6163=>'L', 6164=>'L', 6165=>'L', 6166=>'L', 6167=>'L', 6168=>'L', 6169=>'L', 6176=>'L', 6177=>'L', 6178=>'L', 6179=>'L', 6180=>'L', 6181=>'L', 6182=>'L', 6183=>'L', 6184=>'L', 6185=>'L', 6186=>'L', 6187=>'L', 6188=>'L', 6189=>'L', 6190=>'L', 6191=>'L', 6192=>'L', 6193=>'L', 6194=>'L', 6195=>'L', 6196=>'L', 6197=>'L', 6198=>'L', 6199=>'L', 6200=>'L', 6201=>'L', 6202=>'L', 6203=>'L', 6204=>'L', 6205=>'L', 6206=>'L', 6207=>'L', 6208=>'L', 6209=>'L', 6210=>'L', 6211=>'L', 6212=>'L', 6213=>'L', 6214=>'L', 6215=>'L', 6216=>'L', 6217=>'L', 6218=>'L', 6219=>'L', 6220=>'L', 6221=>'L', 6222=>'L', 6223=>'L', 6224=>'L', 6225=>'L', 6226=>'L', 6227=>'L', 6228=>'L', 6229=>'L', 6230=>'L', 6231=>'L', 6232=>'L', 6233=>'L', 6234=>'L', 6235=>'L', 6236=>'L', 6237=>'L', 6238=>'L', 6239=>'L', 6240=>'L', 6241=>'L', 6242=>'L', 6243=>'L', 6244=>'L', 6245=>'L', 6246=>'L', 6247=>'L', 6248=>'L', 6249=>'L', 6250=>'L', 6251=>'L', 6252=>'L', 6253=>'L', 6254=>'L', 6255=>'L', 6256=>'L', 6257=>'L', 6258=>'L', 6259=>'L', 6260=>'L', 6261=>'L', 6262=>'L', 6263=>'L', 6272=>'L', 6273=>'L', 6274=>'L', 6275=>'L', 6276=>'L', 6277=>'L', 6278=>'L', 6279=>'L', 6280=>'L', 6281=>'L', 6282=>'L', 6283=>'L', 6284=>'L', 6285=>'L', 6286=>'L', 6287=>'L', 6288=>'L', 6289=>'L', 6290=>'L', 6291=>'L', 6292=>'L', 6293=>'L', 6294=>'L', 6295=>'L', 6296=>'L', 6297=>'L', 6298=>'L', 6299=>'L', 6300=>'L', 6301=>'L', 6302=>'L', 6303=>'L', 6304=>'L', 6305=>'L', 6306=>'L', 6307=>'L', 6308=>'L', 6309=>'L', 6310=>'L', 6311=>'L', 6312=>'L', 6313=>'NSM', 6400=>'L', 6401=>'L', 6402=>'L', 6403=>'L', 6404=>'L', 6405=>'L', 6406=>'L', 6407=>'L', 6408=>'L', 6409=>'L', 6410=>'L', 6411=>'L', 6412=>'L', 6413=>'L', 6414=>'L', 6415=>'L', 6416=>'L', 6417=>'L', 6418=>'L', 6419=>'L', 6420=>'L', 6421=>'L', 6422=>'L', 6423=>'L', 6424=>'L', 6425=>'L', 6426=>'L', 6427=>'L', 6428=>'L', 6432=>'NSM', 6433=>'NSM', 6434=>'NSM', 6435=>'L', 6436=>'L', 6437=>'L', 6438=>'L', 6439=>'NSM', 6440=>'NSM', 6441=>'NSM', 6442=>'NSM', 6443=>'NSM', 6448=>'L', 6449=>'L', 6450=>'NSM', 6451=>'L', 6452=>'L', 6453=>'L', 6454=>'L', 6455=>'L', 6456=>'L', 6457=>'NSM', 6458=>'NSM', 6459=>'NSM', 6464=>'ON', 6468=>'ON', 6469=>'ON', 6470=>'L', 6471=>'L', 6472=>'L', 6473=>'L', 6474=>'L', 6475=>'L', 6476=>'L', 6477=>'L', 6478=>'L', 6479=>'L', 6480=>'L', 6481=>'L', 6482=>'L', 6483=>'L', 6484=>'L', 6485=>'L', 6486=>'L', 6487=>'L', 6488=>'L', 6489=>'L', 6490=>'L', 6491=>'L', 6492=>'L', 6493=>'L', 6494=>'L', 6495=>'L', 6496=>'L', 6497=>'L', 6498=>'L', 6499=>'L', 6500=>'L', 6501=>'L', 6502=>'L', 6503=>'L', 6504=>'L', 6505=>'L', 6506=>'L', 6507=>'L', 6508=>'L', 6509=>'L', 6512=>'L', 6513=>'L', 6514=>'L', 6515=>'L', 6516=>'L', 6528=>'L', 6529=>'L', 6530=>'L', 6531=>'L', 6532=>'L', 6533=>'L', 6534=>'L', 6535=>'L', 6536=>'L', 6537=>'L', 6538=>'L', 6539=>'L', 6540=>'L', 6541=>'L', 6542=>'L', 6543=>'L', 6544=>'L', 6545=>'L', 6546=>'L', 6547=>'L', 6548=>'L', 6549=>'L', 6550=>'L', 6551=>'L', 6552=>'L', 6553=>'L', 6554=>'L', 6555=>'L', 6556=>'L', 6557=>'L', 6558=>'L', 6559=>'L', 6560=>'L', 6561=>'L', 6562=>'L', 6563=>'L', 6564=>'L', 6565=>'L', 6566=>'L', 6567=>'L', 6568=>'L', 6569=>'L', 6576=>'L', 6577=>'L', 6578=>'L', 6579=>'L', 6580=>'L', 6581=>'L', 6582=>'L', 6583=>'L', 6584=>'L', 6585=>'L', 6586=>'L', 6587=>'L', 6588=>'L', 6589=>'L', 6590=>'L', 6591=>'L', 6592=>'L', 6593=>'L', 6594=>'L', 6595=>'L', 6596=>'L', 6597=>'L', 6598=>'L', 6599=>'L', 6600=>'L', 6601=>'L', 6608=>'L', 6609=>'L', 6610=>'L', 6611=>'L', 6612=>'L', 6613=>'L', 6614=>'L', 6615=>'L', 6616=>'L', 6617=>'L', 6622=>'ON', 6623=>'ON', 6624=>'ON', 6625=>'ON', 6626=>'ON', 6627=>'ON', 6628=>'ON', 6629=>'ON', 6630=>'ON', 6631=>'ON', 6632=>'ON', 6633=>'ON', 6634=>'ON', 6635=>'ON', 6636=>'ON', 6637=>'ON', 6638=>'ON', 6639=>'ON', 6640=>'ON', 6641=>'ON', 6642=>'ON', 6643=>'ON', 6644=>'ON', 6645=>'ON', 6646=>'ON', 6647=>'ON', 6648=>'ON', 6649=>'ON', 6650=>'ON', 6651=>'ON', 6652=>'ON', 6653=>'ON', 6654=>'ON', 6655=>'ON', 6656=>'L', 6657=>'L', 6658=>'L', 6659=>'L', 6660=>'L', 6661=>'L', 6662=>'L', 6663=>'L', 6664=>'L', 6665=>'L', 6666=>'L', 6667=>'L', 6668=>'L', 6669=>'L', 6670=>'L', 6671=>'L', 6672=>'L', 6673=>'L', 6674=>'L', 6675=>'L', 6676=>'L', 6677=>'L', 6678=>'L', 6679=>'NSM', 6680=>'NSM', 6681=>'L', 6682=>'L', 6683=>'L', 6686=>'L', 6687=>'L', 6912=>'NSM', 6913=>'NSM', 6914=>'NSM', 6915=>'NSM', 6916=>'L', 6917=>'L', 6918=>'L', 6919=>'L', 6920=>'L', 6921=>'L', 6922=>'L', 6923=>'L', 6924=>'L', 6925=>'L', 6926=>'L', 6927=>'L', 6928=>'L', 6929=>'L', 6930=>'L', 6931=>'L', 6932=>'L', 6933=>'L', 6934=>'L', 6935=>'L', 6936=>'L', 6937=>'L', 6938=>'L', 6939=>'L', 6940=>'L', 6941=>'L', 6942=>'L', 6943=>'L', 6944=>'L', 6945=>'L', 6946=>'L', 6947=>'L', 6948=>'L', 6949=>'L', 6950=>'L', 6951=>'L', 6952=>'L', 6953=>'L', 6954=>'L', 6955=>'L', 6956=>'L', 6957=>'L', 6958=>'L', 6959=>'L', 6960=>'L', 6961=>'L', 6962=>'L', 6963=>'L', 6964=>'NSM', 6965=>'L', 6966=>'NSM', 6967=>'NSM', 6968=>'NSM', 6969=>'NSM', 6970=>'NSM', 6971=>'L', 6972=>'NSM', 6973=>'L', 6974=>'L', 6975=>'L', 6976=>'L', 6977=>'L', 6978=>'NSM', 6979=>'L', 6980=>'L', 6981=>'L', 6982=>'L', 6983=>'L', 6984=>'L', 6985=>'L', 6986=>'L', 6987=>'L', 6992=>'L', 6993=>'L', 6994=>'L', 6995=>'L', 6996=>'L', 6997=>'L', 6998=>'L', 6999=>'L', 7000=>'L', 7001=>'L', 7002=>'L', 7003=>'L', 7004=>'L', 7005=>'L', 7006=>'L', 7007=>'L', 7008=>'L', 7009=>'L', 7010=>'L', 7011=>'L', 7012=>'L', 7013=>'L', 7014=>'L', 7015=>'L', 7016=>'L', 7017=>'L', 7018=>'L', 7019=>'NSM', 7020=>'NSM', 7021=>'NSM', 7022=>'NSM', 7023=>'NSM', 7024=>'NSM', 7025=>'NSM', 7026=>'NSM', 7027=>'NSM', 7028=>'L', 7029=>'L', 7030=>'L', 7031=>'L', 7032=>'L', 7033=>'L', 7034=>'L', 7035=>'L', 7036=>'L', 7424=>'L', 7425=>'L', 7426=>'L', 7427=>'L', 7428=>'L', 7429=>'L', 7430=>'L', 7431=>'L', 7432=>'L', 7433=>'L', 7434=>'L', 7435=>'L', 7436=>'L', 7437=>'L', 7438=>'L', 7439=>'L', 7440=>'L', 7441=>'L', 7442=>'L', 7443=>'L', 7444=>'L', 7445=>'L', 7446=>'L', 7447=>'L', 7448=>'L', 7449=>'L', 7450=>'L', 7451=>'L', 7452=>'L', 7453=>'L', 7454=>'L', 7455=>'L', 7456=>'L', 7457=>'L', 7458=>'L', 7459=>'L', 7460=>'L', 7461=>'L', 7462=>'L', 7463=>'L', 7464=>'L', 7465=>'L', 7466=>'L', 7467=>'L', 7468=>'L', 7469=>'L', 7470=>'L', 7471=>'L', 7472=>'L', 7473=>'L', 7474=>'L', 7475=>'L', 7476=>'L', 7477=>'L', 7478=>'L', 7479=>'L', 7480=>'L', 7481=>'L', 7482=>'L', 7483=>'L', 7484=>'L', 7485=>'L', 7486=>'L', 7487=>'L', 7488=>'L', 7489=>'L', 7490=>'L', 7491=>'L', 7492=>'L', 7493=>'L', 7494=>'L', 7495=>'L', 7496=>'L', 7497=>'L', 7498=>'L', 7499=>'L', 7500=>'L', 7501=>'L', 7502=>'L', 7503=>'L', 7504=>'L', 7505=>'L', 7506=>'L', 7507=>'L', 7508=>'L', 7509=>'L', 7510=>'L', 7511=>'L', 7512=>'L', 7513=>'L', 7514=>'L', 7515=>'L', 7516=>'L', 7517=>'L', 7518=>'L', 7519=>'L', 7520=>'L', 7521=>'L', 7522=>'L', 7523=>'L', 7524=>'L', 7525=>'L', 7526=>'L', 7527=>'L', 7528=>'L', 7529=>'L', 7530=>'L', 7531=>'L', 7532=>'L', 7533=>'L', 7534=>'L', 7535=>'L', 7536=>'L', 7537=>'L', 7538=>'L', 7539=>'L', 7540=>'L', 7541=>'L', 7542=>'L', 7543=>'L', 7544=>'L', 7545=>'L', 7546=>'L', 7547=>'L', 7548=>'L', 7549=>'L', 7550=>'L', 7551=>'L', 7552=>'L', 7553=>'L', 7554=>'L', 7555=>'L', 7556=>'L', 7557=>'L', 7558=>'L', 7559=>'L', 7560=>'L', 7561=>'L', 7562=>'L', 7563=>'L', 7564=>'L', 7565=>'L', 7566=>'L', 7567=>'L', 7568=>'L', 7569=>'L', 7570=>'L', 7571=>'L', 7572=>'L', 7573=>'L', 7574=>'L', 7575=>'L', 7576=>'L', 7577=>'L', 7578=>'L', 7579=>'L', 7580=>'L', 7581=>'L', 7582=>'L', 7583=>'L', 7584=>'L', 7585=>'L', 7586=>'L', 7587=>'L', 7588=>'L', 7589=>'L', 7590=>'L', 7591=>'L', 7592=>'L', 7593=>'L', 7594=>'L', 7595=>'L', 7596=>'L', 7597=>'L', 7598=>'L', 7599=>'L', 7600=>'L', 7601=>'L', 7602=>'L', 7603=>'L', 7604=>'L', 7605=>'L', 7606=>'L', 7607=>'L', 7608=>'L', 7609=>'L', 7610=>'L', 7611=>'L', 7612=>'L', 7613=>'L', 7614=>'L', 7615=>'L', 7616=>'NSM', 7617=>'NSM', 7618=>'NSM', 7619=>'NSM', 7620=>'NSM', 7621=>'NSM', 7622=>'NSM', 7623=>'NSM', 7624=>'NSM', 7625=>'NSM', 7626=>'NSM', 7678=>'NSM', 7679=>'NSM', 7680=>'L', 7681=>'L', 7682=>'L', 7683=>'L', 7684=>'L', 7685=>'L', 7686=>'L', 7687=>'L', 7688=>'L', 7689=>'L', 7690=>'L', 7691=>'L', 7692=>'L', 7693=>'L', 7694=>'L', 7695=>'L', 7696=>'L', 7697=>'L', 7698=>'L', 7699=>'L', 7700=>'L', 7701=>'L', 7702=>'L', 7703=>'L', 7704=>'L', 7705=>'L', 7706=>'L', 7707=>'L', 7708=>'L', 7709=>'L', 7710=>'L', 7711=>'L', 7712=>'L', 7713=>'L', 7714=>'L', 7715=>'L', 7716=>'L', 7717=>'L', 7718=>'L', 7719=>'L', 7720=>'L', 7721=>'L', 7722=>'L', 7723=>'L', 7724=>'L', 7725=>'L', 7726=>'L', 7727=>'L', 7728=>'L', 7729=>'L', 7730=>'L', 7731=>'L', 7732=>'L', 7733=>'L', 7734=>'L', 7735=>'L', 7736=>'L', 7737=>'L', 7738=>'L', 7739=>'L', 7740=>'L', 7741=>'L', 7742=>'L', 7743=>'L', 7744=>'L', 7745=>'L', 7746=>'L', 7747=>'L', 7748=>'L', 7749=>'L', 7750=>'L', 7751=>'L', 7752=>'L', 7753=>'L', 7754=>'L', 7755=>'L', 7756=>'L', 7757=>'L', 7758=>'L', 7759=>'L', 7760=>'L', 7761=>'L', 7762=>'L', 7763=>'L', 7764=>'L', 7765=>'L', 7766=>'L', 7767=>'L', 7768=>'L', 7769=>'L', 7770=>'L', 7771=>'L', 7772=>'L', 7773=>'L', 7774=>'L', 7775=>'L', 7776=>'L', 7777=>'L', 7778=>'L', 7779=>'L', 7780=>'L', 7781=>'L', 7782=>'L', 7783=>'L', 7784=>'L', 7785=>'L', 7786=>'L', 7787=>'L', 7788=>'L', 7789=>'L', 7790=>'L', 7791=>'L', 7792=>'L', 7793=>'L', 7794=>'L', 7795=>'L', 7796=>'L', 7797=>'L', 7798=>'L', 7799=>'L', 7800=>'L', 7801=>'L', 7802=>'L', 7803=>'L', 7804=>'L', 7805=>'L', 7806=>'L', 7807=>'L', 7808=>'L', 7809=>'L', 7810=>'L', 7811=>'L', 7812=>'L', 7813=>'L', 7814=>'L', 7815=>'L', 7816=>'L', 7817=>'L', 7818=>'L', 7819=>'L', 7820=>'L', 7821=>'L', 7822=>'L', 7823=>'L', 7824=>'L', 7825=>'L', 7826=>'L', 7827=>'L', 7828=>'L', 7829=>'L', 7830=>'L', 7831=>'L', 7832=>'L', 7833=>'L', 7834=>'L', 7835=>'L', 7840=>'L', 7841=>'L', 7842=>'L', 7843=>'L', 7844=>'L', 7845=>'L', 7846=>'L', 7847=>'L', 7848=>'L', 7849=>'L', 7850=>'L', 7851=>'L', 7852=>'L', 7853=>'L', 7854=>'L', 7855=>'L', 7856=>'L', 7857=>'L', 7858=>'L', 7859=>'L', 7860=>'L', 7861=>'L', 7862=>'L', 7863=>'L', 7864=>'L', 7865=>'L', 7866=>'L', 7867=>'L', 7868=>'L', 7869=>'L', 7870=>'L', 7871=>'L', 7872=>'L', 7873=>'L', 7874=>'L', 7875=>'L', 7876=>'L', 7877=>'L', 7878=>'L', 7879=>'L', 7880=>'L', 7881=>'L', 7882=>'L', 7883=>'L', 7884=>'L', 7885=>'L', 7886=>'L', 7887=>'L', 7888=>'L', 7889=>'L', 7890=>'L', 7891=>'L', 7892=>'L', 7893=>'L', 7894=>'L', 7895=>'L', 7896=>'L', 7897=>'L', 7898=>'L', 7899=>'L', 7900=>'L', 7901=>'L', 7902=>'L', 7903=>'L', 7904=>'L', 7905=>'L', 7906=>'L', 7907=>'L', 7908=>'L', 7909=>'L', 7910=>'L', 7911=>'L', 7912=>'L', 7913=>'L', 7914=>'L', 7915=>'L', 7916=>'L', 7917=>'L', 7918=>'L', 7919=>'L', 7920=>'L', 7921=>'L', 7922=>'L', 7923=>'L', 7924=>'L', 7925=>'L', 7926=>'L', 7927=>'L', 7928=>'L', 7929=>'L', 7936=>'L', 7937=>'L', 7938=>'L', 7939=>'L', 7940=>'L', 7941=>'L', 7942=>'L', 7943=>'L', 7944=>'L', 7945=>'L', 7946=>'L', 7947=>'L', 7948=>'L', 7949=>'L', 7950=>'L', 7951=>'L', 7952=>'L', 7953=>'L', 7954=>'L', 7955=>'L', 7956=>'L', 7957=>'L', 7960=>'L', 7961=>'L', 7962=>'L', 7963=>'L', 7964=>'L', 7965=>'L', 7968=>'L', 7969=>'L', 7970=>'L', 7971=>'L', 7972=>'L', 7973=>'L', 7974=>'L', 7975=>'L', 7976=>'L', 7977=>'L', 7978=>'L', 7979=>'L', 7980=>'L', 7981=>'L', 7982=>'L', 7983=>'L', 7984=>'L', 7985=>'L', 7986=>'L', 7987=>'L', 7988=>'L', 7989=>'L', 7990=>'L', 7991=>'L', 7992=>'L', 7993=>'L', 7994=>'L', 7995=>'L', 7996=>'L', 7997=>'L', 7998=>'L', 7999=>'L', 8000=>'L', 8001=>'L', 8002=>'L', 8003=>'L', 8004=>'L', 8005=>'L', 8008=>'L', 8009=>'L', 8010=>'L', 8011=>'L', 8012=>'L', 8013=>'L', 8016=>'L', 8017=>'L', 8018=>'L', 8019=>'L', 8020=>'L', 8021=>'L', 8022=>'L', 8023=>'L', 8025=>'L', 8027=>'L', 8029=>'L', 8031=>'L', 8032=>'L', 8033=>'L', 8034=>'L', 8035=>'L', 8036=>'L', 8037=>'L', 8038=>'L', 8039=>'L', 8040=>'L', 8041=>'L', 8042=>'L', 8043=>'L', 8044=>'L', 8045=>'L', 8046=>'L', 8047=>'L', 8048=>'L', 8049=>'L', 8050=>'L', 8051=>'L', 8052=>'L', 8053=>'L', 8054=>'L', 8055=>'L', 8056=>'L', 8057=>'L', 8058=>'L', 8059=>'L', 8060=>'L', 8061=>'L', 8064=>'L', 8065=>'L', 8066=>'L', 8067=>'L', 8068=>'L', 8069=>'L', 8070=>'L', 8071=>'L', 8072=>'L', 8073=>'L', 8074=>'L', 8075=>'L', 8076=>'L', 8077=>'L', 8078=>'L', 8079=>'L', 8080=>'L', 8081=>'L', 8082=>'L', 8083=>'L', 8084=>'L', 8085=>'L', 8086=>'L', 8087=>'L', 8088=>'L', 8089=>'L', 8090=>'L', 8091=>'L', 8092=>'L', 8093=>'L', 8094=>'L', 8095=>'L', 8096=>'L', 8097=>'L', 8098=>'L', 8099=>'L', 8100=>'L', 8101=>'L', 8102=>'L', 8103=>'L', 8104=>'L', 8105=>'L', 8106=>'L', 8107=>'L', 8108=>'L', 8109=>'L', 8110=>'L', 8111=>'L', 8112=>'L', 8113=>'L', 8114=>'L', 8115=>'L', 8116=>'L', 8118=>'L', 8119=>'L', 8120=>'L', 8121=>'L', 8122=>'L', 8123=>'L', 8124=>'L', 8125=>'ON', 8126=>'L', 8127=>'ON', 8128=>'ON', 8129=>'ON', 8130=>'L', 8131=>'L', 8132=>'L', 8134=>'L', 8135=>'L', 8136=>'L', 8137=>'L', 8138=>'L', 8139=>'L', 8140=>'L', 8141=>'ON', 8142=>'ON', 8143=>'ON', 8144=>'L', 8145=>'L', 8146=>'L', 8147=>'L', 8150=>'L', 8151=>'L', 8152=>'L', 8153=>'L', 8154=>'L', 8155=>'L', 8157=>'ON', 8158=>'ON', 8159=>'ON', 8160=>'L', 8161=>'L', 8162=>'L', 8163=>'L', 8164=>'L', 8165=>'L', 8166=>'L', 8167=>'L', 8168=>'L', 8169=>'L', 8170=>'L', 8171=>'L', 8172=>'L', 8173=>'ON', 8174=>'ON', 8175=>'ON', 8178=>'L', 8179=>'L', 8180=>'L', 8182=>'L', 8183=>'L', 8184=>'L', 8185=>'L', 8186=>'L', 8187=>'L', 8188=>'L', 8189=>'ON', 8190=>'ON', 8192=>'WS', 8193=>'WS', 8194=>'WS', 8195=>'WS', 8196=>'WS', 8197=>'WS', 8198=>'WS', 8199=>'WS', 8200=>'WS', 8201=>'WS', 8202=>'WS', 8203=>'BN', 8204=>'BN', 8205=>'BN', 8206=>'L', 8207=>'R', 8208=>'ON', 8209=>'ON', 8210=>'ON', 8211=>'ON', 8212=>'ON', 8213=>'ON', 8214=>'ON', 8215=>'ON', 8216=>'ON', 8217=>'ON', 8218=>'ON', 8219=>'ON', 8220=>'ON', 8221=>'ON', 8222=>'ON', 8223=>'ON', 8224=>'ON', 8225=>'ON', 8226=>'ON', 8227=>'ON', 8228=>'ON', 8229=>'ON', 8230=>'ON', 8231=>'ON', 8232=>'WS', 8233=>'B', 8234=>'LRE', 8235=>'RLE', 8236=>'PDF', 8237=>'LRO', 8238=>'RLO', 8239=>'CS', 8240=>'ET', 8241=>'ET', 8242=>'ET', 8243=>'ET', 8244=>'ET', 8245=>'ON', 8246=>'ON', 8247=>'ON', 8248=>'ON', 8249=>'ON', 8250=>'ON', 8251=>'ON', 8252=>'ON', 8253=>'ON', 8254=>'ON', 8255=>'ON', 8256=>'ON', 8257=>'ON', 8258=>'ON', 8259=>'ON', 8260=>'CS', 8261=>'ON', 8262=>'ON', 8263=>'ON', 8264=>'ON', 8265=>'ON', 8266=>'ON', 8267=>'ON', 8268=>'ON', 8269=>'ON', 8270=>'ON', 8271=>'ON', 8272=>'ON', 8273=>'ON', 8274=>'ON', 8275=>'ON', 8276=>'ON', 8277=>'ON', 8278=>'ON', 8279=>'ON', 8280=>'ON', 8281=>'ON', 8282=>'ON', 8283=>'ON', 8284=>'ON', 8285=>'ON', 8286=>'ON', 8287=>'WS', 8288=>'BN', 8289=>'BN', 8290=>'BN', 8291=>'BN', 8298=>'BN', 8299=>'BN', 8300=>'BN', 8301=>'BN', 8302=>'BN', 8303=>'BN', 8304=>'EN', 8305=>'L', 8308=>'EN', 8309=>'EN', 8310=>'EN', 8311=>'EN', 8312=>'EN', 8313=>'EN', 8314=>'ES', 8315=>'ES', 8316=>'ON', 8317=>'ON', 8318=>'ON', 8319=>'L', 8320=>'EN', 8321=>'EN', 8322=>'EN', 8323=>'EN', 8324=>'EN', 8325=>'EN', 8326=>'EN', 8327=>'EN', 8328=>'EN', 8329=>'EN', 8330=>'ES', 8331=>'ES', 8332=>'ON', 8333=>'ON', 8334=>'ON', 8336=>'L', 8337=>'L', 8338=>'L', 8339=>'L', 8340=>'L', 8352=>'ET', 8353=>'ET', 8354=>'ET', 8355=>'ET', 8356=>'ET', 8357=>'ET', 8358=>'ET', 8359=>'ET', 8360=>'ET', 8361=>'ET', 8362=>'ET', 8363=>'ET', 8364=>'ET', 8365=>'ET', 8366=>'ET', 8367=>'ET', 8368=>'ET', 8369=>'ET', 8370=>'ET', 8371=>'ET', 8372=>'ET', 8373=>'ET', 8400=>'NSM', 8401=>'NSM', 8402=>'NSM', 8403=>'NSM', 8404=>'NSM', 8405=>'NSM', 8406=>'NSM', 8407=>'NSM', 8408=>'NSM', 8409=>'NSM', 8410=>'NSM', 8411=>'NSM', 8412=>'NSM', 8413=>'NSM', 8414=>'NSM', 8415=>'NSM', 8416=>'NSM', 8417=>'NSM', 8418=>'NSM', 8419=>'NSM', 8420=>'NSM', 8421=>'NSM', 8422=>'NSM', 8423=>'NSM', 8424=>'NSM', 8425=>'NSM', 8426=>'NSM', 8427=>'NSM', 8428=>'NSM', 8429=>'NSM', 8430=>'NSM', 8431=>'NSM', 8448=>'ON', 8449=>'ON', 8450=>'L', 8451=>'ON', 8452=>'ON', 8453=>'ON', 8454=>'ON', 8455=>'L', 8456=>'ON', 8457=>'ON', 8458=>'L', 8459=>'L', 8460=>'L', 8461=>'L', 8462=>'L', 8463=>'L', 8464=>'L', 8465=>'L', 8466=>'L', 8467=>'L', 8468=>'ON', 8469=>'L', 8470=>'ON', 8471=>'ON', 8472=>'ON', 8473=>'L', 8474=>'L', 8475=>'L', 8476=>'L', 8477=>'L', 8478=>'ON', 8479=>'ON', 8480=>'ON', 8481=>'ON', 8482=>'ON', 8483=>'ON', 8484=>'L', 8485=>'ON', 8486=>'L', 8487=>'ON', 8488=>'L', 8489=>'ON', 8490=>'L', 8491=>'L', 8492=>'L', 8493=>'L', 8494=>'ET', 8495=>'L', 8496=>'L', 8497=>'L', 8498=>'L', 8499=>'L', 8500=>'L', 8501=>'L', 8502=>'L', 8503=>'L', 8504=>'L', 8505=>'L', 8506=>'ON', 8507=>'ON', 8508=>'L', 8509=>'L', 8510=>'L', 8511=>'L', 8512=>'ON', 8513=>'ON', 8514=>'ON', 8515=>'ON', 8516=>'ON', 8517=>'L', 8518=>'L', 8519=>'L', 8520=>'L', 8521=>'L', 8522=>'ON', 8523=>'ON', 8524=>'ON', 8525=>'ON', 8526=>'L', 8531=>'ON', 8532=>'ON', 8533=>'ON', 8534=>'ON', 8535=>'ON', 8536=>'ON', 8537=>'ON', 8538=>'ON', 8539=>'ON', 8540=>'ON', 8541=>'ON', 8542=>'ON', 8543=>'ON', 8544=>'L', 8545=>'L', 8546=>'L', 8547=>'L', 8548=>'L', 8549=>'L', 8550=>'L', 8551=>'L', 8552=>'L', 8553=>'L', 8554=>'L', 8555=>'L', 8556=>'L', 8557=>'L', 8558=>'L', 8559=>'L', 8560=>'L', 8561=>'L', 8562=>'L', 8563=>'L', 8564=>'L', 8565=>'L', 8566=>'L', 8567=>'L', 8568=>'L', 8569=>'L', 8570=>'L', 8571=>'L', 8572=>'L', 8573=>'L', 8574=>'L', 8575=>'L', 8576=>'L', 8577=>'L', 8578=>'L', 8579=>'L', 8580=>'L', 8592=>'ON', 8593=>'ON', 8594=>'ON', 8595=>'ON', 8596=>'ON', 8597=>'ON', 8598=>'ON', 8599=>'ON', 8600=>'ON', 8601=>'ON', 8602=>'ON', 8603=>'ON', 8604=>'ON', 8605=>'ON', 8606=>'ON', 8607=>'ON', 8608=>'ON', 8609=>'ON', 8610=>'ON', 8611=>'ON', 8612=>'ON', 8613=>'ON', 8614=>'ON', 8615=>'ON', 8616=>'ON', 8617=>'ON', 8618=>'ON', 8619=>'ON', 8620=>'ON', 8621=>'ON', 8622=>'ON', 8623=>'ON', 8624=>'ON', 8625=>'ON', 8626=>'ON', 8627=>'ON', 8628=>'ON', 8629=>'ON', 8630=>'ON', 8631=>'ON', 8632=>'ON', 8633=>'ON', 8634=>'ON', 8635=>'ON', 8636=>'ON', 8637=>'ON', 8638=>'ON', 8639=>'ON', 8640=>'ON', 8641=>'ON', 8642=>'ON', 8643=>'ON', 8644=>'ON', 8645=>'ON', 8646=>'ON', 8647=>'ON', 8648=>'ON', 8649=>'ON', 8650=>'ON', 8651=>'ON', 8652=>'ON', 8653=>'ON', 8654=>'ON', 8655=>'ON', 8656=>'ON', 8657=>'ON', 8658=>'ON', 8659=>'ON', 8660=>'ON', 8661=>'ON', 8662=>'ON', 8663=>'ON', 8664=>'ON', 8665=>'ON', 8666=>'ON', 8667=>'ON', 8668=>'ON', 8669=>'ON', 8670=>'ON', 8671=>'ON', 8672=>'ON', 8673=>'ON', 8674=>'ON', 8675=>'ON', 8676=>'ON', 8677=>'ON', 8678=>'ON', 8679=>'ON', 8680=>'ON', 8681=>'ON', 8682=>'ON', 8683=>'ON', 8684=>'ON', 8685=>'ON', 8686=>'ON', 8687=>'ON', 8688=>'ON', 8689=>'ON', 8690=>'ON', 8691=>'ON', 8692=>'ON', 8693=>'ON', 8694=>'ON', 8695=>'ON', 8696=>'ON', 8697=>'ON', 8698=>'ON', 8699=>'ON', 8700=>'ON', 8701=>'ON', 8702=>'ON', 8703=>'ON', 8704=>'ON', 8705=>'ON', 8706=>'ON', 8707=>'ON', 8708=>'ON', 8709=>'ON', 8710=>'ON', 8711=>'ON', 8712=>'ON', 8713=>'ON', 8714=>'ON', 8715=>'ON', 8716=>'ON', 8717=>'ON', 8718=>'ON', 8719=>'ON', 8720=>'ON', 8721=>'ON', 8722=>'ES', 8723=>'ET', 8724=>'ON', 8725=>'ON', 8726=>'ON', 8727=>'ON', 8728=>'ON', 8729=>'ON', 8730=>'ON', 8731=>'ON', 8732=>'ON', 8733=>'ON', 8734=>'ON', 8735=>'ON', 8736=>'ON', 8737=>'ON', 8738=>'ON', 8739=>'ON', 8740=>'ON', 8741=>'ON', 8742=>'ON', 8743=>'ON', 8744=>'ON', 8745=>'ON', 8746=>'ON', 8747=>'ON', 8748=>'ON', 8749=>'ON', 8750=>'ON', 8751=>'ON', 8752=>'ON', 8753=>'ON', 8754=>'ON', 8755=>'ON', 8756=>'ON', 8757=>'ON', 8758=>'ON', 8759=>'ON', 8760=>'ON', 8761=>'ON', 8762=>'ON', 8763=>'ON', 8764=>'ON', 8765=>'ON', 8766=>'ON', 8767=>'ON', 8768=>'ON', 8769=>'ON', 8770=>'ON', 8771=>'ON', 8772=>'ON', 8773=>'ON', 8774=>'ON', 8775=>'ON', 8776=>'ON', 8777=>'ON', 8778=>'ON', 8779=>'ON', 8780=>'ON', 8781=>'ON', 8782=>'ON', 8783=>'ON', 8784=>'ON', 8785=>'ON', 8786=>'ON', 8787=>'ON', 8788=>'ON', 8789=>'ON', 8790=>'ON', 8791=>'ON', 8792=>'ON', 8793=>'ON', 8794=>'ON', 8795=>'ON', 8796=>'ON', 8797=>'ON', 8798=>'ON', 8799=>'ON', 8800=>'ON', 8801=>'ON', 8802=>'ON', 8803=>'ON', 8804=>'ON', 8805=>'ON', 8806=>'ON', 8807=>'ON', 8808=>'ON', 8809=>'ON', 8810=>'ON', 8811=>'ON', 8812=>'ON', 8813=>'ON', 8814=>'ON', 8815=>'ON', 8816=>'ON', 8817=>'ON', 8818=>'ON', 8819=>'ON', 8820=>'ON', 8821=>'ON', 8822=>'ON', 8823=>'ON', 8824=>'ON', 8825=>'ON', 8826=>'ON', 8827=>'ON', 8828=>'ON', 8829=>'ON', 8830=>'ON', 8831=>'ON', 8832=>'ON', 8833=>'ON', 8834=>'ON', 8835=>'ON', 8836=>'ON', 8837=>'ON', 8838=>'ON', 8839=>'ON', 8840=>'ON', 8841=>'ON', 8842=>'ON', 8843=>'ON', 8844=>'ON', 8845=>'ON', 8846=>'ON', 8847=>'ON', 8848=>'ON', 8849=>'ON', 8850=>'ON', 8851=>'ON', 8852=>'ON', 8853=>'ON', 8854=>'ON', 8855=>'ON', 8856=>'ON', 8857=>'ON', 8858=>'ON', 8859=>'ON', 8860=>'ON', 8861=>'ON', 8862=>'ON', 8863=>'ON', 8864=>'ON', 8865=>'ON', 8866=>'ON', 8867=>'ON', 8868=>'ON', 8869=>'ON', 8870=>'ON', 8871=>'ON', 8872=>'ON', 8873=>'ON', 8874=>'ON', 8875=>'ON', 8876=>'ON', 8877=>'ON', 8878=>'ON', 8879=>'ON', 8880=>'ON', 8881=>'ON', 8882=>'ON', 8883=>'ON', 8884=>'ON', 8885=>'ON', 8886=>'ON', 8887=>'ON', 8888=>'ON', 8889=>'ON', 8890=>'ON', 8891=>'ON', 8892=>'ON', 8893=>'ON', 8894=>'ON', 8895=>'ON', 8896=>'ON', 8897=>'ON', 8898=>'ON', 8899=>'ON', 8900=>'ON', 8901=>'ON', 8902=>'ON', 8903=>'ON', 8904=>'ON', 8905=>'ON', 8906=>'ON', 8907=>'ON', 8908=>'ON', 8909=>'ON', 8910=>'ON', 8911=>'ON', 8912=>'ON', 8913=>'ON', 8914=>'ON', 8915=>'ON', 8916=>'ON', 8917=>'ON', 8918=>'ON', 8919=>'ON', 8920=>'ON', 8921=>'ON', 8922=>'ON', 8923=>'ON', 8924=>'ON', 8925=>'ON', 8926=>'ON', 8927=>'ON', 8928=>'ON', 8929=>'ON', 8930=>'ON', 8931=>'ON', 8932=>'ON', 8933=>'ON', 8934=>'ON', 8935=>'ON', 8936=>'ON', 8937=>'ON', 8938=>'ON', 8939=>'ON', 8940=>'ON', 8941=>'ON', 8942=>'ON', 8943=>'ON', 8944=>'ON', 8945=>'ON', 8946=>'ON', 8947=>'ON', 8948=>'ON', 8949=>'ON', 8950=>'ON', 8951=>'ON', 8952=>'ON', 8953=>'ON', 8954=>'ON', 8955=>'ON', 8956=>'ON', 8957=>'ON', 8958=>'ON', 8959=>'ON', 8960=>'ON', 8961=>'ON', 8962=>'ON', 8963=>'ON', 8964=>'ON', 8965=>'ON', 8966=>'ON', 8967=>'ON', 8968=>'ON', 8969=>'ON', 8970=>'ON', 8971=>'ON', 8972=>'ON', 8973=>'ON', 8974=>'ON', 8975=>'ON', 8976=>'ON', 8977=>'ON', 8978=>'ON', 8979=>'ON', 8980=>'ON', 8981=>'ON', 8982=>'ON', 8983=>'ON', 8984=>'ON', 8985=>'ON', 8986=>'ON', 8987=>'ON', 8988=>'ON', 8989=>'ON', 8990=>'ON', 8991=>'ON', 8992=>'ON', 8993=>'ON', 8994=>'ON', 8995=>'ON', 8996=>'ON', 8997=>'ON', 8998=>'ON', 8999=>'ON', 9000=>'ON', 9001=>'ON', 9002=>'ON', 9003=>'ON', 9004=>'ON', 9005=>'ON', 9006=>'ON', 9007=>'ON', 9008=>'ON', 9009=>'ON', 9010=>'ON', 9011=>'ON', 9012=>'ON', 9013=>'ON', 9014=>'L', 9015=>'L', 9016=>'L', 9017=>'L', 9018=>'L', 9019=>'L', 9020=>'L', 9021=>'L', 9022=>'L', 9023=>'L', 9024=>'L', 9025=>'L', 9026=>'L', 9027=>'L', 9028=>'L', 9029=>'L', 9030=>'L', 9031=>'L', 9032=>'L', 9033=>'L', 9034=>'L', 9035=>'L', 9036=>'L', 9037=>'L', 9038=>'L', 9039=>'L', 9040=>'L', 9041=>'L', 9042=>'L', 9043=>'L', 9044=>'L', 9045=>'L', 9046=>'L', 9047=>'L', 9048=>'L', 9049=>'L', 9050=>'L', 9051=>'L', 9052=>'L', 9053=>'L', 9054=>'L', 9055=>'L', 9056=>'L', 9057=>'L', 9058=>'L', 9059=>'L', 9060=>'L', 9061=>'L', 9062=>'L', 9063=>'L', 9064=>'L', 9065=>'L', 9066=>'L', 9067=>'L', 9068=>'L', 9069=>'L', 9070=>'L', 9071=>'L', 9072=>'L', 9073=>'L', 9074=>'L', 9075=>'L', 9076=>'L', 9077=>'L', 9078=>'L', 9079=>'L', 9080=>'L', 9081=>'L', 9082=>'L', 9083=>'ON', 9084=>'ON', 9085=>'ON', 9086=>'ON', 9087=>'ON', 9088=>'ON', 9089=>'ON', 9090=>'ON', 9091=>'ON', 9092=>'ON', 9093=>'ON', 9094=>'ON', 9095=>'ON', 9096=>'ON', 9097=>'ON', 9098=>'ON', 9099=>'ON', 9100=>'ON', 9101=>'ON', 9102=>'ON', 9103=>'ON', 9104=>'ON', 9105=>'ON', 9106=>'ON', 9107=>'ON', 9108=>'ON', 9109=>'L', 9110=>'ON', 9111=>'ON', 9112=>'ON', 9113=>'ON', 9114=>'ON', 9115=>'ON', 9116=>'ON', 9117=>'ON', 9118=>'ON', 9119=>'ON', 9120=>'ON', 9121=>'ON', 9122=>'ON', 9123=>'ON', 9124=>'ON', 9125=>'ON', 9126=>'ON', 9127=>'ON', 9128=>'ON', 9129=>'ON', 9130=>'ON', 9131=>'ON', 9132=>'ON', 9133=>'ON', 9134=>'ON', 9135=>'ON', 9136=>'ON', 9137=>'ON', 9138=>'ON', 9139=>'ON', 9140=>'ON', 9141=>'ON', 9142=>'ON', 9143=>'ON', 9144=>'ON', 9145=>'ON', 9146=>'ON', 9147=>'ON', 9148=>'ON', 9149=>'ON', 9150=>'ON', 9151=>'ON', 9152=>'ON', 9153=>'ON', 9154=>'ON', 9155=>'ON', 9156=>'ON', 9157=>'ON', 9158=>'ON', 9159=>'ON', 9160=>'ON', 9161=>'ON', 9162=>'ON', 9163=>'ON', 9164=>'ON', 9165=>'ON', 9166=>'ON', 9167=>'ON', 9168=>'ON', 9169=>'ON', 9170=>'ON', 9171=>'ON', 9172=>'ON', 9173=>'ON', 9174=>'ON', 9175=>'ON', 9176=>'ON', 9177=>'ON', 9178=>'ON', 9179=>'ON', 9180=>'ON', 9181=>'ON', 9182=>'ON', 9183=>'ON', 9184=>'ON', 9185=>'ON', 9186=>'ON', 9187=>'ON', 9188=>'ON', 9189=>'ON', 9190=>'ON', 9191=>'ON', 9216=>'ON', 9217=>'ON', 9218=>'ON', 9219=>'ON', 9220=>'ON', 9221=>'ON', 9222=>'ON', 9223=>'ON', 9224=>'ON', 9225=>'ON', 9226=>'ON', 9227=>'ON', 9228=>'ON', 9229=>'ON', 9230=>'ON', 9231=>'ON', 9232=>'ON', 9233=>'ON', 9234=>'ON', 9235=>'ON', 9236=>'ON', 9237=>'ON', 9238=>'ON', 9239=>'ON', 9240=>'ON', 9241=>'ON', 9242=>'ON', 9243=>'ON', 9244=>'ON', 9245=>'ON', 9246=>'ON', 9247=>'ON', 9248=>'ON', 9249=>'ON', 9250=>'ON', 9251=>'ON', 9252=>'ON', 9253=>'ON', 9254=>'ON', 9280=>'ON', 9281=>'ON', 9282=>'ON', 9283=>'ON', 9284=>'ON', 9285=>'ON', 9286=>'ON', 9287=>'ON', 9288=>'ON', 9289=>'ON', 9290=>'ON', 9312=>'ON', 9313=>'ON', 9314=>'ON', 9315=>'ON', 9316=>'ON', 9317=>'ON', 9318=>'ON', 9319=>'ON', 9320=>'ON', 9321=>'ON', 9322=>'ON', 9323=>'ON', 9324=>'ON', 9325=>'ON', 9326=>'ON', 9327=>'ON', 9328=>'ON', 9329=>'ON', 9330=>'ON', 9331=>'ON', 9332=>'ON', 9333=>'ON', 9334=>'ON', 9335=>'ON', 9336=>'ON', 9337=>'ON', 9338=>'ON', 9339=>'ON', 9340=>'ON', 9341=>'ON', 9342=>'ON', 9343=>'ON', 9344=>'ON', 9345=>'ON', 9346=>'ON', 9347=>'ON', 9348=>'ON', 9349=>'ON', 9350=>'ON', 9351=>'ON', 9352=>'EN', 9353=>'EN', 9354=>'EN', 9355=>'EN', 9356=>'EN', 9357=>'EN', 9358=>'EN', 9359=>'EN', 9360=>'EN', 9361=>'EN', 9362=>'EN', 9363=>'EN', 9364=>'EN', 9365=>'EN', 9366=>'EN', 9367=>'EN', 9368=>'EN', 9369=>'EN', 9370=>'EN', 9371=>'EN', 9372=>'L', 9373=>'L', 9374=>'L', 9375=>'L', 9376=>'L', 9377=>'L', 9378=>'L', 9379=>'L', 9380=>'L', 9381=>'L', 9382=>'L', 9383=>'L', 9384=>'L', 9385=>'L', 9386=>'L', 9387=>'L', 9388=>'L', 9389=>'L', 9390=>'L', 9391=>'L', 9392=>'L', 9393=>'L', 9394=>'L', 9395=>'L', 9396=>'L', 9397=>'L', 9398=>'L', 9399=>'L', 9400=>'L', 9401=>'L', 9402=>'L', 9403=>'L', 9404=>'L', 9405=>'L', 9406=>'L', 9407=>'L', 9408=>'L', 9409=>'L', 9410=>'L', 9411=>'L', 9412=>'L', 9413=>'L', 9414=>'L', 9415=>'L', 9416=>'L', 9417=>'L', 9418=>'L', 9419=>'L', 9420=>'L', 9421=>'L', 9422=>'L', 9423=>'L', 9424=>'L', 9425=>'L', 9426=>'L', 9427=>'L', 9428=>'L', 9429=>'L', 9430=>'L', 9431=>'L', 9432=>'L', 9433=>'L', 9434=>'L', 9435=>'L', 9436=>'L', 9437=>'L', 9438=>'L', 9439=>'L', 9440=>'L', 9441=>'L', 9442=>'L', 9443=>'L', 9444=>'L', 9445=>'L', 9446=>'L', 9447=>'L', 9448=>'L', 9449=>'L', 9450=>'ON', 9451=>'ON', 9452=>'ON', 9453=>'ON', 9454=>'ON', 9455=>'ON', 9456=>'ON', 9457=>'ON', 9458=>'ON', 9459=>'ON', 9460=>'ON', 9461=>'ON', 9462=>'ON', 9463=>'ON', 9464=>'ON', 9465=>'ON', 9466=>'ON', 9467=>'ON', 9468=>'ON', 9469=>'ON', 9470=>'ON', 9471=>'ON', 9472=>'ON', 9473=>'ON', 9474=>'ON', 9475=>'ON', 9476=>'ON', 9477=>'ON', 9478=>'ON', 9479=>'ON', 9480=>'ON', 9481=>'ON', 9482=>'ON', 9483=>'ON', 9484=>'ON', 9485=>'ON', 9486=>'ON', 9487=>'ON', 9488=>'ON', 9489=>'ON', 9490=>'ON', 9491=>'ON', 9492=>'ON', 9493=>'ON', 9494=>'ON', 9495=>'ON', 9496=>'ON', 9497=>'ON', 9498=>'ON', 9499=>'ON', 9500=>'ON', 9501=>'ON', 9502=>'ON', 9503=>'ON', 9504=>'ON', 9505=>'ON', 9506=>'ON', 9507=>'ON', 9508=>'ON', 9509=>'ON', 9510=>'ON', 9511=>'ON', 9512=>'ON', 9513=>'ON', 9514=>'ON', 9515=>'ON', 9516=>'ON', 9517=>'ON', 9518=>'ON', 9519=>'ON', 9520=>'ON', 9521=>'ON', 9522=>'ON', 9523=>'ON', 9524=>'ON', 9525=>'ON', 9526=>'ON', 9527=>'ON', 9528=>'ON', 9529=>'ON', 9530=>'ON', 9531=>'ON', 9532=>'ON', 9533=>'ON', 9534=>'ON', 9535=>'ON', 9536=>'ON', 9537=>'ON', 9538=>'ON', 9539=>'ON', 9540=>'ON', 9541=>'ON', 9542=>'ON', 9543=>'ON', 9544=>'ON', 9545=>'ON', 9546=>'ON', 9547=>'ON', 9548=>'ON', 9549=>'ON', 9550=>'ON', 9551=>'ON', 9552=>'ON', 9553=>'ON', 9554=>'ON', 9555=>'ON', 9556=>'ON', 9557=>'ON', 9558=>'ON', 9559=>'ON', 9560=>'ON', 9561=>'ON', 9562=>'ON', 9563=>'ON', 9564=>'ON', 9565=>'ON', 9566=>'ON', 9567=>'ON', 9568=>'ON', 9569=>'ON', 9570=>'ON', 9571=>'ON', 9572=>'ON', 9573=>'ON', 9574=>'ON', 9575=>'ON', 9576=>'ON', 9577=>'ON', 9578=>'ON', 9579=>'ON', 9580=>'ON', 9581=>'ON', 9582=>'ON', 9583=>'ON', 9584=>'ON', 9585=>'ON', 9586=>'ON', 9587=>'ON', 9588=>'ON', 9589=>'ON', 9590=>'ON', 9591=>'ON', 9592=>'ON', 9593=>'ON', 9594=>'ON', 9595=>'ON', 9596=>'ON', 9597=>'ON', 9598=>'ON', 9599=>'ON', 9600=>'ON', 9601=>'ON', 9602=>'ON', 9603=>'ON', 9604=>'ON', 9605=>'ON', 9606=>'ON', 9607=>'ON', 9608=>'ON', 9609=>'ON', 9610=>'ON', 9611=>'ON', 9612=>'ON', 9613=>'ON', 9614=>'ON', 9615=>'ON', 9616=>'ON', 9617=>'ON', 9618=>'ON', 9619=>'ON', 9620=>'ON', 9621=>'ON', 9622=>'ON', 9623=>'ON', 9624=>'ON', 9625=>'ON', 9626=>'ON', 9627=>'ON', 9628=>'ON', 9629=>'ON', 9630=>'ON', 9631=>'ON', 9632=>'ON', 9633=>'ON', 9634=>'ON', 9635=>'ON', 9636=>'ON', 9637=>'ON', 9638=>'ON', 9639=>'ON', 9640=>'ON', 9641=>'ON', 9642=>'ON', 9643=>'ON', 9644=>'ON', 9645=>'ON', 9646=>'ON', 9647=>'ON', 9648=>'ON', 9649=>'ON', 9650=>'ON', 9651=>'ON', 9652=>'ON', 9653=>'ON', 9654=>'ON', 9655=>'ON', 9656=>'ON', 9657=>'ON', 9658=>'ON', 9659=>'ON', 9660=>'ON', 9661=>'ON', 9662=>'ON', 9663=>'ON', 9664=>'ON', 9665=>'ON', 9666=>'ON', 9667=>'ON', 9668=>'ON', 9669=>'ON', 9670=>'ON', 9671=>'ON', 9672=>'ON', 9673=>'ON', 9674=>'ON', 9675=>'ON', 9676=>'ON', 9677=>'ON', 9678=>'ON', 9679=>'ON', 9680=>'ON', 9681=>'ON', 9682=>'ON', 9683=>'ON', 9684=>'ON', 9685=>'ON', 9686=>'ON', 9687=>'ON', 9688=>'ON', 9689=>'ON', 9690=>'ON', 9691=>'ON', 9692=>'ON', 9693=>'ON', 9694=>'ON', 9695=>'ON', 9696=>'ON', 9697=>'ON', 9698=>'ON', 9699=>'ON', 9700=>'ON', 9701=>'ON', 9702=>'ON', 9703=>'ON', 9704=>'ON', 9705=>'ON', 9706=>'ON', 9707=>'ON', 9708=>'ON', 9709=>'ON', 9710=>'ON', 9711=>'ON', 9712=>'ON', 9713=>'ON', 9714=>'ON', 9715=>'ON', 9716=>'ON', 9717=>'ON', 9718=>'ON', 9719=>'ON', 9720=>'ON', 9721=>'ON', 9722=>'ON', 9723=>'ON', 9724=>'ON', 9725=>'ON', 9726=>'ON', 9727=>'ON', 9728=>'ON', 9729=>'ON', 9730=>'ON', 9731=>'ON', 9732=>'ON', 9733=>'ON', 9734=>'ON', 9735=>'ON', 9736=>'ON', 9737=>'ON', 9738=>'ON', 9739=>'ON', 9740=>'ON', 9741=>'ON', 9742=>'ON', 9743=>'ON', 9744=>'ON', 9745=>'ON', 9746=>'ON', 9747=>'ON', 9748=>'ON', 9749=>'ON', 9750=>'ON', 9751=>'ON', 9752=>'ON', 9753=>'ON', 9754=>'ON', 9755=>'ON', 9756=>'ON', 9757=>'ON', 9758=>'ON', 9759=>'ON', 9760=>'ON', 9761=>'ON', 9762=>'ON', 9763=>'ON', 9764=>'ON', 9765=>'ON', 9766=>'ON', 9767=>'ON', 9768=>'ON', 9769=>'ON', 9770=>'ON', 9771=>'ON', 9772=>'ON', 9773=>'ON', 9774=>'ON', 9775=>'ON', 9776=>'ON', 9777=>'ON', 9778=>'ON', 9779=>'ON', 9780=>'ON', 9781=>'ON', 9782=>'ON', 9783=>'ON', 9784=>'ON', 9785=>'ON', 9786=>'ON', 9787=>'ON', 9788=>'ON', 9789=>'ON', 9790=>'ON', 9791=>'ON', 9792=>'ON', 9793=>'ON', 9794=>'ON', 9795=>'ON', 9796=>'ON', 9797=>'ON', 9798=>'ON', 9799=>'ON', 9800=>'ON', 9801=>'ON', 9802=>'ON', 9803=>'ON', 9804=>'ON', 9805=>'ON', 9806=>'ON', 9807=>'ON', 9808=>'ON', 9809=>'ON', 9810=>'ON', 9811=>'ON', 9812=>'ON', 9813=>'ON', 9814=>'ON', 9815=>'ON', 9816=>'ON', 9817=>'ON', 9818=>'ON', 9819=>'ON', 9820=>'ON', 9821=>'ON', 9822=>'ON', 9823=>'ON', 9824=>'ON', 9825=>'ON', 9826=>'ON', 9827=>'ON', 9828=>'ON', 9829=>'ON', 9830=>'ON', 9831=>'ON', 9832=>'ON', 9833=>'ON', 9834=>'ON', 9835=>'ON', 9836=>'ON', 9837=>'ON', 9838=>'ON', 9839=>'ON', 9840=>'ON', 9841=>'ON', 9842=>'ON', 9843=>'ON', 9844=>'ON', 9845=>'ON', 9846=>'ON', 9847=>'ON', 9848=>'ON', 9849=>'ON', 9850=>'ON', 9851=>'ON', 9852=>'ON', 9853=>'ON', 9854=>'ON', 9855=>'ON', 9856=>'ON', 9857=>'ON', 9858=>'ON', 9859=>'ON', 9860=>'ON', 9861=>'ON', 9862=>'ON', 9863=>'ON', 9864=>'ON', 9865=>'ON', 9866=>'ON', 9867=>'ON', 9868=>'ON', 9869=>'ON', 9870=>'ON', 9871=>'ON', 9872=>'ON', 9873=>'ON', 9874=>'ON', 9875=>'ON', 9876=>'ON', 9877=>'ON', 9878=>'ON', 9879=>'ON', 9880=>'ON', 9881=>'ON', 9882=>'ON', 9883=>'ON', 9884=>'ON', 9888=>'ON', 9889=>'ON', 9890=>'ON', 9891=>'ON', 9892=>'ON', 9893=>'ON', 9894=>'ON', 9895=>'ON', 9896=>'ON', 9897=>'ON', 9898=>'ON', 9899=>'ON', 9900=>'L', 9901=>'ON', 9902=>'ON', 9903=>'ON', 9904=>'ON', 9905=>'ON', 9906=>'ON', 9985=>'ON', 9986=>'ON', 9987=>'ON', 9988=>'ON', 9990=>'ON', 9991=>'ON', 9992=>'ON', 9993=>'ON', 9996=>'ON', 9997=>'ON', 9998=>'ON', 9999=>'ON', 10000=>'ON', 10001=>'ON', 10002=>'ON', 10003=>'ON', 10004=>'ON', 10005=>'ON', 10006=>'ON', 10007=>'ON', 10008=>'ON', 10009=>'ON', 10010=>'ON', 10011=>'ON', 10012=>'ON', 10013=>'ON', 10014=>'ON', 10015=>'ON', 10016=>'ON', 10017=>'ON', 10018=>'ON', 10019=>'ON', 10020=>'ON', 10021=>'ON', 10022=>'ON', 10023=>'ON', 10025=>'ON', 10026=>'ON', 10027=>'ON', 10028=>'ON', 10029=>'ON', 10030=>'ON', 10031=>'ON', 10032=>'ON', 10033=>'ON', 10034=>'ON', 10035=>'ON', 10036=>'ON', 10037=>'ON', 10038=>'ON', 10039=>'ON', 10040=>'ON', 10041=>'ON', 10042=>'ON', 10043=>'ON', 10044=>'ON', 10045=>'ON', 10046=>'ON', 10047=>'ON', 10048=>'ON', 10049=>'ON', 10050=>'ON', 10051=>'ON', 10052=>'ON', 10053=>'ON', 10054=>'ON', 10055=>'ON', 10056=>'ON', 10057=>'ON', 10058=>'ON', 10059=>'ON', 10061=>'ON', 10063=>'ON', 10064=>'ON', 10065=>'ON', 10066=>'ON', 10070=>'ON', 10072=>'ON', 10073=>'ON', 10074=>'ON', 10075=>'ON', 10076=>'ON', 10077=>'ON', 10078=>'ON', 10081=>'ON', 10082=>'ON', 10083=>'ON', 10084=>'ON', 10085=>'ON', 10086=>'ON', 10087=>'ON', 10088=>'ON', 10089=>'ON', 10090=>'ON', 10091=>'ON', 10092=>'ON', 10093=>'ON', 10094=>'ON', 10095=>'ON', 10096=>'ON', 10097=>'ON', 10098=>'ON', 10099=>'ON', 10100=>'ON', 10101=>'ON', 10102=>'ON', 10103=>'ON', 10104=>'ON', 10105=>'ON', 10106=>'ON', 10107=>'ON', 10108=>'ON', 10109=>'ON', 10110=>'ON', 10111=>'ON', 10112=>'ON', 10113=>'ON', 10114=>'ON', 10115=>'ON', 10116=>'ON', 10117=>'ON', 10118=>'ON', 10119=>'ON', 10120=>'ON', 10121=>'ON', 10122=>'ON', 10123=>'ON', 10124=>'ON', 10125=>'ON', 10126=>'ON', 10127=>'ON', 10128=>'ON', 10129=>'ON', 10130=>'ON', 10131=>'ON', 10132=>'ON', 10136=>'ON', 10137=>'ON', 10138=>'ON', 10139=>'ON', 10140=>'ON', 10141=>'ON', 10142=>'ON', 10143=>'ON', 10144=>'ON', 10145=>'ON', 10146=>'ON', 10147=>'ON', 10148=>'ON', 10149=>'ON', 10150=>'ON', 10151=>'ON', 10152=>'ON', 10153=>'ON', 10154=>'ON', 10155=>'ON', 10156=>'ON', 10157=>'ON', 10158=>'ON', 10159=>'ON', 10161=>'ON', 10162=>'ON', 10163=>'ON', 10164=>'ON', 10165=>'ON', 10166=>'ON', 10167=>'ON', 10168=>'ON', 10169=>'ON', 10170=>'ON', 10171=>'ON', 10172=>'ON', 10173=>'ON', 10174=>'ON', 10176=>'ON', 10177=>'ON', 10178=>'ON', 10179=>'ON', 10180=>'ON', 10181=>'ON', 10182=>'ON', 10183=>'ON', 10184=>'ON', 10185=>'ON', 10186=>'ON', 10192=>'ON', 10193=>'ON', 10194=>'ON', 10195=>'ON', 10196=>'ON', 10197=>'ON', 10198=>'ON', 10199=>'ON', 10200=>'ON', 10201=>'ON', 10202=>'ON', 10203=>'ON', 10204=>'ON', 10205=>'ON', 10206=>'ON', 10207=>'ON', 10208=>'ON', 10209=>'ON', 10210=>'ON', 10211=>'ON', 10212=>'ON', 10213=>'ON', 10214=>'ON', 10215=>'ON', 10216=>'ON', 10217=>'ON', 10218=>'ON', 10219=>'ON', 10224=>'ON', 10225=>'ON', 10226=>'ON', 10227=>'ON', 10228=>'ON', 10229=>'ON', 10230=>'ON', 10231=>'ON', 10232=>'ON', 10233=>'ON', 10234=>'ON', 10235=>'ON', 10236=>'ON', 10237=>'ON', 10238=>'ON', 10239=>'ON', 10240=>'L', 10241=>'L', 10242=>'L', 10243=>'L', 10244=>'L', 10245=>'L', 10246=>'L', 10247=>'L', 10248=>'L', 10249=>'L', 10250=>'L', 10251=>'L', 10252=>'L', 10253=>'L', 10254=>'L', 10255=>'L', 10256=>'L', 10257=>'L', 10258=>'L', 10259=>'L', 10260=>'L', 10261=>'L', 10262=>'L', 10263=>'L', 10264=>'L', 10265=>'L', 10266=>'L', 10267=>'L', 10268=>'L', 10269=>'L', 10270=>'L', 10271=>'L', 10272=>'L', 10273=>'L', 10274=>'L', 10275=>'L', 10276=>'L', 10277=>'L', 10278=>'L', 10279=>'L', 10280=>'L', 10281=>'L', 10282=>'L', 10283=>'L', 10284=>'L', 10285=>'L', 10286=>'L', 10287=>'L', 10288=>'L', 10289=>'L', 10290=>'L', 10291=>'L', 10292=>'L', 10293=>'L', 10294=>'L', 10295=>'L', 10296=>'L', 10297=>'L', 10298=>'L', 10299=>'L', 10300=>'L', 10301=>'L', 10302=>'L', 10303=>'L', 10304=>'L', 10305=>'L', 10306=>'L', 10307=>'L', 10308=>'L', 10309=>'L', 10310=>'L', 10311=>'L', 10312=>'L', 10313=>'L', 10314=>'L', 10315=>'L', 10316=>'L', 10317=>'L', 10318=>'L', 10319=>'L', 10320=>'L', 10321=>'L', 10322=>'L', 10323=>'L', 10324=>'L', 10325=>'L', 10326=>'L', 10327=>'L', 10328=>'L', 10329=>'L', 10330=>'L', 10331=>'L', 10332=>'L', 10333=>'L', 10334=>'L', 10335=>'L', 10336=>'L', 10337=>'L', 10338=>'L', 10339=>'L', 10340=>'L', 10341=>'L', 10342=>'L', 10343=>'L', 10344=>'L', 10345=>'L', 10346=>'L', 10347=>'L', 10348=>'L', 10349=>'L', 10350=>'L', 10351=>'L', 10352=>'L', 10353=>'L', 10354=>'L', 10355=>'L', 10356=>'L', 10357=>'L', 10358=>'L', 10359=>'L', 10360=>'L', 10361=>'L', 10362=>'L', 10363=>'L', 10364=>'L', 10365=>'L', 10366=>'L', 10367=>'L', 10368=>'L', 10369=>'L', 10370=>'L', 10371=>'L', 10372=>'L', 10373=>'L', 10374=>'L', 10375=>'L', 10376=>'L', 10377=>'L', 10378=>'L', 10379=>'L', 10380=>'L', 10381=>'L', 10382=>'L', 10383=>'L', 10384=>'L', 10385=>'L', 10386=>'L', 10387=>'L', 10388=>'L', 10389=>'L', 10390=>'L', 10391=>'L', 10392=>'L', 10393=>'L', 10394=>'L', 10395=>'L', 10396=>'L', 10397=>'L', 10398=>'L', 10399=>'L', 10400=>'L', 10401=>'L', 10402=>'L', 10403=>'L', 10404=>'L', 10405=>'L', 10406=>'L', 10407=>'L', 10408=>'L', 10409=>'L', 10410=>'L', 10411=>'L', 10412=>'L', 10413=>'L', 10414=>'L', 10415=>'L', 10416=>'L', 10417=>'L', 10418=>'L', 10419=>'L', 10420=>'L', 10421=>'L', 10422=>'L', 10423=>'L', 10424=>'L', 10425=>'L', 10426=>'L', 10427=>'L', 10428=>'L', 10429=>'L', 10430=>'L', 10431=>'L', 10432=>'L', 10433=>'L', 10434=>'L', 10435=>'L', 10436=>'L', 10437=>'L', 10438=>'L', 10439=>'L', 10440=>'L', 10441=>'L', 10442=>'L', 10443=>'L', 10444=>'L', 10445=>'L', 10446=>'L', 10447=>'L', 10448=>'L', 10449=>'L', 10450=>'L', 10451=>'L', 10452=>'L', 10453=>'L', 10454=>'L', 10455=>'L', 10456=>'L', 10457=>'L', 10458=>'L', 10459=>'L', 10460=>'L', 10461=>'L', 10462=>'L', 10463=>'L', 10464=>'L', 10465=>'L', 10466=>'L', 10467=>'L', 10468=>'L', 10469=>'L', 10470=>'L', 10471=>'L', 10472=>'L', 10473=>'L', 10474=>'L', 10475=>'L', 10476=>'L', 10477=>'L', 10478=>'L', 10479=>'L', 10480=>'L', 10481=>'L', 10482=>'L', 10483=>'L', 10484=>'L', 10485=>'L', 10486=>'L', 10487=>'L', 10488=>'L', 10489=>'L', 10490=>'L', 10491=>'L', 10492=>'L', 10493=>'L', 10494=>'L', 10495=>'L', 10496=>'ON', 10497=>'ON', 10498=>'ON', 10499=>'ON', 10500=>'ON', 10501=>'ON', 10502=>'ON', 10503=>'ON', 10504=>'ON', 10505=>'ON', 10506=>'ON', 10507=>'ON', 10508=>'ON', 10509=>'ON', 10510=>'ON', 10511=>'ON', 10512=>'ON', 10513=>'ON', 10514=>'ON', 10515=>'ON', 10516=>'ON', 10517=>'ON', 10518=>'ON', 10519=>'ON', 10520=>'ON', 10521=>'ON', 10522=>'ON', 10523=>'ON', 10524=>'ON', 10525=>'ON', 10526=>'ON', 10527=>'ON', 10528=>'ON', 10529=>'ON', 10530=>'ON', 10531=>'ON', 10532=>'ON', 10533=>'ON', 10534=>'ON', 10535=>'ON', 10536=>'ON', 10537=>'ON', 10538=>'ON', 10539=>'ON', 10540=>'ON', 10541=>'ON', 10542=>'ON', 10543=>'ON', 10544=>'ON', 10545=>'ON', 10546=>'ON', 10547=>'ON', 10548=>'ON', 10549=>'ON', 10550=>'ON', 10551=>'ON', 10552=>'ON', 10553=>'ON', 10554=>'ON', 10555=>'ON', 10556=>'ON', 10557=>'ON', 10558=>'ON', 10559=>'ON', 10560=>'ON', 10561=>'ON', 10562=>'ON', 10563=>'ON', 10564=>'ON', 10565=>'ON', 10566=>'ON', 10567=>'ON', 10568=>'ON', 10569=>'ON', 10570=>'ON', 10571=>'ON', 10572=>'ON', 10573=>'ON', 10574=>'ON', 10575=>'ON', 10576=>'ON', 10577=>'ON', 10578=>'ON', 10579=>'ON', 10580=>'ON', 10581=>'ON', 10582=>'ON', 10583=>'ON', 10584=>'ON', 10585=>'ON', 10586=>'ON', 10587=>'ON', 10588=>'ON', 10589=>'ON', 10590=>'ON', 10591=>'ON', 10592=>'ON', 10593=>'ON', 10594=>'ON', 10595=>'ON', 10596=>'ON', 10597=>'ON', 10598=>'ON', 10599=>'ON', 10600=>'ON', 10601=>'ON', 10602=>'ON', 10603=>'ON', 10604=>'ON', 10605=>'ON', 10606=>'ON', 10607=>'ON', 10608=>'ON', 10609=>'ON', 10610=>'ON', 10611=>'ON', 10612=>'ON', 10613=>'ON', 10614=>'ON', 10615=>'ON', 10616=>'ON', 10617=>'ON', 10618=>'ON', 10619=>'ON', 10620=>'ON', 10621=>'ON', 10622=>'ON', 10623=>'ON', 10624=>'ON', 10625=>'ON', 10626=>'ON', 10627=>'ON', 10628=>'ON', 10629=>'ON', 10630=>'ON', 10631=>'ON', 10632=>'ON', 10633=>'ON', 10634=>'ON', 10635=>'ON', 10636=>'ON', 10637=>'ON', 10638=>'ON', 10639=>'ON', 10640=>'ON', 10641=>'ON', 10642=>'ON', 10643=>'ON', 10644=>'ON', 10645=>'ON', 10646=>'ON', 10647=>'ON', 10648=>'ON', 10649=>'ON', 10650=>'ON', 10651=>'ON', 10652=>'ON', 10653=>'ON', 10654=>'ON', 10655=>'ON', 10656=>'ON', 10657=>'ON', 10658=>'ON', 10659=>'ON', 10660=>'ON', 10661=>'ON', 10662=>'ON', 10663=>'ON', 10664=>'ON', 10665=>'ON', 10666=>'ON', 10667=>'ON', 10668=>'ON', 10669=>'ON', 10670=>'ON', 10671=>'ON', 10672=>'ON', 10673=>'ON', 10674=>'ON', 10675=>'ON', 10676=>'ON', 10677=>'ON', 10678=>'ON', 10679=>'ON', 10680=>'ON', 10681=>'ON', 10682=>'ON', 10683=>'ON', 10684=>'ON', 10685=>'ON', 10686=>'ON', 10687=>'ON', 10688=>'ON', 10689=>'ON', 10690=>'ON', 10691=>'ON', 10692=>'ON', 10693=>'ON', 10694=>'ON', 10695=>'ON', 10696=>'ON', 10697=>'ON', 10698=>'ON', 10699=>'ON', 10700=>'ON', 10701=>'ON', 10702=>'ON', 10703=>'ON', 10704=>'ON', 10705=>'ON', 10706=>'ON', 10707=>'ON', 10708=>'ON', 10709=>'ON', 10710=>'ON', 10711=>'ON', 10712=>'ON', 10713=>'ON', 10714=>'ON', 10715=>'ON', 10716=>'ON', 10717=>'ON', 10718=>'ON', 10719=>'ON', 10720=>'ON', 10721=>'ON', 10722=>'ON', 10723=>'ON', 10724=>'ON', 10725=>'ON', 10726=>'ON', 10727=>'ON', 10728=>'ON', 10729=>'ON', 10730=>'ON', 10731=>'ON', 10732=>'ON', 10733=>'ON', 10734=>'ON', 10735=>'ON', 10736=>'ON', 10737=>'ON', 10738=>'ON', 10739=>'ON', 10740=>'ON', 10741=>'ON', 10742=>'ON', 10743=>'ON', 10744=>'ON', 10745=>'ON', 10746=>'ON', 10747=>'ON', 10748=>'ON', 10749=>'ON', 10750=>'ON', 10751=>'ON', 10752=>'ON', 10753=>'ON', 10754=>'ON', 10755=>'ON', 10756=>'ON', 10757=>'ON', 10758=>'ON', 10759=>'ON', 10760=>'ON', 10761=>'ON', 10762=>'ON', 10763=>'ON', 10764=>'ON', 10765=>'ON', 10766=>'ON', 10767=>'ON', 10768=>'ON', 10769=>'ON', 10770=>'ON', 10771=>'ON', 10772=>'ON', 10773=>'ON', 10774=>'ON', 10775=>'ON', 10776=>'ON', 10777=>'ON', 10778=>'ON', 10779=>'ON', 10780=>'ON', 10781=>'ON', 10782=>'ON', 10783=>'ON', 10784=>'ON', 10785=>'ON', 10786=>'ON', 10787=>'ON', 10788=>'ON', 10789=>'ON', 10790=>'ON', 10791=>'ON', 10792=>'ON', 10793=>'ON', 10794=>'ON', 10795=>'ON', 10796=>'ON', 10797=>'ON', 10798=>'ON', 10799=>'ON', 10800=>'ON', 10801=>'ON', 10802=>'ON', 10803=>'ON', 10804=>'ON', 10805=>'ON', 10806=>'ON', 10807=>'ON', 10808=>'ON', 10809=>'ON', 10810=>'ON', 10811=>'ON', 10812=>'ON', 10813=>'ON', 10814=>'ON', 10815=>'ON', 10816=>'ON', 10817=>'ON', 10818=>'ON', 10819=>'ON', 10820=>'ON', 10821=>'ON', 10822=>'ON', 10823=>'ON', 10824=>'ON', 10825=>'ON', 10826=>'ON', 10827=>'ON', 10828=>'ON', 10829=>'ON', 10830=>'ON', 10831=>'ON', 10832=>'ON', 10833=>'ON', 10834=>'ON', 10835=>'ON', 10836=>'ON', 10837=>'ON', 10838=>'ON', 10839=>'ON', 10840=>'ON', 10841=>'ON', 10842=>'ON', 10843=>'ON', 10844=>'ON', 10845=>'ON', 10846=>'ON', 10847=>'ON', 10848=>'ON', 10849=>'ON', 10850=>'ON', 10851=>'ON', 10852=>'ON', 10853=>'ON', 10854=>'ON', 10855=>'ON', 10856=>'ON', 10857=>'ON', 10858=>'ON', 10859=>'ON', 10860=>'ON', 10861=>'ON', 10862=>'ON', 10863=>'ON', 10864=>'ON', 10865=>'ON', 10866=>'ON', 10867=>'ON', 10868=>'ON', 10869=>'ON', 10870=>'ON', 10871=>'ON', 10872=>'ON', 10873=>'ON', 10874=>'ON', 10875=>'ON', 10876=>'ON', 10877=>'ON', 10878=>'ON', 10879=>'ON', 10880=>'ON', 10881=>'ON', 10882=>'ON', 10883=>'ON', 10884=>'ON', 10885=>'ON', 10886=>'ON', 10887=>'ON', 10888=>'ON', 10889=>'ON', 10890=>'ON', 10891=>'ON', 10892=>'ON', 10893=>'ON', 10894=>'ON', 10895=>'ON', 10896=>'ON', 10897=>'ON', 10898=>'ON', 10899=>'ON', 10900=>'ON', 10901=>'ON', 10902=>'ON', 10903=>'ON', 10904=>'ON', 10905=>'ON', 10906=>'ON', 10907=>'ON', 10908=>'ON', 10909=>'ON', 10910=>'ON', 10911=>'ON', 10912=>'ON', 10913=>'ON', 10914=>'ON', 10915=>'ON', 10916=>'ON', 10917=>'ON', 10918=>'ON', 10919=>'ON', 10920=>'ON', 10921=>'ON', 10922=>'ON', 10923=>'ON', 10924=>'ON', 10925=>'ON', 10926=>'ON', 10927=>'ON', 10928=>'ON', 10929=>'ON', 10930=>'ON', 10931=>'ON', 10932=>'ON', 10933=>'ON', 10934=>'ON', 10935=>'ON', 10936=>'ON', 10937=>'ON', 10938=>'ON', 10939=>'ON', 10940=>'ON', 10941=>'ON', 10942=>'ON', 10943=>'ON', 10944=>'ON', 10945=>'ON', 10946=>'ON', 10947=>'ON', 10948=>'ON', 10949=>'ON', 10950=>'ON', 10951=>'ON', 10952=>'ON', 10953=>'ON', 10954=>'ON', 10955=>'ON', 10956=>'ON', 10957=>'ON', 10958=>'ON', 10959=>'ON', 10960=>'ON', 10961=>'ON', 10962=>'ON', 10963=>'ON', 10964=>'ON', 10965=>'ON', 10966=>'ON', 10967=>'ON', 10968=>'ON', 10969=>'ON', 10970=>'ON', 10971=>'ON', 10972=>'ON', 10973=>'ON', 10974=>'ON', 10975=>'ON', 10976=>'ON', 10977=>'ON', 10978=>'ON', 10979=>'ON', 10980=>'ON', 10981=>'ON', 10982=>'ON', 10983=>'ON', 10984=>'ON', 10985=>'ON', 10986=>'ON', 10987=>'ON', 10988=>'ON', 10989=>'ON', 10990=>'ON', 10991=>'ON', 10992=>'ON', 10993=>'ON', 10994=>'ON', 10995=>'ON', 10996=>'ON', 10997=>'ON', 10998=>'ON', 10999=>'ON', 11000=>'ON', 11001=>'ON', 11002=>'ON', 11003=>'ON', 11004=>'ON', 11005=>'ON', 11006=>'ON', 11007=>'ON', 11008=>'ON', 11009=>'ON', 11010=>'ON', 11011=>'ON', 11012=>'ON', 11013=>'ON', 11014=>'ON', 11015=>'ON', 11016=>'ON', 11017=>'ON', 11018=>'ON', 11019=>'ON', 11020=>'ON', 11021=>'ON', 11022=>'ON', 11023=>'ON', 11024=>'ON', 11025=>'ON', 11026=>'ON', 11027=>'ON', 11028=>'ON', 11029=>'ON', 11030=>'ON', 11031=>'ON', 11032=>'ON', 11033=>'ON', 11034=>'ON', 11040=>'ON', 11041=>'ON', 11042=>'ON', 11043=>'ON', 11264=>'L', 11265=>'L', 11266=>'L', 11267=>'L', 11268=>'L', 11269=>'L', 11270=>'L', 11271=>'L', 11272=>'L', 11273=>'L', 11274=>'L', 11275=>'L', 11276=>'L', 11277=>'L', 11278=>'L', 11279=>'L', 11280=>'L', 11281=>'L', 11282=>'L', 11283=>'L', 11284=>'L', 11285=>'L', 11286=>'L', 11287=>'L', 11288=>'L', 11289=>'L', 11290=>'L', 11291=>'L', 11292=>'L', 11293=>'L', 11294=>'L', 11295=>'L', 11296=>'L', 11297=>'L', 11298=>'L', 11299=>'L', 11300=>'L', 11301=>'L', 11302=>'L', 11303=>'L', 11304=>'L', 11305=>'L', 11306=>'L', 11307=>'L', 11308=>'L', 11309=>'L', 11310=>'L', 11312=>'L', 11313=>'L', 11314=>'L', 11315=>'L', 11316=>'L', 11317=>'L', 11318=>'L', 11319=>'L', 11320=>'L', 11321=>'L', 11322=>'L', 11323=>'L', 11324=>'L', 11325=>'L', 11326=>'L', 11327=>'L', 11328=>'L', 11329=>'L', 11330=>'L', 11331=>'L', 11332=>'L', 11333=>'L', 11334=>'L', 11335=>'L', 11336=>'L', 11337=>'L', 11338=>'L', 11339=>'L', 11340=>'L', 11341=>'L', 11342=>'L', 11343=>'L', 11344=>'L', 11345=>'L', 11346=>'L', 11347=>'L', 11348=>'L', 11349=>'L', 11350=>'L', 11351=>'L', 11352=>'L', 11353=>'L', 11354=>'L', 11355=>'L', 11356=>'L', 11357=>'L', 11358=>'L', 11360=>'L', 11361=>'L', 11362=>'L', 11363=>'L', 11364=>'L', 11365=>'L', 11366=>'L', 11367=>'L', 11368=>'L', 11369=>'L', 11370=>'L', 11371=>'L', 11372=>'L', 11380=>'L', 11381=>'L', 11382=>'L', 11383=>'L', 11392=>'L', 11393=>'L', 11394=>'L', 11395=>'L', 11396=>'L', 11397=>'L', 11398=>'L', 11399=>'L', 11400=>'L', 11401=>'L', 11402=>'L', 11403=>'L', 11404=>'L', 11405=>'L', 11406=>'L', 11407=>'L', 11408=>'L', 11409=>'L', 11410=>'L', 11411=>'L', 11412=>'L', 11413=>'L', 11414=>'L', 11415=>'L', 11416=>'L', 11417=>'L', 11418=>'L', 11419=>'L', 11420=>'L', 11421=>'L', 11422=>'L', 11423=>'L', 11424=>'L', 11425=>'L', 11426=>'L', 11427=>'L', 11428=>'L', 11429=>'L', 11430=>'L', 11431=>'L', 11432=>'L', 11433=>'L', 11434=>'L', 11435=>'L', 11436=>'L', 11437=>'L', 11438=>'L', 11439=>'L', 11440=>'L', 11441=>'L', 11442=>'L', 11443=>'L', 11444=>'L', 11445=>'L', 11446=>'L', 11447=>'L', 11448=>'L', 11449=>'L', 11450=>'L', 11451=>'L', 11452=>'L', 11453=>'L', 11454=>'L', 11455=>'L', 11456=>'L', 11457=>'L', 11458=>'L', 11459=>'L', 11460=>'L', 11461=>'L', 11462=>'L', 11463=>'L', 11464=>'L', 11465=>'L', 11466=>'L', 11467=>'L', 11468=>'L', 11469=>'L', 11470=>'L', 11471=>'L', 11472=>'L', 11473=>'L', 11474=>'L', 11475=>'L', 11476=>'L', 11477=>'L', 11478=>'L', 11479=>'L', 11480=>'L', 11481=>'L', 11482=>'L', 11483=>'L', 11484=>'L', 11485=>'L', 11486=>'L', 11487=>'L', 11488=>'L', 11489=>'L', 11490=>'L', 11491=>'L', 11492=>'L', 11493=>'ON', 11494=>'ON', 11495=>'ON', 11496=>'ON', 11497=>'ON', 11498=>'ON', 11513=>'ON', 11514=>'ON', 11515=>'ON', 11516=>'ON', 11517=>'ON', 11518=>'ON', 11519=>'ON', 11520=>'L', 11521=>'L', 11522=>'L', 11523=>'L', 11524=>'L', 11525=>'L', 11526=>'L', 11527=>'L', 11528=>'L', 11529=>'L', 11530=>'L', 11531=>'L', 11532=>'L', 11533=>'L', 11534=>'L', 11535=>'L', 11536=>'L', 11537=>'L', 11538=>'L', 11539=>'L', 11540=>'L', 11541=>'L', 11542=>'L', 11543=>'L', 11544=>'L', 11545=>'L', 11546=>'L', 11547=>'L', 11548=>'L', 11549=>'L', 11550=>'L', 11551=>'L', 11552=>'L', 11553=>'L', 11554=>'L', 11555=>'L', 11556=>'L', 11557=>'L', 11568=>'L', 11569=>'L', 11570=>'L', 11571=>'L', 11572=>'L', 11573=>'L', 11574=>'L', 11575=>'L', 11576=>'L', 11577=>'L', 11578=>'L', 11579=>'L', 11580=>'L', 11581=>'L', 11582=>'L', 11583=>'L', 11584=>'L', 11585=>'L', 11586=>'L', 11587=>'L', 11588=>'L', 11589=>'L', 11590=>'L', 11591=>'L', 11592=>'L', 11593=>'L', 11594=>'L', 11595=>'L', 11596=>'L', 11597=>'L', 11598=>'L', 11599=>'L', 11600=>'L', 11601=>'L', 11602=>'L', 11603=>'L', 11604=>'L', 11605=>'L', 11606=>'L', 11607=>'L', 11608=>'L', 11609=>'L', 11610=>'L', 11611=>'L', 11612=>'L', 11613=>'L', 11614=>'L', 11615=>'L', 11616=>'L', 11617=>'L', 11618=>'L', 11619=>'L', 11620=>'L', 11621=>'L', 11631=>'L', 11648=>'L', 11649=>'L', 11650=>'L', 11651=>'L', 11652=>'L', 11653=>'L', 11654=>'L', 11655=>'L', 11656=>'L', 11657=>'L', 11658=>'L', 11659=>'L', 11660=>'L', 11661=>'L', 11662=>'L', 11663=>'L', 11664=>'L', 11665=>'L', 11666=>'L', 11667=>'L', 11668=>'L', 11669=>'L', 11670=>'L', 11680=>'L', 11681=>'L', 11682=>'L', 11683=>'L', 11684=>'L', 11685=>'L', 11686=>'L', 11688=>'L', 11689=>'L', 11690=>'L', 11691=>'L', 11692=>'L', 11693=>'L', 11694=>'L', 11696=>'L', 11697=>'L', 11698=>'L', 11699=>'L', 11700=>'L', 11701=>'L', 11702=>'L', 11704=>'L', 11705=>'L', 11706=>'L', 11707=>'L', 11708=>'L', 11709=>'L', 11710=>'L', 11712=>'L', 11713=>'L', 11714=>'L', 11715=>'L', 11716=>'L', 11717=>'L', 11718=>'L', 11720=>'L', 11721=>'L', 11722=>'L', 11723=>'L', 11724=>'L', 11725=>'L', 11726=>'L', 11728=>'L', 11729=>'L', 11730=>'L', 11731=>'L', 11732=>'L', 11733=>'L', 11734=>'L', 11736=>'L', 11737=>'L', 11738=>'L', 11739=>'L', 11740=>'L', 11741=>'L', 11742=>'L', 11776=>'ON', 11777=>'ON', 11778=>'ON', 11779=>'ON', 11780=>'ON', 11781=>'ON', 11782=>'ON', 11783=>'ON', 11784=>'ON', 11785=>'ON', 11786=>'ON', 11787=>'ON', 11788=>'ON', 11789=>'ON', 11790=>'ON', 11791=>'ON', 11792=>'ON', 11793=>'ON', 11794=>'ON', 11795=>'ON', 11796=>'ON', 11797=>'ON', 11798=>'ON', 11799=>'ON', 11804=>'ON', 11805=>'ON', 11904=>'ON', 11905=>'ON', 11906=>'ON', 11907=>'ON', 11908=>'ON', 11909=>'ON', 11910=>'ON', 11911=>'ON', 11912=>'ON', 11913=>'ON', 11914=>'ON', 11915=>'ON', 11916=>'ON', 11917=>'ON', 11918=>'ON', 11919=>'ON', 11920=>'ON', 11921=>'ON', 11922=>'ON', 11923=>'ON', 11924=>'ON', 11925=>'ON', 11926=>'ON', 11927=>'ON', 11928=>'ON', 11929=>'ON', 11931=>'ON', 11932=>'ON', 11933=>'ON', 11934=>'ON', 11935=>'ON', 11936=>'ON', 11937=>'ON', 11938=>'ON', 11939=>'ON', 11940=>'ON', 11941=>'ON', 11942=>'ON', 11943=>'ON', 11944=>'ON', 11945=>'ON', 11946=>'ON', 11947=>'ON', 11948=>'ON', 11949=>'ON', 11950=>'ON', 11951=>'ON', 11952=>'ON', 11953=>'ON', 11954=>'ON', 11955=>'ON', 11956=>'ON', 11957=>'ON', 11958=>'ON', 11959=>'ON', 11960=>'ON', 11961=>'ON', 11962=>'ON', 11963=>'ON', 11964=>'ON', 11965=>'ON', 11966=>'ON', 11967=>'ON', 11968=>'ON', 11969=>'ON', 11970=>'ON', 11971=>'ON', 11972=>'ON', 11973=>'ON', 11974=>'ON', 11975=>'ON', 11976=>'ON', 11977=>'ON', 11978=>'ON', 11979=>'ON', 11980=>'ON', 11981=>'ON', 11982=>'ON', 11983=>'ON', 11984=>'ON', 11985=>'ON', 11986=>'ON', 11987=>'ON', 11988=>'ON', 11989=>'ON', 11990=>'ON', 11991=>'ON', 11992=>'ON', 11993=>'ON', 11994=>'ON', 11995=>'ON', 11996=>'ON', 11997=>'ON', 11998=>'ON', 11999=>'ON', 12000=>'ON', 12001=>'ON', 12002=>'ON', 12003=>'ON', 12004=>'ON', 12005=>'ON', 12006=>'ON', 12007=>'ON', 12008=>'ON', 12009=>'ON', 12010=>'ON', 12011=>'ON', 12012=>'ON', 12013=>'ON', 12014=>'ON', 12015=>'ON', 12016=>'ON', 12017=>'ON', 12018=>'ON', 12019=>'ON', 12032=>'ON', 12033=>'ON', 12034=>'ON', 12035=>'ON', 12036=>'ON', 12037=>'ON', 12038=>'ON', 12039=>'ON', 12040=>'ON', 12041=>'ON', 12042=>'ON', 12043=>'ON', 12044=>'ON', 12045=>'ON', 12046=>'ON', 12047=>'ON', 12048=>'ON', 12049=>'ON', 12050=>'ON', 12051=>'ON', 12052=>'ON', 12053=>'ON', 12054=>'ON', 12055=>'ON', 12056=>'ON', 12057=>'ON', 12058=>'ON', 12059=>'ON', 12060=>'ON', 12061=>'ON', 12062=>'ON', 12063=>'ON', 12064=>'ON', 12065=>'ON', 12066=>'ON', 12067=>'ON', 12068=>'ON', 12069=>'ON', 12070=>'ON', 12071=>'ON', 12072=>'ON', 12073=>'ON', 12074=>'ON', 12075=>'ON', 12076=>'ON', 12077=>'ON', 12078=>'ON', 12079=>'ON', 12080=>'ON', 12081=>'ON', 12082=>'ON', 12083=>'ON', 12084=>'ON', 12085=>'ON', 12086=>'ON', 12087=>'ON', 12088=>'ON', 12089=>'ON', 12090=>'ON', 12091=>'ON', 12092=>'ON', 12093=>'ON', 12094=>'ON', 12095=>'ON', 12096=>'ON', 12097=>'ON', 12098=>'ON', 12099=>'ON', 12100=>'ON', 12101=>'ON', 12102=>'ON', 12103=>'ON', 12104=>'ON', 12105=>'ON', 12106=>'ON', 12107=>'ON', 12108=>'ON', 12109=>'ON', 12110=>'ON', 12111=>'ON', 12112=>'ON', 12113=>'ON', 12114=>'ON', 12115=>'ON', 12116=>'ON', 12117=>'ON', 12118=>'ON', 12119=>'ON', 12120=>'ON', 12121=>'ON', 12122=>'ON', 12123=>'ON', 12124=>'ON', 12125=>'ON', 12126=>'ON', 12127=>'ON', 12128=>'ON', 12129=>'ON', 12130=>'ON', 12131=>'ON', 12132=>'ON', 12133=>'ON', 12134=>'ON', 12135=>'ON', 12136=>'ON', 12137=>'ON', 12138=>'ON', 12139=>'ON', 12140=>'ON', 12141=>'ON', 12142=>'ON', 12143=>'ON', 12144=>'ON', 12145=>'ON', 12146=>'ON', 12147=>'ON', 12148=>'ON', 12149=>'ON', 12150=>'ON', 12151=>'ON', 12152=>'ON', 12153=>'ON', 12154=>'ON', 12155=>'ON', 12156=>'ON', 12157=>'ON', 12158=>'ON', 12159=>'ON', 12160=>'ON', 12161=>'ON', 12162=>'ON', 12163=>'ON', 12164=>'ON', 12165=>'ON', 12166=>'ON', 12167=>'ON', 12168=>'ON', 12169=>'ON', 12170=>'ON', 12171=>'ON', 12172=>'ON', 12173=>'ON', 12174=>'ON', 12175=>'ON', 12176=>'ON', 12177=>'ON', 12178=>'ON', 12179=>'ON', 12180=>'ON', 12181=>'ON', 12182=>'ON', 12183=>'ON', 12184=>'ON', 12185=>'ON', 12186=>'ON', 12187=>'ON', 12188=>'ON', 12189=>'ON', 12190=>'ON', 12191=>'ON', 12192=>'ON', 12193=>'ON', 12194=>'ON', 12195=>'ON', 12196=>'ON', 12197=>'ON', 12198=>'ON', 12199=>'ON', 12200=>'ON', 12201=>'ON', 12202=>'ON', 12203=>'ON', 12204=>'ON', 12205=>'ON', 12206=>'ON', 12207=>'ON', 12208=>'ON', 12209=>'ON', 12210=>'ON', 12211=>'ON', 12212=>'ON', 12213=>'ON', 12214=>'ON', 12215=>'ON', 12216=>'ON', 12217=>'ON', 12218=>'ON', 12219=>'ON', 12220=>'ON', 12221=>'ON', 12222=>'ON', 12223=>'ON', 12224=>'ON', 12225=>'ON', 12226=>'ON', 12227=>'ON', 12228=>'ON', 12229=>'ON', 12230=>'ON', 12231=>'ON', 12232=>'ON', 12233=>'ON', 12234=>'ON', 12235=>'ON', 12236=>'ON', 12237=>'ON', 12238=>'ON', 12239=>'ON', 12240=>'ON', 12241=>'ON', 12242=>'ON', 12243=>'ON', 12244=>'ON', 12245=>'ON', 12272=>'ON', 12273=>'ON', 12274=>'ON', 12275=>'ON', 12276=>'ON', 12277=>'ON', 12278=>'ON', 12279=>'ON', 12280=>'ON', 12281=>'ON', 12282=>'ON', 12283=>'ON', 12288=>'WS', 12289=>'ON', 12290=>'ON', 12291=>'ON', 12292=>'ON', 12293=>'L', 12294=>'L', 12295=>'L', 12296=>'ON', 12297=>'ON', 12298=>'ON', 12299=>'ON', 12300=>'ON', 12301=>'ON', 12302=>'ON', 12303=>'ON', 12304=>'ON', 12305=>'ON', 12306=>'ON', 12307=>'ON', 12308=>'ON', 12309=>'ON', 12310=>'ON', 12311=>'ON', 12312=>'ON', 12313=>'ON', 12314=>'ON', 12315=>'ON', 12316=>'ON', 12317=>'ON', 12318=>'ON', 12319=>'ON', 12320=>'ON', 12321=>'L', 12322=>'L', 12323=>'L', 12324=>'L', 12325=>'L', 12326=>'L', 12327=>'L', 12328=>'L', 12329=>'L', 12330=>'NSM', 12331=>'NSM', 12332=>'NSM', 12333=>'NSM', 12334=>'NSM', 12335=>'NSM', 12336=>'ON', 12337=>'L', 12338=>'L', 12339=>'L', 12340=>'L', 12341=>'L', 12342=>'ON', 12343=>'ON', 12344=>'L', 12345=>'L', 12346=>'L', 12347=>'L', 12348=>'L', 12349=>'ON', 12350=>'ON', 12351=>'ON', 12353=>'L', 12354=>'L', 12355=>'L', 12356=>'L', 12357=>'L', 12358=>'L', 12359=>'L', 12360=>'L', 12361=>'L', 12362=>'L', 12363=>'L', 12364=>'L', 12365=>'L', 12366=>'L', 12367=>'L', 12368=>'L', 12369=>'L', 12370=>'L', 12371=>'L', 12372=>'L', 12373=>'L', 12374=>'L', 12375=>'L', 12376=>'L', 12377=>'L', 12378=>'L', 12379=>'L', 12380=>'L', 12381=>'L', 12382=>'L', 12383=>'L', 12384=>'L', 12385=>'L', 12386=>'L', 12387=>'L', 12388=>'L', 12389=>'L', 12390=>'L', 12391=>'L', 12392=>'L', 12393=>'L', 12394=>'L', 12395=>'L', 12396=>'L', 12397=>'L', 12398=>'L', 12399=>'L', 12400=>'L', 12401=>'L', 12402=>'L', 12403=>'L', 12404=>'L', 12405=>'L', 12406=>'L', 12407=>'L', 12408=>'L', 12409=>'L', 12410=>'L', 12411=>'L', 12412=>'L', 12413=>'L', 12414=>'L', 12415=>'L', 12416=>'L', 12417=>'L', 12418=>'L', 12419=>'L', 12420=>'L', 12421=>'L', 12422=>'L', 12423=>'L', 12424=>'L', 12425=>'L', 12426=>'L', 12427=>'L', 12428=>'L', 12429=>'L', 12430=>'L', 12431=>'L', 12432=>'L', 12433=>'L', 12434=>'L', 12435=>'L', 12436=>'L', 12437=>'L', 12438=>'L', 12441=>'NSM', 12442=>'NSM', 12443=>'ON', 12444=>'ON', 12445=>'L', 12446=>'L', 12447=>'L', 12448=>'ON', 12449=>'L', 12450=>'L', 12451=>'L', 12452=>'L', 12453=>'L', 12454=>'L', 12455=>'L', 12456=>'L', 12457=>'L', 12458=>'L', 12459=>'L', 12460=>'L', 12461=>'L', 12462=>'L', 12463=>'L', 12464=>'L', 12465=>'L', 12466=>'L', 12467=>'L', 12468=>'L', 12469=>'L', 12470=>'L', 12471=>'L', 12472=>'L', 12473=>'L', 12474=>'L', 12475=>'L', 12476=>'L', 12477=>'L', 12478=>'L', 12479=>'L', 12480=>'L', 12481=>'L', 12482=>'L', 12483=>'L', 12484=>'L', 12485=>'L', 12486=>'L', 12487=>'L', 12488=>'L', 12489=>'L', 12490=>'L', 12491=>'L', 12492=>'L', 12493=>'L', 12494=>'L', 12495=>'L', 12496=>'L', 12497=>'L', 12498=>'L', 12499=>'L', 12500=>'L', 12501=>'L', 12502=>'L', 12503=>'L', 12504=>'L', 12505=>'L', 12506=>'L', 12507=>'L', 12508=>'L', 12509=>'L', 12510=>'L', 12511=>'L', 12512=>'L', 12513=>'L', 12514=>'L', 12515=>'L', 12516=>'L', 12517=>'L', 12518=>'L', 12519=>'L', 12520=>'L', 12521=>'L', 12522=>'L', 12523=>'L', 12524=>'L', 12525=>'L', 12526=>'L', 12527=>'L', 12528=>'L', 12529=>'L', 12530=>'L', 12531=>'L', 12532=>'L', 12533=>'L', 12534=>'L', 12535=>'L', 12536=>'L', 12537=>'L', 12538=>'L', 12539=>'ON', 12540=>'L', 12541=>'L', 12542=>'L', 12543=>'L', 12549=>'L', 12550=>'L', 12551=>'L', 12552=>'L', 12553=>'L', 12554=>'L', 12555=>'L', 12556=>'L', 12557=>'L', 12558=>'L', 12559=>'L', 12560=>'L', 12561=>'L', 12562=>'L', 12563=>'L', 12564=>'L', 12565=>'L', 12566=>'L', 12567=>'L', 12568=>'L', 12569=>'L', 12570=>'L', 12571=>'L', 12572=>'L', 12573=>'L', 12574=>'L', 12575=>'L', 12576=>'L', 12577=>'L', 12578=>'L', 12579=>'L', 12580=>'L', 12581=>'L', 12582=>'L', 12583=>'L', 12584=>'L', 12585=>'L', 12586=>'L', 12587=>'L', 12588=>'L', 12593=>'L', 12594=>'L', 12595=>'L', 12596=>'L', 12597=>'L', 12598=>'L', 12599=>'L', 12600=>'L', 12601=>'L', 12602=>'L', 12603=>'L', 12604=>'L', 12605=>'L', 12606=>'L', 12607=>'L', 12608=>'L', 12609=>'L', 12610=>'L', 12611=>'L', 12612=>'L', 12613=>'L', 12614=>'L', 12615=>'L', 12616=>'L', 12617=>'L', 12618=>'L', 12619=>'L', 12620=>'L', 12621=>'L', 12622=>'L', 12623=>'L', 12624=>'L', 12625=>'L', 12626=>'L', 12627=>'L', 12628=>'L', 12629=>'L', 12630=>'L', 12631=>'L', 12632=>'L', 12633=>'L', 12634=>'L', 12635=>'L', 12636=>'L', 12637=>'L', 12638=>'L', 12639=>'L', 12640=>'L', 12641=>'L', 12642=>'L', 12643=>'L', 12644=>'L', 12645=>'L', 12646=>'L', 12647=>'L', 12648=>'L', 12649=>'L', 12650=>'L', 12651=>'L', 12652=>'L', 12653=>'L', 12654=>'L', 12655=>'L', 12656=>'L', 12657=>'L', 12658=>'L', 12659=>'L', 12660=>'L', 12661=>'L', 12662=>'L', 12663=>'L', 12664=>'L', 12665=>'L', 12666=>'L', 12667=>'L', 12668=>'L', 12669=>'L', 12670=>'L', 12671=>'L', 12672=>'L', 12673=>'L', 12674=>'L', 12675=>'L', 12676=>'L', 12677=>'L', 12678=>'L', 12679=>'L', 12680=>'L', 12681=>'L', 12682=>'L', 12683=>'L', 12684=>'L', 12685=>'L', 12686=>'L', 12688=>'L', 12689=>'L', 12690=>'L', 12691=>'L', 12692=>'L', 12693=>'L', 12694=>'L', 12695=>'L', 12696=>'L', 12697=>'L', 12698=>'L', 12699=>'L', 12700=>'L', 12701=>'L', 12702=>'L', 12703=>'L', 12704=>'L', 12705=>'L', 12706=>'L', 12707=>'L', 12708=>'L', 12709=>'L', 12710=>'L', 12711=>'L', 12712=>'L', 12713=>'L', 12714=>'L', 12715=>'L', 12716=>'L', 12717=>'L', 12718=>'L', 12719=>'L', 12720=>'L', 12721=>'L', 12722=>'L', 12723=>'L', 12724=>'L', 12725=>'L', 12726=>'L', 12727=>'L', 12736=>'ON', 12737=>'ON', 12738=>'ON', 12739=>'ON', 12740=>'ON', 12741=>'ON', 12742=>'ON', 12743=>'ON', 12744=>'ON', 12745=>'ON', 12746=>'ON', 12747=>'ON', 12748=>'ON', 12749=>'ON', 12750=>'ON', 12751=>'ON', 12784=>'L', 12785=>'L', 12786=>'L', 12787=>'L', 12788=>'L', 12789=>'L', 12790=>'L', 12791=>'L', 12792=>'L', 12793=>'L', 12794=>'L', 12795=>'L', 12796=>'L', 12797=>'L', 12798=>'L', 12799=>'L', 12800=>'L', 12801=>'L', 12802=>'L', 12803=>'L', 12804=>'L', 12805=>'L', 12806=>'L', 12807=>'L', 12808=>'L', 12809=>'L', 12810=>'L', 12811=>'L', 12812=>'L', 12813=>'L', 12814=>'L', 12815=>'L', 12816=>'L', 12817=>'L', 12818=>'L', 12819=>'L', 12820=>'L', 12821=>'L', 12822=>'L', 12823=>'L', 12824=>'L', 12825=>'L', 12826=>'L', 12827=>'L', 12828=>'L', 12829=>'ON', 12830=>'ON', 12832=>'L', 12833=>'L', 12834=>'L', 12835=>'L', 12836=>'L', 12837=>'L', 12838=>'L', 12839=>'L', 12840=>'L', 12841=>'L', 12842=>'L', 12843=>'L', 12844=>'L', 12845=>'L', 12846=>'L', 12847=>'L', 12848=>'L', 12849=>'L', 12850=>'L', 12851=>'L', 12852=>'L', 12853=>'L', 12854=>'L', 12855=>'L', 12856=>'L', 12857=>'L', 12858=>'L', 12859=>'L', 12860=>'L', 12861=>'L', 12862=>'L', 12863=>'L', 12864=>'L', 12865=>'L', 12866=>'L', 12867=>'L', 12880=>'ON', 12881=>'ON', 12882=>'ON', 12883=>'ON', 12884=>'ON', 12885=>'ON', 12886=>'ON', 12887=>'ON', 12888=>'ON', 12889=>'ON', 12890=>'ON', 12891=>'ON', 12892=>'ON', 12893=>'ON', 12894=>'ON', 12895=>'ON', 12896=>'L', 12897=>'L', 12898=>'L', 12899=>'L', 12900=>'L', 12901=>'L', 12902=>'L', 12903=>'L', 12904=>'L', 12905=>'L', 12906=>'L', 12907=>'L', 12908=>'L', 12909=>'L', 12910=>'L', 12911=>'L', 12912=>'L', 12913=>'L', 12914=>'L', 12915=>'L', 12916=>'L', 12917=>'L', 12918=>'L', 12919=>'L', 12920=>'L', 12921=>'L', 12922=>'L', 12923=>'L', 12924=>'ON', 12925=>'ON', 12926=>'ON', 12927=>'L', 12928=>'L', 12929=>'L', 12930=>'L', 12931=>'L', 12932=>'L', 12933=>'L', 12934=>'L', 12935=>'L', 12936=>'L', 12937=>'L', 12938=>'L', 12939=>'L', 12940=>'L', 12941=>'L', 12942=>'L', 12943=>'L', 12944=>'L', 12945=>'L', 12946=>'L', 12947=>'L', 12948=>'L', 12949=>'L', 12950=>'L', 12951=>'L', 12952=>'L', 12953=>'L', 12954=>'L', 12955=>'L', 12956=>'L', 12957=>'L', 12958=>'L', 12959=>'L', 12960=>'L', 12961=>'L', 12962=>'L', 12963=>'L', 12964=>'L', 12965=>'L', 12966=>'L', 12967=>'L', 12968=>'L', 12969=>'L', 12970=>'L', 12971=>'L', 12972=>'L', 12973=>'L', 12974=>'L', 12975=>'L', 12976=>'L', 12977=>'ON', 12978=>'ON', 12979=>'ON', 12980=>'ON', 12981=>'ON', 12982=>'ON', 12983=>'ON', 12984=>'ON', 12985=>'ON', 12986=>'ON', 12987=>'ON', 12988=>'ON', 12989=>'ON', 12990=>'ON', 12991=>'ON', 12992=>'L', 12993=>'L', 12994=>'L', 12995=>'L', 12996=>'L', 12997=>'L', 12998=>'L', 12999=>'L', 13000=>'L', 13001=>'L', 13002=>'L', 13003=>'L', 13004=>'ON', 13005=>'ON', 13006=>'ON', 13007=>'ON', 13008=>'L', 13009=>'L', 13010=>'L', 13011=>'L', 13012=>'L', 13013=>'L', 13014=>'L', 13015=>'L', 13016=>'L', 13017=>'L', 13018=>'L', 13019=>'L', 13020=>'L', 13021=>'L', 13022=>'L', 13023=>'L', 13024=>'L', 13025=>'L', 13026=>'L', 13027=>'L', 13028=>'L', 13029=>'L', 13030=>'L', 13031=>'L', 13032=>'L', 13033=>'L', 13034=>'L', 13035=>'L', 13036=>'L', 13037=>'L', 13038=>'L', 13039=>'L', 13040=>'L', 13041=>'L', 13042=>'L', 13043=>'L', 13044=>'L', 13045=>'L', 13046=>'L', 13047=>'L', 13048=>'L', 13049=>'L', 13050=>'L', 13051=>'L', 13052=>'L', 13053=>'L', 13054=>'L', 13056=>'L', 13057=>'L', 13058=>'L', 13059=>'L', 13060=>'L', 13061=>'L', 13062=>'L', 13063=>'L', 13064=>'L', 13065=>'L', 13066=>'L', 13067=>'L', 13068=>'L', 13069=>'L', 13070=>'L', 13071=>'L', 13072=>'L', 13073=>'L', 13074=>'L', 13075=>'L', 13076=>'L', 13077=>'L', 13078=>'L', 13079=>'L', 13080=>'L', 13081=>'L', 13082=>'L', 13083=>'L', 13084=>'L', 13085=>'L', 13086=>'L', 13087=>'L', 13088=>'L', 13089=>'L', 13090=>'L', 13091=>'L', 13092=>'L', 13093=>'L', 13094=>'L', 13095=>'L', 13096=>'L', 13097=>'L', 13098=>'L', 13099=>'L', 13100=>'L', 13101=>'L', 13102=>'L', 13103=>'L', 13104=>'L', 13105=>'L', 13106=>'L', 13107=>'L', 13108=>'L', 13109=>'L', 13110=>'L', 13111=>'L', 13112=>'L', 13113=>'L', 13114=>'L', 13115=>'L', 13116=>'L', 13117=>'L', 13118=>'L', 13119=>'L', 13120=>'L', 13121=>'L', 13122=>'L', 13123=>'L', 13124=>'L', 13125=>'L', 13126=>'L', 13127=>'L', 13128=>'L', 13129=>'L', 13130=>'L', 13131=>'L', 13132=>'L', 13133=>'L', 13134=>'L', 13135=>'L', 13136=>'L', 13137=>'L', 13138=>'L', 13139=>'L', 13140=>'L', 13141=>'L', 13142=>'L', 13143=>'L', 13144=>'L', 13145=>'L', 13146=>'L', 13147=>'L', 13148=>'L', 13149=>'L', 13150=>'L', 13151=>'L', 13152=>'L', 13153=>'L', 13154=>'L', 13155=>'L', 13156=>'L', 13157=>'L', 13158=>'L', 13159=>'L', 13160=>'L', 13161=>'L', 13162=>'L', 13163=>'L', 13164=>'L', 13165=>'L', 13166=>'L', 13167=>'L', 13168=>'L', 13169=>'L', 13170=>'L', 13171=>'L', 13172=>'L', 13173=>'L', 13174=>'L', 13175=>'ON', 13176=>'ON', 13177=>'ON', 13178=>'ON', 13179=>'L', 13180=>'L', 13181=>'L', 13182=>'L', 13183=>'L', 13184=>'L', 13185=>'L', 13186=>'L', 13187=>'L', 13188=>'L', 13189=>'L', 13190=>'L', 13191=>'L', 13192=>'L', 13193=>'L', 13194=>'L', 13195=>'L', 13196=>'L', 13197=>'L', 13198=>'L', 13199=>'L', 13200=>'L', 13201=>'L', 13202=>'L', 13203=>'L', 13204=>'L', 13205=>'L', 13206=>'L', 13207=>'L', 13208=>'L', 13209=>'L', 13210=>'L', 13211=>'L', 13212=>'L', 13213=>'L', 13214=>'L', 13215=>'L', 13216=>'L', 13217=>'L', 13218=>'L', 13219=>'L', 13220=>'L', 13221=>'L', 13222=>'L', 13223=>'L', 13224=>'L', 13225=>'L', 13226=>'L', 13227=>'L', 13228=>'L', 13229=>'L', 13230=>'L', 13231=>'L', 13232=>'L', 13233=>'L', 13234=>'L', 13235=>'L', 13236=>'L', 13237=>'L', 13238=>'L', 13239=>'L', 13240=>'L', 13241=>'L', 13242=>'L', 13243=>'L', 13244=>'L', 13245=>'L', 13246=>'L', 13247=>'L', 13248=>'L', 13249=>'L', 13250=>'L', 13251=>'L', 13252=>'L', 13253=>'L', 13254=>'L', 13255=>'L', 13256=>'L', 13257=>'L', 13258=>'L', 13259=>'L', 13260=>'L', 13261=>'L', 13262=>'L', 13263=>'L', 13264=>'L', 13265=>'L', 13266=>'L', 13267=>'L', 13268=>'L', 13269=>'L', 13270=>'L', 13271=>'L', 13272=>'L', 13273=>'L', 13274=>'L', 13275=>'L', 13276=>'L', 13277=>'L', 13278=>'ON', 13279=>'ON', 13280=>'L', 13281=>'L', 13282=>'L', 13283=>'L', 13284=>'L', 13285=>'L', 13286=>'L', 13287=>'L', 13288=>'L', 13289=>'L', 13290=>'L', 13291=>'L', 13292=>'L', 13293=>'L', 13294=>'L', 13295=>'L', 13296=>'L', 13297=>'L', 13298=>'L', 13299=>'L', 13300=>'L', 13301=>'L', 13302=>'L', 13303=>'L', 13304=>'L', 13305=>'L', 13306=>'L', 13307=>'L', 13308=>'L', 13309=>'L', 13310=>'L', 13311=>'ON', 13312=>'L', 19893=>'L', 19904=>'ON', 19905=>'ON', 19906=>'ON', 19907=>'ON', 19908=>'ON', 19909=>'ON', 19910=>'ON', 19911=>'ON', 19912=>'ON', 19913=>'ON', 19914=>'ON', 19915=>'ON', 19916=>'ON', 19917=>'ON', 19918=>'ON', 19919=>'ON', 19920=>'ON', 19921=>'ON', 19922=>'ON', 19923=>'ON', 19924=>'ON', 19925=>'ON', 19926=>'ON', 19927=>'ON', 19928=>'ON', 19929=>'ON', 19930=>'ON', 19931=>'ON', 19932=>'ON', 19933=>'ON', 19934=>'ON', 19935=>'ON', 19936=>'ON', 19937=>'ON', 19938=>'ON', 19939=>'ON', 19940=>'ON', 19941=>'ON', 19942=>'ON', 19943=>'ON', 19944=>'ON', 19945=>'ON', 19946=>'ON', 19947=>'ON', 19948=>'ON', 19949=>'ON', 19950=>'ON', 19951=>'ON', 19952=>'ON', 19953=>'ON', 19954=>'ON', 19955=>'ON', 19956=>'ON', 19957=>'ON', 19958=>'ON', 19959=>'ON', 19960=>'ON', 19961=>'ON', 19962=>'ON', 19963=>'ON', 19964=>'ON', 19965=>'ON', 19966=>'ON', 19967=>'ON', 19968=>'L', 40891=>'L', 40960=>'L', 40961=>'L', 40962=>'L', 40963=>'L', 40964=>'L', 40965=>'L', 40966=>'L', 40967=>'L', 40968=>'L', 40969=>'L', 40970=>'L', 40971=>'L', 40972=>'L', 40973=>'L', 40974=>'L', 40975=>'L', 40976=>'L', 40977=>'L', 40978=>'L', 40979=>'L', 40980=>'L', 40981=>'L', 40982=>'L', 40983=>'L', 40984=>'L', 40985=>'L', 40986=>'L', 40987=>'L', 40988=>'L', 40989=>'L', 40990=>'L', 40991=>'L', 40992=>'L', 40993=>'L', 40994=>'L', 40995=>'L', 40996=>'L', 40997=>'L', 40998=>'L', 40999=>'L', 41000=>'L', 41001=>'L', 41002=>'L', 41003=>'L', 41004=>'L', 41005=>'L', 41006=>'L', 41007=>'L', 41008=>'L', 41009=>'L', 41010=>'L', 41011=>'L', 41012=>'L', 41013=>'L', 41014=>'L', 41015=>'L', 41016=>'L', 41017=>'L', 41018=>'L', 41019=>'L', 41020=>'L', 41021=>'L', 41022=>'L', 41023=>'L', 41024=>'L', 41025=>'L', 41026=>'L', 41027=>'L', 41028=>'L', 41029=>'L', 41030=>'L', 41031=>'L', 41032=>'L', 41033=>'L', 41034=>'L', 41035=>'L', 41036=>'L', 41037=>'L', 41038=>'L', 41039=>'L', 41040=>'L', 41041=>'L', 41042=>'L', 41043=>'L', 41044=>'L', 41045=>'L', 41046=>'L', 41047=>'L', 41048=>'L', 41049=>'L', 41050=>'L', 41051=>'L', 41052=>'L', 41053=>'L', 41054=>'L', 41055=>'L', 41056=>'L', 41057=>'L', 41058=>'L', 41059=>'L', 41060=>'L', 41061=>'L', 41062=>'L', 41063=>'L', 41064=>'L', 41065=>'L', 41066=>'L', 41067=>'L', 41068=>'L', 41069=>'L', 41070=>'L', 41071=>'L', 41072=>'L', 41073=>'L', 41074=>'L', 41075=>'L', 41076=>'L', 41077=>'L', 41078=>'L', 41079=>'L', 41080=>'L', 41081=>'L', 41082=>'L', 41083=>'L', 41084=>'L', 41085=>'L', 41086=>'L', 41087=>'L', 41088=>'L', 41089=>'L', 41090=>'L', 41091=>'L', 41092=>'L', 41093=>'L', 41094=>'L', 41095=>'L', 41096=>'L', 41097=>'L', 41098=>'L', 41099=>'L', 41100=>'L', 41101=>'L', 41102=>'L', 41103=>'L', 41104=>'L', 41105=>'L', 41106=>'L', 41107=>'L', 41108=>'L', 41109=>'L', 41110=>'L', 41111=>'L', 41112=>'L', 41113=>'L', 41114=>'L', 41115=>'L', 41116=>'L', 41117=>'L', 41118=>'L', 41119=>'L', 41120=>'L', 41121=>'L', 41122=>'L', 41123=>'L', 41124=>'L', 41125=>'L', 41126=>'L', 41127=>'L', 41128=>'L', 41129=>'L', 41130=>'L', 41131=>'L', 41132=>'L', 41133=>'L', 41134=>'L', 41135=>'L', 41136=>'L', 41137=>'L', 41138=>'L', 41139=>'L', 41140=>'L', 41141=>'L', 41142=>'L', 41143=>'L', 41144=>'L', 41145=>'L', 41146=>'L', 41147=>'L', 41148=>'L', 41149=>'L', 41150=>'L', 41151=>'L', 41152=>'L', 41153=>'L', 41154=>'L', 41155=>'L', 41156=>'L', 41157=>'L', 41158=>'L', 41159=>'L', 41160=>'L', 41161=>'L', 41162=>'L', 41163=>'L', 41164=>'L', 41165=>'L', 41166=>'L', 41167=>'L', 41168=>'L', 41169=>'L', 41170=>'L', 41171=>'L', 41172=>'L', 41173=>'L', 41174=>'L', 41175=>'L', 41176=>'L', 41177=>'L', 41178=>'L', 41179=>'L', 41180=>'L', 41181=>'L', 41182=>'L', 41183=>'L', 41184=>'L', 41185=>'L', 41186=>'L', 41187=>'L', 41188=>'L', 41189=>'L', 41190=>'L', 41191=>'L', 41192=>'L', 41193=>'L', 41194=>'L', 41195=>'L', 41196=>'L', 41197=>'L', 41198=>'L', 41199=>'L', 41200=>'L', 41201=>'L', 41202=>'L', 41203=>'L', 41204=>'L', 41205=>'L', 41206=>'L', 41207=>'L', 41208=>'L', 41209=>'L', 41210=>'L', 41211=>'L', 41212=>'L', 41213=>'L', 41214=>'L', 41215=>'L', 41216=>'L', 41217=>'L', 41218=>'L', 41219=>'L', 41220=>'L', 41221=>'L', 41222=>'L', 41223=>'L', 41224=>'L', 41225=>'L', 41226=>'L', 41227=>'L', 41228=>'L', 41229=>'L', 41230=>'L', 41231=>'L', 41232=>'L', 41233=>'L', 41234=>'L', 41235=>'L', 41236=>'L', 41237=>'L', 41238=>'L', 41239=>'L', 41240=>'L', 41241=>'L', 41242=>'L', 41243=>'L', 41244=>'L', 41245=>'L', 41246=>'L', 41247=>'L', 41248=>'L', 41249=>'L', 41250=>'L', 41251=>'L', 41252=>'L', 41253=>'L', 41254=>'L', 41255=>'L', 41256=>'L', 41257=>'L', 41258=>'L', 41259=>'L', 41260=>'L', 41261=>'L', 41262=>'L', 41263=>'L', 41264=>'L', 41265=>'L', 41266=>'L', 41267=>'L', 41268=>'L', 41269=>'L', 41270=>'L', 41271=>'L', 41272=>'L', 41273=>'L', 41274=>'L', 41275=>'L', 41276=>'L', 41277=>'L', 41278=>'L', 41279=>'L', 41280=>'L', 41281=>'L', 41282=>'L', 41283=>'L', 41284=>'L', 41285=>'L', 41286=>'L', 41287=>'L', 41288=>'L', 41289=>'L', 41290=>'L', 41291=>'L', 41292=>'L', 41293=>'L', 41294=>'L', 41295=>'L', 41296=>'L', 41297=>'L', 41298=>'L', 41299=>'L', 41300=>'L', 41301=>'L', 41302=>'L', 41303=>'L', 41304=>'L', 41305=>'L', 41306=>'L', 41307=>'L', 41308=>'L', 41309=>'L', 41310=>'L', 41311=>'L', 41312=>'L', 41313=>'L', 41314=>'L', 41315=>'L', 41316=>'L', 41317=>'L', 41318=>'L', 41319=>'L', 41320=>'L', 41321=>'L', 41322=>'L', 41323=>'L', 41324=>'L', 41325=>'L', 41326=>'L', 41327=>'L', 41328=>'L', 41329=>'L', 41330=>'L', 41331=>'L', 41332=>'L', 41333=>'L', 41334=>'L', 41335=>'L', 41336=>'L', 41337=>'L', 41338=>'L', 41339=>'L', 41340=>'L', 41341=>'L', 41342=>'L', 41343=>'L', 41344=>'L', 41345=>'L', 41346=>'L', 41347=>'L', 41348=>'L', 41349=>'L', 41350=>'L', 41351=>'L', 41352=>'L', 41353=>'L', 41354=>'L', 41355=>'L', 41356=>'L', 41357=>'L', 41358=>'L', 41359=>'L', 41360=>'L', 41361=>'L', 41362=>'L', 41363=>'L', 41364=>'L', 41365=>'L', 41366=>'L', 41367=>'L', 41368=>'L', 41369=>'L', 41370=>'L', 41371=>'L', 41372=>'L', 41373=>'L', 41374=>'L', 41375=>'L', 41376=>'L', 41377=>'L', 41378=>'L', 41379=>'L', 41380=>'L', 41381=>'L', 41382=>'L', 41383=>'L', 41384=>'L', 41385=>'L', 41386=>'L', 41387=>'L', 41388=>'L', 41389=>'L', 41390=>'L', 41391=>'L', 41392=>'L', 41393=>'L', 41394=>'L', 41395=>'L', 41396=>'L', 41397=>'L', 41398=>'L', 41399=>'L', 41400=>'L', 41401=>'L', 41402=>'L', 41403=>'L', 41404=>'L', 41405=>'L', 41406=>'L', 41407=>'L', 41408=>'L', 41409=>'L', 41410=>'L', 41411=>'L', 41412=>'L', 41413=>'L', 41414=>'L', 41415=>'L', 41416=>'L', 41417=>'L', 41418=>'L', 41419=>'L', 41420=>'L', 41421=>'L', 41422=>'L', 41423=>'L', 41424=>'L', 41425=>'L', 41426=>'L', 41427=>'L', 41428=>'L', 41429=>'L', 41430=>'L', 41431=>'L', 41432=>'L', 41433=>'L', 41434=>'L', 41435=>'L', 41436=>'L', 41437=>'L', 41438=>'L', 41439=>'L', 41440=>'L', 41441=>'L', 41442=>'L', 41443=>'L', 41444=>'L', 41445=>'L', 41446=>'L', 41447=>'L', 41448=>'L', 41449=>'L', 41450=>'L', 41451=>'L', 41452=>'L', 41453=>'L', 41454=>'L', 41455=>'L', 41456=>'L', 41457=>'L', 41458=>'L', 41459=>'L', 41460=>'L', 41461=>'L', 41462=>'L', 41463=>'L', 41464=>'L', 41465=>'L', 41466=>'L', 41467=>'L', 41468=>'L', 41469=>'L', 41470=>'L', 41471=>'L', 41472=>'L', 41473=>'L', 41474=>'L', 41475=>'L', 41476=>'L', 41477=>'L', 41478=>'L', 41479=>'L', 41480=>'L', 41481=>'L', 41482=>'L', 41483=>'L', 41484=>'L', 41485=>'L', 41486=>'L', 41487=>'L', 41488=>'L', 41489=>'L', 41490=>'L', 41491=>'L', 41492=>'L', 41493=>'L', 41494=>'L', 41495=>'L', 41496=>'L', 41497=>'L', 41498=>'L', 41499=>'L', 41500=>'L', 41501=>'L', 41502=>'L', 41503=>'L', 41504=>'L', 41505=>'L', 41506=>'L', 41507=>'L', 41508=>'L', 41509=>'L', 41510=>'L', 41511=>'L', 41512=>'L', 41513=>'L', 41514=>'L', 41515=>'L', 41516=>'L', 41517=>'L', 41518=>'L', 41519=>'L', 41520=>'L', 41521=>'L', 41522=>'L', 41523=>'L', 41524=>'L', 41525=>'L', 41526=>'L', 41527=>'L', 41528=>'L', 41529=>'L', 41530=>'L', 41531=>'L', 41532=>'L', 41533=>'L', 41534=>'L', 41535=>'L', 41536=>'L', 41537=>'L', 41538=>'L', 41539=>'L', 41540=>'L', 41541=>'L', 41542=>'L', 41543=>'L', 41544=>'L', 41545=>'L', 41546=>'L', 41547=>'L', 41548=>'L', 41549=>'L', 41550=>'L', 41551=>'L', 41552=>'L', 41553=>'L', 41554=>'L', 41555=>'L', 41556=>'L', 41557=>'L', 41558=>'L', 41559=>'L', 41560=>'L', 41561=>'L', 41562=>'L', 41563=>'L', 41564=>'L', 41565=>'L', 41566=>'L', 41567=>'L', 41568=>'L', 41569=>'L', 41570=>'L', 41571=>'L', 41572=>'L', 41573=>'L', 41574=>'L', 41575=>'L', 41576=>'L', 41577=>'L', 41578=>'L', 41579=>'L', 41580=>'L', 41581=>'L', 41582=>'L', 41583=>'L', 41584=>'L', 41585=>'L', 41586=>'L', 41587=>'L', 41588=>'L', 41589=>'L', 41590=>'L', 41591=>'L', 41592=>'L', 41593=>'L', 41594=>'L', 41595=>'L', 41596=>'L', 41597=>'L', 41598=>'L', 41599=>'L', 41600=>'L', 41601=>'L', 41602=>'L', 41603=>'L', 41604=>'L', 41605=>'L', 41606=>'L', 41607=>'L', 41608=>'L', 41609=>'L', 41610=>'L', 41611=>'L', 41612=>'L', 41613=>'L', 41614=>'L', 41615=>'L', 41616=>'L', 41617=>'L', 41618=>'L', 41619=>'L', 41620=>'L', 41621=>'L', 41622=>'L', 41623=>'L', 41624=>'L', 41625=>'L', 41626=>'L', 41627=>'L', 41628=>'L', 41629=>'L', 41630=>'L', 41631=>'L', 41632=>'L', 41633=>'L', 41634=>'L', 41635=>'L', 41636=>'L', 41637=>'L', 41638=>'L', 41639=>'L', 41640=>'L', 41641=>'L', 41642=>'L', 41643=>'L', 41644=>'L', 41645=>'L', 41646=>'L', 41647=>'L', 41648=>'L', 41649=>'L', 41650=>'L', 41651=>'L', 41652=>'L', 41653=>'L', 41654=>'L', 41655=>'L', 41656=>'L', 41657=>'L', 41658=>'L', 41659=>'L', 41660=>'L', 41661=>'L', 41662=>'L', 41663=>'L', 41664=>'L', 41665=>'L', 41666=>'L', 41667=>'L', 41668=>'L', 41669=>'L', 41670=>'L', 41671=>'L', 41672=>'L', 41673=>'L', 41674=>'L', 41675=>'L', 41676=>'L', 41677=>'L', 41678=>'L', 41679=>'L', 41680=>'L', 41681=>'L', 41682=>'L', 41683=>'L', 41684=>'L', 41685=>'L', 41686=>'L', 41687=>'L', 41688=>'L', 41689=>'L', 41690=>'L', 41691=>'L', 41692=>'L', 41693=>'L', 41694=>'L', 41695=>'L', 41696=>'L', 41697=>'L', 41698=>'L', 41699=>'L', 41700=>'L', 41701=>'L', 41702=>'L', 41703=>'L', 41704=>'L', 41705=>'L', 41706=>'L', 41707=>'L', 41708=>'L', 41709=>'L', 41710=>'L', 41711=>'L', 41712=>'L', 41713=>'L', 41714=>'L', 41715=>'L', 41716=>'L', 41717=>'L', 41718=>'L', 41719=>'L', 41720=>'L', 41721=>'L', 41722=>'L', 41723=>'L', 41724=>'L', 41725=>'L', 41726=>'L', 41727=>'L', 41728=>'L', 41729=>'L', 41730=>'L', 41731=>'L', 41732=>'L', 41733=>'L', 41734=>'L', 41735=>'L', 41736=>'L', 41737=>'L', 41738=>'L', 41739=>'L', 41740=>'L', 41741=>'L', 41742=>'L', 41743=>'L', 41744=>'L', 41745=>'L', 41746=>'L', 41747=>'L', 41748=>'L', 41749=>'L', 41750=>'L', 41751=>'L', 41752=>'L', 41753=>'L', 41754=>'L', 41755=>'L', 41756=>'L', 41757=>'L', 41758=>'L', 41759=>'L', 41760=>'L', 41761=>'L', 41762=>'L', 41763=>'L', 41764=>'L', 41765=>'L', 41766=>'L', 41767=>'L', 41768=>'L', 41769=>'L', 41770=>'L', 41771=>'L', 41772=>'L', 41773=>'L', 41774=>'L', 41775=>'L', 41776=>'L', 41777=>'L', 41778=>'L', 41779=>'L', 41780=>'L', 41781=>'L', 41782=>'L', 41783=>'L', 41784=>'L', 41785=>'L', 41786=>'L', 41787=>'L', 41788=>'L', 41789=>'L', 41790=>'L', 41791=>'L', 41792=>'L', 41793=>'L', 41794=>'L', 41795=>'L', 41796=>'L', 41797=>'L', 41798=>'L', 41799=>'L', 41800=>'L', 41801=>'L', 41802=>'L', 41803=>'L', 41804=>'L', 41805=>'L', 41806=>'L', 41807=>'L', 41808=>'L', 41809=>'L', 41810=>'L', 41811=>'L', 41812=>'L', 41813=>'L', 41814=>'L', 41815=>'L', 41816=>'L', 41817=>'L', 41818=>'L', 41819=>'L', 41820=>'L', 41821=>'L', 41822=>'L', 41823=>'L', 41824=>'L', 41825=>'L', 41826=>'L', 41827=>'L', 41828=>'L', 41829=>'L', 41830=>'L', 41831=>'L', 41832=>'L', 41833=>'L', 41834=>'L', 41835=>'L', 41836=>'L', 41837=>'L', 41838=>'L', 41839=>'L', 41840=>'L', 41841=>'L', 41842=>'L', 41843=>'L', 41844=>'L', 41845=>'L', 41846=>'L', 41847=>'L', 41848=>'L', 41849=>'L', 41850=>'L', 41851=>'L', 41852=>'L', 41853=>'L', 41854=>'L', 41855=>'L', 41856=>'L', 41857=>'L', 41858=>'L', 41859=>'L', 41860=>'L', 41861=>'L', 41862=>'L', 41863=>'L', 41864=>'L', 41865=>'L', 41866=>'L', 41867=>'L', 41868=>'L', 41869=>'L', 41870=>'L', 41871=>'L', 41872=>'L', 41873=>'L', 41874=>'L', 41875=>'L', 41876=>'L', 41877=>'L', 41878=>'L', 41879=>'L', 41880=>'L', 41881=>'L', 41882=>'L', 41883=>'L', 41884=>'L', 41885=>'L', 41886=>'L', 41887=>'L', 41888=>'L', 41889=>'L', 41890=>'L', 41891=>'L', 41892=>'L', 41893=>'L', 41894=>'L', 41895=>'L', 41896=>'L', 41897=>'L', 41898=>'L', 41899=>'L', 41900=>'L', 41901=>'L', 41902=>'L', 41903=>'L', 41904=>'L', 41905=>'L', 41906=>'L', 41907=>'L', 41908=>'L', 41909=>'L', 41910=>'L', 41911=>'L', 41912=>'L', 41913=>'L', 41914=>'L', 41915=>'L', 41916=>'L', 41917=>'L', 41918=>'L', 41919=>'L', 41920=>'L', 41921=>'L', 41922=>'L', 41923=>'L', 41924=>'L', 41925=>'L', 41926=>'L', 41927=>'L', 41928=>'L', 41929=>'L', 41930=>'L', 41931=>'L', 41932=>'L', 41933=>'L', 41934=>'L', 41935=>'L', 41936=>'L', 41937=>'L', 41938=>'L', 41939=>'L', 41940=>'L', 41941=>'L', 41942=>'L', 41943=>'L', 41944=>'L', 41945=>'L', 41946=>'L', 41947=>'L', 41948=>'L', 41949=>'L', 41950=>'L', 41951=>'L', 41952=>'L', 41953=>'L', 41954=>'L', 41955=>'L', 41956=>'L', 41957=>'L', 41958=>'L', 41959=>'L', 41960=>'L', 41961=>'L', 41962=>'L', 41963=>'L', 41964=>'L', 41965=>'L', 41966=>'L', 41967=>'L', 41968=>'L', 41969=>'L', 41970=>'L', 41971=>'L', 41972=>'L', 41973=>'L', 41974=>'L', 41975=>'L', 41976=>'L', 41977=>'L', 41978=>'L', 41979=>'L', 41980=>'L', 41981=>'L', 41982=>'L', 41983=>'L', 41984=>'L', 41985=>'L', 41986=>'L', 41987=>'L', 41988=>'L', 41989=>'L', 41990=>'L', 41991=>'L', 41992=>'L', 41993=>'L', 41994=>'L', 41995=>'L', 41996=>'L', 41997=>'L', 41998=>'L', 41999=>'L', 42000=>'L', 42001=>'L', 42002=>'L', 42003=>'L', 42004=>'L', 42005=>'L', 42006=>'L', 42007=>'L', 42008=>'L', 42009=>'L', 42010=>'L', 42011=>'L', 42012=>'L', 42013=>'L', 42014=>'L', 42015=>'L', 42016=>'L', 42017=>'L', 42018=>'L', 42019=>'L', 42020=>'L', 42021=>'L', 42022=>'L', 42023=>'L', 42024=>'L', 42025=>'L', 42026=>'L', 42027=>'L', 42028=>'L', 42029=>'L', 42030=>'L', 42031=>'L', 42032=>'L', 42033=>'L', 42034=>'L', 42035=>'L', 42036=>'L', 42037=>'L', 42038=>'L', 42039=>'L', 42040=>'L', 42041=>'L', 42042=>'L', 42043=>'L', 42044=>'L', 42045=>'L', 42046=>'L', 42047=>'L', 42048=>'L', 42049=>'L', 42050=>'L', 42051=>'L', 42052=>'L', 42053=>'L', 42054=>'L', 42055=>'L', 42056=>'L', 42057=>'L', 42058=>'L', 42059=>'L', 42060=>'L', 42061=>'L', 42062=>'L', 42063=>'L', 42064=>'L', 42065=>'L', 42066=>'L', 42067=>'L', 42068=>'L', 42069=>'L', 42070=>'L', 42071=>'L', 42072=>'L', 42073=>'L', 42074=>'L', 42075=>'L', 42076=>'L', 42077=>'L', 42078=>'L', 42079=>'L', 42080=>'L', 42081=>'L', 42082=>'L', 42083=>'L', 42084=>'L', 42085=>'L', 42086=>'L', 42087=>'L', 42088=>'L', 42089=>'L', 42090=>'L', 42091=>'L', 42092=>'L', 42093=>'L', 42094=>'L', 42095=>'L', 42096=>'L', 42097=>'L', 42098=>'L', 42099=>'L', 42100=>'L', 42101=>'L', 42102=>'L', 42103=>'L', 42104=>'L', 42105=>'L', 42106=>'L', 42107=>'L', 42108=>'L', 42109=>'L', 42110=>'L', 42111=>'L', 42112=>'L', 42113=>'L', 42114=>'L', 42115=>'L', 42116=>'L', 42117=>'L', 42118=>'L', 42119=>'L', 42120=>'L', 42121=>'L', 42122=>'L', 42123=>'L', 42124=>'L', 42128=>'ON', 42129=>'ON', 42130=>'ON', 42131=>'ON', 42132=>'ON', 42133=>'ON', 42134=>'ON', 42135=>'ON', 42136=>'ON', 42137=>'ON', 42138=>'ON', 42139=>'ON', 42140=>'ON', 42141=>'ON', 42142=>'ON', 42143=>'ON', 42144=>'ON', 42145=>'ON', 42146=>'ON', 42147=>'ON', 42148=>'ON', 42149=>'ON', 42150=>'ON', 42151=>'ON', 42152=>'ON', 42153=>'ON', 42154=>'ON', 42155=>'ON', 42156=>'ON', 42157=>'ON', 42158=>'ON', 42159=>'ON', 42160=>'ON', 42161=>'ON', 42162=>'ON', 42163=>'ON', 42164=>'ON', 42165=>'ON', 42166=>'ON', 42167=>'ON', 42168=>'ON', 42169=>'ON', 42170=>'ON', 42171=>'ON', 42172=>'ON', 42173=>'ON', 42174=>'ON', 42175=>'ON', 42176=>'ON', 42177=>'ON', 42178=>'ON', 42179=>'ON', 42180=>'ON', 42181=>'ON', 42182=>'ON', 42752=>'ON', 42753=>'ON', 42754=>'ON', 42755=>'ON', 42756=>'ON', 42757=>'ON', 42758=>'ON', 42759=>'ON', 42760=>'ON', 42761=>'ON', 42762=>'ON', 42763=>'ON', 42764=>'ON', 42765=>'ON', 42766=>'ON', 42767=>'ON', 42768=>'ON', 42769=>'ON', 42770=>'ON', 42771=>'ON', 42772=>'ON', 42773=>'ON', 42774=>'ON', 42775=>'ON', 42776=>'ON', 42777=>'ON', 42778=>'ON', 42784=>'ON', 42785=>'ON', 43008=>'L', 43009=>'L', 43010=>'NSM', 43011=>'L', 43012=>'L', 43013=>'L', 43014=>'NSM', 43015=>'L', 43016=>'L', 43017=>'L', 43018=>'L', 43019=>'NSM', 43020=>'L', 43021=>'L', 43022=>'L', 43023=>'L', 43024=>'L', 43025=>'L', 43026=>'L', 43027=>'L', 43028=>'L', 43029=>'L', 43030=>'L', 43031=>'L', 43032=>'L', 43033=>'L', 43034=>'L', 43035=>'L', 43036=>'L', 43037=>'L', 43038=>'L', 43039=>'L', 43040=>'L', 43041=>'L', 43042=>'L', 43043=>'L', 43044=>'L', 43045=>'NSM', 43046=>'NSM', 43047=>'L', 43048=>'ON', 43049=>'ON', 43050=>'ON', 43051=>'ON', 43072=>'L', 43073=>'L', 43074=>'L', 43075=>'L', 43076=>'L', 43077=>'L', 43078=>'L', 43079=>'L', 43080=>'L', 43081=>'L', 43082=>'L', 43083=>'L', 43084=>'L', 43085=>'L', 43086=>'L', 43087=>'L', 43088=>'L', 43089=>'L', 43090=>'L', 43091=>'L', 43092=>'L', 43093=>'L', 43094=>'L', 43095=>'L', 43096=>'L', 43097=>'L', 43098=>'L', 43099=>'L', 43100=>'L', 43101=>'L', 43102=>'L', 43103=>'L', 43104=>'L', 43105=>'L', 43106=>'L', 43107=>'L', 43108=>'L', 43109=>'L', 43110=>'L', 43111=>'L', 43112=>'L', 43113=>'L', 43114=>'L', 43115=>'L', 43116=>'L', 43117=>'L', 43118=>'L', 43119=>'L', 43120=>'L', 43121=>'L', 43122=>'L', 43123=>'L', 43124=>'ON', 43125=>'ON', 43126=>'ON', 43127=>'ON', 44032=>'L', 55203=>'L', 55296=>'L', 56191=>'L', 56192=>'L', 56319=>'L', 56320=>'L', 57343=>'L', 57344=>'L', 63743=>'L', 63744=>'L', 63745=>'L', 63746=>'L', 63747=>'L', 63748=>'L', 63749=>'L', 63750=>'L', 63751=>'L', 63752=>'L', 63753=>'L', 63754=>'L', 63755=>'L', 63756=>'L', 63757=>'L', 63758=>'L', 63759=>'L', 63760=>'L', 63761=>'L', 63762=>'L', 63763=>'L', 63764=>'L', 63765=>'L', 63766=>'L', 63767=>'L', 63768=>'L', 63769=>'L', 63770=>'L', 63771=>'L', 63772=>'L', 63773=>'L', 63774=>'L', 63775=>'L', 63776=>'L', 63777=>'L', 63778=>'L', 63779=>'L', 63780=>'L', 63781=>'L', 63782=>'L', 63783=>'L', 63784=>'L', 63785=>'L', 63786=>'L', 63787=>'L', 63788=>'L', 63789=>'L', 63790=>'L', 63791=>'L', 63792=>'L', 63793=>'L', 63794=>'L', 63795=>'L', 63796=>'L', 63797=>'L', 63798=>'L', 63799=>'L', 63800=>'L', 63801=>'L', 63802=>'L', 63803=>'L', 63804=>'L', 63805=>'L', 63806=>'L', 63807=>'L', 63808=>'L', 63809=>'L', 63810=>'L', 63811=>'L', 63812=>'L', 63813=>'L', 63814=>'L', 63815=>'L', 63816=>'L', 63817=>'L', 63818=>'L', 63819=>'L', 63820=>'L', 63821=>'L', 63822=>'L', 63823=>'L', 63824=>'L', 63825=>'L', 63826=>'L', 63827=>'L', 63828=>'L', 63829=>'L', 63830=>'L', 63831=>'L', 63832=>'L', 63833=>'L', 63834=>'L', 63835=>'L', 63836=>'L', 63837=>'L', 63838=>'L', 63839=>'L', 63840=>'L', 63841=>'L', 63842=>'L', 63843=>'L', 63844=>'L', 63845=>'L', 63846=>'L', 63847=>'L', 63848=>'L', 63849=>'L', 63850=>'L', 63851=>'L', 63852=>'L', 63853=>'L', 63854=>'L', 63855=>'L', 63856=>'L', 63857=>'L', 63858=>'L', 63859=>'L', 63860=>'L', 63861=>'L', 63862=>'L', 63863=>'L', 63864=>'L', 63865=>'L', 63866=>'L', 63867=>'L', 63868=>'L', 63869=>'L', 63870=>'L', 63871=>'L', 63872=>'L', 63873=>'L', 63874=>'L', 63875=>'L', 63876=>'L', 63877=>'L', 63878=>'L', 63879=>'L', 63880=>'L', 63881=>'L', 63882=>'L', 63883=>'L', 63884=>'L', 63885=>'L', 63886=>'L', 63887=>'L', 63888=>'L', 63889=>'L', 63890=>'L', 63891=>'L', 63892=>'L', 63893=>'L', 63894=>'L', 63895=>'L', 63896=>'L', 63897=>'L', 63898=>'L', 63899=>'L', 63900=>'L', 63901=>'L', 63902=>'L', 63903=>'L', 63904=>'L', 63905=>'L', 63906=>'L', 63907=>'L', 63908=>'L', 63909=>'L', 63910=>'L', 63911=>'L', 63912=>'L', 63913=>'L', 63914=>'L', 63915=>'L', 63916=>'L', 63917=>'L', 63918=>'L', 63919=>'L', 63920=>'L', 63921=>'L', 63922=>'L', 63923=>'L', 63924=>'L', 63925=>'L', 63926=>'L', 63927=>'L', 63928=>'L', 63929=>'L', 63930=>'L', 63931=>'L', 63932=>'L', 63933=>'L', 63934=>'L', 63935=>'L', 63936=>'L', 63937=>'L', 63938=>'L', 63939=>'L', 63940=>'L', 63941=>'L', 63942=>'L', 63943=>'L', 63944=>'L', 63945=>'L', 63946=>'L', 63947=>'L', 63948=>'L', 63949=>'L', 63950=>'L', 63951=>'L', 63952=>'L', 63953=>'L', 63954=>'L', 63955=>'L', 63956=>'L', 63957=>'L', 63958=>'L', 63959=>'L', 63960=>'L', 63961=>'L', 63962=>'L', 63963=>'L', 63964=>'L', 63965=>'L', 63966=>'L', 63967=>'L', 63968=>'L', 63969=>'L', 63970=>'L', 63971=>'L', 63972=>'L', 63973=>'L', 63974=>'L', 63975=>'L', 63976=>'L', 63977=>'L', 63978=>'L', 63979=>'L', 63980=>'L', 63981=>'L', 63982=>'L', 63983=>'L', 63984=>'L', 63985=>'L', 63986=>'L', 63987=>'L', 63988=>'L', 63989=>'L', 63990=>'L', 63991=>'L', 63992=>'L', 63993=>'L', 63994=>'L', 63995=>'L', 63996=>'L', 63997=>'L', 63998=>'L', 63999=>'L', 64000=>'L', 64001=>'L', 64002=>'L', 64003=>'L', 64004=>'L', 64005=>'L', 64006=>'L', 64007=>'L', 64008=>'L', 64009=>'L', 64010=>'L', 64011=>'L', 64012=>'L', 64013=>'L', 64014=>'L', 64015=>'L', 64016=>'L', 64017=>'L', 64018=>'L', 64019=>'L', 64020=>'L', 64021=>'L', 64022=>'L', 64023=>'L', 64024=>'L', 64025=>'L', 64026=>'L', 64027=>'L', 64028=>'L', 64029=>'L', 64030=>'L', 64031=>'L', 64032=>'L', 64033=>'L', 64034=>'L', 64035=>'L', 64036=>'L', 64037=>'L', 64038=>'L', 64039=>'L', 64040=>'L', 64041=>'L', 64042=>'L', 64043=>'L', 64044=>'L', 64045=>'L', 64048=>'L', 64049=>'L', 64050=>'L', 64051=>'L', 64052=>'L', 64053=>'L', 64054=>'L', 64055=>'L', 64056=>'L', 64057=>'L', 64058=>'L', 64059=>'L', 64060=>'L', 64061=>'L', 64062=>'L', 64063=>'L', 64064=>'L', 64065=>'L', 64066=>'L', 64067=>'L', 64068=>'L', 64069=>'L', 64070=>'L', 64071=>'L', 64072=>'L', 64073=>'L', 64074=>'L', 64075=>'L', 64076=>'L', 64077=>'L', 64078=>'L', 64079=>'L', 64080=>'L', 64081=>'L', 64082=>'L', 64083=>'L', 64084=>'L', 64085=>'L', 64086=>'L', 64087=>'L', 64088=>'L', 64089=>'L', 64090=>'L', 64091=>'L', 64092=>'L', 64093=>'L', 64094=>'L', 64095=>'L', 64096=>'L', 64097=>'L', 64098=>'L', 64099=>'L', 64100=>'L', 64101=>'L', 64102=>'L', 64103=>'L', 64104=>'L', 64105=>'L', 64106=>'L', 64112=>'L', 64113=>'L', 64114=>'L', 64115=>'L', 64116=>'L', 64117=>'L', 64118=>'L', 64119=>'L', 64120=>'L', 64121=>'L', 64122=>'L', 64123=>'L', 64124=>'L', 64125=>'L', 64126=>'L', 64127=>'L', 64128=>'L', 64129=>'L', 64130=>'L', 64131=>'L', 64132=>'L', 64133=>'L', 64134=>'L', 64135=>'L', 64136=>'L', 64137=>'L', 64138=>'L', 64139=>'L', 64140=>'L', 64141=>'L', 64142=>'L', 64143=>'L', 64144=>'L', 64145=>'L', 64146=>'L', 64147=>'L', 64148=>'L', 64149=>'L', 64150=>'L', 64151=>'L', 64152=>'L', 64153=>'L', 64154=>'L', 64155=>'L', 64156=>'L', 64157=>'L', 64158=>'L', 64159=>'L', 64160=>'L', 64161=>'L', 64162=>'L', 64163=>'L', 64164=>'L', 64165=>'L', 64166=>'L', 64167=>'L', 64168=>'L', 64169=>'L', 64170=>'L', 64171=>'L', 64172=>'L', 64173=>'L', 64174=>'L', 64175=>'L', 64176=>'L', 64177=>'L', 64178=>'L', 64179=>'L', 64180=>'L', 64181=>'L', 64182=>'L', 64183=>'L', 64184=>'L', 64185=>'L', 64186=>'L', 64187=>'L', 64188=>'L', 64189=>'L', 64190=>'L', 64191=>'L', 64192=>'L', 64193=>'L', 64194=>'L', 64195=>'L', 64196=>'L', 64197=>'L', 64198=>'L', 64199=>'L', 64200=>'L', 64201=>'L', 64202=>'L', 64203=>'L', 64204=>'L', 64205=>'L', 64206=>'L', 64207=>'L', 64208=>'L', 64209=>'L', 64210=>'L', 64211=>'L', 64212=>'L', 64213=>'L', 64214=>'L', 64215=>'L', 64216=>'L', 64217=>'L', 64256=>'L', 64257=>'L', 64258=>'L', 64259=>'L', 64260=>'L', 64261=>'L', 64262=>'L', 64275=>'L', 64276=>'L', 64277=>'L', 64278=>'L', 64279=>'L', 64285=>'R', 64286=>'NSM', 64287=>'R', 64288=>'R', 64289=>'R', 64290=>'R', 64291=>'R', 64292=>'R', 64293=>'R', 64294=>'R', 64295=>'R', 64296=>'R', 64297=>'ES', 64298=>'R', 64299=>'R', 64300=>'R', 64301=>'R', 64302=>'R', 64303=>'R', 64304=>'R', 64305=>'R', 64306=>'R', 64307=>'R', 64308=>'R', 64309=>'R', 64310=>'R', 64312=>'R', 64313=>'R', 64314=>'R', 64315=>'R', 64316=>'R', 64318=>'R', 64320=>'R', 64321=>'R', 64323=>'R', 64324=>'R', 64326=>'R', 64327=>'R', 64328=>'R', 64329=>'R', 64330=>'R', 64331=>'R', 64332=>'R', 64333=>'R', 64334=>'R', 64335=>'R', 64336=>'AL', 64337=>'AL', 64338=>'AL', 64339=>'AL', 64340=>'AL', 64341=>'AL', 64342=>'AL', 64343=>'AL', 64344=>'AL', 64345=>'AL', 64346=>'AL', 64347=>'AL', 64348=>'AL', 64349=>'AL', 64350=>'AL', 64351=>'AL', 64352=>'AL', 64353=>'AL', 64354=>'AL', 64355=>'AL', 64356=>'AL', 64357=>'AL', 64358=>'AL', 64359=>'AL', 64360=>'AL', 64361=>'AL', 64362=>'AL', 64363=>'AL', 64364=>'AL', 64365=>'AL', 64366=>'AL', 64367=>'AL', 64368=>'AL', 64369=>'AL', 64370=>'AL', 64371=>'AL', 64372=>'AL', 64373=>'AL', 64374=>'AL', 64375=>'AL', 64376=>'AL', 64377=>'AL', 64378=>'AL', 64379=>'AL', 64380=>'AL', 64381=>'AL', 64382=>'AL', 64383=>'AL', 64384=>'AL', 64385=>'AL', 64386=>'AL', 64387=>'AL', 64388=>'AL', 64389=>'AL', 64390=>'AL', 64391=>'AL', 64392=>'AL', 64393=>'AL', 64394=>'AL', 64395=>'AL', 64396=>'AL', 64397=>'AL', 64398=>'AL', 64399=>'AL', 64400=>'AL', 64401=>'AL', 64402=>'AL', 64403=>'AL', 64404=>'AL', 64405=>'AL', 64406=>'AL', 64407=>'AL', 64408=>'AL', 64409=>'AL', 64410=>'AL', 64411=>'AL', 64412=>'AL', 64413=>'AL', 64414=>'AL', 64415=>'AL', 64416=>'AL', 64417=>'AL', 64418=>'AL', 64419=>'AL', 64420=>'AL', 64421=>'AL', 64422=>'AL', 64423=>'AL', 64424=>'AL', 64425=>'AL', 64426=>'AL', 64427=>'AL', 64428=>'AL', 64429=>'AL', 64430=>'AL', 64431=>'AL', 64432=>'AL', 64433=>'AL', 64467=>'AL', 64468=>'AL', 64469=>'AL', 64470=>'AL', 64471=>'AL', 64472=>'AL', 64473=>'AL', 64474=>'AL', 64475=>'AL', 64476=>'AL', 64477=>'AL', 64478=>'AL', 64479=>'AL', 64480=>'AL', 64481=>'AL', 64482=>'AL', 64483=>'AL', 64484=>'AL', 64485=>'AL', 64486=>'AL', 64487=>'AL', 64488=>'AL', 64489=>'AL', 64490=>'AL', 64491=>'AL', 64492=>'AL', 64493=>'AL', 64494=>'AL', 64495=>'AL', 64496=>'AL', 64497=>'AL', 64498=>'AL', 64499=>'AL', 64500=>'AL', 64501=>'AL', 64502=>'AL', 64503=>'AL', 64504=>'AL', 64505=>'AL', 64506=>'AL', 64507=>'AL', 64508=>'AL', 64509=>'AL', 64510=>'AL', 64511=>'AL', 64512=>'AL', 64513=>'AL', 64514=>'AL', 64515=>'AL', 64516=>'AL', 64517=>'AL', 64518=>'AL', 64519=>'AL', 64520=>'AL', 64521=>'AL', 64522=>'AL', 64523=>'AL', 64524=>'AL', 64525=>'AL', 64526=>'AL', 64527=>'AL', 64528=>'AL', 64529=>'AL', 64530=>'AL', 64531=>'AL', 64532=>'AL', 64533=>'AL', 64534=>'AL', 64535=>'AL', 64536=>'AL', 64537=>'AL', 64538=>'AL', 64539=>'AL', 64540=>'AL', 64541=>'AL', 64542=>'AL', 64543=>'AL', 64544=>'AL', 64545=>'AL', 64546=>'AL', 64547=>'AL', 64548=>'AL', 64549=>'AL', 64550=>'AL', 64551=>'AL', 64552=>'AL', 64553=>'AL', 64554=>'AL', 64555=>'AL', 64556=>'AL', 64557=>'AL', 64558=>'AL', 64559=>'AL', 64560=>'AL', 64561=>'AL', 64562=>'AL', 64563=>'AL', 64564=>'AL', 64565=>'AL', 64566=>'AL', 64567=>'AL', 64568=>'AL', 64569=>'AL', 64570=>'AL', 64571=>'AL', 64572=>'AL', 64573=>'AL', 64574=>'AL', 64575=>'AL', 64576=>'AL', 64577=>'AL', 64578=>'AL', 64579=>'AL', 64580=>'AL', 64581=>'AL', 64582=>'AL', 64583=>'AL', 64584=>'AL', 64585=>'AL', 64586=>'AL', 64587=>'AL', 64588=>'AL', 64589=>'AL', 64590=>'AL', 64591=>'AL', 64592=>'AL', 64593=>'AL', 64594=>'AL', 64595=>'AL', 64596=>'AL', 64597=>'AL', 64598=>'AL', 64599=>'AL', 64600=>'AL', 64601=>'AL', 64602=>'AL', 64603=>'AL', 64604=>'AL', 64605=>'AL', 64606=>'AL', 64607=>'AL', 64608=>'AL', 64609=>'AL', 64610=>'AL', 64611=>'AL', 64612=>'AL', 64613=>'AL', 64614=>'AL', 64615=>'AL', 64616=>'AL', 64617=>'AL', 64618=>'AL', 64619=>'AL', 64620=>'AL', 64621=>'AL', 64622=>'AL', 64623=>'AL', 64624=>'AL', 64625=>'AL', 64626=>'AL', 64627=>'AL', 64628=>'AL', 64629=>'AL', 64630=>'AL', 64631=>'AL', 64632=>'AL', 64633=>'AL', 64634=>'AL', 64635=>'AL', 64636=>'AL', 64637=>'AL', 64638=>'AL', 64639=>'AL', 64640=>'AL', 64641=>'AL', 64642=>'AL', 64643=>'AL', 64644=>'AL', 64645=>'AL', 64646=>'AL', 64647=>'AL', 64648=>'AL', 64649=>'AL', 64650=>'AL', 64651=>'AL', 64652=>'AL', 64653=>'AL', 64654=>'AL', 64655=>'AL', 64656=>'AL', 64657=>'AL', 64658=>'AL', 64659=>'AL', 64660=>'AL', 64661=>'AL', 64662=>'AL', 64663=>'AL', 64664=>'AL', 64665=>'AL', 64666=>'AL', 64667=>'AL', 64668=>'AL', 64669=>'AL', 64670=>'AL', 64671=>'AL', 64672=>'AL', 64673=>'AL', 64674=>'AL', 64675=>'AL', 64676=>'AL', 64677=>'AL', 64678=>'AL', 64679=>'AL', 64680=>'AL', 64681=>'AL', 64682=>'AL', 64683=>'AL', 64684=>'AL', 64685=>'AL', 64686=>'AL', 64687=>'AL', 64688=>'AL', 64689=>'AL', 64690=>'AL', 64691=>'AL', 64692=>'AL', 64693=>'AL', 64694=>'AL', 64695=>'AL', 64696=>'AL', 64697=>'AL', 64698=>'AL', 64699=>'AL', 64700=>'AL', 64701=>'AL', 64702=>'AL', 64703=>'AL', 64704=>'AL', 64705=>'AL', 64706=>'AL', 64707=>'AL', 64708=>'AL', 64709=>'AL', 64710=>'AL', 64711=>'AL', 64712=>'AL', 64713=>'AL', 64714=>'AL', 64715=>'AL', 64716=>'AL', 64717=>'AL', 64718=>'AL', 64719=>'AL', 64720=>'AL', 64721=>'AL', 64722=>'AL', 64723=>'AL', 64724=>'AL', 64725=>'AL', 64726=>'AL', 64727=>'AL', 64728=>'AL', 64729=>'AL', 64730=>'AL', 64731=>'AL', 64732=>'AL', 64733=>'AL', 64734=>'AL', 64735=>'AL', 64736=>'AL', 64737=>'AL', 64738=>'AL', 64739=>'AL', 64740=>'AL', 64741=>'AL', 64742=>'AL', 64743=>'AL', 64744=>'AL', 64745=>'AL', 64746=>'AL', 64747=>'AL', 64748=>'AL', 64749=>'AL', 64750=>'AL', 64751=>'AL', 64752=>'AL', 64753=>'AL', 64754=>'AL', 64755=>'AL', 64756=>'AL', 64757=>'AL', 64758=>'AL', 64759=>'AL', 64760=>'AL', 64761=>'AL', 64762=>'AL', 64763=>'AL', 64764=>'AL', 64765=>'AL', 64766=>'AL', 64767=>'AL', 64768=>'AL', 64769=>'AL', 64770=>'AL', 64771=>'AL', 64772=>'AL', 64773=>'AL', 64774=>'AL', 64775=>'AL', 64776=>'AL', 64777=>'AL', 64778=>'AL', 64779=>'AL', 64780=>'AL', 64781=>'AL', 64782=>'AL', 64783=>'AL', 64784=>'AL', 64785=>'AL', 64786=>'AL', 64787=>'AL', 64788=>'AL', 64789=>'AL', 64790=>'AL', 64791=>'AL', 64792=>'AL', 64793=>'AL', 64794=>'AL', 64795=>'AL', 64796=>'AL', 64797=>'AL', 64798=>'AL', 64799=>'AL', 64800=>'AL', 64801=>'AL', 64802=>'AL', 64803=>'AL', 64804=>'AL', 64805=>'AL', 64806=>'AL', 64807=>'AL', 64808=>'AL', 64809=>'AL', 64810=>'AL', 64811=>'AL', 64812=>'AL', 64813=>'AL', 64814=>'AL', 64815=>'AL', 64816=>'AL', 64817=>'AL', 64818=>'AL', 64819=>'AL', 64820=>'AL', 64821=>'AL', 64822=>'AL', 64823=>'AL', 64824=>'AL', 64825=>'AL', 64826=>'AL', 64827=>'AL', 64828=>'AL', 64829=>'AL', 64830=>'ON', 64831=>'ON', 64848=>'AL', 64849=>'AL', 64850=>'AL', 64851=>'AL', 64852=>'AL', 64853=>'AL', 64854=>'AL', 64855=>'AL', 64856=>'AL', 64857=>'AL', 64858=>'AL', 64859=>'AL', 64860=>'AL', 64861=>'AL', 64862=>'AL', 64863=>'AL', 64864=>'AL', 64865=>'AL', 64866=>'AL', 64867=>'AL', 64868=>'AL', 64869=>'AL', 64870=>'AL', 64871=>'AL', 64872=>'AL', 64873=>'AL', 64874=>'AL', 64875=>'AL', 64876=>'AL', 64877=>'AL', 64878=>'AL', 64879=>'AL', 64880=>'AL', 64881=>'AL', 64882=>'AL', 64883=>'AL', 64884=>'AL', 64885=>'AL', 64886=>'AL', 64887=>'AL', 64888=>'AL', 64889=>'AL', 64890=>'AL', 64891=>'AL', 64892=>'AL', 64893=>'AL', 64894=>'AL', 64895=>'AL', 64896=>'AL', 64897=>'AL', 64898=>'AL', 64899=>'AL', 64900=>'AL', 64901=>'AL', 64902=>'AL', 64903=>'AL', 64904=>'AL', 64905=>'AL', 64906=>'AL', 64907=>'AL', 64908=>'AL', 64909=>'AL', 64910=>'AL', 64911=>'AL', 64914=>'AL', 64915=>'AL', 64916=>'AL', 64917=>'AL', 64918=>'AL', 64919=>'AL', 64920=>'AL', 64921=>'AL', 64922=>'AL', 64923=>'AL', 64924=>'AL', 64925=>'AL', 64926=>'AL', 64927=>'AL', 64928=>'AL', 64929=>'AL', 64930=>'AL', 64931=>'AL', 64932=>'AL', 64933=>'AL', 64934=>'AL', 64935=>'AL', 64936=>'AL', 64937=>'AL', 64938=>'AL', 64939=>'AL', 64940=>'AL', 64941=>'AL', 64942=>'AL', 64943=>'AL', 64944=>'AL', 64945=>'AL', 64946=>'AL', 64947=>'AL', 64948=>'AL', 64949=>'AL', 64950=>'AL', 64951=>'AL', 64952=>'AL', 64953=>'AL', 64954=>'AL', 64955=>'AL', 64956=>'AL', 64957=>'AL', 64958=>'AL', 64959=>'AL', 64960=>'AL', 64961=>'AL', 64962=>'AL', 64963=>'AL', 64964=>'AL', 64965=>'AL', 64966=>'AL', 64967=>'AL', 65008=>'AL', 65009=>'AL', 65010=>'AL', 65011=>'AL', 65012=>'AL', 65013=>'AL', 65014=>'AL', 65015=>'AL', 65016=>'AL', 65017=>'AL', 65018=>'AL', 65019=>'AL', 65020=>'AL', 65021=>'ON', 65024=>'NSM', 65025=>'NSM', 65026=>'NSM', 65027=>'NSM', 65028=>'NSM', 65029=>'NSM', 65030=>'NSM', 65031=>'NSM', 65032=>'NSM', 65033=>'NSM', 65034=>'NSM', 65035=>'NSM', 65036=>'NSM', 65037=>'NSM', 65038=>'NSM', 65039=>'NSM', 65040=>'ON', 65041=>'ON', 65042=>'ON', 65043=>'ON', 65044=>'ON', 65045=>'ON', 65046=>'ON', 65047=>'ON', 65048=>'ON', 65049=>'ON', 65056=>'NSM', 65057=>'NSM', 65058=>'NSM', 65059=>'NSM', 65072=>'ON', 65073=>'ON', 65074=>'ON', 65075=>'ON', 65076=>'ON', 65077=>'ON', 65078=>'ON', 65079=>'ON', 65080=>'ON', 65081=>'ON', 65082=>'ON', 65083=>'ON', 65084=>'ON', 65085=>'ON', 65086=>'ON', 65087=>'ON', 65088=>'ON', 65089=>'ON', 65090=>'ON', 65091=>'ON', 65092=>'ON', 65093=>'ON', 65094=>'ON', 65095=>'ON', 65096=>'ON', 65097=>'ON', 65098=>'ON', 65099=>'ON', 65100=>'ON', 65101=>'ON', 65102=>'ON', 65103=>'ON', 65104=>'CS', 65105=>'ON', 65106=>'CS', 65108=>'ON', 65109=>'CS', 65110=>'ON', 65111=>'ON', 65112=>'ON', 65113=>'ON', 65114=>'ON', 65115=>'ON', 65116=>'ON', 65117=>'ON', 65118=>'ON', 65119=>'ET', 65120=>'ON', 65121=>'ON', 65122=>'ES', 65123=>'ES', 65124=>'ON', 65125=>'ON', 65126=>'ON', 65128=>'ON', 65129=>'ET', 65130=>'ET', 65131=>'ON', 65136=>'AL', 65137=>'AL', 65138=>'AL', 65139=>'AL', 65140=>'AL', 65142=>'AL', 65143=>'AL', 65144=>'AL', 65145=>'AL', 65146=>'AL', 65147=>'AL', 65148=>'AL', 65149=>'AL', 65150=>'AL', 65151=>'AL', 65152=>'AL', 65153=>'AL', 65154=>'AL', 65155=>'AL', 65156=>'AL', 65157=>'AL', 65158=>'AL', 65159=>'AL', 65160=>'AL', 65161=>'AL', 65162=>'AL', 65163=>'AL', 65164=>'AL', 65165=>'AL', 65166=>'AL', 65167=>'AL', 65168=>'AL', 65169=>'AL', 65170=>'AL', 65171=>'AL', 65172=>'AL', 65173=>'AL', 65174=>'AL', 65175=>'AL', 65176=>'AL', 65177=>'AL', 65178=>'AL', 65179=>'AL', 65180=>'AL', 65181=>'AL', 65182=>'AL', 65183=>'AL', 65184=>'AL', 65185=>'AL', 65186=>'AL', 65187=>'AL', 65188=>'AL', 65189=>'AL', 65190=>'AL', 65191=>'AL', 65192=>'AL', 65193=>'AL', 65194=>'AL', 65195=>'AL', 65196=>'AL', 65197=>'AL', 65198=>'AL', 65199=>'AL', 65200=>'AL', 65201=>'AL', 65202=>'AL', 65203=>'AL', 65204=>'AL', 65205=>'AL', 65206=>'AL', 65207=>'AL', 65208=>'AL', 65209=>'AL', 65210=>'AL', 65211=>'AL', 65212=>'AL', 65213=>'AL', 65214=>'AL', 65215=>'AL', 65216=>'AL', 65217=>'AL', 65218=>'AL', 65219=>'AL', 65220=>'AL', 65221=>'AL', 65222=>'AL', 65223=>'AL', 65224=>'AL', 65225=>'AL', 65226=>'AL', 65227=>'AL', 65228=>'AL', 65229=>'AL', 65230=>'AL', 65231=>'AL', 65232=>'AL', 65233=>'AL', 65234=>'AL', 65235=>'AL', 65236=>'AL', 65237=>'AL', 65238=>'AL', 65239=>'AL', 65240=>'AL', 65241=>'AL', 65242=>'AL', 65243=>'AL', 65244=>'AL', 65245=>'AL', 65246=>'AL', 65247=>'AL', 65248=>'AL', 65249=>'AL', 65250=>'AL', 65251=>'AL', 65252=>'AL', 65253=>'AL', 65254=>'AL', 65255=>'AL', 65256=>'AL', 65257=>'AL', 65258=>'AL', 65259=>'AL', 65260=>'AL', 65261=>'AL', 65262=>'AL', 65263=>'AL', 65264=>'AL', 65265=>'AL', 65266=>'AL', 65267=>'AL', 65268=>'AL', 65269=>'AL', 65270=>'AL', 65271=>'AL', 65272=>'AL', 65273=>'AL', 65274=>'AL', 65275=>'AL', 65276=>'AL', 65279=>'BN', 65281=>'ON', 65282=>'ON', 65283=>'ET', 65284=>'ET', 65285=>'ET', 65286=>'ON', 65287=>'ON', 65288=>'ON', 65289=>'ON', 65290=>'ON', 65291=>'ES', 65292=>'CS', 65293=>'ES', 65294=>'CS', 65295=>'CS', 65296=>'EN', 65297=>'EN', 65298=>'EN', 65299=>'EN', 65300=>'EN', 65301=>'EN', 65302=>'EN', 65303=>'EN', 65304=>'EN', 65305=>'EN', 65306=>'CS', 65307=>'ON', 65308=>'ON', 65309=>'ON', 65310=>'ON', 65311=>'ON', 65312=>'ON', 65313=>'L', 65314=>'L', 65315=>'L', 65316=>'L', 65317=>'L', 65318=>'L', 65319=>'L', 65320=>'L', 65321=>'L', 65322=>'L', 65323=>'L', 65324=>'L', 65325=>'L', 65326=>'L', 65327=>'L', 65328=>'L', 65329=>'L', 65330=>'L', 65331=>'L', 65332=>'L', 65333=>'L', 65334=>'L', 65335=>'L', 65336=>'L', 65337=>'L', 65338=>'L', 65339=>'ON', 65340=>'ON', 65341=>'ON', 65342=>'ON', 65343=>'ON', 65344=>'ON', 65345=>'L', 65346=>'L', 65347=>'L', 65348=>'L', 65349=>'L', 65350=>'L', 65351=>'L', 65352=>'L', 65353=>'L', 65354=>'L', 65355=>'L', 65356=>'L', 65357=>'L', 65358=>'L', 65359=>'L', 65360=>'L', 65361=>'L', 65362=>'L', 65363=>'L', 65364=>'L', 65365=>'L', 65366=>'L', 65367=>'L', 65368=>'L', 65369=>'L', 65370=>'L', 65371=>'ON', 65372=>'ON', 65373=>'ON', 65374=>'ON', 65375=>'ON', 65376=>'ON', 65377=>'ON', 65378=>'ON', 65379=>'ON', 65380=>'ON', 65381=>'ON', 65382=>'L', 65383=>'L', 65384=>'L', 65385=>'L', 65386=>'L', 65387=>'L', 65388=>'L', 65389=>'L', 65390=>'L', 65391=>'L', 65392=>'L', 65393=>'L', 65394=>'L', 65395=>'L', 65396=>'L', 65397=>'L', 65398=>'L', 65399=>'L', 65400=>'L', 65401=>'L', 65402=>'L', 65403=>'L', 65404=>'L', 65405=>'L', 65406=>'L', 65407=>'L', 65408=>'L', 65409=>'L', 65410=>'L', 65411=>'L', 65412=>'L', 65413=>'L', 65414=>'L', 65415=>'L', 65416=>'L', 65417=>'L', 65418=>'L', 65419=>'L', 65420=>'L', 65421=>'L', 65422=>'L', 65423=>'L', 65424=>'L', 65425=>'L', 65426=>'L', 65427=>'L', 65428=>'L', 65429=>'L', 65430=>'L', 65431=>'L', 65432=>'L', 65433=>'L', 65434=>'L', 65435=>'L', 65436=>'L', 65437=>'L', 65438=>'L', 65439=>'L', 65440=>'L', 65441=>'L', 65442=>'L', 65443=>'L', 65444=>'L', 65445=>'L', 65446=>'L', 65447=>'L', 65448=>'L', 65449=>'L', 65450=>'L', 65451=>'L', 65452=>'L', 65453=>'L', 65454=>'L', 65455=>'L', 65456=>'L', 65457=>'L', 65458=>'L', 65459=>'L', 65460=>'L', 65461=>'L', 65462=>'L', 65463=>'L', 65464=>'L', 65465=>'L', 65466=>'L', 65467=>'L', 65468=>'L', 65469=>'L', 65470=>'L', 65474=>'L', 65475=>'L', 65476=>'L', 65477=>'L', 65478=>'L', 65479=>'L', 65482=>'L', 65483=>'L', 65484=>'L', 65485=>'L', 65486=>'L', 65487=>'L', 65490=>'L', 65491=>'L', 65492=>'L', 65493=>'L', 65494=>'L', 65495=>'L', 65498=>'L', 65499=>'L', 65500=>'L', 65504=>'ET', 65505=>'ET', 65506=>'ON', 65507=>'ON', 65508=>'ON', 65509=>'ET', 65510=>'ET', 65512=>'ON', 65513=>'ON', 65514=>'ON', 65515=>'ON', 65516=>'ON', 65517=>'ON', 65518=>'ON', 65529=>'ON', 65530=>'ON', 65531=>'ON', 65532=>'ON', 65533=>'ON', 65536=>'L', 65537=>'L', 65538=>'L', 65539=>'L', 65540=>'L', 65541=>'L', 65542=>'L', 65543=>'L', 65544=>'L', 65545=>'L', 65546=>'L', 65547=>'L', 65549=>'L', 65550=>'L', 65551=>'L', 65552=>'L', 65553=>'L', 65554=>'L', 65555=>'L', 65556=>'L', 65557=>'L', 65558=>'L', 65559=>'L', 65560=>'L', 65561=>'L', 65562=>'L', 65563=>'L', 65564=>'L', 65565=>'L', 65566=>'L', 65567=>'L', 65568=>'L', 65569=>'L', 65570=>'L', 65571=>'L', 65572=>'L', 65573=>'L', 65574=>'L', 65576=>'L', 65577=>'L', 65578=>'L', 65579=>'L', 65580=>'L', 65581=>'L', 65582=>'L', 65583=>'L', 65584=>'L', 65585=>'L', 65586=>'L', 65587=>'L', 65588=>'L', 65589=>'L', 65590=>'L', 65591=>'L', 65592=>'L', 65593=>'L', 65594=>'L', 65596=>'L', 65597=>'L', 65599=>'L', 65600=>'L', 65601=>'L', 65602=>'L', 65603=>'L', 65604=>'L', 65605=>'L', 65606=>'L', 65607=>'L', 65608=>'L', 65609=>'L', 65610=>'L', 65611=>'L', 65612=>'L', 65613=>'L', 65616=>'L', 65617=>'L', 65618=>'L', 65619=>'L', 65620=>'L', 65621=>'L', 65622=>'L', 65623=>'L', 65624=>'L', 65625=>'L', 65626=>'L', 65627=>'L', 65628=>'L', 65629=>'L', 65664=>'L', 65665=>'L', 65666=>'L', 65667=>'L', 65668=>'L', 65669=>'L', 65670=>'L', 65671=>'L', 65672=>'L', 65673=>'L', 65674=>'L', 65675=>'L', 65676=>'L', 65677=>'L', 65678=>'L', 65679=>'L', 65680=>'L', 65681=>'L', 65682=>'L', 65683=>'L', 65684=>'L', 65685=>'L', 65686=>'L', 65687=>'L', 65688=>'L', 65689=>'L', 65690=>'L', 65691=>'L', 65692=>'L', 65693=>'L', 65694=>'L', 65695=>'L', 65696=>'L', 65697=>'L', 65698=>'L', 65699=>'L', 65700=>'L', 65701=>'L', 65702=>'L', 65703=>'L', 65704=>'L', 65705=>'L', 65706=>'L', 65707=>'L', 65708=>'L', 65709=>'L', 65710=>'L', 65711=>'L', 65712=>'L', 65713=>'L', 65714=>'L', 65715=>'L', 65716=>'L', 65717=>'L', 65718=>'L', 65719=>'L', 65720=>'L', 65721=>'L', 65722=>'L', 65723=>'L', 65724=>'L', 65725=>'L', 65726=>'L', 65727=>'L', 65728=>'L', 65729=>'L', 65730=>'L', 65731=>'L', 65732=>'L', 65733=>'L', 65734=>'L', 65735=>'L', 65736=>'L', 65737=>'L', 65738=>'L', 65739=>'L', 65740=>'L', 65741=>'L', 65742=>'L', 65743=>'L', 65744=>'L', 65745=>'L', 65746=>'L', 65747=>'L', 65748=>'L', 65749=>'L', 65750=>'L', 65751=>'L', 65752=>'L', 65753=>'L', 65754=>'L', 65755=>'L', 65756=>'L', 65757=>'L', 65758=>'L', 65759=>'L', 65760=>'L', 65761=>'L', 65762=>'L', 65763=>'L', 65764=>'L', 65765=>'L', 65766=>'L', 65767=>'L', 65768=>'L', 65769=>'L', 65770=>'L', 65771=>'L', 65772=>'L', 65773=>'L', 65774=>'L', 65775=>'L', 65776=>'L', 65777=>'L', 65778=>'L', 65779=>'L', 65780=>'L', 65781=>'L', 65782=>'L', 65783=>'L', 65784=>'L', 65785=>'L', 65786=>'L', 65792=>'L', 65793=>'ON', 65794=>'L', 65799=>'L', 65800=>'L', 65801=>'L', 65802=>'L', 65803=>'L', 65804=>'L', 65805=>'L', 65806=>'L', 65807=>'L', 65808=>'L', 65809=>'L', 65810=>'L', 65811=>'L', 65812=>'L', 65813=>'L', 65814=>'L', 65815=>'L', 65816=>'L', 65817=>'L', 65818=>'L', 65819=>'L', 65820=>'L', 65821=>'L', 65822=>'L', 65823=>'L', 65824=>'L', 65825=>'L', 65826=>'L', 65827=>'L', 65828=>'L', 65829=>'L', 65830=>'L', 65831=>'L', 65832=>'L', 65833=>'L', 65834=>'L', 65835=>'L', 65836=>'L', 65837=>'L', 65838=>'L', 65839=>'L', 65840=>'L', 65841=>'L', 65842=>'L', 65843=>'L', 65847=>'L', 65848=>'L', 65849=>'L', 65850=>'L', 65851=>'L', 65852=>'L', 65853=>'L', 65854=>'L', 65855=>'L', 65856=>'ON', 65857=>'ON', 65858=>'ON', 65859=>'ON', 65860=>'ON', 65861=>'ON', 65862=>'ON', 65863=>'ON', 65864=>'ON', 65865=>'ON', 65866=>'ON', 65867=>'ON', 65868=>'ON', 65869=>'ON', 65870=>'ON', 65871=>'ON', 65872=>'ON', 65873=>'ON', 65874=>'ON', 65875=>'ON', 65876=>'ON', 65877=>'ON', 65878=>'ON', 65879=>'ON', 65880=>'ON', 65881=>'ON', 65882=>'ON', 65883=>'ON', 65884=>'ON', 65885=>'ON', 65886=>'ON', 65887=>'ON', 65888=>'ON', 65889=>'ON', 65890=>'ON', 65891=>'ON', 65892=>'ON', 65893=>'ON', 65894=>'ON', 65895=>'ON', 65896=>'ON', 65897=>'ON', 65898=>'ON', 65899=>'ON', 65900=>'ON', 65901=>'ON', 65902=>'ON', 65903=>'ON', 65904=>'ON', 65905=>'ON', 65906=>'ON', 65907=>'ON', 65908=>'ON', 65909=>'ON', 65910=>'ON', 65911=>'ON', 65912=>'ON', 65913=>'ON', 65914=>'ON', 65915=>'ON', 65916=>'ON', 65917=>'ON', 65918=>'ON', 65919=>'ON', 65920=>'ON', 65921=>'ON', 65922=>'ON', 65923=>'ON', 65924=>'ON', 65925=>'ON', 65926=>'ON', 65927=>'ON', 65928=>'ON', 65929=>'ON', 65930=>'ON', 66304=>'L', 66305=>'L', 66306=>'L', 66307=>'L', 66308=>'L', 66309=>'L', 66310=>'L', 66311=>'L', 66312=>'L', 66313=>'L', 66314=>'L', 66315=>'L', 66316=>'L', 66317=>'L', 66318=>'L', 66319=>'L', 66320=>'L', 66321=>'L', 66322=>'L', 66323=>'L', 66324=>'L', 66325=>'L', 66326=>'L', 66327=>'L', 66328=>'L', 66329=>'L', 66330=>'L', 66331=>'L', 66332=>'L', 66333=>'L', 66334=>'L', 66336=>'L', 66337=>'L', 66338=>'L', 66339=>'L', 66352=>'L', 66353=>'L', 66354=>'L', 66355=>'L', 66356=>'L', 66357=>'L', 66358=>'L', 66359=>'L', 66360=>'L', 66361=>'L', 66362=>'L', 66363=>'L', 66364=>'L', 66365=>'L', 66366=>'L', 66367=>'L', 66368=>'L', 66369=>'L', 66370=>'L', 66371=>'L', 66372=>'L', 66373=>'L', 66374=>'L', 66375=>'L', 66376=>'L', 66377=>'L', 66378=>'L', 66432=>'L', 66433=>'L', 66434=>'L', 66435=>'L', 66436=>'L', 66437=>'L', 66438=>'L', 66439=>'L', 66440=>'L', 66441=>'L', 66442=>'L', 66443=>'L', 66444=>'L', 66445=>'L', 66446=>'L', 66447=>'L', 66448=>'L', 66449=>'L', 66450=>'L', 66451=>'L', 66452=>'L', 66453=>'L', 66454=>'L', 66455=>'L', 66456=>'L', 66457=>'L', 66458=>'L', 66459=>'L', 66460=>'L', 66461=>'L', 66463=>'L', 66464=>'L', 66465=>'L', 66466=>'L', 66467=>'L', 66468=>'L', 66469=>'L', 66470=>'L', 66471=>'L', 66472=>'L', 66473=>'L', 66474=>'L', 66475=>'L', 66476=>'L', 66477=>'L', 66478=>'L', 66479=>'L', 66480=>'L', 66481=>'L', 66482=>'L', 66483=>'L', 66484=>'L', 66485=>'L', 66486=>'L', 66487=>'L', 66488=>'L', 66489=>'L', 66490=>'L', 66491=>'L', 66492=>'L', 66493=>'L', 66494=>'L', 66495=>'L', 66496=>'L', 66497=>'L', 66498=>'L', 66499=>'L', 66504=>'L', 66505=>'L', 66506=>'L', 66507=>'L', 66508=>'L', 66509=>'L', 66510=>'L', 66511=>'L', 66512=>'L', 66513=>'L', 66514=>'L', 66515=>'L', 66516=>'L', 66517=>'L', 66560=>'L', 66561=>'L', 66562=>'L', 66563=>'L', 66564=>'L', 66565=>'L', 66566=>'L', 66567=>'L', 66568=>'L', 66569=>'L', 66570=>'L', 66571=>'L', 66572=>'L', 66573=>'L', 66574=>'L', 66575=>'L', 66576=>'L', 66577=>'L', 66578=>'L', 66579=>'L', 66580=>'L', 66581=>'L', 66582=>'L', 66583=>'L', 66584=>'L', 66585=>'L', 66586=>'L', 66587=>'L', 66588=>'L', 66589=>'L', 66590=>'L', 66591=>'L', 66592=>'L', 66593=>'L', 66594=>'L', 66595=>'L', 66596=>'L', 66597=>'L', 66598=>'L', 66599=>'L', 66600=>'L', 66601=>'L', 66602=>'L', 66603=>'L', 66604=>'L', 66605=>'L', 66606=>'L', 66607=>'L', 66608=>'L', 66609=>'L', 66610=>'L', 66611=>'L', 66612=>'L', 66613=>'L', 66614=>'L', 66615=>'L', 66616=>'L', 66617=>'L', 66618=>'L', 66619=>'L', 66620=>'L', 66621=>'L', 66622=>'L', 66623=>'L', 66624=>'L', 66625=>'L', 66626=>'L', 66627=>'L', 66628=>'L', 66629=>'L', 66630=>'L', 66631=>'L', 66632=>'L', 66633=>'L', 66634=>'L', 66635=>'L', 66636=>'L', 66637=>'L', 66638=>'L', 66639=>'L', 66640=>'L', 66641=>'L', 66642=>'L', 66643=>'L', 66644=>'L', 66645=>'L', 66646=>'L', 66647=>'L', 66648=>'L', 66649=>'L', 66650=>'L', 66651=>'L', 66652=>'L', 66653=>'L', 66654=>'L', 66655=>'L', 66656=>'L', 66657=>'L', 66658=>'L', 66659=>'L', 66660=>'L', 66661=>'L', 66662=>'L', 66663=>'L', 66664=>'L', 66665=>'L', 66666=>'L', 66667=>'L', 66668=>'L', 66669=>'L', 66670=>'L', 66671=>'L', 66672=>'L', 66673=>'L', 66674=>'L', 66675=>'L', 66676=>'L', 66677=>'L', 66678=>'L', 66679=>'L', 66680=>'L', 66681=>'L', 66682=>'L', 66683=>'L', 66684=>'L', 66685=>'L', 66686=>'L', 66687=>'L', 66688=>'L', 66689=>'L', 66690=>'L', 66691=>'L', 66692=>'L', 66693=>'L', 66694=>'L', 66695=>'L', 66696=>'L', 66697=>'L', 66698=>'L', 66699=>'L', 66700=>'L', 66701=>'L', 66702=>'L', 66703=>'L', 66704=>'L', 66705=>'L', 66706=>'L', 66707=>'L', 66708=>'L', 66709=>'L', 66710=>'L', 66711=>'L', 66712=>'L', 66713=>'L', 66714=>'L', 66715=>'L', 66716=>'L', 66717=>'L', 66720=>'L', 66721=>'L', 66722=>'L', 66723=>'L', 66724=>'L', 66725=>'L', 66726=>'L', 66727=>'L', 66728=>'L', 66729=>'L', 67584=>'R', 67585=>'R', 67586=>'R', 67587=>'R', 67588=>'R', 67589=>'R', 67592=>'R', 67594=>'R', 67595=>'R', 67596=>'R', 67597=>'R', 67598=>'R', 67599=>'R', 67600=>'R', 67601=>'R', 67602=>'R', 67603=>'R', 67604=>'R', 67605=>'R', 67606=>'R', 67607=>'R', 67608=>'R', 67609=>'R', 67610=>'R', 67611=>'R', 67612=>'R', 67613=>'R', 67614=>'R', 67615=>'R', 67616=>'R', 67617=>'R', 67618=>'R', 67619=>'R', 67620=>'R', 67621=>'R', 67622=>'R', 67623=>'R', 67624=>'R', 67625=>'R', 67626=>'R', 67627=>'R', 67628=>'R', 67629=>'R', 67630=>'R', 67631=>'R', 67632=>'R', 67633=>'R', 67634=>'R', 67635=>'R', 67636=>'R', 67637=>'R', 67639=>'R', 67640=>'R', 67644=>'R', 67647=>'R', 67840=>'R', 67841=>'R', 67842=>'R', 67843=>'R', 67844=>'R', 67845=>'R', 67846=>'R', 67847=>'R', 67848=>'R', 67849=>'R', 67850=>'R', 67851=>'R', 67852=>'R', 67853=>'R', 67854=>'R', 67855=>'R', 67856=>'R', 67857=>'R', 67858=>'R', 67859=>'R', 67860=>'R', 67861=>'R', 67862=>'R', 67863=>'R', 67864=>'R', 67865=>'R', 67871=>'ON', 68096=>'R', 68097=>'NSM', 68098=>'NSM', 68099=>'NSM', 68101=>'NSM', 68102=>'NSM', 68108=>'NSM', 68109=>'NSM', 68110=>'NSM', 68111=>'NSM', 68112=>'R', 68113=>'R', 68114=>'R', 68115=>'R', 68117=>'R', 68118=>'R', 68119=>'R', 68121=>'R', 68122=>'R', 68123=>'R', 68124=>'R', 68125=>'R', 68126=>'R', 68127=>'R', 68128=>'R', 68129=>'R', 68130=>'R', 68131=>'R', 68132=>'R', 68133=>'R', 68134=>'R', 68135=>'R', 68136=>'R', 68137=>'R', 68138=>'R', 68139=>'R', 68140=>'R', 68141=>'R', 68142=>'R', 68143=>'R', 68144=>'R', 68145=>'R', 68146=>'R', 68147=>'R', 68152=>'NSM', 68153=>'NSM', 68154=>'NSM', 68159=>'NSM', 68160=>'R', 68161=>'R', 68162=>'R', 68163=>'R', 68164=>'R', 68165=>'R', 68166=>'R', 68167=>'R', 68176=>'R', 68177=>'R', 68178=>'R', 68179=>'R', 68180=>'R', 68181=>'R', 68182=>'R', 68183=>'R', 68184=>'R', 73728=>'L', 73729=>'L', 73730=>'L', 73731=>'L', 73732=>'L', 73733=>'L', 73734=>'L', 73735=>'L', 73736=>'L', 73737=>'L', 73738=>'L', 73739=>'L', 73740=>'L', 73741=>'L', 73742=>'L', 73743=>'L', 73744=>'L', 73745=>'L', 73746=>'L', 73747=>'L', 73748=>'L', 73749=>'L', 73750=>'L', 73751=>'L', 73752=>'L', 73753=>'L', 73754=>'L', 73755=>'L', 73756=>'L', 73757=>'L', 73758=>'L', 73759=>'L', 73760=>'L', 73761=>'L', 73762=>'L', 73763=>'L', 73764=>'L', 73765=>'L', 73766=>'L', 73767=>'L', 73768=>'L', 73769=>'L', 73770=>'L', 73771=>'L', 73772=>'L', 73773=>'L', 73774=>'L', 73775=>'L', 73776=>'L', 73777=>'L', 73778=>'L', 73779=>'L', 73780=>'L', 73781=>'L', 73782=>'L', 73783=>'L', 73784=>'L', 73785=>'L', 73786=>'L', 73787=>'L', 73788=>'L', 73789=>'L', 73790=>'L', 73791=>'L', 73792=>'L', 73793=>'L', 73794=>'L', 73795=>'L', 73796=>'L', 73797=>'L', 73798=>'L', 73799=>'L', 73800=>'L', 73801=>'L', 73802=>'L', 73803=>'L', 73804=>'L', 73805=>'L', 73806=>'L', 73807=>'L', 73808=>'L', 73809=>'L', 73810=>'L', 73811=>'L', 73812=>'L', 73813=>'L', 73814=>'L', 73815=>'L', 73816=>'L', 73817=>'L', 73818=>'L', 73819=>'L', 73820=>'L', 73821=>'L', 73822=>'L', 73823=>'L', 73824=>'L', 73825=>'L', 73826=>'L', 73827=>'L', 73828=>'L', 73829=>'L', 73830=>'L', 73831=>'L', 73832=>'L', 73833=>'L', 73834=>'L', 73835=>'L', 73836=>'L', 73837=>'L', 73838=>'L', 73839=>'L', 73840=>'L', 73841=>'L', 73842=>'L', 73843=>'L', 73844=>'L', 73845=>'L', 73846=>'L', 73847=>'L', 73848=>'L', 73849=>'L', 73850=>'L', 73851=>'L', 73852=>'L', 73853=>'L', 73854=>'L', 73855=>'L', 73856=>'L', 73857=>'L', 73858=>'L', 73859=>'L', 73860=>'L', 73861=>'L', 73862=>'L', 73863=>'L', 73864=>'L', 73865=>'L', 73866=>'L', 73867=>'L', 73868=>'L', 73869=>'L', 73870=>'L', 73871=>'L', 73872=>'L', 73873=>'L', 73874=>'L', 73875=>'L', 73876=>'L', 73877=>'L', 73878=>'L', 73879=>'L', 73880=>'L', 73881=>'L', 73882=>'L', 73883=>'L', 73884=>'L', 73885=>'L', 73886=>'L', 73887=>'L', 73888=>'L', 73889=>'L', 73890=>'L', 73891=>'L', 73892=>'L', 73893=>'L', 73894=>'L', 73895=>'L', 73896=>'L', 73897=>'L', 73898=>'L', 73899=>'L', 73900=>'L', 73901=>'L', 73902=>'L', 73903=>'L', 73904=>'L', 73905=>'L', 73906=>'L', 73907=>'L', 73908=>'L', 73909=>'L', 73910=>'L', 73911=>'L', 73912=>'L', 73913=>'L', 73914=>'L', 73915=>'L', 73916=>'L', 73917=>'L', 73918=>'L', 73919=>'L', 73920=>'L', 73921=>'L', 73922=>'L', 73923=>'L', 73924=>'L', 73925=>'L', 73926=>'L', 73927=>'L', 73928=>'L', 73929=>'L', 73930=>'L', 73931=>'L', 73932=>'L', 73933=>'L', 73934=>'L', 73935=>'L', 73936=>'L', 73937=>'L', 73938=>'L', 73939=>'L', 73940=>'L', 73941=>'L', 73942=>'L', 73943=>'L', 73944=>'L', 73945=>'L', 73946=>'L', 73947=>'L', 73948=>'L', 73949=>'L', 73950=>'L', 73951=>'L', 73952=>'L', 73953=>'L', 73954=>'L', 73955=>'L', 73956=>'L', 73957=>'L', 73958=>'L', 73959=>'L', 73960=>'L', 73961=>'L', 73962=>'L', 73963=>'L', 73964=>'L', 73965=>'L', 73966=>'L', 73967=>'L', 73968=>'L', 73969=>'L', 73970=>'L', 73971=>'L', 73972=>'L', 73973=>'L', 73974=>'L', 73975=>'L', 73976=>'L', 73977=>'L', 73978=>'L', 73979=>'L', 73980=>'L', 73981=>'L', 73982=>'L', 73983=>'L', 73984=>'L', 73985=>'L', 73986=>'L', 73987=>'L', 73988=>'L', 73989=>'L', 73990=>'L', 73991=>'L', 73992=>'L', 73993=>'L', 73994=>'L', 73995=>'L', 73996=>'L', 73997=>'L', 73998=>'L', 73999=>'L', 74000=>'L', 74001=>'L', 74002=>'L', 74003=>'L', 74004=>'L', 74005=>'L', 74006=>'L', 74007=>'L', 74008=>'L', 74009=>'L', 74010=>'L', 74011=>'L', 74012=>'L', 74013=>'L', 74014=>'L', 74015=>'L', 74016=>'L', 74017=>'L', 74018=>'L', 74019=>'L', 74020=>'L', 74021=>'L', 74022=>'L', 74023=>'L', 74024=>'L', 74025=>'L', 74026=>'L', 74027=>'L', 74028=>'L', 74029=>'L', 74030=>'L', 74031=>'L', 74032=>'L', 74033=>'L', 74034=>'L', 74035=>'L', 74036=>'L', 74037=>'L', 74038=>'L', 74039=>'L', 74040=>'L', 74041=>'L', 74042=>'L', 74043=>'L', 74044=>'L', 74045=>'L', 74046=>'L', 74047=>'L', 74048=>'L', 74049=>'L', 74050=>'L', 74051=>'L', 74052=>'L', 74053=>'L', 74054=>'L', 74055=>'L', 74056=>'L', 74057=>'L', 74058=>'L', 74059=>'L', 74060=>'L', 74061=>'L', 74062=>'L', 74063=>'L', 74064=>'L', 74065=>'L', 74066=>'L', 74067=>'L', 74068=>'L', 74069=>'L', 74070=>'L', 74071=>'L', 74072=>'L', 74073=>'L', 74074=>'L', 74075=>'L', 74076=>'L', 74077=>'L', 74078=>'L', 74079=>'L', 74080=>'L', 74081=>'L', 74082=>'L', 74083=>'L', 74084=>'L', 74085=>'L', 74086=>'L', 74087=>'L', 74088=>'L', 74089=>'L', 74090=>'L', 74091=>'L', 74092=>'L', 74093=>'L', 74094=>'L', 74095=>'L', 74096=>'L', 74097=>'L', 74098=>'L', 74099=>'L', 74100=>'L', 74101=>'L', 74102=>'L', 74103=>'L', 74104=>'L', 74105=>'L', 74106=>'L', 74107=>'L', 74108=>'L', 74109=>'L', 74110=>'L', 74111=>'L', 74112=>'L', 74113=>'L', 74114=>'L', 74115=>'L', 74116=>'L', 74117=>'L', 74118=>'L', 74119=>'L', 74120=>'L', 74121=>'L', 74122=>'L', 74123=>'L', 74124=>'L', 74125=>'L', 74126=>'L', 74127=>'L', 74128=>'L', 74129=>'L', 74130=>'L', 74131=>'L', 74132=>'L', 74133=>'L', 74134=>'L', 74135=>'L', 74136=>'L', 74137=>'L', 74138=>'L', 74139=>'L', 74140=>'L', 74141=>'L', 74142=>'L', 74143=>'L', 74144=>'L', 74145=>'L', 74146=>'L', 74147=>'L', 74148=>'L', 74149=>'L', 74150=>'L', 74151=>'L', 74152=>'L', 74153=>'L', 74154=>'L', 74155=>'L', 74156=>'L', 74157=>'L', 74158=>'L', 74159=>'L', 74160=>'L', 74161=>'L', 74162=>'L', 74163=>'L', 74164=>'L', 74165=>'L', 74166=>'L', 74167=>'L', 74168=>'L', 74169=>'L', 74170=>'L', 74171=>'L', 74172=>'L', 74173=>'L', 74174=>'L', 74175=>'L', 74176=>'L', 74177=>'L', 74178=>'L', 74179=>'L', 74180=>'L', 74181=>'L', 74182=>'L', 74183=>'L', 74184=>'L', 74185=>'L', 74186=>'L', 74187=>'L', 74188=>'L', 74189=>'L', 74190=>'L', 74191=>'L', 74192=>'L', 74193=>'L', 74194=>'L', 74195=>'L', 74196=>'L', 74197=>'L', 74198=>'L', 74199=>'L', 74200=>'L', 74201=>'L', 74202=>'L', 74203=>'L', 74204=>'L', 74205=>'L', 74206=>'L', 74207=>'L', 74208=>'L', 74209=>'L', 74210=>'L', 74211=>'L', 74212=>'L', 74213=>'L', 74214=>'L', 74215=>'L', 74216=>'L', 74217=>'L', 74218=>'L', 74219=>'L', 74220=>'L', 74221=>'L', 74222=>'L', 74223=>'L', 74224=>'L', 74225=>'L', 74226=>'L', 74227=>'L', 74228=>'L', 74229=>'L', 74230=>'L', 74231=>'L', 74232=>'L', 74233=>'L', 74234=>'L', 74235=>'L', 74236=>'L', 74237=>'L', 74238=>'L', 74239=>'L', 74240=>'L', 74241=>'L', 74242=>'L', 74243=>'L', 74244=>'L', 74245=>'L', 74246=>'L', 74247=>'L', 74248=>'L', 74249=>'L', 74250=>'L', 74251=>'L', 74252=>'L', 74253=>'L', 74254=>'L', 74255=>'L', 74256=>'L', 74257=>'L', 74258=>'L', 74259=>'L', 74260=>'L', 74261=>'L', 74262=>'L', 74263=>'L', 74264=>'L', 74265=>'L', 74266=>'L', 74267=>'L', 74268=>'L', 74269=>'L', 74270=>'L', 74271=>'L', 74272=>'L', 74273=>'L', 74274=>'L', 74275=>'L', 74276=>'L', 74277=>'L', 74278=>'L', 74279=>'L', 74280=>'L', 74281=>'L', 74282=>'L', 74283=>'L', 74284=>'L', 74285=>'L', 74286=>'L', 74287=>'L', 74288=>'L', 74289=>'L', 74290=>'L', 74291=>'L', 74292=>'L', 74293=>'L', 74294=>'L', 74295=>'L', 74296=>'L', 74297=>'L', 74298=>'L', 74299=>'L', 74300=>'L', 74301=>'L', 74302=>'L', 74303=>'L', 74304=>'L', 74305=>'L', 74306=>'L', 74307=>'L', 74308=>'L', 74309=>'L', 74310=>'L', 74311=>'L', 74312=>'L', 74313=>'L', 74314=>'L', 74315=>'L', 74316=>'L', 74317=>'L', 74318=>'L', 74319=>'L', 74320=>'L', 74321=>'L', 74322=>'L', 74323=>'L', 74324=>'L', 74325=>'L', 74326=>'L', 74327=>'L', 74328=>'L', 74329=>'L', 74330=>'L', 74331=>'L', 74332=>'L', 74333=>'L', 74334=>'L', 74335=>'L', 74336=>'L', 74337=>'L', 74338=>'L', 74339=>'L', 74340=>'L', 74341=>'L', 74342=>'L', 74343=>'L', 74344=>'L', 74345=>'L', 74346=>'L', 74347=>'L', 74348=>'L', 74349=>'L', 74350=>'L', 74351=>'L', 74352=>'L', 74353=>'L', 74354=>'L', 74355=>'L', 74356=>'L', 74357=>'L', 74358=>'L', 74359=>'L', 74360=>'L', 74361=>'L', 74362=>'L', 74363=>'L', 74364=>'L', 74365=>'L', 74366=>'L', 74367=>'L', 74368=>'L', 74369=>'L', 74370=>'L', 74371=>'L', 74372=>'L', 74373=>'L', 74374=>'L', 74375=>'L', 74376=>'L', 74377=>'L', 74378=>'L', 74379=>'L', 74380=>'L', 74381=>'L', 74382=>'L', 74383=>'L', 74384=>'L', 74385=>'L', 74386=>'L', 74387=>'L', 74388=>'L', 74389=>'L', 74390=>'L', 74391=>'L', 74392=>'L', 74393=>'L', 74394=>'L', 74395=>'L', 74396=>'L', 74397=>'L', 74398=>'L', 74399=>'L', 74400=>'L', 74401=>'L', 74402=>'L', 74403=>'L', 74404=>'L', 74405=>'L', 74406=>'L', 74407=>'L', 74408=>'L', 74409=>'L', 74410=>'L', 74411=>'L', 74412=>'L', 74413=>'L', 74414=>'L', 74415=>'L', 74416=>'L', 74417=>'L', 74418=>'L', 74419=>'L', 74420=>'L', 74421=>'L', 74422=>'L', 74423=>'L', 74424=>'L', 74425=>'L', 74426=>'L', 74427=>'L', 74428=>'L', 74429=>'L', 74430=>'L', 74431=>'L', 74432=>'L', 74433=>'L', 74434=>'L', 74435=>'L', 74436=>'L', 74437=>'L', 74438=>'L', 74439=>'L', 74440=>'L', 74441=>'L', 74442=>'L', 74443=>'L', 74444=>'L', 74445=>'L', 74446=>'L', 74447=>'L', 74448=>'L', 74449=>'L', 74450=>'L', 74451=>'L', 74452=>'L', 74453=>'L', 74454=>'L', 74455=>'L', 74456=>'L', 74457=>'L', 74458=>'L', 74459=>'L', 74460=>'L', 74461=>'L', 74462=>'L', 74463=>'L', 74464=>'L', 74465=>'L', 74466=>'L', 74467=>'L', 74468=>'L', 74469=>'L', 74470=>'L', 74471=>'L', 74472=>'L', 74473=>'L', 74474=>'L', 74475=>'L', 74476=>'L', 74477=>'L', 74478=>'L', 74479=>'L', 74480=>'L', 74481=>'L', 74482=>'L', 74483=>'L', 74484=>'L', 74485=>'L', 74486=>'L', 74487=>'L', 74488=>'L', 74489=>'L', 74490=>'L', 74491=>'L', 74492=>'L', 74493=>'L', 74494=>'L', 74495=>'L', 74496=>'L', 74497=>'L', 74498=>'L', 74499=>'L', 74500=>'L', 74501=>'L', 74502=>'L', 74503=>'L', 74504=>'L', 74505=>'L', 74506=>'L', 74507=>'L', 74508=>'L', 74509=>'L', 74510=>'L', 74511=>'L', 74512=>'L', 74513=>'L', 74514=>'L', 74515=>'L', 74516=>'L', 74517=>'L', 74518=>'L', 74519=>'L', 74520=>'L', 74521=>'L', 74522=>'L', 74523=>'L', 74524=>'L', 74525=>'L', 74526=>'L', 74527=>'L', 74528=>'L', 74529=>'L', 74530=>'L', 74531=>'L', 74532=>'L', 74533=>'L', 74534=>'L', 74535=>'L', 74536=>'L', 74537=>'L', 74538=>'L', 74539=>'L', 74540=>'L', 74541=>'L', 74542=>'L', 74543=>'L', 74544=>'L', 74545=>'L', 74546=>'L', 74547=>'L', 74548=>'L', 74549=>'L', 74550=>'L', 74551=>'L', 74552=>'L', 74553=>'L', 74554=>'L', 74555=>'L', 74556=>'L', 74557=>'L', 74558=>'L', 74559=>'L', 74560=>'L', 74561=>'L', 74562=>'L', 74563=>'L', 74564=>'L', 74565=>'L', 74566=>'L', 74567=>'L', 74568=>'L', 74569=>'L', 74570=>'L', 74571=>'L', 74572=>'L', 74573=>'L', 74574=>'L', 74575=>'L', 74576=>'L', 74577=>'L', 74578=>'L', 74579=>'L', 74580=>'L', 74581=>'L', 74582=>'L', 74583=>'L', 74584=>'L', 74585=>'L', 74586=>'L', 74587=>'L', 74588=>'L', 74589=>'L', 74590=>'L', 74591=>'L', 74592=>'L', 74593=>'L', 74594=>'L', 74595=>'L', 74596=>'L', 74597=>'L', 74598=>'L', 74599=>'L', 74600=>'L', 74601=>'L', 74602=>'L', 74603=>'L', 74604=>'L', 74605=>'L', 74606=>'L', 74752=>'L', 74753=>'L', 74754=>'L', 74755=>'L', 74756=>'L', 74757=>'L', 74758=>'L', 74759=>'L', 74760=>'L', 74761=>'L', 74762=>'L', 74763=>'L', 74764=>'L', 74765=>'L', 74766=>'L', 74767=>'L', 74768=>'L', 74769=>'L', 74770=>'L', 74771=>'L', 74772=>'L', 74773=>'L', 74774=>'L', 74775=>'L', 74776=>'L', 74777=>'L', 74778=>'L', 74779=>'L', 74780=>'L', 74781=>'L', 74782=>'L', 74783=>'L', 74784=>'L', 74785=>'L', 74786=>'L', 74787=>'L', 74788=>'L', 74789=>'L', 74790=>'L', 74791=>'L', 74792=>'L', 74793=>'L', 74794=>'L', 74795=>'L', 74796=>'L', 74797=>'L', 74798=>'L', 74799=>'L', 74800=>'L', 74801=>'L', 74802=>'L', 74803=>'L', 74804=>'L', 74805=>'L', 74806=>'L', 74807=>'L', 74808=>'L', 74809=>'L', 74810=>'L', 74811=>'L', 74812=>'L', 74813=>'L', 74814=>'L', 74815=>'L', 74816=>'L', 74817=>'L', 74818=>'L', 74819=>'L', 74820=>'L', 74821=>'L', 74822=>'L', 74823=>'L', 74824=>'L', 74825=>'L', 74826=>'L', 74827=>'L', 74828=>'L', 74829=>'L', 74830=>'L', 74831=>'L', 74832=>'L', 74833=>'L', 74834=>'L', 74835=>'L', 74836=>'L', 74837=>'L', 74838=>'L', 74839=>'L', 74840=>'L', 74841=>'L', 74842=>'L', 74843=>'L', 74844=>'L', 74845=>'L', 74846=>'L', 74847=>'L', 74848=>'L', 74849=>'L', 74850=>'L', 74864=>'L', 74865=>'L', 74866=>'L', 74867=>'L', 118784=>'L', 118785=>'L', 118786=>'L', 118787=>'L', 118788=>'L', 118789=>'L', 118790=>'L', 118791=>'L', 118792=>'L', 118793=>'L', 118794=>'L', 118795=>'L', 118796=>'L', 118797=>'L', 118798=>'L', 118799=>'L', 118800=>'L', 118801=>'L', 118802=>'L', 118803=>'L', 118804=>'L', 118805=>'L', 118806=>'L', 118807=>'L', 118808=>'L', 118809=>'L', 118810=>'L', 118811=>'L', 118812=>'L', 118813=>'L', 118814=>'L', 118815=>'L', 118816=>'L', 118817=>'L', 118818=>'L', 118819=>'L', 118820=>'L', 118821=>'L', 118822=>'L', 118823=>'L', 118824=>'L', 118825=>'L', 118826=>'L', 118827=>'L', 118828=>'L', 118829=>'L', 118830=>'L', 118831=>'L', 118832=>'L', 118833=>'L', 118834=>'L', 118835=>'L', 118836=>'L', 118837=>'L', 118838=>'L', 118839=>'L', 118840=>'L', 118841=>'L', 118842=>'L', 118843=>'L', 118844=>'L', 118845=>'L', 118846=>'L', 118847=>'L', 118848=>'L', 118849=>'L', 118850=>'L', 118851=>'L', 118852=>'L', 118853=>'L', 118854=>'L', 118855=>'L', 118856=>'L', 118857=>'L', 118858=>'L', 118859=>'L', 118860=>'L', 118861=>'L', 118862=>'L', 118863=>'L', 118864=>'L', 118865=>'L', 118866=>'L', 118867=>'L', 118868=>'L', 118869=>'L', 118870=>'L', 118871=>'L', 118872=>'L', 118873=>'L', 118874=>'L', 118875=>'L', 118876=>'L', 118877=>'L', 118878=>'L', 118879=>'L', 118880=>'L', 118881=>'L', 118882=>'L', 118883=>'L', 118884=>'L', 118885=>'L', 118886=>'L', 118887=>'L', 118888=>'L', 118889=>'L', 118890=>'L', 118891=>'L', 118892=>'L', 118893=>'L', 118894=>'L', 118895=>'L', 118896=>'L', 118897=>'L', 118898=>'L', 118899=>'L', 118900=>'L', 118901=>'L', 118902=>'L', 118903=>'L', 118904=>'L', 118905=>'L', 118906=>'L', 118907=>'L', 118908=>'L', 118909=>'L', 118910=>'L', 118911=>'L', 118912=>'L', 118913=>'L', 118914=>'L', 118915=>'L', 118916=>'L', 118917=>'L', 118918=>'L', 118919=>'L', 118920=>'L', 118921=>'L', 118922=>'L', 118923=>'L', 118924=>'L', 118925=>'L', 118926=>'L', 118927=>'L', 118928=>'L', 118929=>'L', 118930=>'L', 118931=>'L', 118932=>'L', 118933=>'L', 118934=>'L', 118935=>'L', 118936=>'L', 118937=>'L', 118938=>'L', 118939=>'L', 118940=>'L', 118941=>'L', 118942=>'L', 118943=>'L', 118944=>'L', 118945=>'L', 118946=>'L', 118947=>'L', 118948=>'L', 118949=>'L', 118950=>'L', 118951=>'L', 118952=>'L', 118953=>'L', 118954=>'L', 118955=>'L', 118956=>'L', 118957=>'L', 118958=>'L', 118959=>'L', 118960=>'L', 118961=>'L', 118962=>'L', 118963=>'L', 118964=>'L', 118965=>'L', 118966=>'L', 118967=>'L', 118968=>'L', 118969=>'L', 118970=>'L', 118971=>'L', 118972=>'L', 118973=>'L', 118974=>'L', 118975=>'L', 118976=>'L', 118977=>'L', 118978=>'L', 118979=>'L', 118980=>'L', 118981=>'L', 118982=>'L', 118983=>'L', 118984=>'L', 118985=>'L', 118986=>'L', 118987=>'L', 118988=>'L', 118989=>'L', 118990=>'L', 118991=>'L', 118992=>'L', 118993=>'L', 118994=>'L', 118995=>'L', 118996=>'L', 118997=>'L', 118998=>'L', 118999=>'L', 119000=>'L', 119001=>'L', 119002=>'L', 119003=>'L', 119004=>'L', 119005=>'L', 119006=>'L', 119007=>'L', 119008=>'L', 119009=>'L', 119010=>'L', 119011=>'L', 119012=>'L', 119013=>'L', 119014=>'L', 119015=>'L', 119016=>'L', 119017=>'L', 119018=>'L', 119019=>'L', 119020=>'L', 119021=>'L', 119022=>'L', 119023=>'L', 119024=>'L', 119025=>'L', 119026=>'L', 119027=>'L', 119028=>'L', 119029=>'L', 119040=>'L', 119041=>'L', 119042=>'L', 119043=>'L', 119044=>'L', 119045=>'L', 119046=>'L', 119047=>'L', 119048=>'L', 119049=>'L', 119050=>'L', 119051=>'L', 119052=>'L', 119053=>'L', 119054=>'L', 119055=>'L', 119056=>'L', 119057=>'L', 119058=>'L', 119059=>'L', 119060=>'L', 119061=>'L', 119062=>'L', 119063=>'L', 119064=>'L', 119065=>'L', 119066=>'L', 119067=>'L', 119068=>'L', 119069=>'L', 119070=>'L', 119071=>'L', 119072=>'L', 119073=>'L', 119074=>'L', 119075=>'L', 119076=>'L', 119077=>'L', 119078=>'L', 119082=>'L', 119083=>'L', 119084=>'L', 119085=>'L', 119086=>'L', 119087=>'L', 119088=>'L', 119089=>'L', 119090=>'L', 119091=>'L', 119092=>'L', 119093=>'L', 119094=>'L', 119095=>'L', 119096=>'L', 119097=>'L', 119098=>'L', 119099=>'L', 119100=>'L', 119101=>'L', 119102=>'L', 119103=>'L', 119104=>'L', 119105=>'L', 119106=>'L', 119107=>'L', 119108=>'L', 119109=>'L', 119110=>'L', 119111=>'L', 119112=>'L', 119113=>'L', 119114=>'L', 119115=>'L', 119116=>'L', 119117=>'L', 119118=>'L', 119119=>'L', 119120=>'L', 119121=>'L', 119122=>'L', 119123=>'L', 119124=>'L', 119125=>'L', 119126=>'L', 119127=>'L', 119128=>'L', 119129=>'L', 119130=>'L', 119131=>'L', 119132=>'L', 119133=>'L', 119134=>'L', 119135=>'L', 119136=>'L', 119137=>'L', 119138=>'L', 119139=>'L', 119140=>'L', 119141=>'L', 119142=>'L', 119143=>'NSM', 119144=>'NSM', 119145=>'NSM', 119146=>'L', 119147=>'L', 119148=>'L', 119149=>'L', 119150=>'L', 119151=>'L', 119152=>'L', 119153=>'L', 119154=>'L', 119155=>'BN', 119156=>'BN', 119157=>'BN', 119158=>'BN', 119159=>'BN', 119160=>'BN', 119161=>'BN', 119162=>'BN', 119163=>'NSM', 119164=>'NSM', 119165=>'NSM', 119166=>'NSM', 119167=>'NSM', 119168=>'NSM', 119169=>'NSM', 119170=>'NSM', 119171=>'L', 119172=>'L', 119173=>'NSM', 119174=>'NSM', 119175=>'NSM', 119176=>'NSM', 119177=>'NSM', 119178=>'NSM', 119179=>'NSM', 119180=>'L', 119181=>'L', 119182=>'L', 119183=>'L', 119184=>'L', 119185=>'L', 119186=>'L', 119187=>'L', 119188=>'L', 119189=>'L', 119190=>'L', 119191=>'L', 119192=>'L', 119193=>'L', 119194=>'L', 119195=>'L', 119196=>'L', 119197=>'L', 119198=>'L', 119199=>'L', 119200=>'L', 119201=>'L', 119202=>'L', 119203=>'L', 119204=>'L', 119205=>'L', 119206=>'L', 119207=>'L', 119208=>'L', 119209=>'L', 119210=>'NSM', 119211=>'NSM', 119212=>'NSM', 119213=>'NSM', 119214=>'L', 119215=>'L', 119216=>'L', 119217=>'L', 119218=>'L', 119219=>'L', 119220=>'L', 119221=>'L', 119222=>'L', 119223=>'L', 119224=>'L', 119225=>'L', 119226=>'L', 119227=>'L', 119228=>'L', 119229=>'L', 119230=>'L', 119231=>'L', 119232=>'L', 119233=>'L', 119234=>'L', 119235=>'L', 119236=>'L', 119237=>'L', 119238=>'L', 119239=>'L', 119240=>'L', 119241=>'L', 119242=>'L', 119243=>'L', 119244=>'L', 119245=>'L', 119246=>'L', 119247=>'L', 119248=>'L', 119249=>'L', 119250=>'L', 119251=>'L', 119252=>'L', 119253=>'L', 119254=>'L', 119255=>'L', 119256=>'L', 119257=>'L', 119258=>'L', 119259=>'L', 119260=>'L', 119261=>'L', 119296=>'ON', 119297=>'ON', 119298=>'ON', 119299=>'ON', 119300=>'ON', 119301=>'ON', 119302=>'ON', 119303=>'ON', 119304=>'ON', 119305=>'ON', 119306=>'ON', 119307=>'ON', 119308=>'ON', 119309=>'ON', 119310=>'ON', 119311=>'ON', 119312=>'ON', 119313=>'ON', 119314=>'ON', 119315=>'ON', 119316=>'ON', 119317=>'ON', 119318=>'ON', 119319=>'ON', 119320=>'ON', 119321=>'ON', 119322=>'ON', 119323=>'ON', 119324=>'ON', 119325=>'ON', 119326=>'ON', 119327=>'ON', 119328=>'ON', 119329=>'ON', 119330=>'ON', 119331=>'ON', 119332=>'ON', 119333=>'ON', 119334=>'ON', 119335=>'ON', 119336=>'ON', 119337=>'ON', 119338=>'ON', 119339=>'ON', 119340=>'ON', 119341=>'ON', 119342=>'ON', 119343=>'ON', 119344=>'ON', 119345=>'ON', 119346=>'ON', 119347=>'ON', 119348=>'ON', 119349=>'ON', 119350=>'ON', 119351=>'ON', 119352=>'ON', 119353=>'ON', 119354=>'ON', 119355=>'ON', 119356=>'ON', 119357=>'ON', 119358=>'ON', 119359=>'ON', 119360=>'ON', 119361=>'ON', 119362=>'NSM', 119363=>'NSM', 119364=>'NSM', 119365=>'ON', 119552=>'ON', 119553=>'ON', 119554=>'ON', 119555=>'ON', 119556=>'ON', 119557=>'ON', 119558=>'ON', 119559=>'ON', 119560=>'ON', 119561=>'ON', 119562=>'ON', 119563=>'ON', 119564=>'ON', 119565=>'ON', 119566=>'ON', 119567=>'ON', 119568=>'ON', 119569=>'ON', 119570=>'ON', 119571=>'ON', 119572=>'ON', 119573=>'ON', 119574=>'ON', 119575=>'ON', 119576=>'ON', 119577=>'ON', 119578=>'ON', 119579=>'ON', 119580=>'ON', 119581=>'ON', 119582=>'ON', 119583=>'ON', 119584=>'ON', 119585=>'ON', 119586=>'ON', 119587=>'ON', 119588=>'ON', 119589=>'ON', 119590=>'ON', 119591=>'ON', 119592=>'ON', 119593=>'ON', 119594=>'ON', 119595=>'ON', 119596=>'ON', 119597=>'ON', 119598=>'ON', 119599=>'ON', 119600=>'ON', 119601=>'ON', 119602=>'ON', 119603=>'ON', 119604=>'ON', 119605=>'ON', 119606=>'ON', 119607=>'ON', 119608=>'ON', 119609=>'ON', 119610=>'ON', 119611=>'ON', 119612=>'ON', 119613=>'ON', 119614=>'ON', 119615=>'ON', 119616=>'ON', 119617=>'ON', 119618=>'ON', 119619=>'ON', 119620=>'ON', 119621=>'ON', 119622=>'ON', 119623=>'ON', 119624=>'ON', 119625=>'ON', 119626=>'ON', 119627=>'ON', 119628=>'ON', 119629=>'ON', 119630=>'ON', 119631=>'ON', 119632=>'ON', 119633=>'ON', 119634=>'ON', 119635=>'ON', 119636=>'ON', 119637=>'ON', 119638=>'ON', 119648=>'L', 119649=>'L', 119650=>'L', 119651=>'L', 119652=>'L', 119653=>'L', 119654=>'L', 119655=>'L', 119656=>'L', 119657=>'L', 119658=>'L', 119659=>'L', 119660=>'L', 119661=>'L', 119662=>'L', 119663=>'L', 119664=>'L', 119665=>'L', 119808=>'L', 119809=>'L', 119810=>'L', 119811=>'L', 119812=>'L', 119813=>'L', 119814=>'L', 119815=>'L', 119816=>'L', 119817=>'L', 119818=>'L', 119819=>'L', 119820=>'L', 119821=>'L', 119822=>'L', 119823=>'L', 119824=>'L', 119825=>'L', 119826=>'L', 119827=>'L', 119828=>'L', 119829=>'L', 119830=>'L', 119831=>'L', 119832=>'L', 119833=>'L', 119834=>'L', 119835=>'L', 119836=>'L', 119837=>'L', 119838=>'L', 119839=>'L', 119840=>'L', 119841=>'L', 119842=>'L', 119843=>'L', 119844=>'L', 119845=>'L', 119846=>'L', 119847=>'L', 119848=>'L', 119849=>'L', 119850=>'L', 119851=>'L', 119852=>'L', 119853=>'L', 119854=>'L', 119855=>'L', 119856=>'L', 119857=>'L', 119858=>'L', 119859=>'L', 119860=>'L', 119861=>'L', 119862=>'L', 119863=>'L', 119864=>'L', 119865=>'L', 119866=>'L', 119867=>'L', 119868=>'L', 119869=>'L', 119870=>'L', 119871=>'L', 119872=>'L', 119873=>'L', 119874=>'L', 119875=>'L', 119876=>'L', 119877=>'L', 119878=>'L', 119879=>'L', 119880=>'L', 119881=>'L', 119882=>'L', 119883=>'L', 119884=>'L', 119885=>'L', 119886=>'L', 119887=>'L', 119888=>'L', 119889=>'L', 119890=>'L', 119891=>'L', 119892=>'L', 119894=>'L', 119895=>'L', 119896=>'L', 119897=>'L', 119898=>'L', 119899=>'L', 119900=>'L', 119901=>'L', 119902=>'L', 119903=>'L', 119904=>'L', 119905=>'L', 119906=>'L', 119907=>'L', 119908=>'L', 119909=>'L', 119910=>'L', 119911=>'L', 119912=>'L', 119913=>'L', 119914=>'L', 119915=>'L', 119916=>'L', 119917=>'L', 119918=>'L', 119919=>'L', 119920=>'L', 119921=>'L', 119922=>'L', 119923=>'L', 119924=>'L', 119925=>'L', 119926=>'L', 119927=>'L', 119928=>'L', 119929=>'L', 119930=>'L', 119931=>'L', 119932=>'L', 119933=>'L', 119934=>'L', 119935=>'L', 119936=>'L', 119937=>'L', 119938=>'L', 119939=>'L', 119940=>'L', 119941=>'L', 119942=>'L', 119943=>'L', 119944=>'L', 119945=>'L', 119946=>'L', 119947=>'L', 119948=>'L', 119949=>'L', 119950=>'L', 119951=>'L', 119952=>'L', 119953=>'L', 119954=>'L', 119955=>'L', 119956=>'L', 119957=>'L', 119958=>'L', 119959=>'L', 119960=>'L', 119961=>'L', 119962=>'L', 119963=>'L', 119964=>'L', 119966=>'L', 119967=>'L', 119970=>'L', 119973=>'L', 119974=>'L', 119977=>'L', 119978=>'L', 119979=>'L', 119980=>'L', 119982=>'L', 119983=>'L', 119984=>'L', 119985=>'L', 119986=>'L', 119987=>'L', 119988=>'L', 119989=>'L', 119990=>'L', 119991=>'L', 119992=>'L', 119993=>'L', 119995=>'L', 119997=>'L', 119998=>'L', 119999=>'L', 120000=>'L', 120001=>'L', 120002=>'L', 120003=>'L', 120005=>'L', 120006=>'L', 120007=>'L', 120008=>'L', 120009=>'L', 120010=>'L', 120011=>'L', 120012=>'L', 120013=>'L', 120014=>'L', 120015=>'L', 120016=>'L', 120017=>'L', 120018=>'L', 120019=>'L', 120020=>'L', 120021=>'L', 120022=>'L', 120023=>'L', 120024=>'L', 120025=>'L', 120026=>'L', 120027=>'L', 120028=>'L', 120029=>'L', 120030=>'L', 120031=>'L', 120032=>'L', 120033=>'L', 120034=>'L', 120035=>'L', 120036=>'L', 120037=>'L', 120038=>'L', 120039=>'L', 120040=>'L', 120041=>'L', 120042=>'L', 120043=>'L', 120044=>'L', 120045=>'L', 120046=>'L', 120047=>'L', 120048=>'L', 120049=>'L', 120050=>'L', 120051=>'L', 120052=>'L', 120053=>'L', 120054=>'L', 120055=>'L', 120056=>'L', 120057=>'L', 120058=>'L', 120059=>'L', 120060=>'L', 120061=>'L', 120062=>'L', 120063=>'L', 120064=>'L', 120065=>'L', 120066=>'L', 120067=>'L', 120068=>'L', 120069=>'L', 120071=>'L', 120072=>'L', 120073=>'L', 120074=>'L', 120077=>'L', 120078=>'L', 120079=>'L', 120080=>'L', 120081=>'L', 120082=>'L', 120083=>'L', 120084=>'L', 120086=>'L', 120087=>'L', 120088=>'L', 120089=>'L', 120090=>'L', 120091=>'L', 120092=>'L', 120094=>'L', 120095=>'L', 120096=>'L', 120097=>'L', 120098=>'L', 120099=>'L', 120100=>'L', 120101=>'L', 120102=>'L', 120103=>'L', 120104=>'L', 120105=>'L', 120106=>'L', 120107=>'L', 120108=>'L', 120109=>'L', 120110=>'L', 120111=>'L', 120112=>'L', 120113=>'L', 120114=>'L', 120115=>'L', 120116=>'L', 120117=>'L', 120118=>'L', 120119=>'L', 120120=>'L', 120121=>'L', 120123=>'L', 120124=>'L', 120125=>'L', 120126=>'L', 120128=>'L', 120129=>'L', 120130=>'L', 120131=>'L', 120132=>'L', 120134=>'L', 120138=>'L', 120139=>'L', 120140=>'L', 120141=>'L', 120142=>'L', 120143=>'L', 120144=>'L', 120146=>'L', 120147=>'L', 120148=>'L', 120149=>'L', 120150=>'L', 120151=>'L', 120152=>'L', 120153=>'L', 120154=>'L', 120155=>'L', 120156=>'L', 120157=>'L', 120158=>'L', 120159=>'L', 120160=>'L', 120161=>'L', 120162=>'L', 120163=>'L', 120164=>'L', 120165=>'L', 120166=>'L', 120167=>'L', 120168=>'L', 120169=>'L', 120170=>'L', 120171=>'L', 120172=>'L', 120173=>'L', 120174=>'L', 120175=>'L', 120176=>'L', 120177=>'L', 120178=>'L', 120179=>'L', 120180=>'L', 120181=>'L', 120182=>'L', 120183=>'L', 120184=>'L', 120185=>'L', 120186=>'L', 120187=>'L', 120188=>'L', 120189=>'L', 120190=>'L', 120191=>'L', 120192=>'L', 120193=>'L', 120194=>'L', 120195=>'L', 120196=>'L', 120197=>'L', 120198=>'L', 120199=>'L', 120200=>'L', 120201=>'L', 120202=>'L', 120203=>'L', 120204=>'L', 120205=>'L', 120206=>'L', 120207=>'L', 120208=>'L', 120209=>'L', 120210=>'L', 120211=>'L', 120212=>'L', 120213=>'L', 120214=>'L', 120215=>'L', 120216=>'L', 120217=>'L', 120218=>'L', 120219=>'L', 120220=>'L', 120221=>'L', 120222=>'L', 120223=>'L', 120224=>'L', 120225=>'L', 120226=>'L', 120227=>'L', 120228=>'L', 120229=>'L', 120230=>'L', 120231=>'L', 120232=>'L', 120233=>'L', 120234=>'L', 120235=>'L', 120236=>'L', 120237=>'L', 120238=>'L', 120239=>'L', 120240=>'L', 120241=>'L', 120242=>'L', 120243=>'L', 120244=>'L', 120245=>'L', 120246=>'L', 120247=>'L', 120248=>'L', 120249=>'L', 120250=>'L', 120251=>'L', 120252=>'L', 120253=>'L', 120254=>'L', 120255=>'L', 120256=>'L', 120257=>'L', 120258=>'L', 120259=>'L', 120260=>'L', 120261=>'L', 120262=>'L', 120263=>'L', 120264=>'L', 120265=>'L', 120266=>'L', 120267=>'L', 120268=>'L', 120269=>'L', 120270=>'L', 120271=>'L', 120272=>'L', 120273=>'L', 120274=>'L', 120275=>'L', 120276=>'L', 120277=>'L', 120278=>'L', 120279=>'L', 120280=>'L', 120281=>'L', 120282=>'L', 120283=>'L', 120284=>'L', 120285=>'L', 120286=>'L', 120287=>'L', 120288=>'L', 120289=>'L', 120290=>'L', 120291=>'L', 120292=>'L', 120293=>'L', 120294=>'L', 120295=>'L', 120296=>'L', 120297=>'L', 120298=>'L', 120299=>'L', 120300=>'L', 120301=>'L', 120302=>'L', 120303=>'L', 120304=>'L', 120305=>'L', 120306=>'L', 120307=>'L', 120308=>'L', 120309=>'L', 120310=>'L', 120311=>'L', 120312=>'L', 120313=>'L', 120314=>'L', 120315=>'L', 120316=>'L', 120317=>'L', 120318=>'L', 120319=>'L', 120320=>'L', 120321=>'L', 120322=>'L', 120323=>'L', 120324=>'L', 120325=>'L', 120326=>'L', 120327=>'L', 120328=>'L', 120329=>'L', 120330=>'L', 120331=>'L', 120332=>'L', 120333=>'L', 120334=>'L', 120335=>'L', 120336=>'L', 120337=>'L', 120338=>'L', 120339=>'L', 120340=>'L', 120341=>'L', 120342=>'L', 120343=>'L', 120344=>'L', 120345=>'L', 120346=>'L', 120347=>'L', 120348=>'L', 120349=>'L', 120350=>'L', 120351=>'L', 120352=>'L', 120353=>'L', 120354=>'L', 120355=>'L', 120356=>'L', 120357=>'L', 120358=>'L', 120359=>'L', 120360=>'L', 120361=>'L', 120362=>'L', 120363=>'L', 120364=>'L', 120365=>'L', 120366=>'L', 120367=>'L', 120368=>'L', 120369=>'L', 120370=>'L', 120371=>'L', 120372=>'L', 120373=>'L', 120374=>'L', 120375=>'L', 120376=>'L', 120377=>'L', 120378=>'L', 120379=>'L', 120380=>'L', 120381=>'L', 120382=>'L', 120383=>'L', 120384=>'L', 120385=>'L', 120386=>'L', 120387=>'L', 120388=>'L', 120389=>'L', 120390=>'L', 120391=>'L', 120392=>'L', 120393=>'L', 120394=>'L', 120395=>'L', 120396=>'L', 120397=>'L', 120398=>'L', 120399=>'L', 120400=>'L', 120401=>'L', 120402=>'L', 120403=>'L', 120404=>'L', 120405=>'L', 120406=>'L', 120407=>'L', 120408=>'L', 120409=>'L', 120410=>'L', 120411=>'L', 120412=>'L', 120413=>'L', 120414=>'L', 120415=>'L', 120416=>'L', 120417=>'L', 120418=>'L', 120419=>'L', 120420=>'L', 120421=>'L', 120422=>'L', 120423=>'L', 120424=>'L', 120425=>'L', 120426=>'L', 120427=>'L', 120428=>'L', 120429=>'L', 120430=>'L', 120431=>'L', 120432=>'L', 120433=>'L', 120434=>'L', 120435=>'L', 120436=>'L', 120437=>'L', 120438=>'L', 120439=>'L', 120440=>'L', 120441=>'L', 120442=>'L', 120443=>'L', 120444=>'L', 120445=>'L', 120446=>'L', 120447=>'L', 120448=>'L', 120449=>'L', 120450=>'L', 120451=>'L', 120452=>'L', 120453=>'L', 120454=>'L', 120455=>'L', 120456=>'L', 120457=>'L', 120458=>'L', 120459=>'L', 120460=>'L', 120461=>'L', 120462=>'L', 120463=>'L', 120464=>'L', 120465=>'L', 120466=>'L', 120467=>'L', 120468=>'L', 120469=>'L', 120470=>'L', 120471=>'L', 120472=>'L', 120473=>'L', 120474=>'L', 120475=>'L', 120476=>'L', 120477=>'L', 120478=>'L', 120479=>'L', 120480=>'L', 120481=>'L', 120482=>'L', 120483=>'L', 120484=>'L', 120485=>'L', 120488=>'L', 120489=>'L', 120490=>'L', 120491=>'L', 120492=>'L', 120493=>'L', 120494=>'L', 120495=>'L', 120496=>'L', 120497=>'L', 120498=>'L', 120499=>'L', 120500=>'L', 120501=>'L', 120502=>'L', 120503=>'L', 120504=>'L', 120505=>'L', 120506=>'L', 120507=>'L', 120508=>'L', 120509=>'L', 120510=>'L', 120511=>'L', 120512=>'L', 120513=>'L', 120514=>'L', 120515=>'L', 120516=>'L', 120517=>'L', 120518=>'L', 120519=>'L', 120520=>'L', 120521=>'L', 120522=>'L', 120523=>'L', 120524=>'L', 120525=>'L', 120526=>'L', 120527=>'L', 120528=>'L', 120529=>'L', 120530=>'L', 120531=>'L', 120532=>'L', 120533=>'L', 120534=>'L', 120535=>'L', 120536=>'L', 120537=>'L', 120538=>'L', 120539=>'L', 120540=>'L', 120541=>'L', 120542=>'L', 120543=>'L', 120544=>'L', 120545=>'L', 120546=>'L', 120547=>'L', 120548=>'L', 120549=>'L', 120550=>'L', 120551=>'L', 120552=>'L', 120553=>'L', 120554=>'L', 120555=>'L', 120556=>'L', 120557=>'L', 120558=>'L', 120559=>'L', 120560=>'L', 120561=>'L', 120562=>'L', 120563=>'L', 120564=>'L', 120565=>'L', 120566=>'L', 120567=>'L', 120568=>'L', 120569=>'L', 120570=>'L', 120571=>'L', 120572=>'L', 120573=>'L', 120574=>'L', 120575=>'L', 120576=>'L', 120577=>'L', 120578=>'L', 120579=>'L', 120580=>'L', 120581=>'L', 120582=>'L', 120583=>'L', 120584=>'L', 120585=>'L', 120586=>'L', 120587=>'L', 120588=>'L', 120589=>'L', 120590=>'L', 120591=>'L', 120592=>'L', 120593=>'L', 120594=>'L', 120595=>'L', 120596=>'L', 120597=>'L', 120598=>'L', 120599=>'L', 120600=>'L', 120601=>'L', 120602=>'L', 120603=>'L', 120604=>'L', 120605=>'L', 120606=>'L', 120607=>'L', 120608=>'L', 120609=>'L', 120610=>'L', 120611=>'L', 120612=>'L', 120613=>'L', 120614=>'L', 120615=>'L', 120616=>'L', 120617=>'L', 120618=>'L', 120619=>'L', 120620=>'L', 120621=>'L', 120622=>'L', 120623=>'L', 120624=>'L', 120625=>'L', 120626=>'L', 120627=>'L', 120628=>'L', 120629=>'L', 120630=>'L', 120631=>'L', 120632=>'L', 120633=>'L', 120634=>'L', 120635=>'L', 120636=>'L', 120637=>'L', 120638=>'L', 120639=>'L', 120640=>'L', 120641=>'L', 120642=>'L', 120643=>'L', 120644=>'L', 120645=>'L', 120646=>'L', 120647=>'L', 120648=>'L', 120649=>'L', 120650=>'L', 120651=>'L', 120652=>'L', 120653=>'L', 120654=>'L', 120655=>'L', 120656=>'L', 120657=>'L', 120658=>'L', 120659=>'L', 120660=>'L', 120661=>'L', 120662=>'L', 120663=>'L', 120664=>'L', 120665=>'L', 120666=>'L', 120667=>'L', 120668=>'L', 120669=>'L', 120670=>'L', 120671=>'L', 120672=>'L', 120673=>'L', 120674=>'L', 120675=>'L', 120676=>'L', 120677=>'L', 120678=>'L', 120679=>'L', 120680=>'L', 120681=>'L', 120682=>'L', 120683=>'L', 120684=>'L', 120685=>'L', 120686=>'L', 120687=>'L', 120688=>'L', 120689=>'L', 120690=>'L', 120691=>'L', 120692=>'L', 120693=>'L', 120694=>'L', 120695=>'L', 120696=>'L', 120697=>'L', 120698=>'L', 120699=>'L', 120700=>'L', 120701=>'L', 120702=>'L', 120703=>'L', 120704=>'L', 120705=>'L', 120706=>'L', 120707=>'L', 120708=>'L', 120709=>'L', 120710=>'L', 120711=>'L', 120712=>'L', 120713=>'L', 120714=>'L', 120715=>'L', 120716=>'L', 120717=>'L', 120718=>'L', 120719=>'L', 120720=>'L', 120721=>'L', 120722=>'L', 120723=>'L', 120724=>'L', 120725=>'L', 120726=>'L', 120727=>'L', 120728=>'L', 120729=>'L', 120730=>'L', 120731=>'L', 120732=>'L', 120733=>'L', 120734=>'L', 120735=>'L', 120736=>'L', 120737=>'L', 120738=>'L', 120739=>'L', 120740=>'L', 120741=>'L', 120742=>'L', 120743=>'L', 120744=>'L', 120745=>'L', 120746=>'L', 120747=>'L', 120748=>'L', 120749=>'L', 120750=>'L', 120751=>'L', 120752=>'L', 120753=>'L', 120754=>'L', 120755=>'L', 120756=>'L', 120757=>'L', 120758=>'L', 120759=>'L', 120760=>'L', 120761=>'L', 120762=>'L', 120763=>'L', 120764=>'L', 120765=>'L', 120766=>'L', 120767=>'L', 120768=>'L', 120769=>'L', 120770=>'L', 120771=>'L', 120772=>'L', 120773=>'L', 120774=>'L', 120775=>'L', 120776=>'L', 120777=>'L', 120778=>'L', 120779=>'L', 120782=>'EN', 120783=>'EN', 120784=>'EN', 120785=>'EN', 120786=>'EN', 120787=>'EN', 120788=>'EN', 120789=>'EN', 120790=>'EN', 120791=>'EN', 120792=>'EN', 120793=>'EN', 120794=>'EN', 120795=>'EN', 120796=>'EN', 120797=>'EN', 120798=>'EN', 120799=>'EN', 120800=>'EN', 120801=>'EN', 120802=>'EN', 120803=>'EN', 120804=>'EN', 120805=>'EN', 120806=>'EN', 120807=>'EN', 120808=>'EN', 120809=>'EN', 120810=>'EN', 120811=>'EN', 120812=>'EN', 120813=>'EN', 120814=>'EN', 120815=>'EN', 120816=>'EN', 120817=>'EN', 120818=>'EN', 120819=>'EN', 120820=>'EN', 120821=>'EN', 120822=>'EN', 120823=>'EN', 120824=>'EN', 120825=>'EN', 120826=>'EN', 120827=>'EN', 120828=>'EN', 120829=>'EN', 120830=>'EN', 120831=>'EN', 131072=>'L', 173782=>'L', 194560=>'L', 194561=>'L', 194562=>'L', 194563=>'L', 194564=>'L', 194565=>'L', 194566=>'L', 194567=>'L', 194568=>'L', 194569=>'L', 194570=>'L', 194571=>'L', 194572=>'L', 194573=>'L', 194574=>'L', 194575=>'L', 194576=>'L', 194577=>'L', 194578=>'L', 194579=>'L', 194580=>'L', 194581=>'L', 194582=>'L', 194583=>'L', 194584=>'L', 194585=>'L', 194586=>'L', 194587=>'L', 194588=>'L', 194589=>'L', 194590=>'L', 194591=>'L', 194592=>'L', 194593=>'L', 194594=>'L', 194595=>'L', 194596=>'L', 194597=>'L', 194598=>'L', 194599=>'L', 194600=>'L', 194601=>'L', 194602=>'L', 194603=>'L', 194604=>'L', 194605=>'L', 194606=>'L', 194607=>'L', 194608=>'L', 194609=>'L', 194610=>'L', 194611=>'L', 194612=>'L', 194613=>'L', 194614=>'L', 194615=>'L', 194616=>'L', 194617=>'L', 194618=>'L', 194619=>'L', 194620=>'L', 194621=>'L', 194622=>'L', 194623=>'L', 194624=>'L', 194625=>'L', 194626=>'L', 194627=>'L', 194628=>'L', 194629=>'L', 194630=>'L', 194631=>'L', 194632=>'L', 194633=>'L', 194634=>'L', 194635=>'L', 194636=>'L', 194637=>'L', 194638=>'L', 194639=>'L', 194640=>'L', 194641=>'L', 194642=>'L', 194643=>'L', 194644=>'L', 194645=>'L', 194646=>'L', 194647=>'L', 194648=>'L', 194649=>'L', 194650=>'L', 194651=>'L', 194652=>'L', 194653=>'L', 194654=>'L', 194655=>'L', 194656=>'L', 194657=>'L', 194658=>'L', 194659=>'L', 194660=>'L', 194661=>'L', 194662=>'L', 194663=>'L', 194664=>'L', 194665=>'L', 194666=>'L', 194667=>'L', 194668=>'L', 194669=>'L', 194670=>'L', 194671=>'L', 194672=>'L', 194673=>'L', 194674=>'L', 194675=>'L', 194676=>'L', 194677=>'L', 194678=>'L', 194679=>'L', 194680=>'L', 194681=>'L', 194682=>'L', 194683=>'L', 194684=>'L', 194685=>'L', 194686=>'L', 194687=>'L', 194688=>'L', 194689=>'L', 194690=>'L', 194691=>'L', 194692=>'L', 194693=>'L', 194694=>'L', 194695=>'L', 194696=>'L', 194697=>'L', 194698=>'L', 194699=>'L', 194700=>'L', 194701=>'L', 194702=>'L', 194703=>'L', 194704=>'L', 194705=>'L', 194706=>'L', 194707=>'L', 194708=>'L', 194709=>'L', 194710=>'L', 194711=>'L', 194712=>'L', 194713=>'L', 194714=>'L', 194715=>'L', 194716=>'L', 194717=>'L', 194718=>'L', 194719=>'L', 194720=>'L', 194721=>'L', 194722=>'L', 194723=>'L', 194724=>'L', 194725=>'L', 194726=>'L', 194727=>'L', 194728=>'L', 194729=>'L', 194730=>'L', 194731=>'L', 194732=>'L', 194733=>'L', 194734=>'L', 194735=>'L', 194736=>'L', 194737=>'L', 194738=>'L', 194739=>'L', 194740=>'L', 194741=>'L', 194742=>'L', 194743=>'L', 194744=>'L', 194745=>'L', 194746=>'L', 194747=>'L', 194748=>'L', 194749=>'L', 194750=>'L', 194751=>'L', 194752=>'L', 194753=>'L', 194754=>'L', 194755=>'L', 194756=>'L', 194757=>'L', 194758=>'L', 194759=>'L', 194760=>'L', 194761=>'L', 194762=>'L', 194763=>'L', 194764=>'L', 194765=>'L', 194766=>'L', 194767=>'L', 194768=>'L', 194769=>'L', 194770=>'L', 194771=>'L', 194772=>'L', 194773=>'L', 194774=>'L', 194775=>'L', 194776=>'L', 194777=>'L', 194778=>'L', 194779=>'L', 194780=>'L', 194781=>'L', 194782=>'L', 194783=>'L', 194784=>'L', 194785=>'L', 194786=>'L', 194787=>'L', 194788=>'L', 194789=>'L', 194790=>'L', 194791=>'L', 194792=>'L', 194793=>'L', 194794=>'L', 194795=>'L', 194796=>'L', 194797=>'L', 194798=>'L', 194799=>'L', 194800=>'L', 194801=>'L', 194802=>'L', 194803=>'L', 194804=>'L', 194805=>'L', 194806=>'L', 194807=>'L', 194808=>'L', 194809=>'L', 194810=>'L', 194811=>'L', 194812=>'L', 194813=>'L', 194814=>'L', 194815=>'L', 194816=>'L', 194817=>'L', 194818=>'L', 194819=>'L', 194820=>'L', 194821=>'L', 194822=>'L', 194823=>'L', 194824=>'L', 194825=>'L', 194826=>'L', 194827=>'L', 194828=>'L', 194829=>'L', 194830=>'L', 194831=>'L', 194832=>'L', 194833=>'L', 194834=>'L', 194835=>'L', 194836=>'L', 194837=>'L', 194838=>'L', 194839=>'L', 194840=>'L', 194841=>'L', 194842=>'L', 194843=>'L', 194844=>'L', 194845=>'L', 194846=>'L', 194847=>'L', 194848=>'L', 194849=>'L', 194850=>'L', 194851=>'L', 194852=>'L', 194853=>'L', 194854=>'L', 194855=>'L', 194856=>'L', 194857=>'L', 194858=>'L', 194859=>'L', 194860=>'L', 194861=>'L', 194862=>'L', 194863=>'L', 194864=>'L', 194865=>'L', 194866=>'L', 194867=>'L', 194868=>'L', 194869=>'L', 194870=>'L', 194871=>'L', 194872=>'L', 194873=>'L', 194874=>'L', 194875=>'L', 194876=>'L', 194877=>'L', 194878=>'L', 194879=>'L', 194880=>'L', 194881=>'L', 194882=>'L', 194883=>'L', 194884=>'L', 194885=>'L', 194886=>'L', 194887=>'L', 194888=>'L', 194889=>'L', 194890=>'L', 194891=>'L', 194892=>'L', 194893=>'L', 194894=>'L', 194895=>'L', 194896=>'L', 194897=>'L', 194898=>'L', 194899=>'L', 194900=>'L', 194901=>'L', 194902=>'L', 194903=>'L', 194904=>'L', 194905=>'L', 194906=>'L', 194907=>'L', 194908=>'L', 194909=>'L', 194910=>'L', 194911=>'L', 194912=>'L', 194913=>'L', 194914=>'L', 194915=>'L', 194916=>'L', 194917=>'L', 194918=>'L', 194919=>'L', 194920=>'L', 194921=>'L', 194922=>'L', 194923=>'L', 194924=>'L', 194925=>'L', 194926=>'L', 194927=>'L', 194928=>'L', 194929=>'L', 194930=>'L', 194931=>'L', 194932=>'L', 194933=>'L', 194934=>'L', 194935=>'L', 194936=>'L', 194937=>'L', 194938=>'L', 194939=>'L', 194940=>'L', 194941=>'L', 194942=>'L', 194943=>'L', 194944=>'L', 194945=>'L', 194946=>'L', 194947=>'L', 194948=>'L', 194949=>'L', 194950=>'L', 194951=>'L', 194952=>'L', 194953=>'L', 194954=>'L', 194955=>'L', 194956=>'L', 194957=>'L', 194958=>'L', 194959=>'L', 194960=>'L', 194961=>'L', 194962=>'L', 194963=>'L', 194964=>'L', 194965=>'L', 194966=>'L', 194967=>'L', 194968=>'L', 194969=>'L', 194970=>'L', 194971=>'L', 194972=>'L', 194973=>'L', 194974=>'L', 194975=>'L', 194976=>'L', 194977=>'L', 194978=>'L', 194979=>'L', 194980=>'L', 194981=>'L', 194982=>'L', 194983=>'L', 194984=>'L', 194985=>'L', 194986=>'L', 194987=>'L', 194988=>'L', 194989=>'L', 194990=>'L', 194991=>'L', 194992=>'L', 194993=>'L', 194994=>'L', 194995=>'L', 194996=>'L', 194997=>'L', 194998=>'L', 194999=>'L', 195000=>'L', 195001=>'L', 195002=>'L', 195003=>'L', 195004=>'L', 195005=>'L', 195006=>'L', 195007=>'L', 195008=>'L', 195009=>'L', 195010=>'L', 195011=>'L', 195012=>'L', 195013=>'L', 195014=>'L', 195015=>'L', 195016=>'L', 195017=>'L', 195018=>'L', 195019=>'L', 195020=>'L', 195021=>'L', 195022=>'L', 195023=>'L', 195024=>'L', 195025=>'L', 195026=>'L', 195027=>'L', 195028=>'L', 195029=>'L', 195030=>'L', 195031=>'L', 195032=>'L', 195033=>'L', 195034=>'L', 195035=>'L', 195036=>'L', 195037=>'L', 195038=>'L', 195039=>'L', 195040=>'L', 195041=>'L', 195042=>'L', 195043=>'L', 195044=>'L', 195045=>'L', 195046=>'L', 195047=>'L', 195048=>'L', 195049=>'L', 195050=>'L', 195051=>'L', 195052=>'L', 195053=>'L', 195054=>'L', 195055=>'L', 195056=>'L', 195057=>'L', 195058=>'L', 195059=>'L', 195060=>'L', 195061=>'L', 195062=>'L', 195063=>'L', 195064=>'L', 195065=>'L', 195066=>'L', 195067=>'L', 195068=>'L', 195069=>'L', 195070=>'L', 195071=>'L', 195072=>'L', 195073=>'L', 195074=>'L', 195075=>'L', 195076=>'L', 195077=>'L', 195078=>'L', 195079=>'L', 195080=>'L', 195081=>'L', 195082=>'L', 195083=>'L', 195084=>'L', 195085=>'L', 195086=>'L', 195087=>'L', 195088=>'L', 195089=>'L', 195090=>'L', 195091=>'L', 195092=>'L', 195093=>'L', 195094=>'L', 195095=>'L', 195096=>'L', 195097=>'L', 195098=>'L', 195099=>'L', 195100=>'L', 195101=>'L', 917505=>'BN', 917536=>'BN', 917537=>'BN', 917538=>'BN', 917539=>'BN', 917540=>'BN', 917541=>'BN', 917542=>'BN', 917543=>'BN', 917544=>'BN', 917545=>'BN', 917546=>'BN', 917547=>'BN', 917548=>'BN', 917549=>'BN', 917550=>'BN', 917551=>'BN', 917552=>'BN', 917553=>'BN', 917554=>'BN', 917555=>'BN', 917556=>'BN', 917557=>'BN', 917558=>'BN', 917559=>'BN', 917560=>'BN', 917561=>'BN', 917562=>'BN', 917563=>'BN', 917564=>'BN', 917565=>'BN', 917566=>'BN', 917567=>'BN', 917568=>'BN', 917569=>'BN', 917570=>'BN', 917571=>'BN', 917572=>'BN', 917573=>'BN', 917574=>'BN', 917575=>'BN', 917576=>'BN', 917577=>'BN', 917578=>'BN', 917579=>'BN', 917580=>'BN', 917581=>'BN', 917582=>'BN', 917583=>'BN', 917584=>'BN', 917585=>'BN', 917586=>'BN', 917587=>'BN', 917588=>'BN', 917589=>'BN', 917590=>'BN', 917591=>'BN', 917592=>'BN', 917593=>'BN', 917594=>'BN', 917595=>'BN', 917596=>'BN', 917597=>'BN', 917598=>'BN', 917599=>'BN', 917600=>'BN', 917601=>'BN', 917602=>'BN', 917603=>'BN', 917604=>'BN', 917605=>'BN', 917606=>'BN', 917607=>'BN', 917608=>'BN', 917609=>'BN', 917610=>'BN', 917611=>'BN', 917612=>'BN', 917613=>'BN', 917614=>'BN', 917615=>'BN', 917616=>'BN', 917617=>'BN', 917618=>'BN', 917619=>'BN', 917620=>'BN', 917621=>'BN', 917622=>'BN', 917623=>'BN', 917624=>'BN', 917625=>'BN', 917626=>'BN', 917627=>'BN', 917628=>'BN', 917629=>'BN', 917630=>'BN', 917631=>'BN', 917760=>'NSM', 917761=>'NSM', 917762=>'NSM', 917763=>'NSM', 917764=>'NSM', 917765=>'NSM', 917766=>'NSM', 917767=>'NSM', 917768=>'NSM', 917769=>'NSM', 917770=>'NSM', 917771=>'NSM', 917772=>'NSM', 917773=>'NSM', 917774=>'NSM', 917775=>'NSM', 917776=>'NSM', 917777=>'NSM', 917778=>'NSM', 917779=>'NSM', 917780=>'NSM', 917781=>'NSM', 917782=>'NSM', 917783=>'NSM', 917784=>'NSM', 917785=>'NSM', 917786=>'NSM', 917787=>'NSM', 917788=>'NSM', 917789=>'NSM', 917790=>'NSM', 917791=>'NSM', 917792=>'NSM', 917793=>'NSM', 917794=>'NSM', 917795=>'NSM', 917796=>'NSM', 917797=>'NSM', 917798=>'NSM', 917799=>'NSM', 917800=>'NSM', 917801=>'NSM', 917802=>'NSM', 917803=>'NSM', 917804=>'NSM', 917805=>'NSM', 917806=>'NSM', 917807=>'NSM', 917808=>'NSM', 917809=>'NSM', 917810=>'NSM', 917811=>'NSM', 917812=>'NSM', 917813=>'NSM', 917814=>'NSM', 917815=>'NSM', 917816=>'NSM', 917817=>'NSM', 917818=>'NSM', 917819=>'NSM', 917820=>'NSM', 917821=>'NSM', 917822=>'NSM', 917823=>'NSM', 917824=>'NSM', 917825=>'NSM', 917826=>'NSM', 917827=>'NSM', 917828=>'NSM', 917829=>'NSM', 917830=>'NSM', 917831=>'NSM', 917832=>'NSM', 917833=>'NSM', 917834=>'NSM', 917835=>'NSM', 917836=>'NSM', 917837=>'NSM', 917838=>'NSM', 917839=>'NSM', 917840=>'NSM', 917841=>'NSM', 917842=>'NSM', 917843=>'NSM', 917844=>'NSM', 917845=>'NSM', 917846=>'NSM', 917847=>'NSM', 917848=>'NSM', 917849=>'NSM', 917850=>'NSM', 917851=>'NSM', 917852=>'NSM', 917853=>'NSM', 917854=>'NSM', 917855=>'NSM', 917856=>'NSM', 917857=>'NSM', 917858=>'NSM', 917859=>'NSM', 917860=>'NSM', 917861=>'NSM', 917862=>'NSM', 917863=>'NSM', 917864=>'NSM', 917865=>'NSM', 917866=>'NSM', 917867=>'NSM', 917868=>'NSM', 917869=>'NSM', 917870=>'NSM', 917871=>'NSM', 917872=>'NSM', 917873=>'NSM', 917874=>'NSM', 917875=>'NSM', 917876=>'NSM', 917877=>'NSM', 917878=>'NSM', 917879=>'NSM', 917880=>'NSM', 917881=>'NSM', 917882=>'NSM', 917883=>'NSM', 917884=>'NSM', 917885=>'NSM', 917886=>'NSM', 917887=>'NSM', 917888=>'NSM', 917889=>'NSM', 917890=>'NSM', 917891=>'NSM', 917892=>'NSM', 917893=>'NSM', 917894=>'NSM', 917895=>'NSM', 917896=>'NSM', 917897=>'NSM', 917898=>'NSM', 917899=>'NSM', 917900=>'NSM', 917901=>'NSM', 917902=>'NSM', 917903=>'NSM', 917904=>'NSM', 917905=>'NSM', 917906=>'NSM', 917907=>'NSM', 917908=>'NSM', 917909=>'NSM', 917910=>'NSM', 917911=>'NSM', 917912=>'NSM', 917913=>'NSM', 917914=>'NSM', 917915=>'NSM', 917916=>'NSM', 917917=>'NSM', 917918=>'NSM', 917919=>'NSM', 917920=>'NSM', 917921=>'NSM', 917922=>'NSM', 917923=>'NSM', 917924=>'NSM', 917925=>'NSM', 917926=>'NSM', 917927=>'NSM', 917928=>'NSM', 917929=>'NSM', 917930=>'NSM', 917931=>'NSM', 917932=>'NSM', 917933=>'NSM', 917934=>'NSM', 917935=>'NSM', 917936=>'NSM', 917937=>'NSM', 917938=>'NSM', 917939=>'NSM', 917940=>'NSM', 917941=>'NSM', 917942=>'NSM', 917943=>'NSM', 917944=>'NSM', 917945=>'NSM', 917946=>'NSM', 917947=>'NSM', 917948=>'NSM', 917949=>'NSM', 917950=>'NSM', 917951=>'NSM', 917952=>'NSM', 917953=>'NSM', 917954=>'NSM', 917955=>'NSM', 917956=>'NSM', 917957=>'NSM', 917958=>'NSM', 917959=>'NSM', 917960=>'NSM', 917961=>'NSM', 917962=>'NSM', 917963=>'NSM', 917964=>'NSM', 917965=>'NSM', 917966=>'NSM', 917967=>'NSM', 917968=>'NSM', 917969=>'NSM', 917970=>'NSM', 917971=>'NSM', 917972=>'NSM', 917973=>'NSM', 917974=>'NSM', 917975=>'NSM', 917976=>'NSM', 917977=>'NSM', 917978=>'NSM', 917979=>'NSM', 917980=>'NSM', 917981=>'NSM', 917982=>'NSM', 917983=>'NSM', 917984=>'NSM', 917985=>'NSM', 917986=>'NSM', 917987=>'NSM', 917988=>'NSM', 917989=>'NSM', 917990=>'NSM', 917991=>'NSM', 917992=>'NSM', 917993=>'NSM', 917994=>'NSM', 917995=>'NSM', 917996=>'NSM', 917997=>'NSM', 917998=>'NSM', 917999=>'NSM', 983040=>'L', 1048573=>'L', 1048576=>'L', 1114109=>'L' ); /** * Mirror unicode characters. For information on bidi mirroring, see UAX #9: Bidirectional Algorithm, at http://www.unicode.org/unicode/reports/tr9/ * @public */ public static $uni_mirror = array ( 0x0028=>0x0029, 0x0029=>0x0028, 0x003C=>0x003E, 0x003E=>0x003C, 0x005B=>0x005D, 0x005D=>0x005B, 0x007B=>0x007D, 0x007D=>0x007B, 0x00AB=>0x00BB, 0x00BB=>0x00AB, 0x0F3A=>0x0F3B, 0x0F3B=>0x0F3A, 0x0F3C=>0x0F3D, 0x0F3D=>0x0F3C, 0x169B=>0x169C, 0x169C=>0x169B, 0x2018=>0x2019, 0x2019=>0x2018, 0x201C=>0x201D, 0x201D=>0x201C, 0x2039=>0x203A, 0x203A=>0x2039, 0x2045=>0x2046, 0x2046=>0x2045, 0x207D=>0x207E, 0x207E=>0x207D, 0x208D=>0x208E, 0x208E=>0x208D, 0x2208=>0x220B, 0x2209=>0x220C, 0x220A=>0x220D, 0x220B=>0x2208, 0x220C=>0x2209, 0x220D=>0x220A, 0x2215=>0x29F5, 0x223C=>0x223D, 0x223D=>0x223C, 0x2243=>0x22CD, 0x2252=>0x2253, 0x2253=>0x2252, 0x2254=>0x2255, 0x2255=>0x2254, 0x2264=>0x2265, 0x2265=>0x2264, 0x2266=>0x2267, 0x2267=>0x2266, 0x2268=>0x2269, 0x2269=>0x2268, 0x226A=>0x226B, 0x226B=>0x226A, 0x226E=>0x226F, 0x226F=>0x226E, 0x2270=>0x2271, 0x2271=>0x2270, 0x2272=>0x2273, 0x2273=>0x2272, 0x2274=>0x2275, 0x2275=>0x2274, 0x2276=>0x2277, 0x2277=>0x2276, 0x2278=>0x2279, 0x2279=>0x2278, 0x227A=>0x227B, 0x227B=>0x227A, 0x227C=>0x227D, 0x227D=>0x227C, 0x227E=>0x227F, 0x227F=>0x227E, 0x2280=>0x2281, 0x2281=>0x2280, 0x2282=>0x2283, 0x2283=>0x2282, 0x2284=>0x2285, 0x2285=>0x2284, 0x2286=>0x2287, 0x2287=>0x2286, 0x2288=>0x2289, 0x2289=>0x2288, 0x228A=>0x228B, 0x228B=>0x228A, 0x228F=>0x2290, 0x2290=>0x228F, 0x2291=>0x2292, 0x2292=>0x2291, 0x2298=>0x29B8, 0x22A2=>0x22A3, 0x22A3=>0x22A2, 0x22A6=>0x2ADE, 0x22A8=>0x2AE4, 0x22A9=>0x2AE3, 0x22AB=>0x2AE5, 0x22B0=>0x22B1, 0x22B1=>0x22B0, 0x22B2=>0x22B3, 0x22B3=>0x22B2, 0x22B4=>0x22B5, 0x22B5=>0x22B4, 0x22B6=>0x22B7, 0x22B7=>0x22B6, 0x22C9=>0x22CA, 0x22CA=>0x22C9, 0x22CB=>0x22CC, 0x22CC=>0x22CB, 0x22CD=>0x2243, 0x22D0=>0x22D1, 0x22D1=>0x22D0, 0x22D6=>0x22D7, 0x22D7=>0x22D6, 0x22D8=>0x22D9, 0x22D9=>0x22D8, 0x22DA=>0x22DB, 0x22DB=>0x22DA, 0x22DC=>0x22DD, 0x22DD=>0x22DC, 0x22DE=>0x22DF, 0x22DF=>0x22DE, 0x22E0=>0x22E1, 0x22E1=>0x22E0, 0x22E2=>0x22E3, 0x22E3=>0x22E2, 0x22E4=>0x22E5, 0x22E5=>0x22E4, 0x22E6=>0x22E7, 0x22E7=>0x22E6, 0x22E8=>0x22E9, 0x22E9=>0x22E8, 0x22EA=>0x22EB, 0x22EB=>0x22EA, 0x22EC=>0x22ED, 0x22ED=>0x22EC, 0x22F0=>0x22F1, 0x22F1=>0x22F0, 0x22F2=>0x22FA, 0x22F3=>0x22FB, 0x22F4=>0x22FC, 0x22F6=>0x22FD, 0x22F7=>0x22FE, 0x22FA=>0x22F2, 0x22FB=>0x22F3, 0x22FC=>0x22F4, 0x22FD=>0x22F6, 0x22FE=>0x22F7, 0x2308=>0x2309, 0x2309=>0x2308, 0x230A=>0x230B, 0x230B=>0x230A, 0x2329=>0x232A, 0x232A=>0x2329, 0x2768=>0x2769, 0x2769=>0x2768, 0x276A=>0x276B, 0x276B=>0x276A, 0x276C=>0x276D, 0x276D=>0x276C, 0x276E=>0x276F, 0x276F=>0x276E, 0x2770=>0x2771, 0x2771=>0x2770, 0x2772=>0x2773, 0x2773=>0x2772, 0x2774=>0x2775, 0x2775=>0x2774, 0x27C3=>0x27C4, 0x27C4=>0x27C3, 0x27C5=>0x27C6, 0x27C6=>0x27C5, 0x27D5=>0x27D6, 0x27D6=>0x27D5, 0x27DD=>0x27DE, 0x27DE=>0x27DD, 0x27E2=>0x27E3, 0x27E3=>0x27E2, 0x27E4=>0x27E5, 0x27E5=>0x27E4, 0x27E6=>0x27E7, 0x27E7=>0x27E6, 0x27E8=>0x27E9, 0x27E9=>0x27E8, 0x27EA=>0x27EB, 0x27EB=>0x27EA, 0x2983=>0x2984, 0x2984=>0x2983, 0x2985=>0x2986, 0x2986=>0x2985, 0x2987=>0x2988, 0x2988=>0x2987, 0x2989=>0x298A, 0x298A=>0x2989, 0x298B=>0x298C, 0x298C=>0x298B, 0x298D=>0x2990, 0x298E=>0x298F, 0x298F=>0x298E, 0x2990=>0x298D, 0x2991=>0x2992, 0x2992=>0x2991, 0x2993=>0x2994, 0x2994=>0x2993, 0x2995=>0x2996, 0x2996=>0x2995, 0x2997=>0x2998, 0x2998=>0x2997, 0x29B8=>0x2298, 0x29C0=>0x29C1, 0x29C1=>0x29C0, 0x29C4=>0x29C5, 0x29C5=>0x29C4, 0x29CF=>0x29D0, 0x29D0=>0x29CF, 0x29D1=>0x29D2, 0x29D2=>0x29D1, 0x29D4=>0x29D5, 0x29D5=>0x29D4, 0x29D8=>0x29D9, 0x29D9=>0x29D8, 0x29DA=>0x29DB, 0x29DB=>0x29DA, 0x29F5=>0x2215, 0x29F8=>0x29F9, 0x29F9=>0x29F8, 0x29FC=>0x29FD, 0x29FD=>0x29FC, 0x2A2B=>0x2A2C, 0x2A2C=>0x2A2B, 0x2A2D=>0x2A2E, 0x2A2E=>0x2A2D, 0x2A34=>0x2A35, 0x2A35=>0x2A34, 0x2A3C=>0x2A3D, 0x2A3D=>0x2A3C, 0x2A64=>0x2A65, 0x2A65=>0x2A64, 0x2A79=>0x2A7A, 0x2A7A=>0x2A79, 0x2A7D=>0x2A7E, 0x2A7E=>0x2A7D, 0x2A7F=>0x2A80, 0x2A80=>0x2A7F, 0x2A81=>0x2A82, 0x2A82=>0x2A81, 0x2A83=>0x2A84, 0x2A84=>0x2A83, 0x2A8B=>0x2A8C, 0x2A8C=>0x2A8B, 0x2A91=>0x2A92, 0x2A92=>0x2A91, 0x2A93=>0x2A94, 0x2A94=>0x2A93, 0x2A95=>0x2A96, 0x2A96=>0x2A95, 0x2A97=>0x2A98, 0x2A98=>0x2A97, 0x2A99=>0x2A9A, 0x2A9A=>0x2A99, 0x2A9B=>0x2A9C, 0x2A9C=>0x2A9B, 0x2AA1=>0x2AA2, 0x2AA2=>0x2AA1, 0x2AA6=>0x2AA7, 0x2AA7=>0x2AA6, 0x2AA8=>0x2AA9, 0x2AA9=>0x2AA8, 0x2AAA=>0x2AAB, 0x2AAB=>0x2AAA, 0x2AAC=>0x2AAD, 0x2AAD=>0x2AAC, 0x2AAF=>0x2AB0, 0x2AB0=>0x2AAF, 0x2AB3=>0x2AB4, 0x2AB4=>0x2AB3, 0x2ABB=>0x2ABC, 0x2ABC=>0x2ABB, 0x2ABD=>0x2ABE, 0x2ABE=>0x2ABD, 0x2ABF=>0x2AC0, 0x2AC0=>0x2ABF, 0x2AC1=>0x2AC2, 0x2AC2=>0x2AC1, 0x2AC3=>0x2AC4, 0x2AC4=>0x2AC3, 0x2AC5=>0x2AC6, 0x2AC6=>0x2AC5, 0x2ACD=>0x2ACE, 0x2ACE=>0x2ACD, 0x2ACF=>0x2AD0, 0x2AD0=>0x2ACF, 0x2AD1=>0x2AD2, 0x2AD2=>0x2AD1, 0x2AD3=>0x2AD4, 0x2AD4=>0x2AD3, 0x2AD5=>0x2AD6, 0x2AD6=>0x2AD5, 0x2ADE=>0x22A6, 0x2AE3=>0x22A9, 0x2AE4=>0x22A8, 0x2AE5=>0x22AB, 0x2AEC=>0x2AED, 0x2AED=>0x2AEC, 0x2AF7=>0x2AF8, 0x2AF8=>0x2AF7, 0x2AF9=>0x2AFA, 0x2AFA=>0x2AF9, 0x2E02=>0x2E03, 0x2E03=>0x2E02, 0x2E04=>0x2E05, 0x2E05=>0x2E04, 0x2E09=>0x2E0A, 0x2E0A=>0x2E09, 0x2E0C=>0x2E0D, 0x2E0D=>0x2E0C, 0x2E1C=>0x2E1D, 0x2E1D=>0x2E1C, 0x3008=>0x3009, 0x3009=>0x3008, 0x300A=>0x300B, 0x300B=>0x300A, 0x300C=>0x300D, 0x300D=>0x300C, 0x300E=>0x300F, 0x300F=>0x300E, 0x3010=>0x3011, 0x3011=>0x3010, 0x3014=>0x3015, 0x3015=>0x3014, 0x3016=>0x3017, 0x3017=>0x3016, 0x3018=>0x3019, 0x3019=>0x3018, 0x301A=>0x301B, 0x301B=>0x301A, 0x301D=>0x301E, 0x301E=>0x301D, 0xFE59=>0xFE5A, 0xFE5A=>0xFE59, 0xFE5B=>0xFE5C, 0xFE5C=>0xFE5B, 0xFE5D=>0xFE5E, 0xFE5E=>0xFE5D, 0xFE64=>0xFE65, 0xFE65=>0xFE64, 0xFF08=>0xFF09, 0xFF09=>0xFF08, 0xFF1C=>0xFF1E, 0xFF1E=>0xFF1C, 0xFF3B=>0xFF3D, 0xFF3D=>0xFF3B, 0xFF5B=>0xFF5D, 0xFF5D=>0xFF5B, 0xFF5F=>0xFF60, 0xFF60=>0xFF5F, 0xFF62=>0xFF63, 0xFF63=>0xFF62); /** * Arabic shape substitutions: char code => (isolated, final, initial, medial). * @public */ public static $uni_arabicsubst = array( 1569=>array(65152), 1570=>array(65153, 65154, 65153, 65154), 1571=>array(65155, 65156, 65155, 65156), 1572=>array(65157, 65158), 1573=>array(65159, 65160, 65159, 65160), 1574=>array(65161, 65162, 65163, 65164), 1575=>array(65165, 65166, 65165, 65166), 1576=>array(65167, 65168, 65169, 65170), 1577=>array(65171, 65172), 1578=>array(65173, 65174, 65175, 65176), 1579=>array(65177, 65178, 65179, 65180), 1580=>array(65181, 65182, 65183, 65184), 1581=>array(65185, 65186, 65187, 65188), 1582=>array(65189, 65190, 65191, 65192), 1583=>array(65193, 65194, 65193, 65194), 1584=>array(65195, 65196, 65195, 65196), 1585=>array(65197, 65198, 65197, 65198), 1586=>array(65199, 65200, 65199, 65200), 1587=>array(65201, 65202, 65203, 65204), 1588=>array(65205, 65206, 65207, 65208), 1589=>array(65209, 65210, 65211, 65212), 1590=>array(65213, 65214, 65215, 65216), 1591=>array(65217, 65218, 65219, 65220), 1592=>array(65221, 65222, 65223, 65224), 1593=>array(65225, 65226, 65227, 65228), 1594=>array(65229, 65230, 65231, 65232), 1601=>array(65233, 65234, 65235, 65236), 1602=>array(65237, 65238, 65239, 65240), 1603=>array(65241, 65242, 65243, 65244), 1604=>array(65245, 65246, 65247, 65248), 1605=>array(65249, 65250, 65251, 65252), 1606=>array(65253, 65254, 65255, 65256), 1607=>array(65257, 65258, 65259, 65260), 1608=>array(65261, 65262, 65261, 65262), 1609=>array(65263, 65264, 64488, 64489), 1610=>array(65265, 65266, 65267, 65268), 1649=>array(64336, 64337), 1655=>array(64477), 1657=>array(64358, 64359, 64360, 64361), 1658=>array(64350, 64351, 64352, 64353), 1659=>array(64338, 64339, 64340, 64341), 1662=>array(64342, 64343, 64344, 64345), 1663=>array(64354, 64355, 64356, 64357), 1664=>array(64346, 64347, 64348, 64349), 1667=>array(64374, 64375, 64376, 64377), 1668=>array(64370, 64371, 64372, 64373), 1670=>array(64378, 64379, 64380, 64381), 1671=>array(64382, 64383, 64384, 64385), 1672=>array(64392, 64393), 1676=>array(64388, 64389), 1677=>array(64386, 64387), 1678=>array(64390, 64391), 1681=>array(64396, 64397), 1688=>array(64394, 64395, 64394, 64395), 1700=>array(64362, 64363, 64364, 64365), 1702=>array(64366, 64367, 64368, 64369), 1705=>array(64398, 64399, 64400, 64401), 1709=>array(64467, 64468, 64469, 64470), 1711=>array(64402, 64403, 64404, 64405), 1713=>array(64410, 64411, 64412, 64413), 1715=>array(64406, 64407, 64408, 64409), 1722=>array(64414, 64415), 1723=>array(64416, 64417, 64418, 64419), 1726=>array(64426, 64427, 64428, 64429), 1728=>array(64420, 64421), 1729=>array(64422, 64423, 64424, 64425), 1733=>array(64480, 64481), 1734=>array(64473, 64474), 1735=>array(64471, 64472), 1736=>array(64475, 64476), 1737=>array(64482, 64483), 1739=>array(64478, 64479), 1740=>array(64508, 64509, 64510, 64511), 1744=>array(64484, 64485, 64486, 64487), 1746=>array(64430, 64431), 1747=>array(64432, 64433) ); /** * Arabic laa letter: (char code => isolated, final, initial, medial). * @public */ public static $uni_laa_array = array ( 1570 =>array(65269, 65270, 65269, 65270), 1571 =>array(65271, 65272, 65271, 65272), 1573 =>array(65273, 65274, 65273, 65274), 1575 =>array(65275, 65276, 65275, 65276) ); /** * Array of character substitutions for sequences of two diacritics symbols. * Putting the combining mark and character in the same glyph allows us to avoid the two marks overlapping each other in an illegible manner. * second NSM char code => substitution char * @public */ public static $uni_diacritics = array ( 1612=>64606, # Shadda + Dammatan 1613=>64607, # Shadda + Kasratan 1614=>64608, # Shadda + Fatha 1615=>64609, # Shadda + Damma 1616=>64610 # Shadda + Kasra ); /** * Array of character substitutions from UTF-8 Unicode to Latin1. * @public */ public static $uni_utf8tolatin = array ( 8364=>128, # Euro1 338=>140, # OE 352=>138, # Scaron 376=>159, # Ydieresis 381=>142, # Zcaron2 8226=>149, # bullet3 710=>136, # circumflex 8224=>134, # dagger 8225=>135, # daggerdbl 8230=>133, # ellipsis 8212=>151, # emdash 8211=>150, # endash 402=>131, # florin 8249=>139, # guilsinglleft 8250=>155, # guilsinglright 339=>156, # oe 8240=>137, # perthousand 8222=>132, # quotedblbase 8220=>147, # quotedblleft 8221=>148, # quotedblright 8216=>145, # quoteleft 8217=>146, # quoteright 8218=>130, # quotesinglbase 353=>154, # scaron 732=>152, # tilde 8482=>153, # trademark 382=>158 # zcaron2 ); /** * Array of Encoding Maps. * @public static */ public static $encmap = array( // encoding map for: cp874 'cp874' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'ellipsis',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'kokaithai',162=>'khokhaithai',163=>'khokhuatthai',164=>'khokhwaithai',165=>'khokhonthai',166=>'khorakhangthai',167=>'ngonguthai',168=>'chochanthai',169=>'chochingthai',170=>'chochangthai',171=>'sosothai',172=>'chochoethai',173=>'yoyingthai',174=>'dochadathai',175=>'topatakthai',176=>'thothanthai',177=>'thonangmonthothai',178=>'thophuthaothai',179=>'nonenthai',180=>'dodekthai',181=>'totaothai',182=>'thothungthai',183=>'thothahanthai',184=>'thothongthai',185=>'nonuthai',186=>'bobaimaithai',187=>'poplathai',188=>'phophungthai',189=>'fofathai',190=>'phophanthai',191=>'fofanthai',192=>'phosamphaothai',193=>'momathai',194=>'yoyakthai',195=>'roruathai',196=>'ruthai',197=>'lolingthai',198=>'luthai',199=>'wowaenthai',200=>'sosalathai',201=>'sorusithai',202=>'sosuathai',203=>'hohipthai',204=>'lochulathai',205=>'oangthai',206=>'honokhukthai',207=>'paiyannoithai',208=>'saraathai',209=>'maihanakatthai',210=>'saraaathai',211=>'saraamthai',212=>'saraithai',213=>'saraiithai',214=>'sarauethai',215=>'saraueethai',216=>'sarauthai',217=>'sarauuthai',218=>'phinthuthai',219=>'.notdef',220=>'.notdef',221=>'.notdef',222=>'.notdef',223=>'bahtthai',224=>'saraethai',225=>'saraaethai',226=>'saraothai',227=>'saraaimaimuanthai',228=>'saraaimaimalaithai',229=>'lakkhangyaothai',230=>'maiyamokthai',231=>'maitaikhuthai',232=>'maiekthai',233=>'maithothai',234=>'maitrithai',235=>'maichattawathai',236=>'thanthakhatthai',237=>'nikhahitthai',238=>'yamakkanthai',239=>'fongmanthai',240=>'zerothai',241=>'onethai',242=>'twothai',243=>'threethai',244=>'fourthai',245=>'fivethai',246=>'sixthai',247=>'seventhai',248=>'eightthai',249=>'ninethai',250=>'angkhankhuthai',251=>'khomutthai',252=>'.notdef',253=>'.notdef',254=>'.notdef',255=>'.notdef'), // encoding map for: cp1250 'cp1250' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'.notdef',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'.notdef',137=>'perthousand',138=>'Scaron',139=>'guilsinglleft',140=>'Sacute',141=>'Tcaron',142=>'Zcaron',143=>'Zacute',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'.notdef',153=>'trademark',154=>'scaron',155=>'guilsinglright',156=>'sacute',157=>'tcaron',158=>'zcaron',159=>'zacute',160=>'space',161=>'caron',162=>'breve',163=>'Lslash',164=>'currency',165=>'Aogonek',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'Scedilla',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'Zdotaccent',176=>'degree',177=>'plusminus',178=>'ogonek',179=>'lslash',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'aogonek',186=>'scedilla',187=>'guillemotright',188=>'Lcaron',189=>'hungarumlaut',190=>'lcaron',191=>'zdotaccent',192=>'Racute',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Lacute',198=>'Cacute',199=>'Ccedilla',200=>'Ccaron',201=>'Eacute',202=>'Eogonek',203=>'Edieresis',204=>'Ecaron',205=>'Iacute',206=>'Icircumflex',207=>'Dcaron',208=>'Dcroat',209=>'Nacute',210=>'Ncaron',211=>'Oacute',212=>'Ocircumflex',213=>'Ohungarumlaut',214=>'Odieresis',215=>'multiply',216=>'Rcaron',217=>'Uring',218=>'Uacute',219=>'Uhungarumlaut',220=>'Udieresis',221=>'Yacute',222=>'Tcommaaccent',223=>'germandbls',224=>'racute',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'lacute',230=>'cacute',231=>'ccedilla',232=>'ccaron',233=>'eacute',234=>'eogonek',235=>'edieresis',236=>'ecaron',237=>'iacute',238=>'icircumflex',239=>'dcaron',240=>'dcroat',241=>'nacute',242=>'ncaron',243=>'oacute',244=>'ocircumflex',245=>'ohungarumlaut',246=>'odieresis',247=>'divide',248=>'rcaron',249=>'uring',250=>'uacute',251=>'uhungarumlaut',252=>'udieresis',253=>'yacute',254=>'tcommaaccent',255=>'dotaccent'), // encoding map for: cp1251 'cp1251' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'afii10051',129=>'afii10052',130=>'quotesinglbase',131=>'afii10100',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'Euro',137=>'perthousand',138=>'afii10058',139=>'guilsinglleft',140=>'afii10059',141=>'afii10061',142=>'afii10060',143=>'afii10145',144=>'afii10099',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'.notdef',153=>'trademark',154=>'afii10106',155=>'guilsinglright',156=>'afii10107',157=>'afii10109',158=>'afii10108',159=>'afii10193',160=>'space',161=>'afii10062',162=>'afii10110',163=>'afii10057',164=>'currency',165=>'afii10050',166=>'brokenbar',167=>'section',168=>'afii10023',169=>'copyright',170=>'afii10053',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'afii10056',176=>'degree',177=>'plusminus',178=>'afii10055',179=>'afii10103',180=>'afii10098',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'afii10071',185=>'afii61352',186=>'afii10101',187=>'guillemotright',188=>'afii10105',189=>'afii10054',190=>'afii10102',191=>'afii10104',192=>'afii10017',193=>'afii10018',194=>'afii10019',195=>'afii10020',196=>'afii10021',197=>'afii10022',198=>'afii10024',199=>'afii10025',200=>'afii10026',201=>'afii10027',202=>'afii10028',203=>'afii10029',204=>'afii10030',205=>'afii10031',206=>'afii10032',207=>'afii10033',208=>'afii10034',209=>'afii10035',210=>'afii10036',211=>'afii10037',212=>'afii10038',213=>'afii10039',214=>'afii10040',215=>'afii10041',216=>'afii10042',217=>'afii10043',218=>'afii10044',219=>'afii10045',220=>'afii10046',221=>'afii10047',222=>'afii10048',223=>'afii10049',224=>'afii10065',225=>'afii10066',226=>'afii10067',227=>'afii10068',228=>'afii10069',229=>'afii10070',230=>'afii10072',231=>'afii10073',232=>'afii10074',233=>'afii10075',234=>'afii10076',235=>'afii10077',236=>'afii10078',237=>'afii10079',238=>'afii10080',239=>'afii10081',240=>'afii10082',241=>'afii10083',242=>'afii10084',243=>'afii10085',244=>'afii10086',245=>'afii10087',246=>'afii10088',247=>'afii10089',248=>'afii10090',249=>'afii10091',250=>'afii10092',251=>'afii10093',252=>'afii10094',253=>'afii10095',254=>'afii10096',255=>'afii10097'), // encoding map for: cp1252 'cp1252' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'circumflex',137=>'perthousand',138=>'Scaron',139=>'guilsinglleft',140=>'OE',141=>'.notdef',142=>'Zcaron',143=>'.notdef',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'tilde',153=>'trademark',154=>'scaron',155=>'guilsinglright',156=>'oe',157=>'.notdef',158=>'zcaron',159=>'Ydieresis',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Eth',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Yacute',222=>'Thorn',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'eth',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'yacute',254=>'thorn',255=>'ydieresis'), // encoding map for: cp1253 'cp1253' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'.notdef',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'.notdef',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'dieresistonos',162=>'Alphatonos',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'.notdef',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'afii00208',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'tonos',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'Epsilontonos',185=>'Etatonos',186=>'Iotatonos',187=>'guillemotright',188=>'Omicrontonos',189=>'onehalf',190=>'Upsilontonos',191=>'Omegatonos',192=>'iotadieresistonos',193=>'Alpha',194=>'Beta',195=>'Gamma',196=>'Delta',197=>'Epsilon',198=>'Zeta',199=>'Eta',200=>'Theta',201=>'Iota',202=>'Kappa',203=>'Lambda',204=>'Mu',205=>'Nu',206=>'Xi',207=>'Omicron',208=>'Pi',209=>'Rho',210=>'.notdef',211=>'Sigma',212=>'Tau',213=>'Upsilon',214=>'Phi',215=>'Chi',216=>'Psi',217=>'Omega',218=>'Iotadieresis',219=>'Upsilondieresis',220=>'alphatonos',221=>'epsilontonos',222=>'etatonos',223=>'iotatonos',224=>'upsilondieresistonos',225=>'alpha',226=>'beta',227=>'gamma',228=>'delta',229=>'epsilon',230=>'zeta',231=>'eta',232=>'theta',233=>'iota',234=>'kappa',235=>'lambda',236=>'mu',237=>'nu',238=>'xi',239=>'omicron',240=>'pi',241=>'rho',242=>'sigma1',243=>'sigma',244=>'tau',245=>'upsilon',246=>'phi',247=>'chi',248=>'psi',249=>'omega',250=>'iotadieresis',251=>'upsilondieresis',252=>'omicrontonos',253=>'upsilontonos',254=>'omegatonos',255=>'.notdef'), // encoding map for: cp1254 'cp1254' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'circumflex',137=>'perthousand',138=>'Scaron',139=>'guilsinglleft',140=>'OE',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'tilde',153=>'trademark',154=>'scaron',155=>'guilsinglright',156=>'oe',157=>'.notdef',158=>'.notdef',159=>'Ydieresis',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Gbreve',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Idotaccent',222=>'Scedilla',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'gbreve',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'dotlessi',254=>'scedilla',255=>'ydieresis'), // encoding map for: cp1255 'cp1255' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'circumflex',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'tilde',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'afii57636',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'multiply',171=>'guillemotleft',172=>'logicalnot',173=>'sfthyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'middot',184=>'cedilla',185=>'onesuperior',186=>'divide',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',192=>'afii57799',193=>'afii57801',194=>'afii57800',195=>'afii57802',196=>'afii57793',197=>'afii57794',198=>'afii57795',199=>'afii57798',200=>'afii57797',201=>'afii57806',202=>'.notdef',203=>'afii57796',204=>'afii57807',205=>'afii57839',206=>'afii57645',207=>'afii57841',208=>'afii57842',209=>'afii57804',210=>'afii57803',211=>'afii57658',212=>'afii57716',213=>'afii57717',214=>'afii57718',215=>'gereshhebrew',216=>'gershayimhebrew',217=>'.notdef',218=>'.notdef',219=>'.notdef',220=>'.notdef',221=>'.notdef',222=>'.notdef',223=>'.notdef',224=>'afii57664',225=>'afii57665',226=>'afii57666',227=>'afii57667',228=>'afii57668',229=>'afii57669',230=>'afii57670',231=>'afii57671',232=>'afii57672',233=>'afii57673',234=>'afii57674',235=>'afii57675',236=>'afii57676',237=>'afii57677',238=>'afii57678',239=>'afii57679',240=>'afii57680',241=>'afii57681',242=>'afii57682',243=>'afii57683',244=>'afii57684',245=>'afii57685',246=>'afii57686',247=>'afii57687',248=>'afii57688',249=>'afii57689',250=>'afii57690',251=>'.notdef',252=>'.notdef',253=>'afii299',254=>'afii300',255=>'.notdef'), // encoding map for: cp1256 'cp1256' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'afii57506',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'circumflex',137=>'perthousand',138=>'afii57511',139=>'guilsinglleft',140=>'OE',141=>'afii57507',142=>'afii57508',143=>'afii57512',144=>'afii57509',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'.notdef',153=>'trademark',154=>'afii57513',155=>'guilsinglright',156=>'oe',157=>'afii61664',158=>'afii301',159=>'afii57514',160=>'space',161=>'afii57388',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'.notdef',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'onesuperior',186=>'afii57403',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'afii57407',192=>'.notdef',193=>'afii57409',194=>'afii57410',195=>'afii57411',196=>'afii57412',197=>'afii57413',198=>'afii57414',199=>'afii57415',200=>'afii57416',201=>'afii57417',202=>'afii57418',203=>'afii57419',204=>'afii57420',205=>'afii57421',206=>'afii57422',207=>'afii57423',208=>'afii57424',209=>'afii57425',210=>'afii57426',211=>'afii57427',212=>'afii57428',213=>'afii57429',214=>'afii57430',215=>'multiply',216=>'afii57431',217=>'afii57432',218=>'afii57433',219=>'afii57434',220=>'afii57440',221=>'afii57441',222=>'afii57442',223=>'afii57443',224=>'agrave',225=>'afii57444',226=>'acircumflex',227=>'afii57445',228=>'afii57446',229=>'afii57470',230=>'afii57448',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'afii57449',237=>'afii57450',238=>'icircumflex',239=>'idieresis',240=>'afii57451',241=>'afii57452',242=>'afii57453',243=>'afii57454',244=>'ocircumflex',245=>'afii57455',246=>'afii57456',247=>'divide',248=>'afii57457',249=>'ugrave',250=>'afii57458',251=>'ucircumflex',252=>'udieresis',253=>'afii299',254=>'afii300',255=>'afii57519'), // encoding map for: cp1257 'cp1257' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'.notdef',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'.notdef',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'.notdef',141=>'dieresis',142=>'caron',143=>'cedilla',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'.notdef',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'.notdef',157=>'macron',158=>'ogonek',159=>'.notdef',160=>'space',161=>'.notdef',162=>'cent',163=>'sterling',164=>'currency',165=>'.notdef',166=>'brokenbar',167=>'section',168=>'Oslash',169=>'copyright',170=>'Rcommaaccent',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'AE',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'oslash',185=>'onesuperior',186=>'rcommaaccent',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'ae',192=>'Aogonek',193=>'Iogonek',194=>'Amacron',195=>'Cacute',196=>'Adieresis',197=>'Aring',198=>'Eogonek',199=>'Emacron',200=>'Ccaron',201=>'Eacute',202=>'Zacute',203=>'Edotaccent',204=>'Gcommaaccent',205=>'Kcommaaccent',206=>'Imacron',207=>'Lcommaaccent',208=>'Scaron',209=>'Nacute',210=>'Ncommaaccent',211=>'Oacute',212=>'Omacron',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Uogonek',217=>'Lslash',218=>'Sacute',219=>'Umacron',220=>'Udieresis',221=>'Zdotaccent',222=>'Zcaron',223=>'germandbls',224=>'aogonek',225=>'iogonek',226=>'amacron',227=>'cacute',228=>'adieresis',229=>'aring',230=>'eogonek',231=>'emacron',232=>'ccaron',233=>'eacute',234=>'zacute',235=>'edotaccent',236=>'gcommaaccent',237=>'kcommaaccent',238=>'imacron',239=>'lcommaaccent',240=>'scaron',241=>'nacute',242=>'ncommaaccent',243=>'oacute',244=>'omacron',245=>'otilde',246=>'odieresis',247=>'divide',248=>'uogonek',249=>'lslash',250=>'sacute',251=>'umacron',252=>'udieresis',253=>'zdotaccent',254=>'zcaron',255=>'dotaccent'), // encoding map for: cp1258 'cp1258' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'Euro',129=>'.notdef',130=>'quotesinglbase',131=>'florin',132=>'quotedblbase',133=>'ellipsis',134=>'dagger',135=>'daggerdbl',136=>'circumflex',137=>'perthousand',138=>'.notdef',139=>'guilsinglleft',140=>'OE',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'quoteleft',146=>'quoteright',147=>'quotedblleft',148=>'quotedblright',149=>'bullet',150=>'endash',151=>'emdash',152=>'tilde',153=>'trademark',154=>'.notdef',155=>'guilsinglright',156=>'oe',157=>'.notdef',158=>'.notdef',159=>'Ydieresis',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'gravecomb',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Dcroat',209=>'Ntilde',210=>'hookabovecomb',211=>'Oacute',212=>'Ocircumflex',213=>'Ohorn',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Uhorn',222=>'tildecomb',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'acutecomb',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'dcroat',241=>'ntilde',242=>'dotbelowcomb',243=>'oacute',244=>'ocircumflex',245=>'ohorn',246=>'odieresis',247=>'divide',248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'uhorn',254=>'dong',255=>'ydieresis'), // encoding map for: iso-8859-1 'iso-8859-1' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Eth',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Yacute',222=>'Thorn',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'eth',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'yacute',254=>'thorn',255=>'ydieresis'), // encoding map for: iso-8859-2 'iso-8859-2' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'Aogonek',162=>'breve',163=>'Lslash',164=>'currency',165=>'Lcaron',166=>'Sacute',167=>'section',168=>'dieresis',169=>'Scaron',170=>'Scedilla',171=>'Tcaron',172=>'Zacute',173=>'hyphen',174=>'Zcaron',175=>'Zdotaccent',176=>'degree',177=>'aogonek',178=>'ogonek',179=>'lslash',180=>'acute',181=>'lcaron',182=>'sacute',183=>'caron',184=>'cedilla',185=>'scaron',186=>'scedilla',187=>'tcaron',188=>'zacute',189=>'hungarumlaut',190=>'zcaron',191=>'zdotaccent',192=>'Racute',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Lacute',198=>'Cacute',199=>'Ccedilla',200=>'Ccaron',201=>'Eacute',202=>'Eogonek',203=>'Edieresis',204=>'Ecaron',205=>'Iacute',206=>'Icircumflex',207=>'Dcaron',208=>'Dcroat',209=>'Nacute',210=>'Ncaron',211=>'Oacute',212=>'Ocircumflex',213=>'Ohungarumlaut',214=>'Odieresis',215=>'multiply',216=>'Rcaron',217=>'Uring',218=>'Uacute',219=>'Uhungarumlaut',220=>'Udieresis',221=>'Yacute',222=>'Tcommaaccent',223=>'germandbls',224=>'racute',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'lacute',230=>'cacute',231=>'ccedilla',232=>'ccaron',233=>'eacute',234=>'eogonek',235=>'edieresis',236=>'ecaron',237=>'iacute',238=>'icircumflex',239=>'dcaron',240=>'dcroat',241=>'nacute',242=>'ncaron',243=>'oacute',244=>'ocircumflex',245=>'ohungarumlaut',246=>'odieresis',247=>'divide',248=>'rcaron',249=>'uring',250=>'uacute',251=>'uhungarumlaut',252=>'udieresis',253=>'yacute',254=>'tcommaaccent',255=>'dotaccent'), // encoding map for: iso-8859-4 'iso-8859-4' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'Aogonek',162=>'kgreenlandic',163=>'Rcommaaccent',164=>'currency',165=>'Itilde',166=>'Lcommaaccent',167=>'section',168=>'dieresis',169=>'Scaron',170=>'Emacron',171=>'Gcommaaccent',172=>'Tbar',173=>'hyphen',174=>'Zcaron',175=>'macron',176=>'degree',177=>'aogonek',178=>'ogonek',179=>'rcommaaccent',180=>'acute',181=>'itilde',182=>'lcommaaccent',183=>'caron',184=>'cedilla',185=>'scaron',186=>'emacron',187=>'gcommaaccent',188=>'tbar',189=>'Eng',190=>'zcaron',191=>'eng',192=>'Amacron',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Iogonek',200=>'Ccaron',201=>'Eacute',202=>'Eogonek',203=>'Edieresis',204=>'Edotaccent',205=>'Iacute',206=>'Icircumflex',207=>'Imacron',208=>'Dcroat',209=>'Ncommaaccent',210=>'Omacron',211=>'Kcommaaccent',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Uogonek',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Utilde',222=>'Umacron',223=>'germandbls',224=>'amacron',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'iogonek',232=>'ccaron',233=>'eacute',234=>'eogonek',235=>'edieresis',236=>'edotaccent',237=>'iacute',238=>'icircumflex',239=>'imacron',240=>'dcroat',241=>'ncommaaccent',242=>'omacron',243=>'kcommaaccent',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',248=>'oslash',249=>'uogonek',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'utilde',254=>'umacron',255=>'dotaccent'), // encoding map for: iso-8859-5 'iso-8859-5' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'afii10023',162=>'afii10051',163=>'afii10052',164=>'afii10053',165=>'afii10054',166=>'afii10055',167=>'afii10056',168=>'afii10057',169=>'afii10058',170=>'afii10059',171=>'afii10060',172=>'afii10061',173=>'hyphen',174=>'afii10062',175=>'afii10145',176=>'afii10017',177=>'afii10018',178=>'afii10019',179=>'afii10020',180=>'afii10021',181=>'afii10022',182=>'afii10024',183=>'afii10025',184=>'afii10026',185=>'afii10027',186=>'afii10028',187=>'afii10029',188=>'afii10030',189=>'afii10031',190=>'afii10032',191=>'afii10033',192=>'afii10034',193=>'afii10035',194=>'afii10036',195=>'afii10037',196=>'afii10038',197=>'afii10039',198=>'afii10040',199=>'afii10041',200=>'afii10042',201=>'afii10043',202=>'afii10044',203=>'afii10045',204=>'afii10046',205=>'afii10047',206=>'afii10048',207=>'afii10049',208=>'afii10065',209=>'afii10066',210=>'afii10067',211=>'afii10068',212=>'afii10069',213=>'afii10070',214=>'afii10072',215=>'afii10073',216=>'afii10074',217=>'afii10075',218=>'afii10076',219=>'afii10077',220=>'afii10078',221=>'afii10079',222=>'afii10080',223=>'afii10081',224=>'afii10082',225=>'afii10083',226=>'afii10084',227=>'afii10085',228=>'afii10086',229=>'afii10087',230=>'afii10088',231=>'afii10089',232=>'afii10090',233=>'afii10091',234=>'afii10092',235=>'afii10093',236=>'afii10094',237=>'afii10095',238=>'afii10096',239=>'afii10097',240=>'afii61352',241=>'afii10071',242=>'afii10099',243=>'afii10100',244=>'afii10101',245=>'afii10102',246=>'afii10103',247=>'afii10104',248=>'afii10105',249=>'afii10106',250=>'afii10107',251=>'afii10108',252=>'afii10109',253=>'section',254=>'afii10110',255=>'afii10193'), // encoding map for: iso-8859-7 'iso-8859-7' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'quoteleft',162=>'quoteright',163=>'sterling',164=>'.notdef',165=>'.notdef',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'.notdef',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'.notdef',175=>'afii00208',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'tonos',181=>'dieresistonos',182=>'Alphatonos',183=>'periodcentered',184=>'Epsilontonos',185=>'Etatonos',186=>'Iotatonos',187=>'guillemotright',188=>'Omicrontonos',189=>'onehalf',190=>'Upsilontonos',191=>'Omegatonos',192=>'iotadieresistonos',193=>'Alpha',194=>'Beta',195=>'Gamma',196=>'Delta',197=>'Epsilon',198=>'Zeta',199=>'Eta',200=>'Theta',201=>'Iota',202=>'Kappa',203=>'Lambda',204=>'Mu',205=>'Nu',206=>'Xi',207=>'Omicron',208=>'Pi',209=>'Rho',210=>'.notdef',211=>'Sigma',212=>'Tau',213=>'Upsilon',214=>'Phi',215=>'Chi',216=>'Psi',217=>'Omega',218=>'Iotadieresis',219=>'Upsilondieresis',220=>'alphatonos',221=>'epsilontonos',222=>'etatonos',223=>'iotatonos',224=>'upsilondieresistonos',225=>'alpha',226=>'beta',227=>'gamma',228=>'delta',229=>'epsilon',230=>'zeta',231=>'eta',232=>'theta',233=>'iota',234=>'kappa',235=>'lambda',236=>'mu',237=>'nu',238=>'xi',239=>'omicron',240=>'pi',241=>'rho',242=>'sigma1',243=>'sigma',244=>'tau',245=>'upsilon',246=>'phi',247=>'chi',248=>'psi',249=>'omega',250=>'iotadieresis',251=>'upsilondieresis',252=>'omicrontonos',253=>'upsilontonos',254=>'omegatonos',255=>'.notdef'), // encoding map for: iso-8859-9 'iso-8859-9' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'currency',165=>'yen',166=>'brokenbar',167=>'section',168=>'dieresis',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'acute',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'cedilla',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'onequarter',189=>'onehalf',190=>'threequarters',191=>'questiondown',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Gbreve',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Idotaccent',222=>'Scedilla',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'gbreve',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'dotlessi',254=>'scedilla',255=>'ydieresis'), // encoding map for: iso-8859-11 'iso-8859-11' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'kokaithai',162=>'khokhaithai',163=>'khokhuatthai',164=>'khokhwaithai',165=>'khokhonthai',166=>'khorakhangthai',167=>'ngonguthai',168=>'chochanthai',169=>'chochingthai',170=>'chochangthai',171=>'sosothai',172=>'chochoethai',173=>'yoyingthai',174=>'dochadathai',175=>'topatakthai',176=>'thothanthai',177=>'thonangmonthothai',178=>'thophuthaothai',179=>'nonenthai',180=>'dodekthai',181=>'totaothai',182=>'thothungthai',183=>'thothahanthai',184=>'thothongthai',185=>'nonuthai',186=>'bobaimaithai',187=>'poplathai',188=>'phophungthai',189=>'fofathai',190=>'phophanthai',191=>'fofanthai',192=>'phosamphaothai',193=>'momathai',194=>'yoyakthai',195=>'roruathai',196=>'ruthai',197=>'lolingthai',198=>'luthai',199=>'wowaenthai',200=>'sosalathai',201=>'sorusithai',202=>'sosuathai',203=>'hohipthai',204=>'lochulathai',205=>'oangthai',206=>'honokhukthai',207=>'paiyannoithai',208=>'saraathai',209=>'maihanakatthai',210=>'saraaathai',211=>'saraamthai',212=>'saraithai',213=>'saraiithai',214=>'sarauethai',215=>'saraueethai',216=>'sarauthai',217=>'sarauuthai',218=>'phinthuthai',219=>'.notdef',220=>'.notdef',221=>'.notdef',222=>'.notdef',223=>'bahtthai',224=>'saraethai',225=>'saraaethai',226=>'saraothai',227=>'saraaimaimuanthai',228=>'saraaimaimalaithai',229=>'lakkhangyaothai',230=>'maiyamokthai',231=>'maitaikhuthai',232=>'maiekthai',233=>'maithothai',234=>'maitrithai',235=>'maichattawathai',236=>'thanthakhatthai',237=>'nikhahitthai',238=>'yamakkanthai',239=>'fongmanthai',240=>'zerothai',241=>'onethai',242=>'twothai',243=>'threethai',244=>'fourthai',245=>'fivethai',246=>'sixthai',247=>'seventhai',248=>'eightthai',249=>'ninethai',250=>'angkhankhuthai',251=>'khomutthai',252=>'.notdef',253=>'.notdef',254=>'.notdef',255=>'.notdef'), // encoding map for: iso-8859-15 'iso-8859-15' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'exclamdown',162=>'cent',163=>'sterling',164=>'Euro',165=>'yen',166=>'Scaron',167=>'section',168=>'scaron',169=>'copyright',170=>'ordfeminine',171=>'guillemotleft',172=>'logicalnot',173=>'hyphen',174=>'registered',175=>'macron',176=>'degree',177=>'plusminus',178=>'twosuperior',179=>'threesuperior',180=>'Zcaron',181=>'mu',182=>'paragraph',183=>'periodcentered',184=>'zcaron',185=>'onesuperior',186=>'ordmasculine',187=>'guillemotright',188=>'OE',189=>'oe',190=>'Ydieresis',191=>'questiondown',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Atilde',196=>'Adieresis',197=>'Aring',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Eth',209=>'Ntilde',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Otilde',214=>'Odieresis',215=>'multiply',216=>'Oslash',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Yacute',222=>'Thorn',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'atilde',228=>'adieresis',229=>'aring',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'eth',241=>'ntilde',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'otilde',246=>'odieresis',247=>'divide',248=>'oslash',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'yacute',254=>'thorn',255=>'ydieresis'), // encoding map for: iso-8859-16 'iso-8859-16' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'space',161=>'Aogonek',162=>'aogonek',163=>'Lslash',164=>'Euro',165=>'quotedblbase',166=>'Scaron',167=>'section',168=>'scaron',169=>'copyright',170=>'Scommaaccent',171=>'guillemotleft',172=>'Zacute',173=>'hyphen',174=>'zacute',175=>'Zdotaccent',176=>'degree',177=>'plusminus',178=>'Ccaron',179=>'lslash',180=>'Zcaron',181=>'quotedblright',182=>'paragraph',183=>'periodcentered',184=>'zcaron',185=>'ccaron',186=>'scommaaccent',187=>'guillemotright',188=>'OE',189=>'oe',190=>'Ydieresis',191=>'zdotaccent',192=>'Agrave',193=>'Aacute',194=>'Acircumflex',195=>'Abreve',196=>'Adieresis',197=>'Cacute',198=>'AE',199=>'Ccedilla',200=>'Egrave',201=>'Eacute',202=>'Ecircumflex',203=>'Edieresis',204=>'Igrave',205=>'Iacute',206=>'Icircumflex',207=>'Idieresis',208=>'Dcroat',209=>'Nacute',210=>'Ograve',211=>'Oacute',212=>'Ocircumflex',213=>'Ohungarumlaut',214=>'Odieresis',215=>'Sacute',216=>'Uhungarumlaut',217=>'Ugrave',218=>'Uacute',219=>'Ucircumflex',220=>'Udieresis',221=>'Eogonek',222=>'Tcommaaccent',223=>'germandbls',224=>'agrave',225=>'aacute',226=>'acircumflex',227=>'abreve',228=>'adieresis',229=>'cacute',230=>'ae',231=>'ccedilla',232=>'egrave',233=>'eacute',234=>'ecircumflex',235=>'edieresis',236=>'igrave',237=>'iacute',238=>'icircumflex',239=>'idieresis',240=>'dcroat',241=>'nacute',242=>'ograve',243=>'oacute',244=>'ocircumflex',245=>'ohungarumlaut',246=>'odieresis',247=>'sacute',248=>'uhungarumlaut',249=>'ugrave',250=>'uacute',251=>'ucircumflex',252=>'udieresis',253=>'eogonek',254=>'tcommaaccent',255=>'ydieresis'), // encoding map for: koi8-r 'koi8-r' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'SF100000',129=>'SF110000',130=>'SF010000',131=>'SF030000',132=>'SF020000',133=>'SF040000',134=>'SF080000',135=>'SF090000',136=>'SF060000',137=>'SF070000',138=>'SF050000',139=>'upblock',140=>'dnblock',141=>'block',142=>'lfblock',143=>'rtblock',144=>'ltshade',145=>'shade',146=>'dkshade',147=>'integraltp',148=>'filledbox',149=>'periodcentered',150=>'radical',151=>'approxequal',152=>'lessequal',153=>'greaterequal',154=>'space',155=>'integralbt',156=>'degree',157=>'twosuperior',158=>'periodcentered',159=>'divide',160=>'SF430000',161=>'SF240000',162=>'SF510000',163=>'afii10071',164=>'SF520000',165=>'SF390000',166=>'SF220000',167=>'SF210000',168=>'SF250000',169=>'SF500000',170=>'SF490000',171=>'SF380000',172=>'SF280000',173=>'SF270000',174=>'SF260000',175=>'SF360000',176=>'SF370000',177=>'SF420000',178=>'SF190000',179=>'afii10023',180=>'SF200000',181=>'SF230000',182=>'SF470000',183=>'SF480000',184=>'SF410000',185=>'SF450000',186=>'SF460000',187=>'SF400000',188=>'SF540000',189=>'SF530000',190=>'SF440000',191=>'copyright',192=>'afii10096',193=>'afii10065',194=>'afii10066',195=>'afii10088',196=>'afii10069',197=>'afii10070',198=>'afii10086',199=>'afii10068',200=>'afii10087',201=>'afii10074',202=>'afii10075',203=>'afii10076',204=>'afii10077',205=>'afii10078',206=>'afii10079',207=>'afii10080',208=>'afii10081',209=>'afii10097',210=>'afii10082',211=>'afii10083',212=>'afii10084',213=>'afii10085',214=>'afii10072',215=>'afii10067',216=>'afii10094',217=>'afii10093',218=>'afii10073',219=>'afii10090',220=>'afii10095',221=>'afii10091',222=>'afii10089',223=>'afii10092',224=>'afii10048',225=>'afii10017',226=>'afii10018',227=>'afii10040',228=>'afii10021',229=>'afii10022',230=>'afii10038',231=>'afii10020',232=>'afii10039',233=>'afii10026',234=>'afii10027',235=>'afii10028',236=>'afii10029',237=>'afii10030',238=>'afii10031',239=>'afii10032',240=>'afii10033',241=>'afii10049',242=>'afii10034',243=>'afii10035',244=>'afii10036',245=>'afii10037',246=>'afii10024',247=>'afii10019',248=>'afii10046',249=>'afii10045',250=>'afii10025',251=>'afii10042',252=>'afii10047',253=>'afii10043',254=>'afii10041',255=>'afii10044'), // encoding map for: koi8-u 'koi8-u' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'quotedbl',35=>'numbersign',36=>'dollar',37=>'percent',38=>'ampersand',39=>'quotesingle',40=>'parenleft',41=>'parenright',42=>'asterisk',43=>'plus',44=>'comma',45=>'hyphen',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'at',65=>'A',66=>'B',67=>'C',68=>'D',69=>'E',70=>'F',71=>'G',72=>'H',73=>'I',74=>'J',75=>'K',76=>'L',77=>'M',78=>'N',79=>'O',80=>'P',81=>'Q',82=>'R',83=>'S',84=>'T',85=>'U',86=>'V',87=>'W',88=>'X',89=>'Y',90=>'Z',91=>'bracketleft',92=>'backslash',93=>'bracketright',94=>'asciicircum',95=>'underscore',96=>'grave',97=>'a',98=>'b',99=>'c',100=>'d',101=>'e',102=>'f',103=>'g',104=>'h',105=>'i',106=>'j',107=>'k',108=>'l',109=>'m',110=>'n',111=>'o',112=>'p',113=>'q',114=>'r',115=>'s',116=>'t',117=>'u',118=>'v',119=>'w',120=>'x',121=>'y',122=>'z',123=>'braceleft',124=>'bar',125=>'braceright',126=>'asciitilde',127=>'.notdef',128=>'SF100000',129=>'SF110000',130=>'SF010000',131=>'SF030000',132=>'SF020000',133=>'SF040000',134=>'SF080000',135=>'SF090000',136=>'SF060000',137=>'SF070000',138=>'SF050000',139=>'upblock',140=>'dnblock',141=>'block',142=>'lfblock',143=>'rtblock',144=>'ltshade',145=>'shade',146=>'dkshade',147=>'integraltp',148=>'filledbox',149=>'bullet',150=>'radical',151=>'approxequal',152=>'lessequal',153=>'greaterequal',154=>'space',155=>'integralbt',156=>'degree',157=>'twosuperior',158=>'periodcentered',159=>'divide',160=>'SF430000',161=>'SF240000',162=>'SF510000',163=>'afii10071',164=>'afii10101',165=>'SF390000',166=>'afii10103',167=>'afii10104',168=>'SF250000',169=>'SF500000',170=>'SF490000',171=>'SF380000',172=>'SF280000',173=>'afii10098',174=>'SF260000',175=>'SF360000',176=>'SF370000',177=>'SF420000',178=>'SF190000',179=>'afii10023',180=>'afii10053',181=>'SF230000',182=>'afii10055',183=>'afii10056',184=>'SF410000',185=>'SF450000',186=>'SF460000',187=>'SF400000',188=>'SF540000',189=>'afii10050',190=>'SF440000',191=>'copyright',192=>'afii10096',193=>'afii10065',194=>'afii10066',195=>'afii10088',196=>'afii10069',197=>'afii10070',198=>'afii10086',199=>'afii10068',200=>'afii10087',201=>'afii10074',202=>'afii10075',203=>'afii10076',204=>'afii10077',205=>'afii10078',206=>'afii10079',207=>'afii10080',208=>'afii10081',209=>'afii10097',210=>'afii10082',211=>'afii10083',212=>'afii10084',213=>'afii10085',214=>'afii10072',215=>'afii10067',216=>'afii10094',217=>'afii10093',218=>'afii10073',219=>'afii10090',220=>'afii10095',221=>'afii10091',222=>'afii10089',223=>'afii10092',224=>'afii10048',225=>'afii10017',226=>'afii10018',227=>'afii10040',228=>'afii10021',229=>'afii10022',230=>'afii10038',231=>'afii10020',232=>'afii10039',233=>'afii10026',234=>'afii10027',235=>'afii10028',236=>'afii10029',237=>'afii10030',238=>'afii10031',239=>'afii10032',240=>'afii10033',241=>'afii10049',242=>'afii10034',243=>'afii10035',244=>'afii10036',245=>'afii10037',246=>'afii10024',247=>'afii10019',248=>'afii10046',249=>'afii10045',250=>'afii10025',251=>'afii10042',252=>'afii10047',253=>'afii10043',254=>'afii10041',255=>'afii10044'), // encoding map for: symbol 'symbol' => array(0=>'.notdef',1=>'.notdef',2=>'.notdef',3=>'.notdef',4=>'.notdef',5=>'.notdef',6=>'.notdef',7=>'.notdef',8=>'.notdef',9=>'.notdef',10=>'.notdef',11=>'.notdef',12=>'.notdef',13=>'.notdef',14=>'.notdef',15=>'.notdef',16=>'.notdef',17=>'.notdef',18=>'.notdef',19=>'.notdef',20=>'.notdef',21=>'.notdef',22=>'.notdef',23=>'.notdef',24=>'.notdef',25=>'.notdef',26=>'.notdef',27=>'.notdef',28=>'.notdef',29=>'.notdef',30=>'.notdef',31=>'.notdef',32=>'space',33=>'exclam',34=>'universal',35=>'numbersign',36=>'existential',37=>'percent',38=>'ampersand',39=>'suchthat',40=>'parenleft',41=>'parenright',42=>'asteriskmath',43=>'plus',44=>'comma',45=>'minus',46=>'period',47=>'slash',48=>'zero',49=>'one',50=>'two',51=>'three',52=>'four',53=>'five',54=>'six',55=>'seven',56=>'eight',57=>'nine',58=>'colon',59=>'semicolon',60=>'less',61=>'equal',62=>'greater',63=>'question',64=>'congruent',65=>'Alpha',66=>'Beta',67=>'Chi',68=>'Delta',69=>'Epsilon',70=>'Phi',71=>'Gamma',72=>'Eta',73=>'Iota',74=>'theta1',75=>'Kappa',76=>'Lambda',77=>'Mu',78=>'Nu',79=>'Omicron',80=>'Pi',81=>'Theta',82=>'Rho',83=>'Sigma',84=>'Tau',85=>'Upsilon',86=>'sigma1',87=>'Omega',88=>'Xi',89=>'Psi',90=>'Zeta',91=>'bracketleft',92=>'therefore',93=>'bracketright',94=>'perpendicular',95=>'underscore',96=>'radicalex',97=>'alpha',98=>'beta',99=>'chi',100=>'delta',101=>'epsilon',102=>'phi',103=>'gamma',104=>'eta',105=>'iota',106=>'phi1',107=>'kappa',108=>'lambda',109=>'mu',110=>'nu',111=>'omicron',112=>'pi',113=>'theta',114=>'rho',115=>'sigma',116=>'tau',117=>'upsilon',118=>'omega1',119=>'omega',120=>'xi',121=>'psi',122=>'zeta',123=>'braceleft',124=>'bar',125=>'braceright',126=>'similar',127=>'.notdef',128=>'.notdef',129=>'.notdef',130=>'.notdef',131=>'.notdef',132=>'.notdef',133=>'.notdef',134=>'.notdef',135=>'.notdef',136=>'.notdef',137=>'.notdef',138=>'.notdef',139=>'.notdef',140=>'.notdef',141=>'.notdef',142=>'.notdef',143=>'.notdef',144=>'.notdef',145=>'.notdef',146=>'.notdef',147=>'.notdef',148=>'.notdef',149=>'.notdef',150=>'.notdef',151=>'.notdef',152=>'.notdef',153=>'.notdef',154=>'.notdef',155=>'.notdef',156=>'.notdef',157=>'.notdef',158=>'.notdef',159=>'.notdef',160=>'Euro',161=>'Upsilon1',162=>'minute',163=>'lessequal',164=>'fraction',165=>'infinity',166=>'florin',167=>'club',168=>'diamond',169=>'heart',170=>'spade',171=>'arrowboth',172=>'arrowleft',173=>'arrowup',174=>'arrowright',175=>'arrowdown',176=>'degree',177=>'plusminus',178=>'second',179=>'greaterequal',180=>'multiply',181=>'proportional',182=>'partialdiff',183=>'bullet',184=>'divide',185=>'notequal',186=>'equivalence',187=>'approxequal',188=>'ellipsis',189=>'arrowvertex',190=>'arrowhorizex',191=>'carriagereturn',192=>'aleph',193=>'Ifraktur',194=>'Rfraktur',195=>'weierstrass',196=>'circlemultiply',197=>'circleplus',198=>'emptyset',199=>'intersection',200=>'union',201=>'propersuperset',202=>'reflexsuperset',203=>'notsubset',204=>'propersubset',205=>'reflexsubset',206=>'element',207=>'notelement',208=>'angle',209=>'gradient',210=>'registerserif',211=>'copyrightserif',212=>'trademarkserif',213=>'product',214=>'radical',215=>'dotmath',216=>'logicalnot',217=>'logicaland',218=>'logicalor',219=>'arrowdblboth',220=>'arrowdblleft',221=>'arrowdblup',222=>'arrowdblright',223=>'arrowdbldown',224=>'lozenge',225=>'angleleft',226=>'registersans',227=>'copyrightsans',228=>'trademarksans',229=>'summation',230=>'parenlefttp',231=>'parenleftex',232=>'parenleftbt',233=>'bracketlefttp',234=>'bracketleftex',235=>'bracketleftbt',236=>'bracelefttp',237=>'braceleftmid',238=>'braceleftbt',239=>'braceex',240=>'.notdef',241=>'angleright',242=>'integral',243=>'integraltp',244=>'integralex',245=>'integralbt',246=>'parenrighttp',247=>'parenrightex',248=>'parenrightbt',249=>'bracketrighttp',250=>'bracketrightex',251=>'bracketrightbt',252=>'bracerighttp',253=>'bracerightmid',254=>'bracerightbt',255=>'.notdef',1226=>'registered',1227=>'copyright',1228=>'trademark') ); // end of encoding maps /** * ToUnicode map for Identity-H stream * @public static */ public static $uni_identity_h = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n/WMode 0 def\n1 begincodespacerange\n<0000> \nendcodespacerange\n100 beginbfrange\n<0000> <00ff> <0000>\n<0100> <01ff> <0100>\n<0200> <02ff> <0200>\n<0300> <03ff> <0300>\n<0400> <04ff> <0400>\n<0500> <05ff> <0500>\n<0600> <06ff> <0600>\n<0700> <07ff> <0700>\n<0800> <08ff> <0800>\n<0900> <09ff> <0900>\n<0a00> <0aff> <0a00>\n<0b00> <0bff> <0b00>\n<0c00> <0cff> <0c00>\n<0d00> <0dff> <0d00>\n<0e00> <0eff> <0e00>\n<0f00> <0fff> <0f00>\n<1000> <10ff> <1000>\n<1100> <11ff> <1100>\n<1200> <12ff> <1200>\n<1300> <13ff> <1300>\n<1400> <14ff> <1400>\n<1500> <15ff> <1500>\n<1600> <16ff> <1600>\n<1700> <17ff> <1700>\n<1800> <18ff> <1800>\n<1900> <19ff> <1900>\n<1a00> <1aff> <1a00>\n<1b00> <1bff> <1b00>\n<1c00> <1cff> <1c00>\n<1d00> <1dff> <1d00>\n<1e00> <1eff> <1e00>\n<1f00> <1fff> <1f00>\n<2000> <20ff> <2000>\n<2100> <21ff> <2100>\n<2200> <22ff> <2200>\n<2300> <23ff> <2300>\n<2400> <24ff> <2400>\n<2500> <25ff> <2500>\n<2600> <26ff> <2600>\n<2700> <27ff> <2700>\n<2800> <28ff> <2800>\n<2900> <29ff> <2900>\n<2a00> <2aff> <2a00>\n<2b00> <2bff> <2b00>\n<2c00> <2cff> <2c00>\n<2d00> <2dff> <2d00>\n<2e00> <2eff> <2e00>\n<2f00> <2fff> <2f00>\n<3000> <30ff> <3000>\n<3100> <31ff> <3100>\n<3200> <32ff> <3200>\n<3300> <33ff> <3300>\n<3400> <34ff> <3400>\n<3500> <35ff> <3500>\n<3600> <36ff> <3600>\n<3700> <37ff> <3700>\n<3800> <38ff> <3800>\n<3900> <39ff> <3900>\n<3a00> <3aff> <3a00>\n<3b00> <3bff> <3b00>\n<3c00> <3cff> <3c00>\n<3d00> <3dff> <3d00>\n<3e00> <3eff> <3e00>\n<3f00> <3fff> <3f00>\n<4000> <40ff> <4000>\n<4100> <41ff> <4100>\n<4200> <42ff> <4200>\n<4300> <43ff> <4300>\n<4400> <44ff> <4400>\n<4500> <45ff> <4500>\n<4600> <46ff> <4600>\n<4700> <47ff> <4700>\n<4800> <48ff> <4800>\n<4900> <49ff> <4900>\n<4a00> <4aff> <4a00>\n<4b00> <4bff> <4b00>\n<4c00> <4cff> <4c00>\n<4d00> <4dff> <4d00>\n<4e00> <4eff> <4e00>\n<4f00> <4fff> <4f00>\n<5000> <50ff> <5000>\n<5100> <51ff> <5100>\n<5200> <52ff> <5200>\n<5300> <53ff> <5300>\n<5400> <54ff> <5400>\n<5500> <55ff> <5500>\n<5600> <56ff> <5600>\n<5700> <57ff> <5700>\n<5800> <58ff> <5800>\n<5900> <59ff> <5900>\n<5a00> <5aff> <5a00>\n<5b00> <5bff> <5b00>\n<5c00> <5cff> <5c00>\n<5d00> <5dff> <5d00>\n<5e00> <5eff> <5e00>\n<5f00> <5fff> <5f00>\n<6000> <60ff> <6000>\n<6100> <61ff> <6100>\n<6200> <62ff> <6200>\n<6300> <63ff> <6300>\nendbfrange\n100 beginbfrange\n<6400> <64ff> <6400>\n<6500> <65ff> <6500>\n<6600> <66ff> <6600>\n<6700> <67ff> <6700>\n<6800> <68ff> <6800>\n<6900> <69ff> <6900>\n<6a00> <6aff> <6a00>\n<6b00> <6bff> <6b00>\n<6c00> <6cff> <6c00>\n<6d00> <6dff> <6d00>\n<6e00> <6eff> <6e00>\n<6f00> <6fff> <6f00>\n<7000> <70ff> <7000>\n<7100> <71ff> <7100>\n<7200> <72ff> <7200>\n<7300> <73ff> <7300>\n<7400> <74ff> <7400>\n<7500> <75ff> <7500>\n<7600> <76ff> <7600>\n<7700> <77ff> <7700>\n<7800> <78ff> <7800>\n<7900> <79ff> <7900>\n<7a00> <7aff> <7a00>\n<7b00> <7bff> <7b00>\n<7c00> <7cff> <7c00>\n<7d00> <7dff> <7d00>\n<7e00> <7eff> <7e00>\n<7f00> <7fff> <7f00>\n<8000> <80ff> <8000>\n<8100> <81ff> <8100>\n<8200> <82ff> <8200>\n<8300> <83ff> <8300>\n<8400> <84ff> <8400>\n<8500> <85ff> <8500>\n<8600> <86ff> <8600>\n<8700> <87ff> <8700>\n<8800> <88ff> <8800>\n<8900> <89ff> <8900>\n<8a00> <8aff> <8a00>\n<8b00> <8bff> <8b00>\n<8c00> <8cff> <8c00>\n<8d00> <8dff> <8d00>\n<8e00> <8eff> <8e00>\n<8f00> <8fff> <8f00>\n<9000> <90ff> <9000>\n<9100> <91ff> <9100>\n<9200> <92ff> <9200>\n<9300> <93ff> <9300>\n<9400> <94ff> <9400>\n<9500> <95ff> <9500>\n<9600> <96ff> <9600>\n<9700> <97ff> <9700>\n<9800> <98ff> <9800>\n<9900> <99ff> <9900>\n<9a00> <9aff> <9a00>\n<9b00> <9bff> <9b00>\n<9c00> <9cff> <9c00>\n<9d00> <9dff> <9d00>\n<9e00> <9eff> <9e00>\n<9f00> <9fff> <9f00>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \nendbfrange\n56 beginbfrange\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \nendbfrange\nendcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"; } // --- END OF CLASS --- //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/tcpdf_fonts.php000066400000000000000000002663711237252063700215550ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description :Font methods for TCPDF library. // //============================================================+ /** * @file * Unicode data and font methods for TCPDF library. * @author Nicola Asuni * @package com.tecnick.tcpdf */ /** * @class TCPDF_FONTS * Font methods for TCPDF library. * @package com.tecnick.tcpdf * @version 1.0.005 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_FONTS { /** * Convert and add the selected TrueType or Type1 font to the fonts folder (that must be writeable). * @param $fontfile (string) Font file (full path). * @param $fonttype (string) Font type. Leave empty for autodetect mode. Valid values are: TrueTypeUnicode, TrueType, Type1, CID0JP = CID-0 Japanese, CID0KR = CID-0 Korean, CID0CS = CID-0 Chinese Simplified, CID0CT = CID-0 Chinese Traditional. * @param $enc (string) Name of the encoding table to use. Leave empty for default mode. Omit this parameter for TrueType Unicode and symbolic fonts like Symbol or ZapfDingBats. * @param $flags (int) Unsigned 32-bit integer containing flags specifying various characteristics of the font (PDF32000:2008 - 9.8.2 Font Descriptor Flags): +1 for fixed font; +4 for symbol or +32 for non-symbol; +64 for italic. Fixed and Italic mode are generally autodetected so you have to set it to 32 = non-symbolic font (default) or 4 = symbolic font. * @param $outpath (string) Output path for generated font files (must be writeable by the web server). Leave empty for default font folder. * @param $platid (int) Platform ID for CMAP table to extract (when building a Unicode font for Windows this value should be 3, for Macintosh should be 1). * @param $encid (int) Encoding ID for CMAP table to extract (when building a Unicode font for Windows this value should be 1, for Macintosh should be 0). When Platform ID is 3, legal values for Encoding ID are: 0=Symbol, 1=Unicode, 2=ShiftJIS, 3=PRC, 4=Big5, 5=Wansung, 6=Johab, 7=Reserved, 8=Reserved, 9=Reserved, 10=UCS-4. * @param $addcbbox (boolean) If true includes the character bounding box information on the php font file. * @return (string) TCPDF font name. * @author Nicola Asuni * @since 5.9.123 (2010-09-30) * @public static */ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='', $platid=3, $encid=1, $addcbbox=false) { if (!file_exists($fontfile)) { // Could not find file return false; } // font metrics $fmetric = array(); // build new font name for TCPDF compatibility $font_path_parts = pathinfo($fontfile); if (!isset($font_path_parts['filename'])) { $font_path_parts['filename'] = substr($font_path_parts['basename'], 0, -(strlen($font_path_parts['extension']) + 1)); } $font_name = strtolower($font_path_parts['filename']); $font_name = preg_replace('/[^a-z0-9_]/', '', $font_name); $search = array('bold', 'oblique', 'italic', 'regular'); $replace = array('b', 'i', 'i', ''); $font_name = str_replace($search, $replace, $font_name); if (empty($font_name)) { // set generic name $font_name = 'tcpdffont'; } // set output path if (empty($outpath)) { $outpath = self::_getfontpath(); } // check if this font already exist if (file_exists($outpath.$font_name.'.php')) { // this font already exist (delete it from fonts folder to rebuild it) return $font_name; } $fmetric['file'] = $font_name.'.z'; $fmetric['ctg'] = $font_name.'.ctg.z'; // get font data $font = file_get_contents($fontfile); $fmetric['originalsize'] = strlen($font); // autodetect font type if (empty($fonttype)) { if (TCPDF_STATIC::_getULONG($font, 0) == 0x10000) { // True Type (Unicode or not) $fonttype = 'TrueTypeUnicode'; } elseif (substr($font, 0, 4) == 'OTTO') { // Open Type (Unicode or not) //Unsupported font format: OpenType with CFF data return false; } else { // Type 1 $fonttype = 'Type1'; } } // set font type switch ($fonttype) { case 'CID0CT': case 'CID0CS': case 'CID0KR': case 'CID0JP': { $fmetric['type'] = 'cidfont0'; break; } case 'Type1': { $fmetric['type'] = 'Type1'; if (empty($enc) AND (($flags & 4) == 0)) { $enc = 'cp1252'; } break; } case 'TrueType': { $fmetric['type'] = 'TrueType'; break; } case 'TrueTypeUnicode': default: { $fmetric['type'] = 'TrueTypeUnicode'; break; } } // set encoding maps (if any) $fmetric['enc'] = preg_replace('/[^A-Za-z0-9_\-]/', '', $enc); $fmetric['diff'] = ''; if (($fmetric['type'] == 'TrueType') OR ($fmetric['type'] == 'Type1')) { if (!empty($enc) AND ($enc != 'cp1252') AND isset(TCPDF_FONT_DATA::$encmap[$enc])) { // build differences from reference encoding $enc_ref = TCPDF_FONT_DATA::$encmap['cp1252']; $enc_target = TCPDF_FONT_DATA::$encmap[$enc]; $last = 0; for ($i = 32; $i <= 255; ++$i) { if ($enc_target != $enc_ref[$i]) { if ($i != ($last + 1)) { $fmetric['diff'] .= $i.' '; } $last = $i; $fmetric['diff'] .= '/'.$enc_target[$i].' '; } } } } // parse the font by type if ($fmetric['type'] == 'Type1') { // ---------- TYPE 1 ---------- // read first segment $a = unpack('Cmarker/Ctype/Vsize', substr($font, 0, 6)); if ($a['marker'] != 128) { // Font file is not a valid binary Type1 return false; } $fmetric['size1'] = $a['size']; $data = substr($font, 6, $fmetric['size1']); // read second segment $a = unpack('Cmarker/Ctype/Vsize', substr($font, (6 + $fmetric['size1']), 6)); if ($a['marker'] != 128) { // Font file is not a valid binary Type1 return false; } $fmetric['size2'] = $a['size']; $encrypted = substr($font, (12 + $fmetric['size1']), $fmetric['size2']); $data .= $encrypted; // store compressed font $fp = fopen($outpath.$fmetric['file'], 'wb'); fwrite($fp, gzcompress($data)); fclose($fp); // get font info $fmetric['Flags'] = $flags; preg_match ('#/FullName[\s]*\(([^\)]*)#', $font, $matches); $fmetric['name'] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $matches[1]); preg_match('#/FontBBox[\s]*{([^}]*)#', $font, $matches); $fmetric['bbox'] = trim($matches[1]); $bv = explode(' ', $fmetric['bbox']); $fmetric['Ascent'] = intval($bv[3]); $fmetric['Descent'] = intval($bv[1]); preg_match('#/ItalicAngle[\s]*([0-9\+\-]*)#', $font, $matches); $fmetric['italicAngle'] = intval($matches[1]); if ($fmetric['italicAngle'] != 0) { $fmetric['Flags'] |= 64; } preg_match('#/UnderlinePosition[\s]*([0-9\+\-]*)#', $font, $matches); $fmetric['underlinePosition'] = intval($matches[1]); preg_match('#/UnderlineThickness[\s]*([0-9\+\-]*)#', $font, $matches); $fmetric['underlineThickness'] = intval($matches[1]); preg_match('#/isFixedPitch[\s]*([^\s]*)#', $font, $matches); if ($matches[1] == 'true') { $fmetric['Flags'] |= 1; } // get internal map $imap = array(); if (preg_match_all('#dup[\s]([0-9]+)[\s]*/([^\s]*)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) { foreach ($fmap as $v) { $imap[$v[2]] = $v[1]; } } // decrypt eexec encrypted part $r = 55665; // eexec encryption constant $c1 = 52845; $c2 = 22719; $elen = strlen($encrypted); $eplain = ''; for ($i = 0; $i < $elen; ++$i) { $chr = ord($encrypted[$i]); $eplain .= chr($chr ^ ($r >> 8)); $r = ((($chr + $r) * $c1 + $c2) % 65536); } if (preg_match('#/ForceBold[\s]*([^\s]*)#', $eplain, $matches) > 0) { if ($matches[1] == 'true') { $fmetric['Flags'] |= 0x40000; } } if (preg_match('#/StdVW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) { $fmetric['StemV'] = intval($matches[1]); } else { $fmetric['StemV'] = 70; } if (preg_match('#/StdHW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) { $fmetric['StemH'] = intval($matches[1]); } else { $fmetric['StemH'] = 30; } if (preg_match('#/BlueValues[\s]*\[([^\]]*)#', $eplain, $matches) > 0) { $bv = explode(' ', $matches[1]); if (count($bv) >= 6) { $v1 = intval($bv[2]); $v2 = intval($bv[4]); if ($v1 <= $v2) { $fmetric['XHeight'] = $v1; $fmetric['CapHeight'] = $v2; } else { $fmetric['XHeight'] = $v2; $fmetric['CapHeight'] = $v1; } } else { $fmetric['XHeight'] = 450; $fmetric['CapHeight'] = 700; } } else { $fmetric['XHeight'] = 450; $fmetric['CapHeight'] = 700; } // get the number of random bytes at the beginning of charstrings if (preg_match('#/lenIV[\s]*([0-9]*)#', $eplain, $matches) > 0) { $lenIV = intval($matches[1]); } else { $lenIV = 4; } $fmetric['Leading'] = 0; // get charstring data $eplain = substr($eplain, (strpos($eplain, '/CharStrings') + 1)); preg_match_all('#/([A-Za-z0-9\.]*)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER); if (!empty($enc) AND isset(TCPDF_FONT_DATA::$encmap[$enc])) { $enc_map = TCPDF_FONT_DATA::$encmap[$enc]; } else { $enc_map = false; } $fmetric['cw'] = ''; $fmetric['MaxWidth'] = 0; $cwidths = array(); foreach ($matches as $k => $v) { $cid = 0; if (isset($imap[$v[1]])) { $cid = $imap[$v[1]]; } elseif ($enc_map !== false) { $cid = array_search($v[1], $enc_map); if ($cid === false) { $cid = 0; } elseif ($cid > 1000) { $cid -= 1000; } } // decrypt charstring encrypted part $r = 4330; // charstring encryption constant $c1 = 52845; $c2 = 22719; $cd = $v[2]; $clen = strlen($cd); $ccom = array(); for ($i = 0; $i < $clen; ++$i) { $chr = ord($cd[$i]); $ccom[] = ($chr ^ ($r >> 8)); $r = ((($chr + $r) * $c1 + $c2) % 65536); } // decode numbers $cdec = array(); $ck = 0; $i = $lenIV; while ($i < $clen) { if ($ccom[$i] < 32) { $cdec[$ck] = $ccom[$i]; if (($ck > 0) AND ($cdec[$ck] == 13)) { // hsbw command: update width $cwidths[$cid] = $cdec[($ck - 1)]; } ++$i; } elseif (($ccom[$i] >= 32) AND ($ccom[$i] <= 246)) { $cdec[$ck] = ($ccom[$i] - 139); ++$i; } elseif (($ccom[$i] >= 247) AND ($ccom[$i] <= 250)) { $cdec[$ck] = ((($ccom[$i] - 247) * 256) + $ccom[($i + 1)] + 108); $i += 2; } elseif (($ccom[$i] >= 251) AND ($ccom[$i] <= 254)) { $cdec[$ck] = ((-($ccom[$i] - 251) * 256) - $ccom[($i + 1)] - 108); $i += 2; } elseif ($ccom[$i] == 255) { $sval = chr($ccom[($i + 1)]).chr($ccom[($i + 2)]).chr($ccom[($i + 3)]).chr($ccom[($i + 4)]); $vsval = unpack('li', $sval); $cdec[$ck] = $vsval['i']; $i += 5; } ++$ck; } } // end for each matches $fmetric['MissingWidth'] = $cwidths[0]; $fmetric['MaxWidth'] = $fmetric['MissingWidth']; $fmetric['AvgWidth'] = 0; // set chars widths for ($cid = 0; $cid <= 255; ++$cid) { if (isset($cwidths[$cid])) { if ($cwidths[$cid] > $fmetric['MaxWidth']) { $fmetric['MaxWidth'] = $cwidths[$cid]; } $fmetric['AvgWidth'] += $cwidths[$cid]; $fmetric['cw'] .= ','.$cid.'=>'.$cwidths[$cid]; } else { $fmetric['cw'] .= ','.$cid.'=>'.$fmetric['MissingWidth']; } } $fmetric['AvgWidth'] = round($fmetric['AvgWidth'] / count($cwidths)); } else { // ---------- TRUE TYPE ---------- if ($fmetric['type'] != 'cidfont0') { // store compressed font $fp = fopen($outpath.$fmetric['file'], 'wb'); fwrite($fp, gzcompress($font)); fclose($fp); } $offset = 0; // offset position of the font data if (TCPDF_STATIC::_getULONG($font, $offset) != 0x10000) { // sfnt version must be 0x00010000 for TrueType version 1.0. return false; } $offset += 4; // get number of tables $numTables = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; // skip searchRange, entrySelector and rangeShift $offset += 6; // tables array $table = array(); // ---------- get tables ---------- for ($i = 0; $i < $numTables; ++$i) { // get table info $tag = substr($font, $offset, 4); $offset += 4; $table[$tag] = array(); $table[$tag]['checkSum'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $table[$tag]['offset'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $table[$tag]['length'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; } // check magicNumber $offset = $table['head']['offset'] + 12; if (TCPDF_STATIC::_getULONG($font, $offset) != 0x5F0F3CF5) { // magicNumber must be 0x5F0F3CF5 return false; } $offset += 4; $offset += 2; // skip flags // get FUnits $fmetric['unitsPerEm'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; // units ratio constant $urk = (1000 / $fmetric['unitsPerEm']); $offset += 16; // skip created, modified $xMin = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; $yMin = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; $xMax = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; $yMax = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; $fmetric['bbox'] = ''.$xMin.' '.$yMin.' '.$xMax.' '.$yMax.''; $macStyle = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; // PDF font flags $fmetric['Flags'] = $flags; if (($macStyle & 2) == 2) { // italic flag $fmetric['Flags'] |= 64; } // get offset mode (indexToLocFormat : 0 = short, 1 = long) $offset = $table['head']['offset'] + 50; $short_offset = (TCPDF_STATIC::_getSHORT($font, $offset) == 0); $offset += 2; // get the offsets to the locations of the glyphs in the font, relative to the beginning of the glyphData table $indexToLoc = array(); $offset = $table['loca']['offset']; if ($short_offset) { // short version $tot_num_glyphs = ($table['loca']['length'] / 2); // numGlyphs + 1 for ($i = 0; $i < $tot_num_glyphs; ++$i) { $indexToLoc[$i] = TCPDF_STATIC::_getUSHORT($font, $offset) * 2; $offset += 2; } } else { // long version $tot_num_glyphs = ($table['loca']['length'] / 4); // numGlyphs + 1 for ($i = 0; $i < $tot_num_glyphs; ++$i) { $indexToLoc[$i] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; } } // get glyphs indexes of chars from cmap table $offset = $table['cmap']['offset'] + 2; $numEncodingTables = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $encodingTables = array(); for ($i = 0; $i < $numEncodingTables; ++$i) { $encodingTables[$i]['platformID'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $encodingTables[$i]['encodingID'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $encodingTables[$i]['offset'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; } // ---------- get os/2 metrics ---------- $offset = $table['OS/2']['offset']; $offset += 2; // skip version // xAvgCharWidth $fmetric['AvgWidth'] = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; // usWeightClass $usWeightClass = round(TCPDF_STATIC::_getUFWORD($font, $offset) * $urk); // estimate StemV and StemH (400 = usWeightClass for Normal - Regular font) $fmetric['StemV'] = round((70 * $usWeightClass) / 400); $fmetric['StemH'] = round((30 * $usWeightClass) / 400); $offset += 2; $offset += 2; // usWidthClass $fsType = TCPDF_STATIC::_getSHORT($font, $offset); $offset += 2; if ($fsType == 2) { // This Font cannot be modified, embedded or exchanged in any manner without first obtaining permission of the legal owner. return false; } // ---------- get font name ---------- $fmetric['name'] = ''; $offset = $table['name']['offset']; $offset += 2; // skip Format selector (=0). // Number of NameRecords that follow n. $numNameRecords = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; // Offset to start of string storage (from start of table). $stringStorageOffset = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; for ($i = 0; $i < $numNameRecords; ++$i) { $offset += 6; // skip Platform ID, Platform-specific encoding ID, Language ID. // Name ID. $nameID = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; if ($nameID == 6) { // String length (in bytes). $stringLength = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; // String offset from start of storage area (in bytes). $stringOffset = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $offset = ($table['name']['offset'] + $stringStorageOffset + $stringOffset); $fmetric['name'] = substr($font, $offset, $stringLength); $fmetric['name'] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $fmetric['name']); break; } else { $offset += 4; // skip String length, String offset } } if (empty($fmetric['name'])) { $fmetric['name'] = $font_name; } // ---------- get post data ---------- $offset = $table['post']['offset']; $offset += 4; // skip Format Type $fmetric['italicAngle'] = TCPDF_STATIC::_getFIXED($font, $offset); $offset += 4; $fmetric['underlinePosition'] = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; $fmetric['underlineThickness'] = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; $isFixedPitch = (TCPDF_STATIC::_getULONG($font, $offset) == 0) ? false : true; $offset += 2; if ($isFixedPitch) { $fmetric['Flags'] |= 1; } // ---------- get hhea data ---------- $offset = $table['hhea']['offset']; $offset += 4; // skip Table version number // Ascender $fmetric['Ascent'] = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; // Descender $fmetric['Descent'] = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; // LineGap $fmetric['Leading'] = round(TCPDF_STATIC::_getFWORD($font, $offset) * $urk); $offset += 2; // advanceWidthMax $fmetric['MaxWidth'] = round(TCPDF_STATIC::_getUFWORD($font, $offset) * $urk); $offset += 2; $offset += 22; // skip some values // get the number of hMetric entries in hmtx table $numberOfHMetrics = TCPDF_STATIC::_getUSHORT($font, $offset); // ---------- get maxp data ---------- $offset = $table['maxp']['offset']; $offset += 4; // skip Table version number // get the the number of glyphs in the font. $numGlyphs = TCPDF_STATIC::_getUSHORT($font, $offset); // ---------- get CIDToGIDMap ---------- $ctg = array(); foreach ($encodingTables as $enctable) { // get only specified Platform ID and Encoding ID if (($enctable['platformID'] == $platid) AND ($enctable['encodingID'] == $encid)) { $offset = $table['cmap']['offset'] + $enctable['offset']; $format = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; switch ($format) { case 0: { // Format 0: Byte encoding table $offset += 4; // skip length and version/language for ($c = 0; $c < 256; ++$c) { $g = TCPDF_STATIC::_getBYTE($font, $offset); $ctg[$c] = $g; ++$offset; } break; } case 2: { // Format 2: High-byte mapping through table $offset += 4; // skip length and version/language $numSubHeaders = 0; for ($i = 0; $i < 256; ++$i) { // Array that maps high bytes to subHeaders: value is subHeader index * 8. $subHeaderKeys[$i] = (TCPDF_STATIC::_getUSHORT($font, $offset) / 8); $offset += 2; if ($numSubHeaders < $subHeaderKeys[$i]) { $numSubHeaders = $subHeaderKeys[$i]; } } // the number of subHeaders is equal to the max of subHeaderKeys + 1 ++$numSubHeaders; // read subHeader structures $subHeaders = array(); $numGlyphIndexArray = 0; for ($k = 0; $k < $numSubHeaders; ++$k) { $subHeaders[$k]['firstCode'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['entryCount'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['idDelta'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['idRangeOffset'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8)); $subHeaders[$k]['idRangeOffset'] /= 2; $numGlyphIndexArray += $subHeaders[$k]['entryCount']; } for ($k = 0; $k < $numGlyphIndexArray; ++$k) { $glyphIndexArray[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } for ($i = 0; $i < 256; ++$i) { $k = $subHeaderKeys[$i]; if ($k == 0) { // one byte code $c = $i; $g = $glyphIndexArray[0]; $ctg[$c] = $g; } else { // two bytes code $start_byte = $subHeaders[$k]['firstCode']; $end_byte = $start_byte + $subHeaders[$k]['entryCount']; for ($j = $start_byte; $j < $end_byte; ++$j) { // combine high and low bytes $c = (($i << 8) + $j); $idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']); $g = ($glyphIndexArray[$idRangeOffset] + $idDelta[$k]) % 65536; if ($g < 0) { $g = 0; } $ctg[$c] = $g; } } } break; } case 4: { // Format 4: Segment mapping to delta values $length = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $offset += 2; // skip version/language $segCount = (TCPDF_STATIC::_getUSHORT($font, $offset) / 2); $offset += 2; $offset += 6; // skip searchRange, entrySelector, rangeShift $endCount = array(); // array of end character codes for each segment for ($k = 0; $k < $segCount; ++$k) { $endCount[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $offset += 2; // skip reservedPad $startCount = array(); // array of start character codes for each segment for ($k = 0; $k < $segCount; ++$k) { $startCount[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $idDelta = array(); // delta for all character codes in segment for ($k = 0; $k < $segCount; ++$k) { $idDelta[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $idRangeOffset = array(); // Offsets into glyphIdArray or 0 for ($k = 0; $k < $segCount; ++$k) { $idRangeOffset[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $gidlen = ($length / 2) - 8 - (4 * $segCount); $glyphIdArray = array(); // glyph index array for ($k = 0; $k < $gidlen; ++$k) { $glyphIdArray[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } for ($k = 0; $k < $segCount; ++$k) { for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) { if ($idRangeOffset[$k] == 0) { $g = ($idDelta[$k] + $c) % 65536; } else { $gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k)); $g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536; } if ($g < 0) { $g = 0; } $ctg[$c] = $g; } } break; } case 6: { // Format 6: Trimmed table mapping $offset += 4; // skip length and version/language $firstCode = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $entryCount = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; for ($k = 0; $k < $entryCount; ++$k) { $c = ($k + $firstCode); $g = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $ctg[$c] = $g; } break; } case 8: { // Format 8: Mixed 16-bit and 32-bit coverage $offset += 10; // skip reserved, length and version/language for ($k = 0; $k < 8192; ++$k) { $is32[$k] = TCPDF_STATIC::_getBYTE($font, $offset); ++$offset; } $nGroups = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($i = 0; $i < $nGroups; ++$i) { $startCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $endCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $startGlyphID = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($k = $startCharCode; $k <= $endCharCode; ++$k) { $is32idx = floor($c / 8); if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - ($c % 8)))) == 0)) { $c = $k; } else { // 32 bit format // convert to decimal (http://www.unicode.org/faq//utf_bom.html#utf16-4) //LEAD_OFFSET = (0xD800 - (0x10000 >> 10)) = 55232 //SURROGATE_OFFSET = (0x10000 - (0xD800 << 10) - 0xDC00) = -56613888 $c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888; } $ctg[$c] = 0; ++$startGlyphID; } } break; } case 10: { // Format 10: Trimmed array $offset += 10; // skip reserved, length and version/language $startCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $numChars = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($k = 0; $k < $numChars; ++$k) { $c = ($k + $startCharCode); $g = TCPDF_STATIC::_getUSHORT($font, $offset); $ctg[$c] = $g; $offset += 2; } break; } case 12: { // Format 12: Segmented coverage $offset += 10; // skip length and version/language $nGroups = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($k = 0; $k < $nGroups; ++$k) { $startCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $endCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $startGlyphCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($c = $startCharCode; $c <= $endCharCode; ++$c) { $ctg[$c] = $startGlyphCode; ++$startGlyphCode; } } break; } case 13: { // Format 13: Many-to-one range mappings // to be implemented ... break; } case 14: { // Format 14: Unicode Variation Sequences // to be implemented ... break; } } } } if (!isset($ctg[0])) { $ctg[0] = 0; } // get xHeight (height of x) $offset = ($table['glyf']['offset'] + $indexToLoc[$ctg[120]] + 4); $yMin = TCPDF_STATIC::_getFWORD($font, $offset); $offset += 4; $yMax = TCPDF_STATIC::_getFWORD($font, $offset); $offset += 2; $fmetric['XHeight'] = round(($yMax - $yMin) * $urk); // get CapHeight (height of H) $offset = ($table['glyf']['offset'] + $indexToLoc[$ctg[72]] + 4); $yMin = TCPDF_STATIC::_getFWORD($font, $offset); $offset += 4; $yMax = TCPDF_STATIC::_getFWORD($font, $offset); $offset += 2; $fmetric['CapHeight'] = round(($yMax - $yMin) * $urk); // ceate widths array $cw = array(); $offset = $table['hmtx']['offset']; for ($i = 0 ; $i < $numberOfHMetrics; ++$i) { $cw[$i] = round(TCPDF_STATIC::_getUFWORD($font, $offset) * $urk); $offset += 4; // skip lsb } if ($numberOfHMetrics < $numGlyphs) { // fill missing widths with the last value $cw = array_pad($cw, $numGlyphs, $cw[($numberOfHMetrics - 1)]); } $fmetric['MissingWidth'] = $cw[0]; $fmetric['cw'] = ''; for ($cid = 0; $cid <= 65535; ++$cid) { if (isset($ctg[$cid])) { if (isset($cw[$ctg[$cid]])) { $fmetric['cw'] .= ','.$cid.'=>'.$cw[$ctg[$cid]]; } if ($addcbbox AND isset($indexToLoc[$ctg[$cid]])) { $offset = ($table['glyf']['offset'] + $indexToLoc[$ctg[$cid]]); $xMin = round(TCPDF_STATIC::_getFWORD($font, $offset + 2)) * $urk; $yMin = round(TCPDF_STATIC::_getFWORD($font, $offset + 4)) * $urk; $xMax = round(TCPDF_STATIC::_getFWORD($font, $offset + 6)) * $urk; $yMax = round(TCPDF_STATIC::_getFWORD($font, $offset + 8)) * $urk; $fmetric['cbbox'] .= ','.$cid.'=>array('.$xMin.','.$yMin.','.$xMax.','.$yMax.')'; } } } } // end of true type if (($fmetric['type'] == 'TrueTypeUnicode') AND (count($ctg) == 256)) { $fmetric['type'] == 'TrueType'; } // ---------- create php font file ---------- $pfile = '<'.'?'.'php'."\n"; $pfile .= '// TCPDF FONT FILE DESCRIPTION'."\n"; $pfile .= '$type=\''.$fmetric['type'].'\';'."\n"; $pfile .= '$name=\''.$fmetric['name'].'\';'."\n"; $pfile .= '$up='.$fmetric['underlinePosition'].';'."\n"; $pfile .= '$ut='.$fmetric['underlineThickness'].';'."\n"; if ($fmetric['MissingWidth'] > 0) { $pfile .= '$dw='.$fmetric['MissingWidth'].';'."\n"; } else { $pfile .= '$dw='.$fmetric['AvgWidth'].';'."\n"; } $pfile .= '$diff=\''.$fmetric['diff'].'\';'."\n"; if ($fmetric['type'] == 'Type1') { // Type 1 $pfile .= '$enc=\''.$fmetric['enc'].'\';'."\n"; $pfile .= '$file=\''.$fmetric['file'].'\';'."\n"; $pfile .= '$size1='.$fmetric['size1'].';'."\n"; $pfile .= '$size2='.$fmetric['size2'].';'."\n"; } else { $pfile .= '$originalsize='.$fmetric['originalsize'].';'."\n"; if ($fmetric['type'] == 'cidfont0') { // CID-0 switch ($fonttype) { case 'CID0JP': { $pfile .= '// Japanese'."\n"; $pfile .= '$enc=\'UniJIS-UTF16-H\';'."\n"; $pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'Japan1\',\'Supplement\'=>5);'."\n"; $pfile .= 'include(dirname(__FILE__).\'/uni2cid_aj16.php\');'."\n"; break; } case 'CID0KR': { $pfile .= '// Korean'."\n"; $pfile .= '$enc=\'UniKS-UTF16-H\';'."\n"; $pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'Korea1\',\'Supplement\'=>0);'."\n"; $pfile .= 'include(dirname(__FILE__).\'/uni2cid_ak12.php\');'."\n"; break; } case 'CID0CS': { $pfile .= '// Chinese Simplified'."\n"; $pfile .= '$enc=\'UniGB-UTF16-H\';'."\n"; $pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'GB1\',\'Supplement\'=>2);'."\n"; $pfile .= 'include(dirname(__FILE__).\'/uni2cid_ag15.php\');'."\n"; break; } case 'CID0CT': default: { $pfile .= '// Chinese Traditional'."\n"; $pfile .= '$enc=\'UniCNS-UTF16-H\';'."\n"; $pfile .= '$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'CNS1\',\'Supplement\'=>0);'."\n"; $pfile .= 'include(dirname(__FILE__).\'/uni2cid_aj16.php\');'."\n"; break; } } } else { // TrueType $pfile .= '$enc=\''.$fmetric['enc'].'\';'."\n"; $pfile .= '$file=\''.$fmetric['file'].'\';'."\n"; $pfile .= '$ctg=\''.$fmetric['ctg'].'\';'."\n"; // create CIDToGIDMap $cidtogidmap = str_pad('', 131072, "\x00"); // (256 * 256 * 2) = 131072 foreach ($ctg as $cid => $gid) { $cidtogidmap = self::updateCIDtoGIDmap($cidtogidmap, $cid, $ctg[$cid]); } // store compressed CIDToGIDMap $fp = fopen($outpath.$fmetric['ctg'], 'wb'); fwrite($fp, gzcompress($cidtogidmap)); fclose($fp); } } $pfile .= '$desc=array('; $pfile .= '\'Flags\'=>'.$fmetric['Flags'].','; $pfile .= '\'FontBBox\'=>\'['.$fmetric['bbox'].']\','; $pfile .= '\'ItalicAngle\'=>'.$fmetric['italicAngle'].','; $pfile .= '\'Ascent\'=>'.$fmetric['Ascent'].','; $pfile .= '\'Descent\'=>'.$fmetric['Descent'].','; $pfile .= '\'Leading\'=>'.$fmetric['Leading'].','; $pfile .= '\'CapHeight\'=>'.$fmetric['CapHeight'].','; $pfile .= '\'XHeight\'=>'.$fmetric['XHeight'].','; $pfile .= '\'StemV\'=>'.$fmetric['StemV'].','; $pfile .= '\'StemH\'=>'.$fmetric['StemH'].','; $pfile .= '\'AvgWidth\'=>'.$fmetric['AvgWidth'].','; $pfile .= '\'MaxWidth\'=>'.$fmetric['MaxWidth'].','; $pfile .= '\'MissingWidth\'=>'.$fmetric['MissingWidth'].''; $pfile .= ');'."\n"; if (isset($fmetric['cbbox'])) { $pfile .= '$cbbox=array('.substr($fmetric['cbbox'], 1).');'."\n"; } $pfile .= '$cw=array('.substr($fmetric['cw'], 1).');'."\n"; $pfile .= '// --- EOF ---'."\n"; // store file $fp = fopen($outpath.$font_name.'.php', 'w'); fwrite($fp, $pfile); fclose($fp); // return TCPDF font name return $font_name; } /** * Returs the checksum of a TTF table. * @param $table (string) table to check * @param $length (int) length of table in bytes * @return int checksum * @author Nicola Asuni * @since 5.2.000 (2010-06-02) * @public static */ public static function _getTTFtableChecksum($table, $length) { $sum = 0; $tlen = ($length / 4); $offset = 0; for ($i = 0; $i < $tlen; ++$i) { $v = unpack('Ni', substr($table, $offset, 4)); $sum += $v['i']; $offset += 4; } $sum = unpack('Ni', pack('N', $sum)); return $sum['i']; } /** * Returns a subset of the TrueType font data without the unused glyphs. * @param $font (string) TrueType font data. * @param $subsetchars (array) Array of used characters (the glyphs to keep). * @return (string) A subset of TrueType font data without the unused glyphs. * @author Nicola Asuni * @since 5.2.000 (2010-06-02) * @public static */ public static function _getTrueTypeFontSubset($font, $subsetchars) { ksort($subsetchars); $offset = 0; // offset position of the font data if (TCPDF_STATIC::_getULONG($font, $offset) != 0x10000) { // sfnt version must be 0x00010000 for TrueType version 1.0. return $font; } $offset += 4; // get number of tables $numTables = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; // skip searchRange, entrySelector and rangeShift $offset += 6; // tables array $table = array(); // for each table for ($i = 0; $i < $numTables; ++$i) { // get table info $tag = substr($font, $offset, 4); $offset += 4; $table[$tag] = array(); $table[$tag]['checkSum'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $table[$tag]['offset'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $table[$tag]['length'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; } // check magicNumber $offset = $table['head']['offset'] + 12; if (TCPDF_STATIC::_getULONG($font, $offset) != 0x5F0F3CF5) { // magicNumber must be 0x5F0F3CF5 return $font; } $offset += 4; // get offset mode (indexToLocFormat : 0 = short, 1 = long) $offset = $table['head']['offset'] + 50; $short_offset = (TCPDF_STATIC::_getSHORT($font, $offset) == 0); $offset += 2; // get the offsets to the locations of the glyphs in the font, relative to the beginning of the glyphData table $indexToLoc = array(); $offset = $table['loca']['offset']; if ($short_offset) { // short version $tot_num_glyphs = ($table['loca']['length'] / 2); // numGlyphs + 1 for ($i = 0; $i < $tot_num_glyphs; ++$i) { $indexToLoc[$i] = TCPDF_STATIC::_getUSHORT($font, $offset) * 2; $offset += 2; } } else { // long version $tot_num_glyphs = ($table['loca']['length'] / 4); // numGlyphs + 1 for ($i = 0; $i < $tot_num_glyphs; ++$i) { $indexToLoc[$i] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; } } // get glyphs indexes of chars from cmap table $subsetglyphs = array(); // glyph IDs on key $subsetglyphs[0] = true; // character codes that do not correspond to any glyph in the font should be mapped to glyph index 0 $offset = $table['cmap']['offset'] + 2; $numEncodingTables = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $encodingTables = array(); for ($i = 0; $i < $numEncodingTables; ++$i) { $encodingTables[$i]['platformID'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $encodingTables[$i]['encodingID'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $encodingTables[$i]['offset'] = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; } foreach ($encodingTables as $enctable) { // get all platforms and encodings $offset = $table['cmap']['offset'] + $enctable['offset']; $format = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; switch ($format) { case 0: { // Format 0: Byte encoding table $offset += 4; // skip length and version/language for ($c = 0; $c < 256; ++$c) { if (isset($subsetchars[$c])) { $g = TCPDF_STATIC::_getBYTE($font, $offset); $subsetglyphs[$g] = true; } ++$offset; } break; } case 2: { // Format 2: High-byte mapping through table $offset += 4; // skip length and version/language $numSubHeaders = 0; for ($i = 0; $i < 256; ++$i) { // Array that maps high bytes to subHeaders: value is subHeader index * 8. $subHeaderKeys[$i] = (TCPDF_STATIC::_getUSHORT($font, $offset) / 8); $offset += 2; if ($numSubHeaders < $subHeaderKeys[$i]) { $numSubHeaders = $subHeaderKeys[$i]; } } // the number of subHeaders is equal to the max of subHeaderKeys + 1 ++$numSubHeaders; // read subHeader structures $subHeaders = array(); $numGlyphIndexArray = 0; for ($k = 0; $k < $numSubHeaders; ++$k) { $subHeaders[$k]['firstCode'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['entryCount'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['idDelta'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['idRangeOffset'] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $subHeaders[$k]['idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8)); $subHeaders[$k]['idRangeOffset'] /= 2; $numGlyphIndexArray += $subHeaders[$k]['entryCount']; } for ($k = 0; $k < $numGlyphIndexArray; ++$k) { $glyphIndexArray[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } for ($i = 0; $i < 256; ++$i) { $k = $subHeaderKeys[$i]; if ($k == 0) { // one byte code $c = $i; if (isset($subsetchars[$c])) { $g = $glyphIndexArray[0]; $subsetglyphs[$g] = true; } } else { // two bytes code $start_byte = $subHeaders[$k]['firstCode']; $end_byte = $start_byte + $subHeaders[$k]['entryCount']; for ($j = $start_byte; $j < $end_byte; ++$j) { // combine high and low bytes $c = (($i << 8) + $j); if (isset($subsetchars[$c])) { $idRangeOffset = ($subHeaders[$k]['idRangeOffset'] + $j - $subHeaders[$k]['firstCode']); $g = ($glyphIndexArray[$idRangeOffset] + $idDelta[$k]) % 65536; if ($g < 0) { $g = 0; } $subsetglyphs[$g] = true; } } } } break; } case 4: { // Format 4: Segment mapping to delta values $length = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $offset += 2; // skip version/language $segCount = (TCPDF_STATIC::_getUSHORT($font, $offset) / 2); $offset += 2; $offset += 6; // skip searchRange, entrySelector, rangeShift $endCount = array(); // array of end character codes for each segment for ($k = 0; $k < $segCount; ++$k) { $endCount[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $offset += 2; // skip reservedPad $startCount = array(); // array of start character codes for each segment for ($k = 0; $k < $segCount; ++$k) { $startCount[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $idDelta = array(); // delta for all character codes in segment for ($k = 0; $k < $segCount; ++$k) { $idDelta[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $idRangeOffset = array(); // Offsets into glyphIdArray or 0 for ($k = 0; $k < $segCount; ++$k) { $idRangeOffset[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } $gidlen = ($length / 2) - 8 - (4 * $segCount); $glyphIdArray = array(); // glyph index array for ($k = 0; $k < $gidlen; ++$k) { $glyphIdArray[$k] = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; } for ($k = 0; $k < $segCount; ++$k) { for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) { if (isset($subsetchars[$c])) { if ($idRangeOffset[$k] == 0) { $g = ($idDelta[$k] + $c) % 65536; } else { $gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k)); $g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536; } if ($g < 0) { $g = 0; } $subsetglyphs[$g] = true; } } } break; } case 6: { // Format 6: Trimmed table mapping $offset += 4; // skip length and version/language $firstCode = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $entryCount = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; for ($k = 0; $k < $entryCount; ++$k) { $c = ($k + $firstCode); if (isset($subsetchars[$c])) { $g = TCPDF_STATIC::_getUSHORT($font, $offset); $subsetglyphs[$g] = true; } $offset += 2; } break; } case 8: { // Format 8: Mixed 16-bit and 32-bit coverage $offset += 10; // skip reserved, length and version/language for ($k = 0; $k < 8192; ++$k) { $is32[$k] = TCPDF_STATIC::_getBYTE($font, $offset); ++$offset; } $nGroups = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($i = 0; $i < $nGroups; ++$i) { $startCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $endCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $startGlyphID = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($k = $startCharCode; $k <= $endCharCode; ++$k) { $is32idx = floor($c / 8); if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - ($c % 8)))) == 0)) { $c = $k; } else { // 32 bit format // convert to decimal (http://www.unicode.org/faq//utf_bom.html#utf16-4) //LEAD_OFFSET = (0xD800 - (0x10000 >> 10)) = 55232 //SURROGATE_OFFSET = (0x10000 - (0xD800 << 10) - 0xDC00) = -56613888 $c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888; } if (isset($subsetchars[$c])) { $subsetglyphs[$startGlyphID] = true; } ++$startGlyphID; } } break; } case 10: { // Format 10: Trimmed array $offset += 10; // skip reserved, length and version/language $startCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $numChars = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($k = 0; $k < $numChars; ++$k) { $c = ($k + $startCharCode); if (isset($subsetchars[$c])) { $g = TCPDF_STATIC::_getUSHORT($font, $offset); $subsetglyphs[$g] = true; } $offset += 2; } break; } case 12: { // Format 12: Segmented coverage $offset += 10; // skip length and version/language $nGroups = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($k = 0; $k < $nGroups; ++$k) { $startCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $endCharCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; $startGlyphCode = TCPDF_STATIC::_getULONG($font, $offset); $offset += 4; for ($c = $startCharCode; $c <= $endCharCode; ++$c) { if (isset($subsetchars[$c])) { $subsetglyphs[$startGlyphCode] = true; } ++$startGlyphCode; } } break; } case 13: { // Format 13: Many-to-one range mappings // to be implemented ... break; } case 14: { // Format 14: Unicode Variation Sequences // to be implemented ... break; } } } // include all parts of composite glyphs $new_sga = $subsetglyphs; while (!empty($new_sga)) { $sga = $new_sga; $new_sga = array(); foreach ($sga as $key => $val) { if (isset($indexToLoc[$key])) { $offset = ($table['glyf']['offset'] + $indexToLoc[$key]); $numberOfContours = TCPDF_STATIC::_getSHORT($font, $offset); $offset += 2; if ($numberOfContours < 0) { // composite glyph $offset += 8; // skip xMin, yMin, xMax, yMax do { $flags = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; $glyphIndex = TCPDF_STATIC::_getUSHORT($font, $offset); $offset += 2; if (!isset($subsetglyphs[$glyphIndex])) { // add missing glyphs $new_sga[$glyphIndex] = true; } // skip some bytes by case if ($flags & 1) { $offset += 4; } else { $offset += 2; } if ($flags & 8) { $offset += 2; } elseif ($flags & 64) { $offset += 4; } elseif ($flags & 128) { $offset += 8; } } while ($flags & 32); } } } $subsetglyphs += $new_sga; } // sort glyphs by key (and remove duplicates) ksort($subsetglyphs); // build new glyf and loca tables $glyf = ''; $loca = ''; $offset = 0; $glyf_offset = $table['glyf']['offset']; for ($i = 0; $i < $tot_num_glyphs; ++$i) { if (isset($subsetglyphs[$i])) { $length = ($indexToLoc[($i + 1)] - $indexToLoc[$i]); $glyf .= substr($font, ($glyf_offset + $indexToLoc[$i]), $length); } else { $length = 0; } if ($short_offset) { $loca .= pack('n', ($offset / 2)); } else { $loca .= pack('N', $offset); } $offset += $length; } // array of table names to preserve (loca and glyf tables will be added later) // the cmap table is not needed and shall not be present, since the mapping from character codes to glyph descriptions is provided separately $table_names = array ('head', 'hhea', 'hmtx', 'maxp', 'cvt ', 'fpgm', 'prep'); // minimum required table names // get the tables to preserve $offset = 12; foreach ($table as $tag => $val) { if (in_array($tag, $table_names)) { $table[$tag]['data'] = substr($font, $table[$tag]['offset'], $table[$tag]['length']); if ($tag == 'head') { // set the checkSumAdjustment to 0 $table[$tag]['data'] = substr($table[$tag]['data'], 0, 8)."\x0\x0\x0\x0".substr($table[$tag]['data'], 12); } $pad = 4 - ($table[$tag]['length'] % 4); if ($pad != 4) { // the length of a table must be a multiple of four bytes $table[$tag]['length'] += $pad; $table[$tag]['data'] .= str_repeat("\x0", $pad); } $table[$tag]['offset'] = $offset; $offset += $table[$tag]['length']; // check sum is not changed (so keep the following line commented) //$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length']); } else { unset($table[$tag]); } } // add loca $table['loca']['data'] = $loca; $table['loca']['length'] = strlen($loca); $pad = 4 - ($table['loca']['length'] % 4); if ($pad != 4) { // the length of a table must be a multiple of four bytes $table['loca']['length'] += $pad; $table['loca']['data'] .= str_repeat("\x0", $pad); } $table['loca']['offset'] = $offset; $table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length']); $offset += $table['loca']['length']; // add glyf $table['glyf']['data'] = $glyf; $table['glyf']['length'] = strlen($glyf); $pad = 4 - ($table['glyf']['length'] % 4); if ($pad != 4) { // the length of a table must be a multiple of four bytes $table['glyf']['length'] += $pad; $table['glyf']['data'] .= str_repeat("\x0", $pad); } $table['glyf']['offset'] = $offset; $table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length']); // rebuild font $font = ''; $font .= pack('N', 0x10000); // sfnt version $numTables = count($table); $font .= pack('n', $numTables); // numTables $entrySelector = floor(log($numTables, 2)); $searchRange = pow(2, $entrySelector) * 16; $rangeShift = ($numTables * 16) - $searchRange; $font .= pack('n', $searchRange); // searchRange $font .= pack('n', $entrySelector); // entrySelector $font .= pack('n', $rangeShift); // rangeShift $offset = ($numTables * 16); foreach ($table as $tag => $data) { $font .= $tag; // tag $font .= pack('N', $data['checkSum']); // checkSum $font .= pack('N', ($data['offset'] + $offset)); // offset $font .= pack('N', $data['length']); // length } foreach ($table as $data) { $font .= $data['data']; } // set checkSumAdjustment on head table $checkSumAdjustment = 0xB1B0AFBA - self::_getTTFtableChecksum($font, strlen($font)); $font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12); return $font; } /** * Outputs font widths * @param $font (array) font data * @param $cidoffset (int) offset for CID values * @return PDF command string for font widths * @author Nicola Asuni * @since 4.4.000 (2008-12-07) * @public static */ public static function _putfontwidths($font, $cidoffset=0) { ksort($font['cw']); $rangeid = 0; $range = array(); $prevcid = -2; $prevwidth = -1; $interval = false; // for each character foreach ($font['cw'] as $cid => $width) { $cid -= $cidoffset; if ($font['subset'] AND (!isset($font['subsetchars'][$cid]))) { // ignore the unused characters (font subsetting) continue; } if ($width != $font['dw']) { if ($cid == ($prevcid + 1)) { // consecutive CID if ($width == $prevwidth) { if ($width == $range[$rangeid][0]) { $range[$rangeid][] = $width; } else { array_pop($range[$rangeid]); // new range $rangeid = $prevcid; $range[$rangeid] = array(); $range[$rangeid][] = $prevwidth; $range[$rangeid][] = $width; } $interval = true; $range[$rangeid]['interval'] = true; } else { if ($interval) { // new range $rangeid = $cid; $range[$rangeid] = array(); $range[$rangeid][] = $width; } else { $range[$rangeid][] = $width; } $interval = false; } } else { // new range $rangeid = $cid; $range[$rangeid] = array(); $range[$rangeid][] = $width; $interval = false; } $prevcid = $cid; $prevwidth = $width; } } // optimize ranges $prevk = -1; $nextk = -1; $prevint = false; foreach ($range as $k => $ws) { $cws = count($ws); if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) { if (isset($range[$k]['interval'])) { unset($range[$k]['interval']); } $range[$prevk] = array_merge($range[$prevk], $range[$k]); unset($range[$k]); } else { $prevk = $k; } $nextk = $k + $cws; if (isset($ws['interval'])) { if ($cws > 3) { $prevint = true; } else { $prevint = false; } if (isset($range[$k]['interval'])) { unset($range[$k]['interval']); } --$nextk; } else { $prevint = false; } } // output data $w = ''; foreach ($range as $k => $ws) { if (count(array_count_values($ws)) == 1) { // interval mode is more compact $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0]; } else { // range mode $w .= ' '.$k.' [ '.implode(' ', $ws).' ]'; } } return '/W ['.$w.' ]'; } /** * Returns the unicode caracter specified by the value * @param $c (int) UTF-8 value * @param $unicode (boolean) True if we are in unicode mode, false otherwise. * @return Returns the specified character. * @since 2.3.000 (2008-03-05) * @public static */ public static function unichr($c, $unicode=true) { if (!$unicode) { return chr($c); } elseif ($c <= 0x7F) { // one byte return chr($c); } elseif ($c <= 0x7FF) { // two bytes return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F); } elseif ($c <= 0xFFFF) { // three bytes return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F); } elseif ($c <= 0x10FFFF) { // four bytes return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F); } else { return ''; } } /** * Returns the unicode caracter specified by UTF-8 value * @param $c (int) UTF-8 value * @return Returns the specified character. * @public static */ public static function unichrUnicode($c) { return self::unichr($c, true); } /** * Returns the unicode caracter specified by ASCII value * @param $c (int) UTF-8 value * @return Returns the specified character. * @public static */ public static function unichrASCII($c) { return self::unichr($c, false); } /** * Converts array of UTF-8 characters to UTF16-BE string.
      * Based on: http://www.faqs.org/rfcs/rfc2781.html *
      	 *   Encoding UTF-16:
      	 *
      	 *   Encoding of a single character from an ISO 10646 character value to
      	 *    UTF-16 proceeds as follows. Let U be the character number, no greater
      	 *    than 0x10FFFF.
      	 *
      	 *    1) If U < 0x10000, encode U as a 16-bit unsigned integer and
      	 *       terminate.
      	 *
      	 *    2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
      	 *       U' must be less than or equal to 0xFFFFF. That is, U' can be
      	 *       represented in 20 bits.
      	 *
      	 *    3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
      	 *       0xDC00, respectively. These integers each have 10 bits free to
      	 *       encode the character value, for a total of 20 bits.
      	 *
      	 *    4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
      	 *       bits of W1 and the 10 low-order bits of U' to the 10 low-order
      	 *       bits of W2. Terminate.
      	 *
      	 *    Graphically, steps 2 through 4 look like:
      	 *    U' = yyyyyyyyyyxxxxxxxxxx
      	 *    W1 = 110110yyyyyyyyyy
      	 *    W2 = 110111xxxxxxxxxx
      	 * 
      * @param $unicode (array) array containing UTF-8 unicode values * @param $setbom (boolean) if true set the Byte Order Mark (BOM = 0xFEFF) * @return string * @protected * @author Nicola Asuni * @since 2.1.000 (2008-01-08) * @public static */ public static function arrUTF8ToUTF16BE($unicode, $setbom=false) { $outstr = ''; // string to be returned if ($setbom) { $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM) } foreach ($unicode as $char) { if ($char == 0x200b) { // skip Unicode Character 'ZERO WIDTH SPACE' (DEC:8203, U+200B) } elseif ($char == 0xFFFD) { $outstr .= "\xFF\xFD"; // replacement character } elseif ($char < 0x10000) { $outstr .= chr($char >> 0x08); $outstr .= chr($char & 0xFF); } else { $char -= 0x10000; $w1 = 0xD800 | ($char >> 0x0a); $w2 = 0xDC00 | ($char & 0x3FF); $outstr .= chr($w1 >> 0x08); $outstr .= chr($w1 & 0xFF); $outstr .= chr($w2 >> 0x08); $outstr .= chr($w2 & 0xFF); } } return $outstr; } /** * Convert an array of UTF8 values to array of unicode characters * @param $ta (array) The input array of UTF8 values. * @param $isunicode (boolean) True for Unicode mode, false otherwise. * @return Return array of unicode characters * @since 4.5.037 (2009-04-07) * @public static */ public static function UTF8ArrayToUniArray($ta, $isunicode=true) { if ($isunicode) { return array_map(array('self', 'unichrUnicode'), $ta); } return array_map(array('self', 'unichrASCII'), $ta); } /** * Extract a slice of the $strarr array and return it as string. * @param $strarr (string) The input array of characters. * @param $start (int) the starting element of $strarr. * @param $end (int) first element that will not be returned. * @param $unicode (boolean) True if we are in unicode mode, false otherwise. * @return Return part of a string * @public static */ public static function UTF8ArrSubString($strarr, $start='', $end='', $unicode=true) { if (strlen($start) == 0) { $start = 0; } if (strlen($end) == 0) { $end = count($strarr); } $string = ''; for ($i = $start; $i < $end; ++$i) { $string .= self::unichr($strarr[$i], $unicode); } return $string; } /** * Extract a slice of the $uniarr array and return it as string. * @param $uniarr (string) The input array of characters. * @param $start (int) the starting element of $strarr. * @param $end (int) first element that will not be returned. * @return Return part of a string * @since 4.5.037 (2009-04-07) * @public static */ public static function UniArrSubString($uniarr, $start='', $end='') { if (strlen($start) == 0) { $start = 0; } if (strlen($end) == 0) { $end = count($uniarr); } $string = ''; for ($i=$start; $i < $end; ++$i) { $string .= $uniarr[$i]; } return $string; } /** * Update the CIDToGIDMap string with a new value. * @param $map (string) CIDToGIDMap. * @param $cid (int) CID value. * @param $gid (int) GID value. * @return (string) CIDToGIDMap. * @author Nicola Asuni * @since 5.9.123 (2011-09-29) * @public static */ public static function updateCIDtoGIDmap($map, $cid, $gid) { if (($cid >= 0) AND ($cid <= 0xFFFF) AND ($gid >= 0)) { if ($gid > 0xFFFF) { $gid -= 0x10000; } $map[($cid * 2)] = chr($gid >> 8); $map[(($cid * 2) + 1)] = chr($gid & 0xFF); } return $map; } /** * Return fonts path * @return string * @public static */ public static function _getfontpath() { if (!defined('K_PATH_FONTS') AND is_dir($fdir = realpath(dirname(__FILE__).'/../fonts'))) { if (substr($fdir, -1) != '/') { $fdir .= '/'; } define('K_PATH_FONTS', $fdir); } return defined('K_PATH_FONTS') ? K_PATH_FONTS : ''; } /** * Converts UTF-8 characters array to array of Latin1 characters array
      * @param $unicode (array) array containing UTF-8 unicode values * @return array * @author Nicola Asuni * @since 4.8.023 (2010-01-15) * @public static */ public static function UTF8ArrToLatin1Arr($unicode) { $outarr = array(); // array to be returned foreach ($unicode as $char) { if ($char < 256) { $outarr[] = $char; } elseif (array_key_exists($char, TCPDF_FONT_DATA::$uni_utf8tolatin)) { // map from UTF-8 $outarr[] = TCPDF_FONT_DATA::$uni_utf8tolatin[$char]; } elseif ($char == 0xFFFD) { // skip } else { $outarr[] = 63; // '?' character } } return $outarr; } /** * Converts UTF-8 characters array to array of Latin1 string
      * @param $unicode (array) array containing UTF-8 unicode values * @return array * @author Nicola Asuni * @since 4.8.023 (2010-01-15) * @public static */ public static function UTF8ArrToLatin1($unicode) { $outstr = ''; // string to be returned foreach ($unicode as $char) { if ($char < 256) { $outstr .= chr($char); } elseif (array_key_exists($char, TCPDF_FONT_DATA::$uni_utf8tolatin)) { // map from UTF-8 $outstr .= chr(TCPDF_FONT_DATA::$uni_utf8tolatin[$char]); } elseif ($char == 0xFFFD) { // skip } else { $outstr .= '?'; } } return $outstr; } /** * Converts UTF-8 character to integer value.
      * Invalid byte sequences will be replaced with 0xFFFD (replacement character)
      * Based on: http://www.faqs.org/rfcs/rfc3629.html *
      	 *    Char. number range  |        UTF-8 octet sequence
      	 *       (hexadecimal)    |              (binary)
      	 *    --------------------+-----------------------------------------------
      	 *    0000 0000-0000 007F | 0xxxxxxx
      	 *    0000 0080-0000 07FF | 110xxxxx 10xxxxxx
      	 *    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
      	 *    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
      	 *    ---------------------------------------------------------------------
      	 *
      	 *   ABFN notation:
      	 *   ---------------------------------------------------------------------
      	 *   UTF8-octets = *( UTF8-char )
      	 *   UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
      	 *   UTF8-1      = %x00-7F
      	 *   UTF8-2      = %xC2-DF UTF8-tail
      	 *
      	 *   UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
      	 *                 %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
      	 *   UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
      	 *                 %xF4 %x80-8F 2( UTF8-tail )
      	 *   UTF8-tail   = %x80-BF
      	 *   ---------------------------------------------------------------------
      	 * 
      * @param $uch (string) character string to process. * @return integer Unicode value * @author Nicola Asuni * @public static */ public static function uniord($uch) { if (function_exists('mb_convert_encoding')) { list(, $char) = @unpack('N', mb_convert_encoding($uch, 'UCS-4BE', 'UTF-8')); if ($char >= 0) { return $char; } } $bytes = array(); // array containing single character byte sequences $countbytes = 0; $numbytes = 1; // number of octetc needed to represent the UTF-8 character $length = strlen($uch); for ($i = 0; $i < $length; ++$i) { $char = ord($uch[$i]); // get one string character at time if ($countbytes == 0) { // get starting octect if ($char <= 0x7F) { return $char; // use the character "as is" because is ASCII } elseif (($char >> 0x05) == 0x06) { // 2 bytes character (0x06 = 110 BIN) $bytes[] = ($char - 0xC0) << 0x06; ++$countbytes; $numbytes = 2; } elseif (($char >> 0x04) == 0x0E) { // 3 bytes character (0x0E = 1110 BIN) $bytes[] = ($char - 0xE0) << 0x0C; ++$countbytes; $numbytes = 3; } elseif (($char >> 0x03) == 0x1E) { // 4 bytes character (0x1E = 11110 BIN) $bytes[] = ($char - 0xF0) << 0x12; ++$countbytes; $numbytes = 4; } else { // use replacement character for other invalid sequences return 0xFFFD; } } elseif (($char >> 0x06) == 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN $bytes[] = $char - 0x80; ++$countbytes; if ($countbytes == $numbytes) { // compose UTF-8 bytes to a single unicode value $char = $bytes[0]; for ($j = 1; $j < $numbytes; ++$j) { $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06)); } if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) { // The definition of UTF-8 prohibits encoding character numbers between // U+D800 and U+DFFF, which are reserved for use with the UTF-16 // encoding form (as surrogate pairs) and do not directly represent // characters. return 0xFFFD; // use replacement character } else { return $char; // add char to array } } } else { // use replacement character for other invalid sequences return 0xFFFD; } } return 0xFFFD; } /** * Converts UTF-8 strings to codepoints array.
      * Invalid byte sequences will be replaced with 0xFFFD (replacement character)
      * @param $str (string) string to process. * @param $isunicode (boolean) True when the documetn is in Unicode mode, false otherwise. * @param $currentfont (array) Reference to current font array. * @return array containing codepoints (UTF-8 characters values) * @author Nicola Asuni * @public static */ public static function UTF8StringToArray($str, $isunicode=true, &$currentfont) { if ($isunicode) { // requires PCRE unicode support turned on $chars = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY); $carr = array_map(array('self', 'uniord'), $chars); } else { $chars = str_split($str); $carr = array_map('ord', $chars); } $currentfont['subsetchars'] += array_fill_keys($carr, true); return $carr; } /** * Converts UTF-8 strings to Latin1 when using the standard 14 core fonts.
      * @param $str (string) string to process. * @param $isunicode (boolean) True when the documetn is in Unicode mode, false otherwise. * @param $currentfont (array) Reference to current font array. * @return string * @since 3.2.000 (2008-06-23) * @public static */ public static function UTF8ToLatin1($str, $isunicode=true, &$currentfont) { $unicode = self::UTF8StringToArray($str, $isunicode, $currentfont); // array containing UTF-8 unicode values return self::UTF8ArrToLatin1($unicode); } /** * Converts UTF-8 strings to UTF16-BE.
      * @param $str (string) string to process. * @param $setbom (boolean) if true set the Byte Order Mark (BOM = 0xFEFF) * @param $isunicode (boolean) True when the documetn is in Unicode mode, false otherwise. * @param $currentfont (array) Reference to current font array. * @return string * @author Nicola Asuni * @since 1.53.0.TC005 (2005-01-05) * @public static */ public static function UTF8ToUTF16BE($str, $setbom=false, $isunicode=true, &$currentfont) { if (!$isunicode) { return $str; // string is not in unicode } $unicode = self::UTF8StringToArray($str, $isunicode, $currentfont); // array containing UTF-8 unicode values return self::arrUTF8ToUTF16BE($unicode, $setbom); } /** * Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/). * @param $str (string) string to manipulate. * @param $setbom (bool) if true set the Byte Order Mark (BOM = 0xFEFF) * @param $forcertl (bool) if true forces RTL text direction * @param $isunicode (boolean) True if the document is in Unicode mode, false otherwise. * @param $currentfont (array) Reference to current font array. * @return string * @author Nicola Asuni * @since 2.1.000 (2008-01-08) * @public static */ public static function utf8StrRev($str, $setbom=false, $forcertl=false, $isunicode=true, &$currentfont) { return self::utf8StrArrRev(self::UTF8StringToArray($str, $isunicode, $currentfont), $str, $setbom, $forcertl, $isunicode, $currentfont); } /** * Reverse the RLT substrings array using the Bidirectional Algorithm (http://unicode.org/reports/tr9/). * @param $arr (array) array of unicode values. * @param $str (string) string to manipulate (or empty value). * @param $setbom (bool) if true set the Byte Order Mark (BOM = 0xFEFF) * @param $forcertl (bool) if true forces RTL text direction * @param $isunicode (boolean) True if the document is in Unicode mode, false otherwise. * @param $currentfont (array) Reference to current font array. * @return string * @author Nicola Asuni * @since 4.9.000 (2010-03-27) * @public static */ public static function utf8StrArrRev($arr, $str='', $setbom=false, $forcertl=false, $isunicode=true, &$currentfont) { return self::arrUTF8ToUTF16BE(self::utf8Bidi($arr, $str, $forcertl, $isunicode, $currentfont), $setbom); } /** * Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/). * @param $ta (array) array of characters composing the string. * @param $str (string) string to process * @param $forcertl (bool) if 'R' forces RTL, if 'L' forces LTR * @param $isunicode (boolean) True if the document is in Unicode mode, false otherwise. * @param $currentfont (array) Reference to current font array. * @return array of unicode chars * @author Nicola Asuni * @since 2.4.000 (2008-03-06) * @public static */ public static function utf8Bidi($ta, $str='', $forcertl=false, $isunicode=true, &$currentfont) { // paragraph embedding level $pel = 0; // max level $maxlevel = 0; if (TCPDF_STATIC::empty_string($str)) { // create string from array $str = self::UTF8ArrSubString($ta, '', '', $isunicode); } // check if string contains arabic text if (preg_match(TCPDF_FONT_DATA::$uni_RE_PATTERN_ARABIC, $str)) { $arabic = true; } else { $arabic = false; } // check if string contains RTL text if (!($forcertl OR $arabic OR preg_match(TCPDF_FONT_DATA::$uni_RE_PATTERN_RTL, $str))) { return $ta; } // get number of chars $numchars = count($ta); if ($forcertl == 'R') { $pel = 1; } elseif ($forcertl == 'L') { $pel = 0; } else { // P2. In each paragraph, find the first character of type L, AL, or R. // P3. If a character is found in P2 and it is of type AL or R, then set the paragraph embedding level to one; otherwise, set it to zero. for ($i=0; $i < $numchars; ++$i) { $type = TCPDF_FONT_DATA::$uni_type[$ta[$i]]; if ($type == 'L') { $pel = 0; break; } elseif (($type == 'AL') OR ($type == 'R')) { $pel = 1; break; } } } // Current Embedding Level $cel = $pel; // directional override status $dos = 'N'; $remember = array(); // start-of-level-run $sor = $pel % 2 ? 'R' : 'L'; $eor = $sor; // Array of characters data $chardata = Array(); // X1. Begin by setting the current embedding level to the paragraph embedding level. Set the directional override status to neutral. Process each character iteratively, applying rules X2 through X9. Only embedding levels from 0 to 61 are valid in this phase. // In the resolution of levels in rules I1 and I2, the maximum embedding level of 62 can be reached. for ($i=0; $i < $numchars; ++$i) { if ($ta[$i] == TCPDF_FONT_DATA::$uni_RLE) { // X2. With each RLE, compute the least greater odd embedding level. // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral. // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. $next_level = $cel + ($cel % 2) + 1; if ($next_level < 62) { $remember[] = array('num' => TCPDF_FONT_DATA::$uni_RLE, 'cel' => $cel, 'dos' => $dos); $cel = $next_level; $dos = 'N'; $sor = $eor; $eor = $cel % 2 ? 'R' : 'L'; } } elseif ($ta[$i] == TCPDF_FONT_DATA::$uni_LRE) { // X3. With each LRE, compute the least greater even embedding level. // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral. // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. $next_level = $cel + 2 - ($cel % 2); if ( $next_level < 62 ) { $remember[] = array('num' => TCPDF_FONT_DATA::$uni_LRE, 'cel' => $cel, 'dos' => $dos); $cel = $next_level; $dos = 'N'; $sor = $eor; $eor = $cel % 2 ? 'R' : 'L'; } } elseif ($ta[$i] == TCPDF_FONT_DATA::$uni_RLO) { // X4. With each RLO, compute the least greater odd embedding level. // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to right-to-left. // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. $next_level = $cel + ($cel % 2) + 1; if ($next_level < 62) { $remember[] = array('num' => TCPDF_FONT_DATA::$uni_RLO, 'cel' => $cel, 'dos' => $dos); $cel = $next_level; $dos = 'R'; $sor = $eor; $eor = $cel % 2 ? 'R' : 'L'; } } elseif ($ta[$i] == TCPDF_FONT_DATA::$uni_LRO) { // X5. With each LRO, compute the least greater even embedding level. // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to left-to-right. // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. $next_level = $cel + 2 - ($cel % 2); if ( $next_level < 62 ) { $remember[] = array('num' => TCPDF_FONT_DATA::$uni_LRO, 'cel' => $cel, 'dos' => $dos); $cel = $next_level; $dos = 'L'; $sor = $eor; $eor = $cel % 2 ? 'R' : 'L'; } } elseif ($ta[$i] == TCPDF_FONT_DATA::$uni_PDF) { // X7. With each PDF, determine the matching embedding or override code. If there was a valid matching code, restore (pop) the last remembered (pushed) embedding level and directional override. if (count($remember)) { $last = count($remember ) - 1; if (($remember[$last]['num'] == TCPDF_FONT_DATA::$uni_RLE) OR ($remember[$last]['num'] == TCPDF_FONT_DATA::$uni_LRE) OR ($remember[$last]['num'] == TCPDF_FONT_DATA::$uni_RLO) OR ($remember[$last]['num'] == TCPDF_FONT_DATA::$uni_LRO)) { $match = array_pop($remember); $cel = $match['cel']; $dos = $match['dos']; $sor = $eor; $eor = ($cel > $match['cel'] ? $cel : $match['cel']) % 2 ? 'R' : 'L'; } } } elseif (($ta[$i] != TCPDF_FONT_DATA::$uni_RLE) AND ($ta[$i] != TCPDF_FONT_DATA::$uni_LRE) AND ($ta[$i] != TCPDF_FONT_DATA::$uni_RLO) AND ($ta[$i] != TCPDF_FONT_DATA::$uni_LRO) AND ($ta[$i] != TCPDF_FONT_DATA::$uni_PDF)) { // X6. For all types besides RLE, LRE, RLO, LRO, and PDF: // a. Set the level of the current character to the current embedding level. // b. Whenever the directional override status is not neutral, reset the current character type to the directional override status. if ($dos != 'N') { $chardir = $dos; } else { if (isset(TCPDF_FONT_DATA::$uni_type[$ta[$i]])) { $chardir = TCPDF_FONT_DATA::$uni_type[$ta[$i]]; } else { $chardir = 'L'; } } // stores string characters and other information $chardata[] = array('char' => $ta[$i], 'level' => $cel, 'type' => $chardir, 'sor' => $sor, 'eor' => $eor); } } // end for each char // X8. All explicit directional embeddings and overrides are completely terminated at the end of each paragraph. Paragraph separators are not included in the embedding. // X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. // X10. The remaining rules are applied to each run of characters at the same level. For each run, determine the start-of-level-run (sor) and end-of-level-run (eor) type, either L or R. This depends on the higher of the two levels on either side of the boundary (at the start or end of the paragraph, the level of the 'other' run is the base embedding level). If the higher level is odd, the type is R; otherwise, it is L. // 3.3.3 Resolving Weak Types // Weak types are now resolved one level run at a time. At level run boundaries where the type of the character on the other side of the boundary is required, the type assigned to sor or eor is used. // Nonspacing marks are now resolved based on the previous characters. $numchars = count($chardata); // W1. Examine each nonspacing mark (NSM) in the level run, and change the type of the NSM to the type of the previous character. If the NSM is at the start of the level run, it will get the type of sor. $prevlevel = -1; // track level changes $levcount = 0; // counts consecutive chars at the same level for ($i=0; $i < $numchars; ++$i) { if ($chardata[$i]['type'] == 'NSM') { if ($levcount) { $chardata[$i]['type'] = $chardata[$i]['sor']; } elseif ($i > 0) { $chardata[$i]['type'] = $chardata[($i-1)]['type']; } } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } // W2. Search backward from each instance of a European number until the first strong type (R, L, AL, or sor) is found. If an AL is found, change the type of the European number to Arabic number. $prevlevel = -1; $levcount = 0; for ($i=0; $i < $numchars; ++$i) { if ($chardata[$i]['char'] == 'EN') { for ($j=$levcount; $j >= 0; $j--) { if ($chardata[$j]['type'] == 'AL') { $chardata[$i]['type'] = 'AN'; } elseif (($chardata[$j]['type'] == 'L') OR ($chardata[$j]['type'] == 'R')) { break; } } } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } // W3. Change all ALs to R. for ($i=0; $i < $numchars; ++$i) { if ($chardata[$i]['type'] == 'AL') { $chardata[$i]['type'] = 'R'; } } // W4. A single European separator between two European numbers changes to a European number. A single common separator between two numbers of the same type changes to that type. $prevlevel = -1; $levcount = 0; for ($i=0; $i < $numchars; ++$i) { if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) { if (($chardata[$i]['type'] == 'ES') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) { $chardata[$i]['type'] = 'EN'; } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) { $chardata[$i]['type'] = 'EN'; } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'AN') AND ($chardata[($i+1)]['type'] == 'AN')) { $chardata[$i]['type'] = 'AN'; } } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } // W5. A sequence of European terminators adjacent to European numbers changes to all European numbers. $prevlevel = -1; $levcount = 0; for ($i=0; $i < $numchars; ++$i) { if ($chardata[$i]['type'] == 'ET') { if (($levcount > 0) AND ($chardata[($i-1)]['type'] == 'EN')) { $chardata[$i]['type'] = 'EN'; } else { $j = $i+1; while (($j < $numchars) AND ($chardata[$j]['level'] == $prevlevel)) { if ($chardata[$j]['type'] == 'EN') { $chardata[$i]['type'] = 'EN'; break; } elseif ($chardata[$j]['type'] != 'ET') { break; } ++$j; } } } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } // W6. Otherwise, separators and terminators change to Other Neutral. $prevlevel = -1; $levcount = 0; for ($i=0; $i < $numchars; ++$i) { if (($chardata[$i]['type'] == 'ET') OR ($chardata[$i]['type'] == 'ES') OR ($chardata[$i]['type'] == 'CS')) { $chardata[$i]['type'] = 'ON'; } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } //W7. Search backward from each instance of a European number until the first strong type (R, L, or sor) is found. If an L is found, then change the type of the European number to L. $prevlevel = -1; $levcount = 0; for ($i=0; $i < $numchars; ++$i) { if ($chardata[$i]['char'] == 'EN') { for ($j=$levcount; $j >= 0; $j--) { if ($chardata[$j]['type'] == 'L') { $chardata[$i]['type'] = 'L'; } elseif ($chardata[$j]['type'] == 'R') { break; } } } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } // N1. A sequence of neutrals takes the direction of the surrounding strong text if the text on both sides has the same direction. European and Arabic numbers act as if they were R in terms of their influence on neutrals. Start-of-level-run (sor) and end-of-level-run (eor) are used at level run boundaries. $prevlevel = -1; $levcount = 0; for ($i=0; $i < $numchars; ++$i) { if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) { if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) { $chardata[$i]['type'] = 'L'; } elseif (($chardata[$i]['type'] == 'N') AND (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) { $chardata[$i]['type'] = 'R'; } elseif ($chardata[$i]['type'] == 'N') { // N2. Any remaining neutrals take the embedding direction $chardata[$i]['type'] = $chardata[$i]['sor']; } } elseif (($levcount == 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) { // first char if (($chardata[$i]['type'] == 'N') AND ($chardata[$i]['sor'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) { $chardata[$i]['type'] = 'L'; } elseif (($chardata[$i]['type'] == 'N') AND (($chardata[$i]['sor'] == 'R') OR ($chardata[$i]['sor'] == 'EN') OR ($chardata[$i]['sor'] == 'AN')) AND (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) { $chardata[$i]['type'] = 'R'; } elseif ($chardata[$i]['type'] == 'N') { // N2. Any remaining neutrals take the embedding direction $chardata[$i]['type'] = $chardata[$i]['sor']; } } elseif (($levcount > 0) AND ((($i+1) == $numchars) OR (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] != $prevlevel))) { //last char if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[$i]['eor'] == 'L')) { $chardata[$i]['type'] = 'L'; } elseif (($chardata[$i]['type'] == 'N') AND (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND (($chardata[$i]['eor'] == 'R') OR ($chardata[$i]['eor'] == 'EN') OR ($chardata[$i]['eor'] == 'AN'))) { $chardata[$i]['type'] = 'R'; } elseif ($chardata[$i]['type'] == 'N') { // N2. Any remaining neutrals take the embedding direction $chardata[$i]['type'] = $chardata[$i]['sor']; } } elseif ($chardata[$i]['type'] == 'N') { // N2. Any remaining neutrals take the embedding direction $chardata[$i]['type'] = $chardata[$i]['sor']; } if ($chardata[$i]['level'] != $prevlevel) { $levcount = 0; } else { ++$levcount; } $prevlevel = $chardata[$i]['level']; } // I1. For all characters with an even (left-to-right) embedding direction, those of type R go up one level and those of type AN or EN go up two levels. // I2. For all characters with an odd (right-to-left) embedding direction, those of type L, EN or AN go up one level. for ($i=0; $i < $numchars; ++$i) { $odd = $chardata[$i]['level'] % 2; if ($odd) { if (($chardata[$i]['type'] == 'L') OR ($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) { $chardata[$i]['level'] += 1; } } else { if ($chardata[$i]['type'] == 'R') { $chardata[$i]['level'] += 1; } elseif (($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) { $chardata[$i]['level'] += 2; } } $maxlevel = max($chardata[$i]['level'],$maxlevel); } // L1. On each line, reset the embedding level of the following characters to the paragraph embedding level: // 1. Segment separators, // 2. Paragraph separators, // 3. Any sequence of whitespace characters preceding a segment separator or paragraph separator, and // 4. Any sequence of white space characters at the end of the line. for ($i=0; $i < $numchars; ++$i) { if (($chardata[$i]['type'] == 'B') OR ($chardata[$i]['type'] == 'S')) { $chardata[$i]['level'] = $pel; } elseif ($chardata[$i]['type'] == 'WS') { $j = $i+1; while ($j < $numchars) { if ((($chardata[$j]['type'] == 'B') OR ($chardata[$j]['type'] == 'S')) OR (($j == ($numchars-1)) AND ($chardata[$j]['type'] == 'WS'))) { $chardata[$i]['level'] = $pel; break; } elseif ($chardata[$j]['type'] != 'WS') { break; } ++$j; } } } // Arabic Shaping // Cursively connected scripts, such as Arabic or Syriac, require the selection of positional character shapes that depend on adjacent characters. Shaping is logically applied after the Bidirectional Algorithm is used and is limited to characters within the same directional run. if ($arabic) { $endedletter = array(1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688); $alfletter = array(1570,1571,1573,1575); $chardata2 = $chardata; $laaletter = false; $charAL = array(); $x = 0; for ($i=0; $i < $numchars; ++$i) { if ((TCPDF_FONT_DATA::$uni_type[$chardata[$i]['char']] == 'AL') OR ($chardata[$i]['char'] == 32) OR ($chardata[$i]['char'] == 8204)) { $charAL[$x] = $chardata[$i]; $charAL[$x]['i'] = $i; $chardata[$i]['x'] = $x; ++$x; } } $numAL = $x; for ($i=0; $i < $numchars; ++$i) { $thischar = $chardata[$i]; if ($i > 0) { $prevchar = $chardata[($i-1)]; } else { $prevchar = false; } if (($i+1) < $numchars) { $nextchar = $chardata[($i+1)]; } else { $nextchar = false; } if (TCPDF_FONT_DATA::$uni_type[$thischar['char']] == 'AL') { $x = $thischar['x']; if ($x > 0) { $prevchar = $charAL[($x-1)]; } else { $prevchar = false; } if (($x+1) < $numAL) { $nextchar = $charAL[($x+1)]; } else { $nextchar = false; } // if laa letter if (($prevchar !== false) AND ($prevchar['char'] == 1604) AND (in_array($thischar['char'], $alfletter))) { $arabicarr = TCPDF_FONT_DATA::$uni_laa_array; $laaletter = true; if ($x > 1) { $prevchar = $charAL[($x-2)]; } else { $prevchar = false; } } else { $arabicarr = TCPDF_FONT_DATA::$uni_arabicsubst; $laaletter = false; } if (($prevchar !== false) AND ($nextchar !== false) AND ((TCPDF_FONT_DATA::$uni_type[$prevchar['char']] == 'AL') OR (TCPDF_FONT_DATA::$uni_type[$prevchar['char']] == 'NSM')) AND ((TCPDF_FONT_DATA::$uni_type[$nextchar['char']] == 'AL') OR (TCPDF_FONT_DATA::$uni_type[$nextchar['char']] == 'NSM')) AND ($prevchar['type'] == $thischar['type']) AND ($nextchar['type'] == $thischar['type']) AND ($nextchar['char'] != 1567)) { if (in_array($prevchar['char'], $endedletter)) { if (isset($arabicarr[$thischar['char']][2])) { // initial $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2]; } } else { if (isset($arabicarr[$thischar['char']][3])) { // medial $chardata2[$i]['char'] = $arabicarr[$thischar['char']][3]; } } } elseif (($nextchar !== false) AND ((TCPDF_FONT_DATA::$uni_type[$nextchar['char']] == 'AL') OR (TCPDF_FONT_DATA::$uni_type[$nextchar['char']] == 'NSM')) AND ($nextchar['type'] == $thischar['type']) AND ($nextchar['char'] != 1567)) { if (isset($arabicarr[$chardata[$i]['char']][2])) { // initial $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2]; } } elseif ((($prevchar !== false) AND ((TCPDF_FONT_DATA::$uni_type[$prevchar['char']] == 'AL') OR (TCPDF_FONT_DATA::$uni_type[$prevchar['char']] == 'NSM')) AND ($prevchar['type'] == $thischar['type'])) OR (($nextchar !== false) AND ($nextchar['char'] == 1567))) { // final if (($i > 1) AND ($thischar['char'] == 1607) AND ($chardata[$i-1]['char'] == 1604) AND ($chardata[$i-2]['char'] == 1604)) { //Allah Word // mark characters to delete with false $chardata2[$i-2]['char'] = false; $chardata2[$i-1]['char'] = false; $chardata2[$i]['char'] = 65010; } else { if (($prevchar !== false) AND in_array($prevchar['char'], $endedletter)) { if (isset($arabicarr[$thischar['char']][0])) { // isolated $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0]; } } else { if (isset($arabicarr[$thischar['char']][1])) { // final $chardata2[$i]['char'] = $arabicarr[$thischar['char']][1]; } } } } elseif (isset($arabicarr[$thischar['char']][0])) { // isolated $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0]; } // if laa letter if ($laaletter) { // mark characters to delete with false $chardata2[($charAL[($x-1)]['i'])]['char'] = false; } } // end if AL (Arabic Letter) } // end for each char /* * Combining characters that can occur with Arabic Shadda (0651 HEX, 1617 DEC) are replaced. * Putting the combining mark and shadda in the same glyph allows us to avoid the two marks overlapping each other in an illegible manner. */ for ($i = 0; $i < ($numchars-1); ++$i) { if (($chardata2[$i]['char'] == 1617) AND (isset(TCPDF_FONT_DATA::$uni_diacritics[($chardata2[$i+1]['char'])]))) { // check if the subtitution font is defined on current font if (isset($currentfont['cw'][(TCPDF_FONT_DATA::$uni_diacritics[($chardata2[$i+1]['char'])])])) { $chardata2[$i]['char'] = false; $chardata2[$i+1]['char'] = TCPDF_FONT_DATA::$uni_diacritics[($chardata2[$i+1]['char'])]; } } } // remove marked characters foreach ($chardata2 as $key => $value) { if ($value['char'] === false) { unset($chardata2[$key]); } } $chardata = array_values($chardata2); $numchars = count($chardata); unset($chardata2); unset($arabicarr); unset($laaletter); unset($charAL); } // L2. From the highest level found in the text to the lowest odd level on each line, including intermediate levels not actually present in the text, reverse any contiguous sequence of characters that are at that level or higher. for ($j=$maxlevel; $j > 0; $j--) { $ordarray = Array(); $revarr = Array(); $onlevel = false; for ($i=0; $i < $numchars; ++$i) { if ($chardata[$i]['level'] >= $j) { $onlevel = true; if (isset(TCPDF_FONT_DATA::$uni_mirror[$chardata[$i]['char']])) { // L4. A character is depicted by a mirrored glyph if and only if (a) the resolved directionality of that character is R, and (b) the Bidi_Mirrored property value of that character is true. $chardata[$i]['char'] = TCPDF_FONT_DATA::$uni_mirror[$chardata[$i]['char']]; } $revarr[] = $chardata[$i]; } else { if ($onlevel) { $revarr = array_reverse($revarr); $ordarray = array_merge($ordarray, $revarr); $revarr = Array(); $onlevel = false; } $ordarray[] = $chardata[$i]; } } if ($onlevel) { $revarr = array_reverse($revarr); $ordarray = array_merge($ordarray, $revarr); } $chardata = $ordarray; } $ordarray = array(); foreach ($chardata as $cd) { $ordarray[] = $cd['char']; // store char values for subsetting $currentfont['subsetchars'][$cd['char']] = true; } return $ordarray; } /** * Get a reference font size. * @param $size (string) String containing font size value. * @param $refsize (float) Reference font size in points. * @return float value in points * @public static */ public static function getFontRefSize($size, $refsize=12) { switch ($size) { case 'xx-small': { $size = ($refsize - 4); break; } case 'x-small': { $size = ($refsize - 3); break; } case 'small': { $size = ($refsize - 2); break; } case 'medium': { $size = $refsize; break; } case 'large': { $size = ($refsize + 2); break; } case 'x-large': { $size = ($refsize + 4); break; } case 'xx-large': { $size = ($refsize + 6); break; } case 'smaller': { $size = ($refsize - 3); break; } case 'larger': { $size = ($refsize + 3); break; } } return $size; } } // --- END OF CLASS --- //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/tcpdf_images.php000066400000000000000000000260001237252063700216500ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : // Static image methods used by the TCPDF class. // //============================================================+ /** * @file * This is a PHP class that contains static image methods for the TCPDF class.
      * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.000 */ /** * @class TCPDF_IMAGES * Static image methods used by the TCPDF class. * @package com.tecnick.tcpdf * @brief PHP class for generating PDF documents without requiring external extensions. * @version 1.0.000 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_IMAGES { /** * Array of hinheritable SVG properties. * @since 5.0.000 (2010-05-02) * @public static */ public static $svginheritprop = array('clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'fill', 'fill-opacity', 'fill-rule', 'font', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'marker', 'marker-end', 'marker-mid', 'marker-start', 'pointer-events', 'shape-rendering', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-rendering', 'visibility', 'word-spacing', 'writing-mode'); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Return the image type given the file name or array returned by getimagesize() function. * @param $imgfile (string) image file name * @param $iminfo (array) array of image information returned by getimagesize() function. * @return string image type * @since 4.8.017 (2009-11-27) * @public static */ public static function getImageFileType($imgfile, $iminfo=array()) { $type = ''; if (isset($iminfo['mime']) AND !empty($iminfo['mime'])) { $mime = explode('/', $iminfo['mime']); if ((count($mime) > 1) AND ($mime[0] == 'image') AND (!empty($mime[1]))) { $type = strtolower(trim($mime[1])); } } if (empty($type)) { $fileinfo = pathinfo($imgfile); if (isset($fileinfo['extension']) AND (!TCPDF_STATIC::empty_string($fileinfo['extension']))) { $type = strtolower(trim($fileinfo['extension'])); } } if ($type == 'jpg') { $type = 'jpeg'; } return $type; } /** * Set the transparency for the given GD image. * @param $new_image (image) GD image object * @param $image (image) GD image object. * return GD image object. * @since 4.9.016 (2010-04-20) * @public static */ public static function setGDImageTransparency($new_image, $image) { // transparency index $tid = imagecolortransparent($image); // default transparency color $tcol = array('red' => 255, 'green' => 255, 'blue' => 255); if ($tid >= 0) { // get the colors for the transparency index $tcol = imagecolorsforindex($image, $tid); } $tid = imagecolorallocate($new_image, $tcol['red'], $tcol['green'], $tcol['blue']); imagefill($new_image, 0, 0, $tid); imagecolortransparent($new_image, $tid); return $new_image; } /** * Convert the loaded image to a PNG and then return a structure for the PDF creator. * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant. * @param $image (image) Image object. * return image PNG image object. * @since 4.9.016 (2010-04-20) * @public static */ public static function _toPNG($image) { // set temporary image file name $tempname = TCPDF_STATIC::getObjFilename('png'); // turn off interlaced mode imageinterlace($image, 0); // create temporary PNG image imagepng($image, $tempname); // remove image from memory imagedestroy($image); // get PNG image data $retvars = self::_parsepng($tempname); // tidy up by removing temporary image unlink($tempname); return $retvars; } /** * Convert the loaded image to a JPEG and then return a structure for the PDF creator. * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant. * @param $image (image) Image object. * @param $quality (int) JPEG quality. * return image JPEG image object. * @public static */ public static function _toJPEG($image, $quality) { $tempname = TCPDF_STATIC::getObjFilename('jpg'); imagejpeg($image, $tempname, $quality); imagedestroy($image); $retvars = self::_parsejpeg($tempname); // tidy up by removing temporary image unlink($tempname); return $retvars; } /** * Extract info from a JPEG file without using the GD library. * @param $file (string) image file to parse * @return array structure containing the image data * @public static */ public static function _parsejpeg($file) { $a = getimagesize($file); if (empty($a)) { //Missing or incorrect image file return false; } if ($a[2] != 2) { // Not a JPEG file return false; } // bits per pixel $bpc = isset($a['bits']) ? intval($a['bits']) : 8; // number of image channels if (!isset($a['channels'])) { $channels = 3; } else { $channels = intval($a['channels']); } // default colour space switch ($channels) { case 1: { $colspace = 'DeviceGray'; break; } case 3: { $colspace = 'DeviceRGB'; break; } case 4: { $colspace = 'DeviceCMYK'; break; } default: { $channels = 3; $colspace = 'DeviceRGB'; break; } } // get file content $data = file_get_contents($file); // check for embedded ICC profile $icc = array(); $offset = 0; while (($pos = strpos($data, "ICC_PROFILE\0", $offset)) !== false) { // get ICC sequence length $length = (TCPDF_STATIC::_getUSHORT($data, ($pos - 2)) - 16); // marker sequence number $msn = max(1, ord($data[($pos + 12)])); // number of markers (total of APP2 used) $nom = max(1, ord($data[($pos + 13)])); // get sequence segment $icc[($msn - 1)] = substr($data, ($pos + 14), $length); // move forward to next sequence $offset = ($pos + 14 + $length); } // order and compact ICC segments if (count($icc) > 0) { ksort($icc); $icc = implode('', $icc); if ((ord($icc{36}) != 0x61) OR (ord($icc{37}) != 0x63) OR (ord($icc{38}) != 0x73) OR (ord($icc{39}) != 0x70)) { // invalid ICC profile $icc = false; } } else { $icc = false; } return array('w' => $a[0], 'h' => $a[1], 'ch' => $channels, 'icc' => $icc, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data); } /** * Extract info from a PNG file without using the GD library. * @param $file (string) image file to parse * @return array structure containing the image data * @public static */ public static function _parsepng($file) { $f = fopen($file, 'rb'); if ($f === false) { // Can't open image file return false; } //Check signature if (fread($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) { // Not a PNG file return false; } //Read header chunk fread($f, 4); if (fread($f, 4) != 'IHDR') { //Incorrect PNG file return false; } $w = TCPDF_STATIC::_freadint($f); $h = TCPDF_STATIC::_freadint($f); $bpc = ord(fread($f, 1)); if ($bpc > 8) { // 16-bit depth not supported fclose($f); return false; } $ct = ord(fread($f, 1)); if ($ct == 0) { $colspace = 'DeviceGray'; } elseif ($ct == 2) { $colspace = 'DeviceRGB'; } elseif ($ct == 3) { $colspace = 'Indexed'; } else { // alpha channel fclose($f); return 'pngalpha'; } if (ord(fread($f, 1)) != 0) { // Unknown compression method fclose($f); return false; } if (ord(fread($f, 1)) != 0) { // Unknown filter method fclose($f); return false; } if (ord(fread($f, 1)) != 0) { // Interlacing not supported fclose($f); return false; } fread($f, 4); $channels = ($ct == 2 ? 3 : 1); $parms = '/DecodeParms << /Predictor 15 /Colors '.$channels.' /BitsPerComponent '.$bpc.' /Columns '.$w.' >>'; //Scan chunks looking for palette, transparency and image data $pal = ''; $trns = ''; $data = ''; $icc = false; do { $n = TCPDF_STATIC::_freadint($f); $type = fread($f, 4); if ($type == 'PLTE') { // read palette $pal = TCPDF_STATIC::rfread($f, $n); fread($f, 4); } elseif ($type == 'tRNS') { // read transparency info $t = TCPDF_STATIC::rfread($f, $n); if ($ct == 0) { $trns = array(ord($t{1})); } elseif ($ct == 2) { $trns = array(ord($t{1}), ord($t{3}), ord($t{5})); } else { $pos = strpos($t, chr(0)); if ($pos !== false) { $trns = array($pos); } } fread($f, 4); } elseif ($type == 'IDAT') { // read image data block $data .= TCPDF_STATIC::rfread($f, $n); fread($f, 4); } elseif ($type == 'iCCP') { // skip profile name $len = 0; while ((ord(fread($f, 1)) > 0) AND ($len < 80)) { ++$len; } // skip null separator fread($f, 1); // get compression method if (ord(fread($f, 1)) != 0) { // Unknown filter method fclose($f); return false; } // read ICC Color Profile $icc = TCPDF_STATIC::rfread($f, ($n - $len - 2)); // decompress profile $icc = gzuncompress($icc); fread($f, 4); } elseif ($type == 'IEND') { break; } else { TCPDF_STATIC::rfread($f, $n + 4); } } while ($n); if (($colspace == 'Indexed') AND (empty($pal))) { // Missing palette fclose($f); return false; } fclose($f); return array('w' => $w, 'h' => $h, 'ch' => $channels, 'icc' => $icc, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data); } } // END OF TCPDF_STATIC CLASS //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/include/tcpdf_static.php000066400000000000000000003100151237252063700216740ustar00rootroot00000000000000. // // See LICENSE.TXT file for more information. // ------------------------------------------------------------------- // // Description : // Static methods used by the TCPDF class. // //============================================================+ /** * @file * This is a PHP class that contains static methods for the TCPDF class.
      * @package com.tecnick.tcpdf * @author Nicola Asuni * @version 1.0.000 */ /** * @class TCPDF_STATIC * Static methods used by the TCPDF class. * @package com.tecnick.tcpdf * @brief PHP class for generating PDF documents without requiring external extensions. * @version 1.0.000 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_STATIC { /** * Current TCPDF version. * @private static */ private static $tcpdf_version = '6.0.011'; /** * String alias for total number of pages. * @public static */ public static $alias_tot_pages = '{:ptp:}'; /** * String alias for page number. * @public static */ public static $alias_num_page = '{:pnp:}'; /** * String alias for total number of pages in a single group. * @public static */ public static $alias_group_tot_pages = '{:ptg:}'; /** * String alias for group page number. * @public static */ public static $alias_group_num_page = '{:png:}'; /** * String alias for right shift compensation used to correctly align page numbers on the right. * @public static */ public static $alias_right_shift = '{rsc:'; /** * Encryption padding string. * @public static */ public static $enc_padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A"; /** * ByteRange placemark used during digital signature process. * @since 4.6.028 (2009-08-25) * @public static */ public static $byterange_string = '/ByteRange[0 ********** ********** **********]'; /** * Array page boxes names * @public static */ public static $pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /** * Return the current TCPDF version. * @return TCPDF version string * @since 5.9.012 (2010-11-10) * @public static */ public static function getTCPDFVersion() { return self::$tcpdf_version; } /** * Return the current TCPDF producer. * @return TCPDF producer string * @since 6.0.000 (2013-03-16) * @public static */ public static function getTCPDFProducer() { return "\x54\x43\x50\x44\x46\x20".self::getTCPDFVersion()."\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29"; } /** * Sets the current active configuration setting of magic_quotes_runtime (if the set_magic_quotes_runtime function exist) * @param $mqr (boolean) FALSE for off, TRUE for on. * @since 4.6.025 (2009-08-17) * @public static */ public static function set_mqr($mqr) { if (!defined('PHP_VERSION_ID')) { $version = PHP_VERSION; define('PHP_VERSION_ID', (($version{0} * 10000) + ($version{2} * 100) + $version{4})); } if (PHP_VERSION_ID < 50300) { @set_magic_quotes_runtime($mqr); } } /** * Gets the current active configuration setting of magic_quotes_runtime (if the get_magic_quotes_runtime function exist) * @return Returns 0 if magic quotes runtime is off or get_magic_quotes_runtime doesn't exist, 1 otherwise. * @since 4.6.025 (2009-08-17) * @public static */ public static function get_mqr() { if (!defined('PHP_VERSION_ID')) { $version = PHP_VERSION; define('PHP_VERSION_ID', (($version{0} * 10000) + ($version{2} * 100) + $version{4})); } if (PHP_VERSION_ID < 50300) { return @get_magic_quotes_runtime(); } return 0; } /** * Get page dimensions from format name. * @param $format (mixed) The format name. It can be:
        *
      • ISO 216 A Series + 2 SIS 014711 extensions
      • *
      • A0 (841x1189 mm ; 33.11x46.81 in)
      • *
      • A1 (594x841 mm ; 23.39x33.11 in)
      • *
      • A2 (420x594 mm ; 16.54x23.39 in)
      • *
      • A3 (297x420 mm ; 11.69x16.54 in)
      • *
      • A4 (210x297 mm ; 8.27x11.69 in)
      • *
      • A5 (148x210 mm ; 5.83x8.27 in)
      • *
      • A6 (105x148 mm ; 4.13x5.83 in)
      • *
      • A7 (74x105 mm ; 2.91x4.13 in)
      • *
      • A8 (52x74 mm ; 2.05x2.91 in)
      • *
      • A9 (37x52 mm ; 1.46x2.05 in)
      • *
      • A10 (26x37 mm ; 1.02x1.46 in)
      • *
      • A11 (18x26 mm ; 0.71x1.02 in)
      • *
      • A12 (13x18 mm ; 0.51x0.71 in)
      • *
      • ISO 216 B Series + 2 SIS 014711 extensions
      • *
      • B0 (1000x1414 mm ; 39.37x55.67 in)
      • *
      • B1 (707x1000 mm ; 27.83x39.37 in)
      • *
      • B2 (500x707 mm ; 19.69x27.83 in)
      • *
      • B3 (353x500 mm ; 13.90x19.69 in)
      • *
      • B4 (250x353 mm ; 9.84x13.90 in)
      • *
      • B5 (176x250 mm ; 6.93x9.84 in)
      • *
      • B6 (125x176 mm ; 4.92x6.93 in)
      • *
      • B7 (88x125 mm ; 3.46x4.92 in)
      • *
      • B8 (62x88 mm ; 2.44x3.46 in)
      • *
      • B9 (44x62 mm ; 1.73x2.44 in)
      • *
      • B10 (31x44 mm ; 1.22x1.73 in)
      • *
      • B11 (22x31 mm ; 0.87x1.22 in)
      • *
      • B12 (15x22 mm ; 0.59x0.87 in)
      • *
      • ISO 216 C Series + 2 SIS 014711 extensions + 2 EXTENSION
      • *
      • C0 (917x1297 mm ; 36.10x51.06 in)
      • *
      • C1 (648x917 mm ; 25.51x36.10 in)
      • *
      • C2 (458x648 mm ; 18.03x25.51 in)
      • *
      • C3 (324x458 mm ; 12.76x18.03 in)
      • *
      • C4 (229x324 mm ; 9.02x12.76 in)
      • *
      • C5 (162x229 mm ; 6.38x9.02 in)
      • *
      • C6 (114x162 mm ; 4.49x6.38 in)
      • *
      • C7 (81x114 mm ; 3.19x4.49 in)
      • *
      • C8 (57x81 mm ; 2.24x3.19 in)
      • *
      • C9 (40x57 mm ; 1.57x2.24 in)
      • *
      • C10 (28x40 mm ; 1.10x1.57 in)
      • *
      • C11 (20x28 mm ; 0.79x1.10 in)
      • *
      • C12 (14x20 mm ; 0.55x0.79 in)
      • *
      • C76 (81x162 mm ; 3.19x6.38 in)
      • *
      • DL (110x220 mm ; 4.33x8.66 in)
      • *
      • SIS 014711 E Series
      • *
      • E0 (879x1241 mm ; 34.61x48.86 in)
      • *
      • E1 (620x879 mm ; 24.41x34.61 in)
      • *
      • E2 (440x620 mm ; 17.32x24.41 in)
      • *
      • E3 (310x440 mm ; 12.20x17.32 in)
      • *
      • E4 (220x310 mm ; 8.66x12.20 in)
      • *
      • E5 (155x220 mm ; 6.10x8.66 in)
      • *
      • E6 (110x155 mm ; 4.33x6.10 in)
      • *
      • E7 (78x110 mm ; 3.07x4.33 in)
      • *
      • E8 (55x78 mm ; 2.17x3.07 in)
      • *
      • E9 (39x55 mm ; 1.54x2.17 in)
      • *
      • E10 (27x39 mm ; 1.06x1.54 in)
      • *
      • E11 (19x27 mm ; 0.75x1.06 in)
      • *
      • E12 (13x19 mm ; 0.51x0.75 in)
      • *
      • SIS 014711 G Series
      • *
      • G0 (958x1354 mm ; 37.72x53.31 in)
      • *
      • G1 (677x958 mm ; 26.65x37.72 in)
      • *
      • G2 (479x677 mm ; 18.86x26.65 in)
      • *
      • G3 (338x479 mm ; 13.31x18.86 in)
      • *
      • G4 (239x338 mm ; 9.41x13.31 in)
      • *
      • G5 (169x239 mm ; 6.65x9.41 in)
      • *
      • G6 (119x169 mm ; 4.69x6.65 in)
      • *
      • G7 (84x119 mm ; 3.31x4.69 in)
      • *
      • G8 (59x84 mm ; 2.32x3.31 in)
      • *
      • G9 (42x59 mm ; 1.65x2.32 in)
      • *
      • G10 (29x42 mm ; 1.14x1.65 in)
      • *
      • G11 (21x29 mm ; 0.83x1.14 in)
      • *
      • G12 (14x21 mm ; 0.55x0.83 in)
      • *
      • ISO Press
      • *
      • RA0 (860x1220 mm ; 33.86x48.03 in)
      • *
      • RA1 (610x860 mm ; 24.02x33.86 in)
      • *
      • RA2 (430x610 mm ; 16.93x24.02 in)
      • *
      • RA3 (305x430 mm ; 12.01x16.93 in)
      • *
      • RA4 (215x305 mm ; 8.46x12.01 in)
      • *
      • SRA0 (900x1280 mm ; 35.43x50.39 in)
      • *
      • SRA1 (640x900 mm ; 25.20x35.43 in)
      • *
      • SRA2 (450x640 mm ; 17.72x25.20 in)
      • *
      • SRA3 (320x450 mm ; 12.60x17.72 in)
      • *
      • SRA4 (225x320 mm ; 8.86x12.60 in)
      • *
      • German DIN 476
      • *
      • 4A0 (1682x2378 mm ; 66.22x93.62 in)
      • *
      • 2A0 (1189x1682 mm ; 46.81x66.22 in)
      • *
      • Variations on the ISO Standard
      • *
      • A2_EXTRA (445x619 mm ; 17.52x24.37 in)
      • *
      • A3+ (329x483 mm ; 12.95x19.02 in)
      • *
      • A3_EXTRA (322x445 mm ; 12.68x17.52 in)
      • *
      • A3_SUPER (305x508 mm ; 12.01x20.00 in)
      • *
      • SUPER_A3 (305x487 mm ; 12.01x19.17 in)
      • *
      • A4_EXTRA (235x322 mm ; 9.25x12.68 in)
      • *
      • A4_SUPER (229x322 mm ; 9.02x12.68 in)
      • *
      • SUPER_A4 (227x356 mm ; 8.94x14.02 in)
      • *
      • A4_LONG (210x348 mm ; 8.27x13.70 in)
      • *
      • F4 (210x330 mm ; 8.27x12.99 in)
      • *
      • SO_B5_EXTRA (202x276 mm ; 7.95x10.87 in)
      • *
      • A5_EXTRA (173x235 mm ; 6.81x9.25 in)
      • *
      • ANSI Series
      • *
      • ANSI_E (864x1118 mm ; 34.00x44.00 in)
      • *
      • ANSI_D (559x864 mm ; 22.00x34.00 in)
      • *
      • ANSI_C (432x559 mm ; 17.00x22.00 in)
      • *
      • ANSI_B (279x432 mm ; 11.00x17.00 in)
      • *
      • ANSI_A (216x279 mm ; 8.50x11.00 in)
      • *
      • Traditional 'Loose' North American Paper Sizes
      • *
      • LEDGER, USLEDGER (432x279 mm ; 17.00x11.00 in)
      • *
      • TABLOID, USTABLOID, BIBLE, ORGANIZERK (279x432 mm ; 11.00x17.00 in)
      • *
      • LETTER, USLETTER, ORGANIZERM (216x279 mm ; 8.50x11.00 in)
      • *
      • LEGAL, USLEGAL (216x356 mm ; 8.50x14.00 in)
      • *
      • GLETTER, GOVERNMENTLETTER (203x267 mm ; 8.00x10.50 in)
      • *
      • JLEGAL, JUNIORLEGAL (203x127 mm ; 8.00x5.00 in)
      • *
      • Other North American Paper Sizes
      • *
      • QUADDEMY (889x1143 mm ; 35.00x45.00 in)
      • *
      • SUPER_B (330x483 mm ; 13.00x19.00 in)
      • *
      • QUARTO (229x279 mm ; 9.00x11.00 in)
      • *
      • FOLIO, GOVERNMENTLEGAL (216x330 mm ; 8.50x13.00 in)
      • *
      • EXECUTIVE, MONARCH (184x267 mm ; 7.25x10.50 in)
      • *
      • MEMO, STATEMENT, ORGANIZERL (140x216 mm ; 5.50x8.50 in)
      • *
      • FOOLSCAP (210x330 mm ; 8.27x13.00 in)
      • *
      • COMPACT (108x171 mm ; 4.25x6.75 in)
      • *
      • ORGANIZERJ (70x127 mm ; 2.75x5.00 in)
      • *
      • Canadian standard CAN 2-9.60M
      • *
      • P1 (560x860 mm ; 22.05x33.86 in)
      • *
      • P2 (430x560 mm ; 16.93x22.05 in)
      • *
      • P3 (280x430 mm ; 11.02x16.93 in)
      • *
      • P4 (215x280 mm ; 8.46x11.02 in)
      • *
      • P5 (140x215 mm ; 5.51x8.46 in)
      • *
      • P6 (107x140 mm ; 4.21x5.51 in)
      • *
      • North American Architectural Sizes
      • *
      • ARCH_E (914x1219 mm ; 36.00x48.00 in)
      • *
      • ARCH_E1 (762x1067 mm ; 30.00x42.00 in)
      • *
      • ARCH_D (610x914 mm ; 24.00x36.00 in)
      • *
      • ARCH_C, BROADSHEET (457x610 mm ; 18.00x24.00 in)
      • *
      • ARCH_B (305x457 mm ; 12.00x18.00 in)
      • *
      • ARCH_A (229x305 mm ; 9.00x12.00 in)
      • *
      • Announcement Envelopes
      • *
      • ANNENV_A2 (111x146 mm ; 4.37x5.75 in)
      • *
      • ANNENV_A6 (121x165 mm ; 4.75x6.50 in)
      • *
      • ANNENV_A7 (133x184 mm ; 5.25x7.25 in)
      • *
      • ANNENV_A8 (140x206 mm ; 5.50x8.12 in)
      • *
      • ANNENV_A10 (159x244 mm ; 6.25x9.62 in)
      • *
      • ANNENV_SLIM (98x225 mm ; 3.87x8.87 in)
      • *
      • Commercial Envelopes
      • *
      • COMMENV_N6_1/4 (89x152 mm ; 3.50x6.00 in)
      • *
      • COMMENV_N6_3/4 (92x165 mm ; 3.62x6.50 in)
      • *
      • COMMENV_N8 (98x191 mm ; 3.87x7.50 in)
      • *
      • COMMENV_N9 (98x225 mm ; 3.87x8.87 in)
      • *
      • COMMENV_N10 (105x241 mm ; 4.12x9.50 in)
      • *
      • COMMENV_N11 (114x263 mm ; 4.50x10.37 in)
      • *
      • COMMENV_N12 (121x279 mm ; 4.75x11.00 in)
      • *
      • COMMENV_N14 (127x292 mm ; 5.00x11.50 in)
      • *
      • Catalogue Envelopes
      • *
      • CATENV_N1 (152x229 mm ; 6.00x9.00 in)
      • *
      • CATENV_N1_3/4 (165x241 mm ; 6.50x9.50 in)
      • *
      • CATENV_N2 (165x254 mm ; 6.50x10.00 in)
      • *
      • CATENV_N3 (178x254 mm ; 7.00x10.00 in)
      • *
      • CATENV_N6 (191x267 mm ; 7.50x10.50 in)
      • *
      • CATENV_N7 (203x279 mm ; 8.00x11.00 in)
      • *
      • CATENV_N8 (210x286 mm ; 8.25x11.25 in)
      • *
      • CATENV_N9_1/2 (216x267 mm ; 8.50x10.50 in)
      • *
      • CATENV_N9_3/4 (222x286 mm ; 8.75x11.25 in)
      • *
      • CATENV_N10_1/2 (229x305 mm ; 9.00x12.00 in)
      • *
      • CATENV_N12_1/2 (241x318 mm ; 9.50x12.50 in)
      • *
      • CATENV_N13_1/2 (254x330 mm ; 10.00x13.00 in)
      • *
      • CATENV_N14_1/4 (286x311 mm ; 11.25x12.25 in)
      • *
      • CATENV_N14_1/2 (292x368 mm ; 11.50x14.50 in)
      • *
      • Japanese (JIS P 0138-61) Standard B-Series
      • *
      • JIS_B0 (1030x1456 mm ; 40.55x57.32 in)
      • *
      • JIS_B1 (728x1030 mm ; 28.66x40.55 in)
      • *
      • JIS_B2 (515x728 mm ; 20.28x28.66 in)
      • *
      • JIS_B3 (364x515 mm ; 14.33x20.28 in)
      • *
      • JIS_B4 (257x364 mm ; 10.12x14.33 in)
      • *
      • JIS_B5 (182x257 mm ; 7.17x10.12 in)
      • *
      • JIS_B6 (128x182 mm ; 5.04x7.17 in)
      • *
      • JIS_B7 (91x128 mm ; 3.58x5.04 in)
      • *
      • JIS_B8 (64x91 mm ; 2.52x3.58 in)
      • *
      • JIS_B9 (45x64 mm ; 1.77x2.52 in)
      • *
      • JIS_B10 (32x45 mm ; 1.26x1.77 in)
      • *
      • JIS_B11 (22x32 mm ; 0.87x1.26 in)
      • *
      • JIS_B12 (16x22 mm ; 0.63x0.87 in)
      • *
      • PA Series
      • *
      • PA0 (840x1120 mm ; 33.07x44.09 in)
      • *
      • PA1 (560x840 mm ; 22.05x33.07 in)
      • *
      • PA2 (420x560 mm ; 16.54x22.05 in)
      • *
      • PA3 (280x420 mm ; 11.02x16.54 in)
      • *
      • PA4 (210x280 mm ; 8.27x11.02 in)
      • *
      • PA5 (140x210 mm ; 5.51x8.27 in)
      • *
      • PA6 (105x140 mm ; 4.13x5.51 in)
      • *
      • PA7 (70x105 mm ; 2.76x4.13 in)
      • *
      • PA8 (52x70 mm ; 2.05x2.76 in)
      • *
      • PA9 (35x52 mm ; 1.38x2.05 in)
      • *
      • PA10 (26x35 mm ; 1.02x1.38 in)
      • *
      • Standard Photographic Print Sizes
      • *
      • PASSPORT_PHOTO (35x45 mm ; 1.38x1.77 in)
      • *
      • E (82x120 mm ; 3.25x4.72 in)
      • *
      • 3R, L (89x127 mm ; 3.50x5.00 in)
      • *
      • 4R, KG (102x152 mm ; 4.02x5.98 in)
      • *
      • 4D (120x152 mm ; 4.72x5.98 in)
      • *
      • 5R, 2L (127x178 mm ; 5.00x7.01 in)
      • *
      • 6R, 8P (152x203 mm ; 5.98x7.99 in)
      • *
      • 8R, 6P (203x254 mm ; 7.99x10.00 in)
      • *
      • S8R, 6PW (203x305 mm ; 7.99x12.01 in)
      • *
      • 10R, 4P (254x305 mm ; 10.00x12.01 in)
      • *
      • S10R, 4PW (254x381 mm ; 10.00x15.00 in)
      • *
      • 11R (279x356 mm ; 10.98x14.02 in)
      • *
      • S11R (279x432 mm ; 10.98x17.01 in)
      • *
      • 12R (305x381 mm ; 12.01x15.00 in)
      • *
      • S12R (305x456 mm ; 12.01x17.95 in)
      • *
      • Common Newspaper Sizes
      • *
      • NEWSPAPER_BROADSHEET (750x600 mm ; 29.53x23.62 in)
      • *
      • NEWSPAPER_BERLINER (470x315 mm ; 18.50x12.40 in)
      • *
      • NEWSPAPER_COMPACT, NEWSPAPER_TABLOID (430x280 mm ; 16.93x11.02 in)
      • *
      • Business Cards
      • *
      • CREDIT_CARD, BUSINESS_CARD, BUSINESS_CARD_ISO7810 (54x86 mm ; 2.13x3.37 in)
      • *
      • BUSINESS_CARD_ISO216 (52x74 mm ; 2.05x2.91 in)
      • *
      • BUSINESS_CARD_IT, BUSINESS_CARD_UK, BUSINESS_CARD_FR, BUSINESS_CARD_DE, BUSINESS_CARD_ES (55x85 mm ; 2.17x3.35 in)
      • *
      • BUSINESS_CARD_US, BUSINESS_CARD_CA (51x89 mm ; 2.01x3.50 in)
      • *
      • BUSINESS_CARD_JP (55x91 mm ; 2.17x3.58 in)
      • *
      • BUSINESS_CARD_HK (54x90 mm ; 2.13x3.54 in)
      • *
      • BUSINESS_CARD_AU, BUSINESS_CARD_DK, BUSINESS_CARD_SE (55x90 mm ; 2.17x3.54 in)
      • *
      • BUSINESS_CARD_RU, BUSINESS_CARD_CZ, BUSINESS_CARD_FI, BUSINESS_CARD_HU, BUSINESS_CARD_IL (50x90 mm ; 1.97x3.54 in)
      • *
      • Billboards
      • *
      • 4SHEET (1016x1524 mm ; 40.00x60.00 in)
      • *
      • 6SHEET (1200x1800 mm ; 47.24x70.87 in)
      • *
      • 12SHEET (3048x1524 mm ; 120.00x60.00 in)
      • *
      • 16SHEET (2032x3048 mm ; 80.00x120.00 in)
      • *
      • 32SHEET (4064x3048 mm ; 160.00x120.00 in)
      • *
      • 48SHEET (6096x3048 mm ; 240.00x120.00 in)
      • *
      • 64SHEET (8128x3048 mm ; 320.00x120.00 in)
      • *
      • 96SHEET (12192x3048 mm ; 480.00x120.00 in)
      • *
      • Old Imperial English (some are still used in USA)
      • *
      • EN_EMPEROR (1219x1829 mm ; 48.00x72.00 in)
      • *
      • EN_ANTIQUARIAN (787x1346 mm ; 31.00x53.00 in)
      • *
      • EN_GRAND_EAGLE (730x1067 mm ; 28.75x42.00 in)
      • *
      • EN_DOUBLE_ELEPHANT (679x1016 mm ; 26.75x40.00 in)
      • *
      • EN_ATLAS (660x864 mm ; 26.00x34.00 in)
      • *
      • EN_COLOMBIER (597x876 mm ; 23.50x34.50 in)
      • *
      • EN_ELEPHANT (584x711 mm ; 23.00x28.00 in)
      • *
      • EN_DOUBLE_DEMY (572x902 mm ; 22.50x35.50 in)
      • *
      • EN_IMPERIAL (559x762 mm ; 22.00x30.00 in)
      • *
      • EN_PRINCESS (546x711 mm ; 21.50x28.00 in)
      • *
      • EN_CARTRIDGE (533x660 mm ; 21.00x26.00 in)
      • *
      • EN_DOUBLE_LARGE_POST (533x838 mm ; 21.00x33.00 in)
      • *
      • EN_ROYAL (508x635 mm ; 20.00x25.00 in)
      • *
      • EN_SHEET, EN_HALF_POST (495x597 mm ; 19.50x23.50 in)
      • *
      • EN_SUPER_ROYAL (483x686 mm ; 19.00x27.00 in)
      • *
      • EN_DOUBLE_POST (483x775 mm ; 19.00x30.50 in)
      • *
      • EN_MEDIUM (445x584 mm ; 17.50x23.00 in)
      • *
      • EN_DEMY (445x572 mm ; 17.50x22.50 in)
      • *
      • EN_LARGE_POST (419x533 mm ; 16.50x21.00 in)
      • *
      • EN_COPY_DRAUGHT (406x508 mm ; 16.00x20.00 in)
      • *
      • EN_POST (394x489 mm ; 15.50x19.25 in)
      • *
      • EN_CROWN (381x508 mm ; 15.00x20.00 in)
      • *
      • EN_PINCHED_POST (375x470 mm ; 14.75x18.50 in)
      • *
      • EN_BRIEF (343x406 mm ; 13.50x16.00 in)
      • *
      • EN_FOOLSCAP (343x432 mm ; 13.50x17.00 in)
      • *
      • EN_SMALL_FOOLSCAP (337x419 mm ; 13.25x16.50 in)
      • *
      • EN_POTT (318x381 mm ; 12.50x15.00 in)
      • *
      • Old Imperial Belgian
      • *
      • BE_GRAND_AIGLE (700x1040 mm ; 27.56x40.94 in)
      • *
      • BE_COLOMBIER (620x850 mm ; 24.41x33.46 in)
      • *
      • BE_DOUBLE_CARRE (620x920 mm ; 24.41x36.22 in)
      • *
      • BE_ELEPHANT (616x770 mm ; 24.25x30.31 in)
      • *
      • BE_PETIT_AIGLE (600x840 mm ; 23.62x33.07 in)
      • *
      • BE_GRAND_JESUS (550x730 mm ; 21.65x28.74 in)
      • *
      • BE_JESUS (540x730 mm ; 21.26x28.74 in)
      • *
      • BE_RAISIN (500x650 mm ; 19.69x25.59 in)
      • *
      • BE_GRAND_MEDIAN (460x605 mm ; 18.11x23.82 in)
      • *
      • BE_DOUBLE_POSTE (435x565 mm ; 17.13x22.24 in)
      • *
      • BE_COQUILLE (430x560 mm ; 16.93x22.05 in)
      • *
      • BE_PETIT_MEDIAN (415x530 mm ; 16.34x20.87 in)
      • *
      • BE_RUCHE (360x460 mm ; 14.17x18.11 in)
      • *
      • BE_PROPATRIA (345x430 mm ; 13.58x16.93 in)
      • *
      • BE_LYS (317x397 mm ; 12.48x15.63 in)
      • *
      • BE_POT (307x384 mm ; 12.09x15.12 in)
      • *
      • BE_ROSETTE (270x347 mm ; 10.63x13.66 in)
      • *
      • Old Imperial French
      • *
      • FR_UNIVERS (1000x1300 mm ; 39.37x51.18 in)
      • *
      • FR_DOUBLE_COLOMBIER (900x1260 mm ; 35.43x49.61 in)
      • *
      • FR_GRANDE_MONDE (900x1260 mm ; 35.43x49.61 in)
      • *
      • FR_DOUBLE_SOLEIL (800x1200 mm ; 31.50x47.24 in)
      • *
      • FR_DOUBLE_JESUS (760x1120 mm ; 29.92x44.09 in)
      • *
      • FR_GRAND_AIGLE (750x1060 mm ; 29.53x41.73 in)
      • *
      • FR_PETIT_AIGLE (700x940 mm ; 27.56x37.01 in)
      • *
      • FR_DOUBLE_RAISIN (650x1000 mm ; 25.59x39.37 in)
      • *
      • FR_JOURNAL (650x940 mm ; 25.59x37.01 in)
      • *
      • FR_COLOMBIER_AFFICHE (630x900 mm ; 24.80x35.43 in)
      • *
      • FR_DOUBLE_CAVALIER (620x920 mm ; 24.41x36.22 in)
      • *
      • FR_CLOCHE (600x800 mm ; 23.62x31.50 in)
      • *
      • FR_SOLEIL (600x800 mm ; 23.62x31.50 in)
      • *
      • FR_DOUBLE_CARRE (560x900 mm ; 22.05x35.43 in)
      • *
      • FR_DOUBLE_COQUILLE (560x880 mm ; 22.05x34.65 in)
      • *
      • FR_JESUS (560x760 mm ; 22.05x29.92 in)
      • *
      • FR_RAISIN (500x650 mm ; 19.69x25.59 in)
      • *
      • FR_CAVALIER (460x620 mm ; 18.11x24.41 in)
      • *
      • FR_DOUBLE_COURONNE (460x720 mm ; 18.11x28.35 in)
      • *
      • FR_CARRE (450x560 mm ; 17.72x22.05 in)
      • *
      • FR_COQUILLE (440x560 mm ; 17.32x22.05 in)
      • *
      • FR_DOUBLE_TELLIERE (440x680 mm ; 17.32x26.77 in)
      • *
      • FR_DOUBLE_CLOCHE (400x600 mm ; 15.75x23.62 in)
      • *
      • FR_DOUBLE_POT (400x620 mm ; 15.75x24.41 in)
      • *
      • FR_ECU (400x520 mm ; 15.75x20.47 in)
      • *
      • FR_COURONNE (360x460 mm ; 14.17x18.11 in)
      • *
      • FR_TELLIERE (340x440 mm ; 13.39x17.32 in)
      • *
      • FR_POT (310x400 mm ; 12.20x15.75 in)
      • *
      * @return array containing page width and height in points * @since 5.0.010 (2010-05-17) * @public static */ public static function getPageSizeFromFormat($format) { // Paper cordinates are calculated in this way: (inches * 72) where (1 inch = 25.4 mm) switch (strtoupper($format)) { // ISO 216 A Series + 2 SIS 014711 extensions case 'A0' : {$pf = array( 2383.937, 3370.394); break;} case 'A1' : {$pf = array( 1683.780, 2383.937); break;} case 'A2' : {$pf = array( 1190.551, 1683.780); break;} case 'A3' : {$pf = array( 841.890, 1190.551); break;} case 'A4' : {$pf = array( 595.276, 841.890); break;} case 'A5' : {$pf = array( 419.528, 595.276); break;} case 'A6' : {$pf = array( 297.638, 419.528); break;} case 'A7' : {$pf = array( 209.764, 297.638); break;} case 'A8' : {$pf = array( 147.402, 209.764); break;} case 'A9' : {$pf = array( 104.882, 147.402); break;} case 'A10': {$pf = array( 73.701, 104.882); break;} case 'A11': {$pf = array( 51.024, 73.701); break;} case 'A12': {$pf = array( 36.850, 51.024); break;} // ISO 216 B Series + 2 SIS 014711 extensions case 'B0' : {$pf = array( 2834.646, 4008.189); break;} case 'B1' : {$pf = array( 2004.094, 2834.646); break;} case 'B2' : {$pf = array( 1417.323, 2004.094); break;} case 'B3' : {$pf = array( 1000.630, 1417.323); break;} case 'B4' : {$pf = array( 708.661, 1000.630); break;} case 'B5' : {$pf = array( 498.898, 708.661); break;} case 'B6' : {$pf = array( 354.331, 498.898); break;} case 'B7' : {$pf = array( 249.449, 354.331); break;} case 'B8' : {$pf = array( 175.748, 249.449); break;} case 'B9' : {$pf = array( 124.724, 175.748); break;} case 'B10': {$pf = array( 87.874, 124.724); break;} case 'B11': {$pf = array( 62.362, 87.874); break;} case 'B12': {$pf = array( 42.520, 62.362); break;} // ISO 216 C Series + 2 SIS 014711 extensions + 2 EXTENSION case 'C0' : {$pf = array( 2599.370, 3676.535); break;} case 'C1' : {$pf = array( 1836.850, 2599.370); break;} case 'C2' : {$pf = array( 1298.268, 1836.850); break;} case 'C3' : {$pf = array( 918.425, 1298.268); break;} case 'C4' : {$pf = array( 649.134, 918.425); break;} case 'C5' : {$pf = array( 459.213, 649.134); break;} case 'C6' : {$pf = array( 323.150, 459.213); break;} case 'C7' : {$pf = array( 229.606, 323.150); break;} case 'C8' : {$pf = array( 161.575, 229.606); break;} case 'C9' : {$pf = array( 113.386, 161.575); break;} case 'C10': {$pf = array( 79.370, 113.386); break;} case 'C11': {$pf = array( 56.693, 79.370); break;} case 'C12': {$pf = array( 39.685, 56.693); break;} case 'C76': {$pf = array( 229.606, 459.213); break;} case 'DL' : {$pf = array( 311.811, 623.622); break;} // SIS 014711 E Series case 'E0' : {$pf = array( 2491.654, 3517.795); break;} case 'E1' : {$pf = array( 1757.480, 2491.654); break;} case 'E2' : {$pf = array( 1247.244, 1757.480); break;} case 'E3' : {$pf = array( 878.740, 1247.244); break;} case 'E4' : {$pf = array( 623.622, 878.740); break;} case 'E5' : {$pf = array( 439.370, 623.622); break;} case 'E6' : {$pf = array( 311.811, 439.370); break;} case 'E7' : {$pf = array( 221.102, 311.811); break;} case 'E8' : {$pf = array( 155.906, 221.102); break;} case 'E9' : {$pf = array( 110.551, 155.906); break;} case 'E10': {$pf = array( 76.535, 110.551); break;} case 'E11': {$pf = array( 53.858, 76.535); break;} case 'E12': {$pf = array( 36.850, 53.858); break;} // SIS 014711 G Series case 'G0' : {$pf = array( 2715.591, 3838.110); break;} case 'G1' : {$pf = array( 1919.055, 2715.591); break;} case 'G2' : {$pf = array( 1357.795, 1919.055); break;} case 'G3' : {$pf = array( 958.110, 1357.795); break;} case 'G4' : {$pf = array( 677.480, 958.110); break;} case 'G5' : {$pf = array( 479.055, 677.480); break;} case 'G6' : {$pf = array( 337.323, 479.055); break;} case 'G7' : {$pf = array( 238.110, 337.323); break;} case 'G8' : {$pf = array( 167.244, 238.110); break;} case 'G9' : {$pf = array( 119.055, 167.244); break;} case 'G10': {$pf = array( 82.205, 119.055); break;} case 'G11': {$pf = array( 59.528, 82.205); break;} case 'G12': {$pf = array( 39.685, 59.528); break;} // ISO Press case 'RA0': {$pf = array( 2437.795, 3458.268); break;} case 'RA1': {$pf = array( 1729.134, 2437.795); break;} case 'RA2': {$pf = array( 1218.898, 1729.134); break;} case 'RA3': {$pf = array( 864.567, 1218.898); break;} case 'RA4': {$pf = array( 609.449, 864.567); break;} case 'SRA0': {$pf = array( 2551.181, 3628.346); break;} case 'SRA1': {$pf = array( 1814.173, 2551.181); break;} case 'SRA2': {$pf = array( 1275.591, 1814.173); break;} case 'SRA3': {$pf = array( 907.087, 1275.591); break;} case 'SRA4': {$pf = array( 637.795, 907.087); break;} // German DIN 476 case '4A0': {$pf = array( 4767.874, 6740.787); break;} case '2A0': {$pf = array( 3370.394, 4767.874); break;} // Variations on the ISO Standard case 'A2_EXTRA' : {$pf = array( 1261.417, 1754.646); break;} case 'A3+' : {$pf = array( 932.598, 1369.134); break;} case 'A3_EXTRA' : {$pf = array( 912.756, 1261.417); break;} case 'A3_SUPER' : {$pf = array( 864.567, 1440.000); break;} case 'SUPER_A3' : {$pf = array( 864.567, 1380.472); break;} case 'A4_EXTRA' : {$pf = array( 666.142, 912.756); break;} case 'A4_SUPER' : {$pf = array( 649.134, 912.756); break;} case 'SUPER_A4' : {$pf = array( 643.465, 1009.134); break;} case 'A4_LONG' : {$pf = array( 595.276, 986.457); break;} case 'F4' : {$pf = array( 595.276, 935.433); break;} case 'SO_B5_EXTRA': {$pf = array( 572.598, 782.362); break;} case 'A5_EXTRA' : {$pf = array( 490.394, 666.142); break;} // ANSI Series case 'ANSI_E': {$pf = array( 2448.000, 3168.000); break;} case 'ANSI_D': {$pf = array( 1584.000, 2448.000); break;} case 'ANSI_C': {$pf = array( 1224.000, 1584.000); break;} case 'ANSI_B': {$pf = array( 792.000, 1224.000); break;} case 'ANSI_A': {$pf = array( 612.000, 792.000); break;} // Traditional 'Loose' North American Paper Sizes case 'USLEDGER': case 'LEDGER' : {$pf = array( 1224.000, 792.000); break;} case 'ORGANIZERK': case 'BIBLE': case 'USTABLOID': case 'TABLOID': {$pf = array( 792.000, 1224.000); break;} case 'ORGANIZERM': case 'USLETTER': case 'LETTER' : {$pf = array( 612.000, 792.000); break;} case 'USLEGAL': case 'LEGAL' : {$pf = array( 612.000, 1008.000); break;} case 'GOVERNMENTLETTER': case 'GLETTER': {$pf = array( 576.000, 756.000); break;} case 'JUNIORLEGAL': case 'JLEGAL' : {$pf = array( 576.000, 360.000); break;} // Other North American Paper Sizes case 'QUADDEMY': {$pf = array( 2520.000, 3240.000); break;} case 'SUPER_B': {$pf = array( 936.000, 1368.000); break;} case 'QUARTO': {$pf = array( 648.000, 792.000); break;} case 'GOVERNMENTLEGAL': case 'FOLIO': {$pf = array( 612.000, 936.000); break;} case 'MONARCH': case 'EXECUTIVE': {$pf = array( 522.000, 756.000); break;} case 'ORGANIZERL': case 'STATEMENT': case 'MEMO': {$pf = array( 396.000, 612.000); break;} case 'FOOLSCAP': {$pf = array( 595.440, 936.000); break;} case 'COMPACT': {$pf = array( 306.000, 486.000); break;} case 'ORGANIZERJ': {$pf = array( 198.000, 360.000); break;} // Canadian standard CAN 2-9.60M case 'P1': {$pf = array( 1587.402, 2437.795); break;} case 'P2': {$pf = array( 1218.898, 1587.402); break;} case 'P3': {$pf = array( 793.701, 1218.898); break;} case 'P4': {$pf = array( 609.449, 793.701); break;} case 'P5': {$pf = array( 396.850, 609.449); break;} case 'P6': {$pf = array( 303.307, 396.850); break;} // North American Architectural Sizes case 'ARCH_E' : {$pf = array( 2592.000, 3456.000); break;} case 'ARCH_E1': {$pf = array( 2160.000, 3024.000); break;} case 'ARCH_D' : {$pf = array( 1728.000, 2592.000); break;} case 'BROADSHEET': case 'ARCH_C' : {$pf = array( 1296.000, 1728.000); break;} case 'ARCH_B' : {$pf = array( 864.000, 1296.000); break;} case 'ARCH_A' : {$pf = array( 648.000, 864.000); break;} // --- North American Envelope Sizes --- // - Announcement Envelopes case 'ANNENV_A2' : {$pf = array( 314.640, 414.000); break;} case 'ANNENV_A6' : {$pf = array( 342.000, 468.000); break;} case 'ANNENV_A7' : {$pf = array( 378.000, 522.000); break;} case 'ANNENV_A8' : {$pf = array( 396.000, 584.640); break;} case 'ANNENV_A10' : {$pf = array( 450.000, 692.640); break;} case 'ANNENV_SLIM': {$pf = array( 278.640, 638.640); break;} // - Commercial Envelopes case 'COMMENV_N6_1/4': {$pf = array( 252.000, 432.000); break;} case 'COMMENV_N6_3/4': {$pf = array( 260.640, 468.000); break;} case 'COMMENV_N8' : {$pf = array( 278.640, 540.000); break;} case 'COMMENV_N9' : {$pf = array( 278.640, 638.640); break;} case 'COMMENV_N10' : {$pf = array( 296.640, 684.000); break;} case 'COMMENV_N11' : {$pf = array( 324.000, 746.640); break;} case 'COMMENV_N12' : {$pf = array( 342.000, 792.000); break;} case 'COMMENV_N14' : {$pf = array( 360.000, 828.000); break;} // - Catalogue Envelopes case 'CATENV_N1' : {$pf = array( 432.000, 648.000); break;} case 'CATENV_N1_3/4' : {$pf = array( 468.000, 684.000); break;} case 'CATENV_N2' : {$pf = array( 468.000, 720.000); break;} case 'CATENV_N3' : {$pf = array( 504.000, 720.000); break;} case 'CATENV_N6' : {$pf = array( 540.000, 756.000); break;} case 'CATENV_N7' : {$pf = array( 576.000, 792.000); break;} case 'CATENV_N8' : {$pf = array( 594.000, 810.000); break;} case 'CATENV_N9_1/2' : {$pf = array( 612.000, 756.000); break;} case 'CATENV_N9_3/4' : {$pf = array( 630.000, 810.000); break;} case 'CATENV_N10_1/2': {$pf = array( 648.000, 864.000); break;} case 'CATENV_N12_1/2': {$pf = array( 684.000, 900.000); break;} case 'CATENV_N13_1/2': {$pf = array( 720.000, 936.000); break;} case 'CATENV_N14_1/4': {$pf = array( 810.000, 882.000); break;} case 'CATENV_N14_1/2': {$pf = array( 828.000, 1044.000); break;} // Japanese (JIS P 0138-61) Standard B-Series case 'JIS_B0' : {$pf = array( 2919.685, 4127.244); break;} case 'JIS_B1' : {$pf = array( 2063.622, 2919.685); break;} case 'JIS_B2' : {$pf = array( 1459.843, 2063.622); break;} case 'JIS_B3' : {$pf = array( 1031.811, 1459.843); break;} case 'JIS_B4' : {$pf = array( 728.504, 1031.811); break;} case 'JIS_B5' : {$pf = array( 515.906, 728.504); break;} case 'JIS_B6' : {$pf = array( 362.835, 515.906); break;} case 'JIS_B7' : {$pf = array( 257.953, 362.835); break;} case 'JIS_B8' : {$pf = array( 181.417, 257.953); break;} case 'JIS_B9' : {$pf = array( 127.559, 181.417); break;} case 'JIS_B10': {$pf = array( 90.709, 127.559); break;} case 'JIS_B11': {$pf = array( 62.362, 90.709); break;} case 'JIS_B12': {$pf = array( 45.354, 62.362); break;} // PA Series case 'PA0' : {$pf = array( 2381.102, 3174.803,); break;} case 'PA1' : {$pf = array( 1587.402, 2381.102); break;} case 'PA2' : {$pf = array( 1190.551, 1587.402); break;} case 'PA3' : {$pf = array( 793.701, 1190.551); break;} case 'PA4' : {$pf = array( 595.276, 793.701); break;} case 'PA5' : {$pf = array( 396.850, 595.276); break;} case 'PA6' : {$pf = array( 297.638, 396.850); break;} case 'PA7' : {$pf = array( 198.425, 297.638); break;} case 'PA8' : {$pf = array( 147.402, 198.425); break;} case 'PA9' : {$pf = array( 99.213, 147.402); break;} case 'PA10': {$pf = array( 73.701, 99.213); break;} // Standard Photographic Print Sizes case 'PASSPORT_PHOTO': {$pf = array( 99.213, 127.559); break;} case 'E' : {$pf = array( 233.858, 340.157); break;} case 'L': case '3R' : {$pf = array( 252.283, 360.000); break;} case 'KG': case '4R' : {$pf = array( 289.134, 430.866); break;} case '4D' : {$pf = array( 340.157, 430.866); break;} case '2L': case '5R' : {$pf = array( 360.000, 504.567); break;} case '8P': case '6R' : {$pf = array( 430.866, 575.433); break;} case '6P': case '8R' : {$pf = array( 575.433, 720.000); break;} case '6PW': case 'S8R' : {$pf = array( 575.433, 864.567); break;} case '4P': case '10R' : {$pf = array( 720.000, 864.567); break;} case '4PW': case 'S10R': {$pf = array( 720.000, 1080.000); break;} case '11R' : {$pf = array( 790.866, 1009.134); break;} case 'S11R': {$pf = array( 790.866, 1224.567); break;} case '12R' : {$pf = array( 864.567, 1080.000); break;} case 'S12R': {$pf = array( 864.567, 1292.598); break;} // Common Newspaper Sizes case 'NEWSPAPER_BROADSHEET': {$pf = array( 2125.984, 1700.787); break;} case 'NEWSPAPER_BERLINER' : {$pf = array( 1332.283, 892.913); break;} case 'NEWSPAPER_TABLOID': case 'NEWSPAPER_COMPACT' : {$pf = array( 1218.898, 793.701); break;} // Business Cards case 'CREDIT_CARD': case 'BUSINESS_CARD': case 'BUSINESS_CARD_ISO7810': {$pf = array( 153.014, 242.646); break;} case 'BUSINESS_CARD_ISO216' : {$pf = array( 147.402, 209.764); break;} case 'BUSINESS_CARD_IT': case 'BUSINESS_CARD_UK': case 'BUSINESS_CARD_FR': case 'BUSINESS_CARD_DE': case 'BUSINESS_CARD_ES' : {$pf = array( 155.906, 240.945); break;} case 'BUSINESS_CARD_CA': case 'BUSINESS_CARD_US' : {$pf = array( 144.567, 252.283); break;} case 'BUSINESS_CARD_JP' : {$pf = array( 155.906, 257.953); break;} case 'BUSINESS_CARD_HK' : {$pf = array( 153.071, 255.118); break;} case 'BUSINESS_CARD_AU': case 'BUSINESS_CARD_DK': case 'BUSINESS_CARD_SE' : {$pf = array( 155.906, 255.118); break;} case 'BUSINESS_CARD_RU': case 'BUSINESS_CARD_CZ': case 'BUSINESS_CARD_FI': case 'BUSINESS_CARD_HU': case 'BUSINESS_CARD_IL' : {$pf = array( 141.732, 255.118); break;} // Billboards case '4SHEET' : {$pf = array( 2880.000, 4320.000); break;} case '6SHEET' : {$pf = array( 3401.575, 5102.362); break;} case '12SHEET': {$pf = array( 8640.000, 4320.000); break;} case '16SHEET': {$pf = array( 5760.000, 8640.000); break;} case '32SHEET': {$pf = array(11520.000, 8640.000); break;} case '48SHEET': {$pf = array(17280.000, 8640.000); break;} case '64SHEET': {$pf = array(23040.000, 8640.000); break;} case '96SHEET': {$pf = array(34560.000, 8640.000); break;} // Old European Sizes // - Old Imperial English Sizes case 'EN_EMPEROR' : {$pf = array( 3456.000, 5184.000); break;} case 'EN_ANTIQUARIAN' : {$pf = array( 2232.000, 3816.000); break;} case 'EN_GRAND_EAGLE' : {$pf = array( 2070.000, 3024.000); break;} case 'EN_DOUBLE_ELEPHANT' : {$pf = array( 1926.000, 2880.000); break;} case 'EN_ATLAS' : {$pf = array( 1872.000, 2448.000); break;} case 'EN_COLOMBIER' : {$pf = array( 1692.000, 2484.000); break;} case 'EN_ELEPHANT' : {$pf = array( 1656.000, 2016.000); break;} case 'EN_DOUBLE_DEMY' : {$pf = array( 1620.000, 2556.000); break;} case 'EN_IMPERIAL' : {$pf = array( 1584.000, 2160.000); break;} case 'EN_PRINCESS' : {$pf = array( 1548.000, 2016.000); break;} case 'EN_CARTRIDGE' : {$pf = array( 1512.000, 1872.000); break;} case 'EN_DOUBLE_LARGE_POST': {$pf = array( 1512.000, 2376.000); break;} case 'EN_ROYAL' : {$pf = array( 1440.000, 1800.000); break;} case 'EN_SHEET': case 'EN_HALF_POST' : {$pf = array( 1404.000, 1692.000); break;} case 'EN_SUPER_ROYAL' : {$pf = array( 1368.000, 1944.000); break;} case 'EN_DOUBLE_POST' : {$pf = array( 1368.000, 2196.000); break;} case 'EN_MEDIUM' : {$pf = array( 1260.000, 1656.000); break;} case 'EN_DEMY' : {$pf = array( 1260.000, 1620.000); break;} case 'EN_LARGE_POST' : {$pf = array( 1188.000, 1512.000); break;} case 'EN_COPY_DRAUGHT' : {$pf = array( 1152.000, 1440.000); break;} case 'EN_POST' : {$pf = array( 1116.000, 1386.000); break;} case 'EN_CROWN' : {$pf = array( 1080.000, 1440.000); break;} case 'EN_PINCHED_POST' : {$pf = array( 1062.000, 1332.000); break;} case 'EN_BRIEF' : {$pf = array( 972.000, 1152.000); break;} case 'EN_FOOLSCAP' : {$pf = array( 972.000, 1224.000); break;} case 'EN_SMALL_FOOLSCAP' : {$pf = array( 954.000, 1188.000); break;} case 'EN_POTT' : {$pf = array( 900.000, 1080.000); break;} // - Old Imperial Belgian Sizes case 'BE_GRAND_AIGLE' : {$pf = array( 1984.252, 2948.031); break;} case 'BE_COLOMBIER' : {$pf = array( 1757.480, 2409.449); break;} case 'BE_DOUBLE_CARRE': {$pf = array( 1757.480, 2607.874); break;} case 'BE_ELEPHANT' : {$pf = array( 1746.142, 2182.677); break;} case 'BE_PETIT_AIGLE' : {$pf = array( 1700.787, 2381.102); break;} case 'BE_GRAND_JESUS' : {$pf = array( 1559.055, 2069.291); break;} case 'BE_JESUS' : {$pf = array( 1530.709, 2069.291); break;} case 'BE_RAISIN' : {$pf = array( 1417.323, 1842.520); break;} case 'BE_GRAND_MEDIAN': {$pf = array( 1303.937, 1714.961); break;} case 'BE_DOUBLE_POSTE': {$pf = array( 1233.071, 1601.575); break;} case 'BE_COQUILLE' : {$pf = array( 1218.898, 1587.402); break;} case 'BE_PETIT_MEDIAN': {$pf = array( 1176.378, 1502.362); break;} case 'BE_RUCHE' : {$pf = array( 1020.472, 1303.937); break;} case 'BE_PROPATRIA' : {$pf = array( 977.953, 1218.898); break;} case 'BE_LYS' : {$pf = array( 898.583, 1125.354); break;} case 'BE_POT' : {$pf = array( 870.236, 1088.504); break;} case 'BE_ROSETTE' : {$pf = array( 765.354, 983.622); break;} // - Old Imperial French Sizes case 'FR_UNIVERS' : {$pf = array( 2834.646, 3685.039); break;} case 'FR_DOUBLE_COLOMBIER' : {$pf = array( 2551.181, 3571.654); break;} case 'FR_GRANDE_MONDE' : {$pf = array( 2551.181, 3571.654); break;} case 'FR_DOUBLE_SOLEIL' : {$pf = array( 2267.717, 3401.575); break;} case 'FR_DOUBLE_JESUS' : {$pf = array( 2154.331, 3174.803); break;} case 'FR_GRAND_AIGLE' : {$pf = array( 2125.984, 3004.724); break;} case 'FR_PETIT_AIGLE' : {$pf = array( 1984.252, 2664.567); break;} case 'FR_DOUBLE_RAISIN' : {$pf = array( 1842.520, 2834.646); break;} case 'FR_JOURNAL' : {$pf = array( 1842.520, 2664.567); break;} case 'FR_COLOMBIER_AFFICHE': {$pf = array( 1785.827, 2551.181); break;} case 'FR_DOUBLE_CAVALIER' : {$pf = array( 1757.480, 2607.874); break;} case 'FR_CLOCHE' : {$pf = array( 1700.787, 2267.717); break;} case 'FR_SOLEIL' : {$pf = array( 1700.787, 2267.717); break;} case 'FR_DOUBLE_CARRE' : {$pf = array( 1587.402, 2551.181); break;} case 'FR_DOUBLE_COQUILLE' : {$pf = array( 1587.402, 2494.488); break;} case 'FR_JESUS' : {$pf = array( 1587.402, 2154.331); break;} case 'FR_RAISIN' : {$pf = array( 1417.323, 1842.520); break;} case 'FR_CAVALIER' : {$pf = array( 1303.937, 1757.480); break;} case 'FR_DOUBLE_COURONNE' : {$pf = array( 1303.937, 2040.945); break;} case 'FR_CARRE' : {$pf = array( 1275.591, 1587.402); break;} case 'FR_COQUILLE' : {$pf = array( 1247.244, 1587.402); break;} case 'FR_DOUBLE_TELLIERE' : {$pf = array( 1247.244, 1927.559); break;} case 'FR_DOUBLE_CLOCHE' : {$pf = array( 1133.858, 1700.787); break;} case 'FR_DOUBLE_POT' : {$pf = array( 1133.858, 1757.480); break;} case 'FR_ECU' : {$pf = array( 1133.858, 1474.016); break;} case 'FR_COURONNE' : {$pf = array( 1020.472, 1303.937); break;} case 'FR_TELLIERE' : {$pf = array( 963.780, 1247.244); break;} case 'FR_POT' : {$pf = array( 878.740, 1133.858); break;} // DEFAULT ISO A4 default: {$pf = array( 595.276, 841.890); break;} } return $pf; } /** * Set page boundaries. * @param $page (int) page number * @param $type (string) valid values are:
      • 'MediaBox' : the boundaries of the physical medium on which the page shall be displayed or printed;
      • 'CropBox' : the visible region of default user space;
      • 'BleedBox' : the region to which the contents of the page shall be clipped when output in a production environment;
      • 'TrimBox' : the intended dimensions of the finished page after trimming;
      • 'ArtBox' : the page's meaningful content (including potential white space).
      * @param $llx (float) lower-left x coordinate in user units. * @param $lly (float) lower-left y coordinate in user units. * @param $urx (float) upper-right x coordinate in user units. * @param $ury (float) upper-right y coordinate in user units. * @param $points (boolean) If true uses user units as unit of measure, otherwise uses PDF points. * @param $k (float) Scale factor (number of points in user unit). * @param $pagedim (array) Array of page dimensions. * @return pagedim array of page dimensions. * @since 5.0.010 (2010-05-17) * @public static */ public static function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points=false, $k, $pagedim=array()) { if (!isset($pagedim[$page])) { // initialize array $pagedim[$page] = array(); } if (!in_array($type, self::$pageboxes)) { return; } if ($points) { $k = 1; } $pagedim[$page][$type]['llx'] = ($llx * $k); $pagedim[$page][$type]['lly'] = ($lly * $k); $pagedim[$page][$type]['urx'] = ($urx * $k); $pagedim[$page][$type]['ury'] = ($ury * $k); return $pagedim; } /** * Swap X and Y coordinates of page boxes (change page boxes orientation). * @param $page (int) page number * @param $pagedim (array) Array of page dimensions. * @return pagedim array of page dimensions. * @since 5.0.010 (2010-05-17) * @public static */ public static function swapPageBoxCoordinates($page, $pagedim) { foreach (self::$pageboxes as $type) { // swap X and Y coordinates if (isset($pagedim[$page][$type])) { $tmp = $pagedim[$page][$type]['llx']; $pagedim[$page][$type]['llx'] = $pagedim[$page][$type]['lly']; $pagedim[$page][$type]['lly'] = $tmp; $tmp = $pagedim[$page][$type]['urx']; $pagedim[$page][$type]['urx'] = $pagedim[$page][$type]['ury']; $pagedim[$page][$type]['ury'] = $tmp; } } return $pagedim; } /** * Get the canonical page layout mode. * @param $layout (string) The page layout. Possible values are:
      • SinglePage Display one page at a time
      • OneColumn Display the pages in one column
      • TwoColumnLeft Display the pages in two columns, with odd-numbered pages on the left
      • TwoColumnRight Display the pages in two columns, with odd-numbered pages on the right
      • TwoPageLeft (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left
      • TwoPageRight (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right
      * @return (string) Canonical page layout name. * @public static */ public static function getPageLayoutMode($layout='SinglePage') { switch ($layout) { case 'default': case 'single': case 'SinglePage': { $layout_mode = 'SinglePage'; break; } case 'continuous': case 'OneColumn': { $layout_mode = 'OneColumn'; break; } case 'two': case 'TwoColumnLeft': { $layout_mode = 'TwoColumnLeft'; break; } case 'TwoColumnRight': { $layout_mode = 'TwoColumnRight'; break; } case 'TwoPageLeft': { $layout_mode = 'TwoPageLeft'; break; } case 'TwoPageRight': { $layout_mode = 'TwoPageRight'; break; } default: { $layout_mode = 'SinglePage'; } } return $layout_mode; } /** * Get the canonical page layout mode. * @param $mode (string) A name object specifying how the document should be displayed when opened:
      • UseNone Neither document outline nor thumbnail images visible
      • UseOutlines Document outline visible
      • UseThumbs Thumbnail images visible
      • FullScreen Full-screen mode, with no menu bar, window controls, or any other window visible
      • UseOC (PDF 1.5) Optional content group panel visible
      • UseAttachments (PDF 1.6) Attachments panel visible
      * @return (string) Canonical page mode name. * @public static */ public static function getPageMode($mode='UseNone') { switch ($mode) { case 'UseNone': { $page_mode = 'UseNone'; break; } case 'UseOutlines': { $page_mode = 'UseOutlines'; break; } case 'UseThumbs': { $page_mode = 'UseThumbs'; break; } case 'FullScreen': { $page_mode = 'FullScreen'; break; } case 'UseOC': { $page_mode = 'UseOC'; break; } case '': { $page_mode = 'UseAttachments'; break; } default: { $page_mode = 'UseNone'; } } return $page_mode; } /** * Check if the URL exist. * @param $url (string) URL to check. * @return Boolean true if the URl exist, false otherwise. * @since 5.9.204 (2013-01-28) * @public static */ public static function isValidURL($url) { $headers = @get_headers($url); return (strpos($headers[0], '200') !== false); } /** * Removes SHY characters from text. * Unicode Data:
        *
      • Name : SOFT HYPHEN, commonly abbreviated as SHY
      • *
      • HTML Entity (decimal): "&#173;"
      • *
      • HTML Entity (hex): "&#xad;"
      • *
      • HTML Entity (named): "&shy;"
      • *
      • How to type in Microsoft Windows: [Alt +00AD] or [Alt 0173]
      • *
      • UTF-8 (hex): 0xC2 0xAD (c2ad)
      • *
      • UTF-8 character: chr(194).chr(173)
      • *
      * @param $txt (string) input string * @param $unicode (boolean) True if we are in unicode mode, false otherwise. * @return string without SHY characters. * @since (4.5.019) 2009-02-28 * @public static */ public static function removeSHY($txt='', $unicode=true) { $txt = preg_replace('/([\\xc2]{1}[\\xad]{1})/', '', $txt); if (!$unicode) { $txt = preg_replace('/([\\xad]{1})/', '', $txt); } return $txt; } /** * Get the border mode accounting for multicell position (opens bottom side of multicell crossing pages) * @param $brd (mixed) Indicates if borders must be drawn around the cell block. The value can be a number:
      • 0: no border (default)
      • 1: frame
      or a string containing some or all of the following characters (in any order):
      • L: left
      • T: top
      • R: right
      • B: bottom
      or an array of line styles for each border group: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))) * @param $position (string) multicell position: 'start', 'middle', 'end' * @param $opencell (boolean) True when the cell is left open at the page bottom, false otherwise. * @return border mode array * @since 4.4.002 (2008-12-09) * @public static */ public static function getBorderMode($brd, $position='start', $opencell=true) { if ((!$opencell) OR empty($brd)) { return $brd; } if ($brd == 1) { $brd = 'LTRB'; } if (is_string($brd)) { // convert string to array $slen = strlen($brd); $newbrd = array(); for ($i = 0; $i < $slen; ++$i) { $newbrd[$brd[$i]] = array('cap' => 'square', 'join' => 'miter'); } $brd = $newbrd; } foreach ($brd as $border => $style) { switch ($position) { case 'start': { if (strpos($border, 'B') !== false) { // remove bottom line $newkey = str_replace('B', '', $border); if (strlen($newkey) > 0) { $brd[$newkey] = $style; } unset($brd[$border]); } break; } case 'middle': { if (strpos($border, 'B') !== false) { // remove bottom line $newkey = str_replace('B', '', $border); if (strlen($newkey) > 0) { $brd[$newkey] = $style; } unset($brd[$border]); $border = $newkey; } if (strpos($border, 'T') !== false) { // remove bottom line $newkey = str_replace('T', '', $border); if (strlen($newkey) > 0) { $brd[$newkey] = $style; } unset($brd[$border]); } break; } case 'end': { if (strpos($border, 'T') !== false) { // remove bottom line $newkey = str_replace('T', '', $border); if (strlen($newkey) > 0) { $brd[$newkey] = $style; } unset($brd[$border]); } break; } } } return $brd; } /** * Determine whether a string is empty. * @param $str (string) string to be checked * @return boolean true if string is empty * @since 4.5.044 (2009-04-16) * @public static */ public static function empty_string($str) { return (is_null($str) OR (is_string($str) AND (strlen($str) == 0))); } /** * Returns a temporary filename for caching object on filesystem. * @param $name (string) Prefix to add to the file name. * @return string filename. * @since 4.5.000 (2008-12-31) * @public static */ public static function getObjFilename($name) { return tempnam(K_PATH_CACHE, $name.'_'); } /** * Add "\" before "\", "(" and ")" * @param $s (string) string to escape. * @return string escaped string. * @public static */ public static function _escape($s) { // the chr(13) substitution fixes the Bugs item #1421290. return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r')); } /** * Escape some special characters (< > &) for XML output. * @param $str (string) Input string to convert. * @return converted string * @since 5.9.121 (2011-09-28) * @public static */ public static function _escapeXML($str) { $replaceTable = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); $str = strtr($str, $replaceTable); return $str; } /** * Creates a copy of a class object * @param $object (object) class object to be cloned * @return cloned object * @since 4.5.029 (2009-03-19) * @public static */ public static function objclone($object) { if (($object instanceof Imagick) AND (version_compare(phpversion('imagick'), '3.0.1') !== 1)) { // on the versions after 3.0.1 the clone() method was deprecated in favour of clone keyword return @$object->clone(); } return @clone($object); } /** * Ouput input data and compress it if possible. * @param $data (string) Data to output. * @param $length (int) Data length in bytes. * @since 5.9.086 * @public static */ public static function sendOutputData($data, $length) { if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) { // the content length may vary if the server is using compression header('Content-Length: '.$length); } echo $data; } /** * Replace page number aliases with number. * @param $page (string) Page content. * @param $replace (array) Array of replacements (array keys are replacement strings, values are alias arrays). * @param $diff (int) If passed, this will be set to the total char number difference between alias and replacements. * @return replaced page content and updated $diff parameter as array. * @public static */ public static function replacePageNumAliases($page, $replace, $diff=0) { foreach ($replace as $rep) { foreach ($rep[3] as $a) { if (strpos($page, $a) !== false) { $page = str_replace($a, $rep[0], $page); $diff += ($rep[2] - $rep[1]); } } } return array($page, $diff); } /** * Returns timestamp in seconds from formatted date-time. * @param $date (string) Formatted date-time. * @return int seconds. * @since 5.9.152 (2012-03-23) * @public static */ public static function getTimestamp($date) { if (($date[0] == 'D') AND ($date[1] == ':')) { // remove date prefix if present $date = substr($date, 2); } return strtotime($date); } /** * Returns a formatted date-time. * @param $time (int) Time in seconds. * @return string escaped date string. * @since 5.9.152 (2012-03-23) * @public static */ public static function getFormattedDate($time) { return substr_replace(date('YmdHisO', intval($time)), '\'', (0 - 2), 0).'\''; } /** * Get ULONG from string (Big Endian 32-bit unsigned integer). * @param $str (string) string from where to extract value * @param $offset (int) point from where to read the data * @return int 32 bit value * @author Nicola Asuni * @since 5.2.000 (2010-06-02) * @public static */ public static function _getULONG($str, $offset) { $v = unpack('Ni', substr($str, $offset, 4)); return $v['i']; } /** * Get USHORT from string (Big Endian 16-bit unsigned integer). * @param $str (string) string from where to extract value * @param $offset (int) point from where to read the data * @return int 16 bit value * @author Nicola Asuni * @since 5.2.000 (2010-06-02) * @public static */ public static function _getUSHORT($str, $offset) { $v = unpack('ni', substr($str, $offset, 2)); return $v['i']; } /** * Get SHORT from string (Big Endian 16-bit signed integer). * @param $str (string) String from where to extract value. * @param $offset (int) Point from where to read the data. * @return int 16 bit value * @author Nicola Asuni * @since 5.2.000 (2010-06-02) * @public static */ public static function _getSHORT($str, $offset) { $v = unpack('si', substr($str, $offset, 2)); return $v['i']; } /** * Get FWORD from string (Big Endian 16-bit signed integer). * @param $str (string) String from where to extract value. * @param $offset (int) Point from where to read the data. * @return int 16 bit value * @author Nicola Asuni * @since 5.9.123 (2011-09-30) * @public static */ public static function _getFWORD($str, $offset) { $v = self::_getUSHORT($str, $offset); if ($v > 0x7fff) { $v -= 0x10000; } return $v; } /** * Get UFWORD from string (Big Endian 16-bit unsigned integer). * @param $str (string) string from where to extract value * @param $offset (int) point from where to read the data * @return int 16 bit value * @author Nicola Asuni * @since 5.9.123 (2011-09-30) * @public static */ public static function _getUFWORD($str, $offset) { $v = self::_getUSHORT($str, $offset); return $v; } /** * Get FIXED from string (32-bit signed fixed-point number (16.16). * @param $str (string) string from where to extract value * @param $offset (int) point from where to read the data * @return int 16 bit value * @author Nicola Asuni * @since 5.9.123 (2011-09-30) * @public static */ public static function _getFIXED($str, $offset) { // mantissa $m = self::_getFWORD($str, $offset); // fraction $f = self::_getUSHORT($str, ($offset + 2)); $v = floatval(''.$m.'.'.$f.''); return $v; } /** * Get BYTE from string (8-bit unsigned integer). * @param $str (string) String from where to extract value. * @param $offset (int) Point from where to read the data. * @return int 8 bit value * @author Nicola Asuni * @since 5.2.000 (2010-06-02) * @public static */ public static function _getBYTE($str, $offset) { $v = unpack('Ci', substr($str, $offset, 1)); return $v['i']; } /** * Binary-safe and URL-safe file read. * Reads up to length bytes from the file pointer referenced by handle. Reading stops as soon as one of the following conditions is met: length bytes have been read; EOF (end of file) is reached. * @param $handle (resource) * @param $length (int) * @return Returns the read string or FALSE in case of error. * @author Nicola Asuni * @since 4.5.027 (2009-03-16) * @public static */ public static function rfread($handle, $length) { $data = fread($handle, $length); if ($data === false) { return false; } $rest = ($length - strlen($data)); if ($rest > 0) { $data .= self::rfread($handle, $rest); } return $data; } /** * Read a 4-byte (32 bit) integer from file. * @param $f (string) file name. * @return 4-byte integer * @public static */ public static function _freadint($f) { $a = unpack('Ni', fread($f, 4)); return $a['i']; } /** * Returns a string containing random data to be used as a seed for encryption methods. * @param $seed (string) starting seed value * @return string containing random data * @author Nicola Asuni * @since 5.9.006 (2010-10-19) * @public static */ public static function getRandomSeed($seed='') { $seed .= microtime(); if (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // this is not used on windows systems because it is very slow for a know bug $seed .= openssl_random_pseudo_bytes(512); } else { for ($i = 0; $i < 23; ++$i) { $seed .= uniqid('', true); } } $seed .= uniqid('', true); $seed .= rand(); $seed .= getmypid(); $seed .= __FILE__; if (isset($_SERVER['REMOTE_ADDR'])) { $seed .= $_SERVER['REMOTE_ADDR']; } if (isset($_SERVER['HTTP_USER_AGENT'])) { $seed .= $_SERVER['HTTP_USER_AGENT']; } if (isset($_SERVER['HTTP_ACCEPT'])) { $seed .= $_SERVER['HTTP_ACCEPT']; } if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { $seed .= $_SERVER['HTTP_ACCEPT_ENCODING']; } if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $seed .= $_SERVER['HTTP_ACCEPT_LANGUAGE']; } if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) { $seed .= $_SERVER['HTTP_ACCEPT_CHARSET']; } $seed .= rand(); $seed .= uniqid('', true); $seed .= microtime(); return $seed; } /** * Encrypts a string using MD5 and returns it's value as a binary string. * @param $str (string) input string * @return String MD5 encrypted binary string * @since 2.0.000 (2008-01-02) * @public static */ public static function _md5_16($str) { return pack('H*', md5($str)); } /** * Returns the input text exrypted using AES algorithm and the specified key. * This method requires mcrypt. * @param $key (string) encryption key * @param $text (String) input text to be encrypted * @return String encrypted text * @author Nicola Asuni * @since 5.0.005 (2010-05-11) * @public static */ public static function _AES($key, $text) { // padding (RFC 2898, PKCS #5: Password-Based Cryptography Specification Version 2.0) $padding = 16 - (strlen($text) % 16); $text .= str_repeat(chr($padding), $padding); $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND); $text = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv); $text = $iv.$text; return $text; } /** * Returns the input text encrypted using RC4 algorithm and the specified key. * RC4 is the standard encryption algorithm used in PDF format * @param $key (string) Encryption key. * @param $text (String) Input text to be encrypted. * @param $last_enc_key (String) Reference to last RC4 key encrypted. * @param $last_enc_key_c (String) Reference to last RC4 computed key. * @return String encrypted text * @since 2.0.000 (2008-01-02) * @author Klemen Vodopivec, Nicola Asuni * @public static */ public static function _RC4($key, $text, &$last_enc_key, &$last_enc_key_c) { if (function_exists('mcrypt_decrypt') AND ($out = @mcrypt_decrypt(MCRYPT_ARCFOUR, $key, $text, MCRYPT_MODE_STREAM, ''))) { // try to use mcrypt function if exist return $out; } if ($last_enc_key != $key) { $k = str_repeat($key, ((256 / strlen($key)) + 1)); $rc4 = range(0, 255); $j = 0; for ($i = 0; $i < 256; ++$i) { $t = $rc4[$i]; $j = ($j + $t + ord($k[$i])) % 256; $rc4[$i] = $rc4[$j]; $rc4[$j] = $t; } $last_enc_key = $key; $last_enc_key_c = $rc4; } else { $rc4 = $last_enc_key_c; } $len = strlen($text); $a = 0; $b = 0; $out = ''; for ($i = 0; $i < $len; ++$i) { $a = ($a + 1) % 256; $t = $rc4[$a]; $b = ($b + $t) % 256; $rc4[$a] = $rc4[$b]; $rc4[$b] = $t; $k = $rc4[($rc4[$a] + $rc4[$b]) % 256]; $out .= chr(ord($text[$i]) ^ $k); } return $out; } /** * Return the premission code used on encryption (P value). * @param $permissions (Array) the set of permissions (specify the ones you want to block). * @param $mode (int) encryption strength: 0 = RC4 40 bit; 1 = RC4 128 bit; 2 = AES 128 bit; 3 = AES 256 bit. * @since 5.0.005 (2010-05-12) * @author Nicola Asuni * @public static */ public static function getUserPermissionCode($permissions, $mode=0) { $options = array( 'owner' => 2, // bit 2 -- inverted logic: cleared by default 'print' => 4, // bit 3 'modify' => 8, // bit 4 'copy' => 16, // bit 5 'annot-forms' => 32, // bit 6 'fill-forms' => 256, // bit 9 'extract' => 512, // bit 10 'assemble' => 1024,// bit 11 'print-high' => 2048 // bit 12 ); $protection = 2147422012; // 32 bit: (01111111 11111111 00001111 00111100) foreach ($permissions as $permission) { if (isset($options[$permission])) { if (($mode > 0) OR ($options[$permission] <= 32)) { // set only valid permissions if ($options[$permission] == 2) { // the logic for bit 2 is inverted (cleared by default) $protection += $options[$permission]; } else { $protection -= $options[$permission]; } } } } return $protection; } /** * Convert hexadecimal string to string * @param $bs (string) byte-string to convert * @return String * @since 5.0.005 (2010-05-12) * @author Nicola Asuni * @public static */ public static function convertHexStringToString($bs) { $string = ''; // string to be returned $bslength = strlen($bs); if (($bslength % 2) != 0) { // padding $bs .= '0'; ++$bslength; } for ($i = 0; $i < $bslength; $i += 2) { $string .= chr(hexdec($bs[$i].$bs[($i + 1)])); } return $string; } /** * Convert string to hexadecimal string (byte string) * @param $s (string) string to convert * @return byte string * @since 5.0.010 (2010-05-17) * @author Nicola Asuni * @public static */ public static function convertStringToHexString($s) { $bs = ''; $chars = preg_split('//', $s, -1, PREG_SPLIT_NO_EMPTY); foreach ($chars as $c) { $bs .= sprintf('%02s', dechex(ord($c))); } return $bs; } /** * Convert encryption P value to a string of bytes, low-order byte first. * @param $protection (string) 32bit encryption permission value (P value) * @return String * @since 5.0.005 (2010-05-12) * @author Nicola Asuni * @public static */ public static function getEncPermissionsString($protection) { $binprot = sprintf('%032b', $protection); $str = chr(bindec(substr($binprot, 24, 8))); $str .= chr(bindec(substr($binprot, 16, 8))); $str .= chr(bindec(substr($binprot, 8, 8))); $str .= chr(bindec(substr($binprot, 0, 8))); return $str; } /** * Encode a name object. * @param $name (string) Name object to encode. * @return (string) Encoded name object. * @author Nicola Asuni * @since 5.9.097 (2011-06-23) * @public static */ public static function encodeNameObject($name) { $escname = ''; $length = strlen($name); for ($i = 0; $i < $length; ++$i) { $chr = $name[$i]; if (preg_match('/[0-9a-zA-Z]/', $chr) == 1) { $escname .= $chr; } else { $escname .= sprintf('#%02X', ord($chr)); } } return $escname; } /** * Convert JavaScript form fields properties array to Annotation Properties array. * @param $prop (array) javascript field properties. Possible values are described on official Javascript for Acrobat API reference. * @param $spot_colors (array) Reference to spot colors array. * @param $rtl (boolean) True if in Right-To-Left text direction mode, false otherwise. * @return array of annotation properties * @author Nicola Asuni * @since 4.8.000 (2009-09-06) * @public static */ public static function getAnnotOptFromJSProp($prop, &$spot_colors, $rtl=false) { if (isset($prop['aopt']) AND is_array($prop['aopt'])) { // the annotation options area lready defined return $prop['aopt']; } $opt = array(); // value to be returned // alignment: Controls how the text is laid out within the text field. if (isset($prop['alignment'])) { switch ($prop['alignment']) { case 'left': { $opt['q'] = 0; break; } case 'center': { $opt['q'] = 1; break; } case 'right': { $opt['q'] = 2; break; } default: { $opt['q'] = ($rtl)?2:0; break; } } } // lineWidth: Specifies the thickness of the border when stroking the perimeter of a field's rectangle. if (isset($prop['lineWidth'])) { $linewidth = intval($prop['lineWidth']); } else { $linewidth = 1; } // borderStyle: The border style for a field. if (isset($prop['borderStyle'])) { switch ($prop['borderStyle']) { case 'border.d': case 'dashed': { $opt['border'] = array(0, 0, $linewidth, array(3, 2)); $opt['bs'] = array('w'=>$linewidth, 's'=>'D', 'd'=>array(3, 2)); break; } case 'border.b': case 'beveled': { $opt['border'] = array(0, 0, $linewidth); $opt['bs'] = array('w'=>$linewidth, 's'=>'B'); break; } case 'border.i': case 'inset': { $opt['border'] = array(0, 0, $linewidth); $opt['bs'] = array('w'=>$linewidth, 's'=>'I'); break; } case 'border.u': case 'underline': { $opt['border'] = array(0, 0, $linewidth); $opt['bs'] = array('w'=>$linewidth, 's'=>'U'); break; } case 'border.s': case 'solid': { $opt['border'] = array(0, 0, $linewidth); $opt['bs'] = array('w'=>$linewidth, 's'=>'S'); break; } default: { break; } } } if (isset($prop['border']) AND is_array($prop['border'])) { $opt['border'] = $prop['border']; } if (!isset($opt['mk'])) { $opt['mk'] = array(); } if (!isset($opt['mk']['if'])) { $opt['mk']['if'] = array(); } $opt['mk']['if']['a'] = array(0.5, 0.5); // buttonAlignX: Controls how space is distributed from the left of the button face with respect to the icon. if (isset($prop['buttonAlignX'])) { $opt['mk']['if']['a'][0] = $prop['buttonAlignX']; } // buttonAlignY: Controls how unused space is distributed from the bottom of the button face with respect to the icon. if (isset($prop['buttonAlignY'])) { $opt['mk']['if']['a'][1] = $prop['buttonAlignY']; } // buttonFitBounds: If true, the extent to which the icon may be scaled is set to the bounds of the button field. if (isset($prop['buttonFitBounds']) AND ($prop['buttonFitBounds'] == 'true')) { $opt['mk']['if']['fb'] = true; } // buttonScaleHow: Controls how the icon is scaled (if necessary) to fit inside the button face. if (isset($prop['buttonScaleHow'])) { switch ($prop['buttonScaleHow']) { case 'scaleHow.proportional': { $opt['mk']['if']['s'] = 'P'; break; } case 'scaleHow.anamorphic': { $opt['mk']['if']['s'] = 'A'; break; } } } // buttonScaleWhen: Controls when an icon is scaled to fit inside the button face. if (isset($prop['buttonScaleWhen'])) { switch ($prop['buttonScaleWhen']) { case 'scaleWhen.always': { $opt['mk']['if']['sw'] = 'A'; break; } case 'scaleWhen.never': { $opt['mk']['if']['sw'] = 'N'; break; } case 'scaleWhen.tooBig': { $opt['mk']['if']['sw'] = 'B'; break; } case 'scaleWhen.tooSmall': { $opt['mk']['if']['sw'] = 'S'; break; } } } // buttonPosition: Controls how the text and the icon of the button are positioned with respect to each other within the button face. if (isset($prop['buttonPosition'])) { switch ($prop['buttonPosition']) { case 0: case 'position.textOnly': { $opt['mk']['tp'] = 0; break; } case 1: case 'position.iconOnly': { $opt['mk']['tp'] = 1; break; } case 2: case 'position.iconTextV': { $opt['mk']['tp'] = 2; break; } case 3: case 'position.textIconV': { $opt['mk']['tp'] = 3; break; } case 4: case 'position.iconTextH': { $opt['mk']['tp'] = 4; break; } case 5: case 'position.textIconH': { $opt['mk']['tp'] = 5; break; } case 6: case 'position.overlay': { $opt['mk']['tp'] = 6; break; } } } // fillColor: Specifies the background color for a field. if (isset($prop['fillColor'])) { if (is_array($prop['fillColor'])) { $opt['mk']['bg'] = $prop['fillColor']; } else { $opt['mk']['bg'] = TCPDF_COLORS::convertHTMLColorToDec($prop['fillColor'], $spot_colors); } } // strokeColor: Specifies the stroke color for a field that is used to stroke the rectangle of the field with a line as large as the line width. if (isset($prop['strokeColor'])) { if (is_array($prop['strokeColor'])) { $opt['mk']['bc'] = $prop['strokeColor']; } else { $opt['mk']['bc'] = TCPDF_COLORS::convertHTMLColorToDec($prop['strokeColor'], $spot_colors); } } // rotation: The rotation of a widget in counterclockwise increments. if (isset($prop['rotation'])) { $opt['mk']['r'] = $prop['rotation']; } // charLimit: Limits the number of characters that a user can type into a text field. if (isset($prop['charLimit'])) { $opt['maxlen'] = intval($prop['charLimit']); } if (!isset($ff)) { $ff = 0; // default value } // readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it. if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) { $ff += 1 << 0; } // required: Specifies whether a field requires a value. if (isset($prop['required']) AND ($prop['required'] == 'true')) { $ff += 1 << 1; } // multiline: Controls how text is wrapped within the field. if (isset($prop['multiline']) AND ($prop['multiline'] == 'true')) { $ff += 1 << 12; } // password: Specifies whether the field should display asterisks when data is entered in the field. if (isset($prop['password']) AND ($prop['password'] == 'true')) { $ff += 1 << 13; } // NoToggleToOff: If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect. if (isset($prop['NoToggleToOff']) AND ($prop['NoToggleToOff'] == 'true')) { $ff += 1 << 14; } // Radio: If set, the field is a set of radio buttons. if (isset($prop['Radio']) AND ($prop['Radio'] == 'true')) { $ff += 1 << 15; } // Pushbutton: If set, the field is a pushbutton that does not retain a permanent value. if (isset($prop['Pushbutton']) AND ($prop['Pushbutton'] == 'true')) { $ff += 1 << 16; } // Combo: If set, the field is a combo box; if clear, the field is a list box. if (isset($prop['Combo']) AND ($prop['Combo'] == 'true')) { $ff += 1 << 17; } // editable: Controls whether a combo box is editable. if (isset($prop['editable']) AND ($prop['editable'] == 'true')) { $ff += 1 << 18; } // Sort: If set, the field's option items shall be sorted alphabetically. if (isset($prop['Sort']) AND ($prop['Sort'] == 'true')) { $ff += 1 << 19; } // fileSelect: If true, sets the file-select flag in the Options tab of the text field (Field is Used for File Selection). if (isset($prop['fileSelect']) AND ($prop['fileSelect'] == 'true')) { $ff += 1 << 20; } // multipleSelection: If true, indicates that a list box allows a multiple selection of items. if (isset($prop['multipleSelection']) AND ($prop['multipleSelection'] == 'true')) { $ff += 1 << 21; } // doNotSpellCheck: If true, spell checking is not performed on this editable text field. if (isset($prop['doNotSpellCheck']) AND ($prop['doNotSpellCheck'] == 'true')) { $ff += 1 << 22; } // doNotScroll: If true, the text field does not scroll and the user, therefore, is limited by the rectangular region designed for the field. if (isset($prop['doNotScroll']) AND ($prop['doNotScroll'] == 'true')) { $ff += 1 << 23; } // comb: If set to true, the field background is drawn as series of boxes (one for each character in the value of the field) and each character of the content is drawn within those boxes. The number of boxes drawn is determined from the charLimit property. It applies only to text fields. The setter will also raise if any of the following field properties are also set multiline, password, and fileSelect. A side-effect of setting this property is that the doNotScroll property is also set. if (isset($prop['comb']) AND ($prop['comb'] == 'true')) { $ff += 1 << 24; } // radiosInUnison: If false, even if a group of radio buttons have the same name and export value, they behave in a mutually exclusive fashion, like HTML radio buttons. if (isset($prop['radiosInUnison']) AND ($prop['radiosInUnison'] == 'true')) { $ff += 1 << 25; } // richText: If true, the field allows rich text formatting. if (isset($prop['richText']) AND ($prop['richText'] == 'true')) { $ff += 1 << 25; } // commitOnSelChange: Controls whether a field value is committed after a selection change. if (isset($prop['commitOnSelChange']) AND ($prop['commitOnSelChange'] == 'true')) { $ff += 1 << 26; } $opt['ff'] = $ff; // defaultValue: The default value of a field - that is, the value that the field is set to when the form is reset. if (isset($prop['defaultValue'])) { $opt['dv'] = $prop['defaultValue']; } $f = 4; // default value for annotation flags // readonly: The read-only characteristic of a field. If a field is read-only, the user can see the field but cannot change it. if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) { $f += 1 << 6; } // display: Controls whether the field is hidden or visible on screen and in print. if (isset($prop['display'])) { if ($prop['display'] == 'display.visible') { // } elseif ($prop['display'] == 'display.hidden') { $f += 1 << 1; } elseif ($prop['display'] == 'display.noPrint') { $f -= 1 << 2; } elseif ($prop['display'] == 'display.noView') { $f += 1 << 5; } } $opt['f'] = $f; // currentValueIndices: Reads and writes single or multiple values of a list box or combo box. if (isset($prop['currentValueIndices']) AND is_array($prop['currentValueIndices'])) { $opt['i'] = $prop['currentValueIndices']; } // value: The value of the field data that the user has entered. if (isset($prop['value'])) { if (is_array($prop['value'])) { $opt['opt'] = array(); foreach ($prop['value'] AS $key => $optval) { // exportValues: An array of strings representing the export values for the field. if (isset($prop['exportValues'][$key])) { $opt['opt'][$key] = array($prop['exportValues'][$key], $prop['value'][$key]); } else { $opt['opt'][$key] = $prop['value'][$key]; } } } else { $opt['v'] = $prop['value']; } } // richValue: This property specifies the text contents and formatting of a rich text field. if (isset($prop['richValue'])) { $opt['rv'] = $prop['richValue']; } // submitName: If nonempty, used during form submission instead of name. Only applicable if submitting in HTML format (that is, URL-encoded). if (isset($prop['submitName'])) { $opt['tm'] = $prop['submitName']; } // name: Fully qualified field name. if (isset($prop['name'])) { $opt['t'] = $prop['name']; } // userName: The user name (short description string) of the field. if (isset($prop['userName'])) { $opt['tu'] = $prop['userName']; } // highlight: Defines how a button reacts when a user clicks it. if (isset($prop['highlight'])) { switch ($prop['highlight']) { case 'none': case 'highlight.n': { $opt['h'] = 'N'; break; } case 'invert': case 'highlight.i': { $opt['h'] = 'i'; break; } case 'push': case 'highlight.p': { $opt['h'] = 'P'; break; } case 'outline': case 'highlight.o': { $opt['h'] = 'O'; break; } } } // Unsupported options: // - calcOrderIndex: Changes the calculation order of fields in the document. // - delay: Delays the redrawing of a field's appearance. // - defaultStyle: This property defines the default style attributes for the form field. // - style: Allows the user to set the glyph style of a check box or radio button. // - textColor, textFont, textSize return $opt; } /** * Format the page numbers. * This method can be overriden for custom formats. * @param $num (int) page number * @since 4.2.005 (2008-11-06) * @public static */ public static function formatPageNumber($num) { return number_format((float)$num, 0, '', '.'); } /** * Format the page numbers on the Table Of Content. * This method can be overriden for custom formats. * @param $num (int) page number * @since 4.5.001 (2009-01-04) * @see addTOC(), addHTMLTOC() * @public static */ public static function formatTOCPageNumber($num) { return number_format((float)$num, 0, '', '.'); } /** * Extracts the CSS properties from a CSS string. * @param $cssdata (string) string containing CSS definitions. * @return An array where the keys are the CSS selectors and the values are the CSS properties. * @author Nicola Asuni * @since 5.1.000 (2010-05-25) * @public static */ public static function extractCSSproperties($cssdata) { if (empty($cssdata)) { return array(); } // remove comments $cssdata = preg_replace('/\/\*[^\*]*\*\//', '', $cssdata); // remove newlines and multiple spaces $cssdata = preg_replace('/[\s]+/', ' ', $cssdata); // remove some spaces $cssdata = preg_replace('/[\s]*([;:\{\}]{1})[\s]*/', '\\1', $cssdata); // remove empty blocks $cssdata = preg_replace('/([^\}\{]+)\{\}/', '', $cssdata); // replace media type parenthesis $cssdata = preg_replace('/@media[\s]+([^\{]*)\{/i', '@media \\1§', $cssdata); $cssdata = preg_replace('/\}\}/si', '}§', $cssdata); // trim string $cssdata = trim($cssdata); // find media blocks (all, braille, embossed, handheld, print, projection, screen, speech, tty, tv) $cssblocks = array(); $matches = array(); if (preg_match_all('/@media[\s]+([^\§]*)§([^§]*)§/i', $cssdata, $matches) > 0) { foreach ($matches[1] as $key => $type) { $cssblocks[$type] = $matches[2][$key]; } // remove media blocks $cssdata = preg_replace('/@media[\s]+([^\§]*)§([^§]*)§/i', '', $cssdata); } // keep 'all' and 'print' media, other media types are discarded if (isset($cssblocks['all']) AND !empty($cssblocks['all'])) { $cssdata .= $cssblocks['all']; } if (isset($cssblocks['print']) AND !empty($cssblocks['print'])) { $cssdata .= $cssblocks['print']; } // reset css blocks array $cssblocks = array(); $matches = array(); // explode css data string into array if (substr($cssdata, -1) == '}') { // remove last parethesis $cssdata = substr($cssdata, 0, -1); } $matches = explode('}', $cssdata); foreach ($matches as $key => $block) { // index 0 contains the CSS selector, index 1 contains CSS properties $cssblocks[$key] = explode('{', $block); if (!isset($cssblocks[$key][1])) { // remove empty definitions unset($cssblocks[$key]); } } // split groups of selectors (comma-separated list of selectors) foreach ($cssblocks as $key => $block) { if (strpos($block[0], ',') > 0) { $selectors = explode(',', $block[0]); foreach ($selectors as $sel) { $cssblocks[] = array(0 => trim($sel), 1 => $block[1]); } unset($cssblocks[$key]); } } // covert array to selector => properties $cssdata = array(); foreach ($cssblocks as $block) { $selector = $block[0]; // calculate selector's specificity $matches = array(); $a = 0; // the declaration is not from is a 'style' attribute $b = intval(preg_match_all('/[\#]/', $selector, $matches)); // number of ID attributes $c = intval(preg_match_all('/[\[\.]/', $selector, $matches)); // number of other attributes $c += intval(preg_match_all('/[\:]link|visited|hover|active|focus|target|lang|enabled|disabled|checked|indeterminate|root|nth|first|last|only|empty|contains|not/i', $selector, $matches)); // number of pseudo-classes $d = intval(preg_match_all('/[\>\+\~\s]{1}[a-zA-Z0-9]+/', ' '.$selector, $matches)); // number of element names $d += intval(preg_match_all('/[\:][\:]/', $selector, $matches)); // number of pseudo-elements $specificity = $a.$b.$c.$d; // add specificity to the beginning of the selector $cssdata[$specificity.' '.$selector] = $block[1]; } // sort selectors alphabetically to account for specificity ksort($cssdata, SORT_STRING); // return array return $cssdata; } /** * Cleanup HTML code (requires HTML Tidy library). * @param $html (string) htmlcode to fix * @param $default_css (string) CSS commands to add * @param $tagvs (array) parameters for setHtmlVSpace method * @param $tidy_options (array) options for tidy_parse_string function * @param $tagvspaces (array) Array of vertical spaces for tags. * @return string XHTML code cleaned up * @author Nicola Asuni * @since 5.9.017 (2010-11-16) * @see setHtmlVSpace() * @public static */ public static function fixHTMLCode($html, $default_css='', $tagvs='', $tidy_options='', &$tagvspaces) { // configure parameters for HTML Tidy if ($tidy_options === '') { $tidy_options = array ( 'clean' => 1, 'drop-empty-paras' => 0, 'drop-proprietary-attributes' => 1, 'fix-backslash' => 1, 'hide-comments' => 1, 'join-styles' => 1, 'lower-literals' => 1, 'merge-divs' => 1, 'merge-spans' => 1, 'output-xhtml' => 1, 'word-2000' => 1, 'wrap' => 0, 'output-bom' => 0, //'char-encoding' => 'utf8', //'input-encoding' => 'utf8', //'output-encoding' => 'utf8' ); } // clean up the HTML code $tidy = tidy_parse_string($html, $tidy_options); // fix the HTML $tidy->cleanRepair(); // get the CSS part $tidy_head = tidy_get_head($tidy); $css = $tidy_head->value; $css = preg_replace('/]+)>/ims', ''; // get the body part $tidy_body = tidy_get_body($tidy); $html = $tidy_body->value; // fix some self-closing tags $html = str_replace('
      ', '
      ', $html); // remove some empty tag blocks $html = preg_replace('/]*)><\/div>/', '', $html); $html = preg_replace('/]*)><\/p>/', '', $html); if ($tagvs !== '') { // set vertical space for some XHTML tags $tagvspaces = $tagvs; } // return the cleaned XHTML code + CSS return $css.$html; } /** * Returns true if the CSS selector is valid for the selected HTML tag * @param $dom (array) array of HTML tags and properties * @param $key (int) key of the current HTML tag * @param $selector (string) CSS selector string * @return true if the selector is valid, false otherwise * @since 5.1.000 (2010-05-25) * @public static */ public static function isValidCSSSelectorForTag($dom, $key, $selector) { $valid = false; // value to be returned $tag = $dom[$key]['value']; $class = array(); if (isset($dom[$key]['attribute']['class']) AND !empty($dom[$key]['attribute']['class'])) { $class = explode(' ', strtolower($dom[$key]['attribute']['class'])); } $id = ''; if (isset($dom[$key]['attribute']['id']) AND !empty($dom[$key]['attribute']['id'])) { $id = strtolower($dom[$key]['attribute']['id']); } $selector = preg_replace('/([\>\+\~\s]{1})([\.]{1})([^\>\+\~\s]*)/si', '\\1*.\\3', $selector); $matches = array(); if (preg_match_all('/([\>\+\~\s]{1})([a-zA-Z0-9\*]+)([^\>\+\~\s]*)/si', $selector, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) > 0) { $parentop = array_pop($matches[1]); $operator = $parentop[0]; $offset = $parentop[1]; $lasttag = array_pop($matches[2]); $lasttag = strtolower(trim($lasttag[0])); if (($lasttag == '*') OR ($lasttag == $tag)) { // the last element on selector is our tag or 'any tag' $attrib = array_pop($matches[3]); $attrib = strtolower(trim($attrib[0])); if (!empty($attrib)) { // check if matches class, id, attribute, pseudo-class or pseudo-element switch ($attrib{0}) { case '.': { // class if (in_array(substr($attrib, 1), $class)) { $valid = true; } break; } case '#': { // ID if (substr($attrib, 1) == $id) { $valid = true; } break; } case '[': { // attribute $attrmatch = array(); if (preg_match('/\[([a-zA-Z0-9]*)[\s]*([\~\^\$\*\|\=]*)[\s]*["]?([^"\]]*)["]?\]/i', $attrib, $attrmatch) > 0) { $att = strtolower($attrmatch[1]); $val = $attrmatch[3]; if (isset($dom[$key]['attribute'][$att])) { switch ($attrmatch[2]) { case '=': { if ($dom[$key]['attribute'][$att] == $val) { $valid = true; } break; } case '~=': { if (in_array($val, explode(' ', $dom[$key]['attribute'][$att]))) { $valid = true; } break; } case '^=': { if ($val == substr($dom[$key]['attribute'][$att], 0, strlen($val))) { $valid = true; } break; } case '$=': { if ($val == substr($dom[$key]['attribute'][$att], -strlen($val))) { $valid = true; } break; } case '*=': { if (strpos($dom[$key]['attribute'][$att], $val) !== false) { $valid = true; } break; } case '|=': { if ($dom[$key]['attribute'][$att] == $val) { $valid = true; } elseif (preg_match('/'.$val.'[\-]{1}/i', $dom[$key]['attribute'][$att]) > 0) { $valid = true; } break; } default: { $valid = true; } } } } break; } case ':': { // pseudo-class or pseudo-element if ($attrib{1} == ':') { // pseudo-element // pseudo-elements are not supported! // (::first-line, ::first-letter, ::before, ::after) } else { // pseudo-class // pseudo-classes are not supported! // (:root, :nth-child(n), :nth-last-child(n), :nth-of-type(n), :nth-last-of-type(n), :first-child, :last-child, :first-of-type, :last-of-type, :only-child, :only-of-type, :empty, :link, :visited, :active, :hover, :focus, :target, :lang(fr), :enabled, :disabled, :checked) } break; } } // end of switch } else { $valid = true; } if ($valid AND ($offset > 0)) { $valid = false; // check remaining selector part $selector = substr($selector, 0, $offset); switch ($operator) { case ' ': { // descendant of an element while ($dom[$key]['parent'] > 0) { if (self::isValidCSSSelectorForTag($dom, $dom[$key]['parent'], $selector)) { $valid = true; break; } else { $key = $dom[$key]['parent']; } } break; } case '>': { // child of an element $valid = self::isValidCSSSelectorForTag($dom, $dom[$key]['parent'], $selector); break; } case '+': { // immediately preceded by an element for ($i = ($key - 1); $i > $dom[$key]['parent']; --$i) { if ($dom[$i]['tag'] AND $dom[$i]['opening']) { $valid = self::isValidCSSSelectorForTag($dom, $i, $selector); break; } } break; } case '~': { // preceded by an element for ($i = ($key - 1); $i > $dom[$key]['parent']; --$i) { if ($dom[$i]['tag'] AND $dom[$i]['opening']) { if (self::isValidCSSSelectorForTag($dom, $i, $selector)) { break; } } } break; } } } } } return $valid; } /** * Returns the styles array that apply for the selected HTML tag. * @param $dom (array) array of HTML tags and properties * @param $key (int) key of the current HTML tag * @param $css (array) array of CSS properties * @return array containing CSS properties * @since 5.1.000 (2010-05-25) * @public static */ public static function getCSSdataArray($dom, $key, $css) { $cssarray = array(); // style to be returned // get parent CSS selectors $selectors = array(); if (isset($dom[($dom[$key]['parent'])]['csssel'])) { $selectors = $dom[($dom[$key]['parent'])]['csssel']; } // get all styles that apply foreach($css as $selector => $style) { $pos = strpos($selector, ' '); // get specificity $specificity = substr($selector, 0, $pos); // remove specificity $selector = substr($selector, $pos); // check if this selector apply to current tag if (self::isValidCSSSelectorForTag($dom, $key, $selector)) { if (!in_array($selector, $selectors)) { // add style if not already added on parent selector $cssarray[] = array('k' => $selector, 's' => $specificity, 'c' => $style); $selectors[] = $selector; } } } if (isset($dom[$key]['attribute']['style'])) { // attach inline style (latest properties have high priority) $cssarray[] = array('k' => '', 's' => '1000', 'c' => $dom[$key]['attribute']['style']); } // order the css array to account for specificity $cssordered = array(); foreach ($cssarray as $key => $val) { $skey = sprintf('%04d', $key); $cssordered[$val['s'].'_'.$skey] = $val; } // sort selectors alphabetically to account for specificity ksort($cssordered, SORT_STRING); return array($selectors, $cssordered); } /** * Compact CSS data array into single string. * @param $css (array) array of CSS properties * @return string containing merged CSS properties * @since 5.9.070 (2011-04-19) * @public static */ public static function getTagStyleFromCSSarray($css) { $tagstyle = ''; // value to be returned foreach ($css as $style) { // split single css commands $csscmds = explode(';', $style['c']); foreach ($csscmds as $cmd) { if (!empty($cmd)) { $pos = strpos($cmd, ':'); if ($pos !== false) { $cmd = substr($cmd, 0, ($pos + 1)); if (strpos($tagstyle, $cmd) !== false) { // remove duplicate commands (last commands have high priority) $tagstyle = preg_replace('/'.$cmd.'[^;]+/i', '', $tagstyle); } } } } $tagstyle .= ';'.$style['c']; } // remove multiple semicolons $tagstyle = preg_replace('/[;]+/', ';', $tagstyle); return $tagstyle; } /** * Returns the Roman representation of an integer number * @param $number (int) number to convert * @return string roman representation of the specified number * @since 4.4.004 (2008-12-10) * @public static */ public static function intToRoman($number) { $roman = ''; while ($number >= 1000) { $roman .= 'M'; $number -= 1000; } while ($number >= 900) { $roman .= 'CM'; $number -= 900; } while ($number >= 500) { $roman .= 'D'; $number -= 500; } while ($number >= 400) { $roman .= 'CD'; $number -= 400; } while ($number >= 100) { $roman .= 'C'; $number -= 100; } while ($number >= 90) { $roman .= 'XC'; $number -= 90; } while ($number >= 50) { $roman .= 'L'; $number -= 50; } while ($number >= 40) { $roman .= 'XL'; $number -= 40; } while ($number >= 10) { $roman .= 'X'; $number -= 10; } while ($number >= 9) { $roman .= 'IX'; $number -= 9; } while ($number >= 5) { $roman .= 'V'; $number -= 5; } while ($number >= 4) { $roman .= 'IV'; $number -= 4; } while ($number >= 1) { $roman .= 'I'; --$number; } return $roman; } /** * Find position of last occurrence of a substring in a string * @param $haystack (string) The string to search in. * @param $needle (string) substring to search. * @param $offset (int) May be specified to begin searching an arbitrary number of characters into the string. * @return Returns the position where the needle exists. Returns FALSE if the needle was not found. * @since 4.8.038 (2010-03-13) * @public static */ public static function revstrpos($haystack, $needle, $offset = 0) { $length = strlen($haystack); $offset = ($offset > 0)?($length - $offset):abs($offset); $pos = strpos(strrev($haystack), strrev($needle), $offset); return ($pos === false)?false:($length - $pos - strlen($needle)); } /** * Serialize an array of parameters to be used with TCPDF tag in HTML code. * @param $pararray (array) parameters array * @return sting containing serialized data * @since 4.9.006 (2010-04-02) * @public static */ public static function serializeTCPDFtagParameters($pararray) { return urlencode(serialize($pararray)); } /** * Returns an array of hyphenation patterns. * @param $file (string) TEX file containing hypenation patterns. TEX pattrns can be downloaded from http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/ * @return array of hyphenation patterns * @author Nicola Asuni * @since 4.9.012 (2010-04-12) * @public static */ public static function getHyphenPatternsFromTEX($file) { // TEX patterns are available at: // http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/ $data = file_get_contents($file); $patterns = array(); // remove comments $data = preg_replace('/\%[^\n]*/', '', $data); // extract the patterns part preg_match('/\\\\patterns\{([^\}]*)\}/i', $data, $matches); $data = trim(substr($matches[0], 10, -1)); // extract each pattern $patterns_array = preg_split('/[\s]+/', $data); // create new language array of patterns $patterns = array(); foreach($patterns_array as $val) { if (!TCPDF_STATIC::empty_string($val)) { $val = trim($val); $val = str_replace('\'', '\\\'', $val); $key = preg_replace('/[0-9]+/', '', $val); $patterns[$key] = $val; } } return $patterns; } /** * Get the Path-Painting Operators. * @param $style (string) Style of rendering. Possible values are: *
        *
      • S or D: Stroke the path.
      • *
      • s or d: Close and stroke the path.
      • *
      • f or F: Fill the path, using the nonzero winding number rule to determine the region to fill.
      • *
      • f* or F*: Fill the path, using the even-odd rule to determine the region to fill.
      • *
      • B or FD or DF: Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill.
      • *
      • B* or F*D or DF*: Fill and then stroke the path, using the even-odd rule to determine the region to fill.
      • *
      • b or fd or df: Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill.
      • *
      • b or f*d or df*: Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill.
      • *
      • CNZ: Clipping mode using the even-odd rule to determine which regions lie inside the clipping path.
      • *
      • CEO: Clipping mode using the nonzero winding number rule to determine which regions lie inside the clipping path
      • *
      • n: End the path object without filling or stroking it.
      • *
      * @param $default (string) default style * @author Nicola Asuni * @since 5.0.000 (2010-04-30) * @public static */ public static function getPathPaintOperator($style, $default='S') { $op = ''; switch($style) { case 'S': case 'D': { $op = 'S'; break; } case 's': case 'd': { $op = 's'; break; } case 'f': case 'F': { $op = 'f'; break; } case 'f*': case 'F*': { $op = 'f*'; break; } case 'B': case 'FD': case 'DF': { $op = 'B'; break; } case 'B*': case 'F*D': case 'DF*': { $op = 'B*'; break; } case 'b': case 'fd': case 'df': { $op = 'b'; break; } case 'b*': case 'f*d': case 'df*': { $op = 'b*'; break; } case 'CNZ': { $op = 'W n'; break; } case 'CEO': { $op = 'W* n'; break; } case 'n': { $op = 'n'; break; } default: { if (!empty($default)) { $op = self::getPathPaintOperator($default, ''); } else { $op = ''; } } } return $op; } /** * Get the product of two SVG tranformation matrices * @param $ta (array) first SVG tranformation matrix * @param $tb (array) second SVG tranformation matrix * @return transformation array * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @public static */ public static function getTransformationMatrixProduct($ta, $tb) { $tm = array(); $tm[0] = ($ta[0] * $tb[0]) + ($ta[2] * $tb[1]); $tm[1] = ($ta[1] * $tb[0]) + ($ta[3] * $tb[1]); $tm[2] = ($ta[0] * $tb[2]) + ($ta[2] * $tb[3]); $tm[3] = ($ta[1] * $tb[2]) + ($ta[3] * $tb[3]); $tm[4] = ($ta[0] * $tb[4]) + ($ta[2] * $tb[5]) + $ta[4]; $tm[5] = ($ta[1] * $tb[4]) + ($ta[3] * $tb[5]) + $ta[5]; return $tm; } /** * Get the tranformation matrix from SVG transform attribute * @param $attribute (string) transformation * @return array of transformations * @author Nicola Asuni * @since 5.0.000 (2010-05-02) * @public static */ public static function getSVGTransformMatrix($attribute) { // identity matrix $tm = array(1, 0, 0, 1, 0, 0); $transform = array(); if (preg_match_all('/(matrix|translate|scale|rotate|skewX|skewY)[\s]*\(([^\)]+)\)/si', $attribute, $transform, PREG_SET_ORDER) > 0) { foreach ($transform as $key => $data) { if (!empty($data[2])) { $a = 1; $b = 0; $c = 0; $d = 1; $e = 0; $f = 0; $regs = array(); switch ($data[1]) { case 'matrix': { if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) { $a = $regs[1]; $b = $regs[2]; $c = $regs[3]; $d = $regs[4]; $e = $regs[5]; $f = $regs[6]; } break; } case 'translate': { if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) { $e = $regs[1]; $f = $regs[2]; } elseif (preg_match('/([a-z0-9\-\.]+)/si', $data[2], $regs)) { $e = $regs[1]; } break; } case 'scale': { if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) { $a = $regs[1]; $d = $regs[2]; } elseif (preg_match('/([a-z0-9\-\.]+)/si', $data[2], $regs)) { $a = $regs[1]; $d = $a; } break; } case 'rotate': { if (preg_match('/([0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) { $ang = deg2rad($regs[1]); $x = $regs[2]; $y = $regs[3]; $a = cos($ang); $b = sin($ang); $c = -$b; $d = $a; $e = ($x * (1 - $a)) - ($y * $c); $f = ($y * (1 - $d)) - ($x * $b); } elseif (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) { $ang = deg2rad($regs[1]); $a = cos($ang); $b = sin($ang); $c = -$b; $d = $a; $e = 0; $f = 0; } break; } case 'skewX': { if (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) { $c = tan(deg2rad($regs[1])); } break; } case 'skewY': { if (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) { $b = tan(deg2rad($regs[1])); } break; } } $tm = self::getTransformationMatrixProduct($tm, array($a, $b, $c, $d, $e, $f)); } } } return $tm; } /** * Returns the angle in radiants between two vectors * @param $x1 (int) X coordinate of first vector point * @param $y1 (int) Y coordinate of first vector point * @param $x2 (int) X coordinate of second vector point * @param $y2 (int) Y coordinate of second vector point * @author Nicola Asuni * @since 5.0.000 (2010-05-04) * @public static */ public static function getVectorsAngle($x1, $y1, $x2, $y2) { $dprod = ($x1 * $x2) + ($y1 * $y2); $dist1 = sqrt(($x1 * $x1) + ($y1 * $y1)); $dist2 = sqrt(($x2 * $x2) + ($y2 * $y2)); $angle = acos($dprod / ($dist1 * $dist2)); if (is_nan($angle)) { $angle = M_PI; } if ((($x1 * $y2) - ($x2 * $y1)) < 0) { $angle *= -1; } return $angle; } } // END OF TCPDF_STATIC CLASS //============================================================+ // END OF FILE //============================================================+ Collabtive-2.0/include/initfunctions.php000066400000000000000000000117341237252063700205040ustar00rootroot00000000000000query("SELECT ID FROM projekte_assigned WHERE projekt = $project AND user = $user")->fetch(); $chk = $chk[0]; if ($chk != "") { return true; } else { return false; } } function getAvailableLanguages() { $dir = scandir(CL_ROOT . "/language/"); $languages = array(); if (!empty($dir)) { foreach($dir as $folder) { if ($folder != "." and $folder != "..") { array_push($languages, $folder); } } } if (!empty($languages)) { return $languages; } else { return false; } } function countLanguageStrings($locale) { if (file_exists(CL_ROOT . "/language/$locale/lng.conf")) { $langfile = file("./language/$locale/lng.conf"); $cou1 = (int) 0; $cou2 = (int) 0; } if (!empty($langfile)) { foreach($langfile as $lang) { if (strstr($lang, "=")) { $cou1 = $cou1 + 1; $slang = explode("=", $lang); if (trim($slang[1]) != "") { $cou2 = $cou2 + 1; } } } } if ($cou1 > 0 and $cou2 > 0) { $proz = $cou2 / $cou1 * 100; return floor($proz); } else { return 0; } } function readLangfile($locale) { $langfile = file("./language/$locale/lng.conf"); $langkeys = array(); $langvalues = array(); foreach($langfile as $lang) { if (strstr($lang, "=")) { $slang = explode("=", $lang); array_push($langkeys, trim($slang[0])); array_push($langvalues, trim($slang[1])); } } $langfile = array_combine($langkeys, $langvalues); if (!empty($langfile)) { return $langfile; } else { return false; } } function detectSSL() { if (getArrayVal($_SERVER, "https") == "on") { return true; } elseif (getArrayVal($_SERVER, "https") == 1) { return true; } elseif (getArrayVal($_SERVER, "HTTPS") == 1) { return true; } elseif (getArrayVal($_SERVER, "SERVER_PORT") == 443) { return true; } else { return false; } } function getMyUrl() { if (isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI'])) { $requri = $_SERVER['REQUEST_URI']; } else { // assume IIS $requri = $_SERVER['SCRIPT_NAME']; if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) { $requri .= '?' . $_SERVER['QUERY_STRING']; } } $host = $_SERVER['HTTP_HOST']; $pos1 = strrpos($requri, "/"); $requri = substr($requri, 0, $pos1 + 1); if (detectSSL()) { $host = "https://" . $host; } else { $host = "http://" . $host; } $url = $host . $requri; return $url; } function getArrayVal(array $array, $name) { if (array_key_exists($name, $array)) { $config = HTMLPurifier_Config::createDefault(); if(file_exists(CL_ROOT . "/files/standard/ics")) { $config->set('Cache.SerializerPath', CL_ROOT . "/files/standard/ics"); } else { $config->set('Cache.SerializerPath', NULL); } $purifier = new HTMLPurifier($config); if (!is_array($array[$name])) { $clean = $purifier->purify($array[$name]); }else { $clean = $array[$name]; } return $clean; } else { return false; } } function delete_directory($dirname) { if (is_dir($dirname)) { $dir_handle = opendir($dirname); } if (!$dir_handle) { return false; } while ($file = readdir($dir_handle)) { if ($file != "." && $file != "..") { if (!is_dir($dirname . "/" . $file)) { unlink($dirname . "/" . $file); } else { delete_directory($dirname . '/' . $file); } } } closedir($dir_handle); rmdir($dirname); return true; } function reduceArray(array $arr) { $num = count($arr); $earr = array(); for($i = 0;$i < $num;$i++) { if (!empty($arr[$i])) { $earr = array_merge($earr, $arr[$i]); } } return $earr; } function getUpdateNotify() { return json_decode(@file_get_contents("http://collabtive.o-dyn.de/update/chk.php")); } function full_url() { $s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : ""; $sp = strtolower($_SERVER["SERVER_PROTOCOL"]); $protocol = substr($sp, 0, strpos($sp, "/")) . $s; $port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":" . $_SERVER["SERVER_PORT"]); return $_SERVER['REQUEST_URI']; } ?> Collabtive-2.0/include/internals/000077500000000000000000000000001237252063700170705ustar00rootroot00000000000000Collabtive-2.0/include/internals/core.assemble_plugin_filepath.php000066400000000000000000000036351237252063700255640ustar00rootroot00000000000000plugins_dir as $_plugin_dir) { $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; // see if path is relative if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) { $_relative_paths[] = $_plugin_dir; // relative path, see if it is in the SMARTY_DIR if (@is_readable(SMARTY_DIR . $_plugin_filepath)) { $_return = SMARTY_DIR . $_plugin_filepath; break; } } // try relative to cwd (or absolute) if (@is_readable($_plugin_filepath)) { $_return = $_plugin_filepath; break; } } if($_return === false) { // still not found, try PHP include_path if(isset($_relative_paths)) { foreach ((array)$_relative_paths as $_plugin_dir) { $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; $_params = array('file_path' => $_plugin_filepath); require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); if(smarty_core_get_include_path($_params, $smarty)) { $_return = $_params['new_file_path']; break; } } } } $_filepaths_cache[$_plugin_filename] = $_return; return $_return; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.assign_smarty_interface.php000066400000000000000000000023521237252063700254350ustar00rootroot00000000000000 * Name: assign_smarty_interface
      * Purpose: assign the $smarty interface variable * @param array Format: null * @param Smarty */ function smarty_core_assign_smarty_interface($params, &$smarty) { if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) { return; } $_globals_map = array('g' => 'HTTP_GET_VARS', 'p' => 'HTTP_POST_VARS', 'c' => 'HTTP_COOKIE_VARS', 's' => 'HTTP_SERVER_VARS', 'e' => 'HTTP_ENV_VARS'); $_smarty_vars_request = array(); foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) { if (isset($_globals_map[$_c])) { $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]); } } $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']); $smarty->_smarty_vars['request'] = $_smarty_vars_request; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.create_dir_structure.php000066400000000000000000000047131237252063700247560ustar00rootroot00000000000000_dir_perms) && !is_dir($_new_dir)) { $smarty->trigger_error("problem creating directory '" . $_new_dir . "'"); return false; } $_new_dir .= '/'; } } } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.display_debug_console.php000066400000000000000000000030571237252063700250720ustar00rootroot00000000000000 * Name: display_debug_console
      * Purpose: display the javascript debug console window * @param array Format: null * @param Smarty */ function smarty_core_display_debug_console($params, &$smarty) { // we must force compile the debug template in case the environment // changed between separate applications. if(empty($smarty->debug_tpl)) { // set path to debug template from SMARTY_DIR $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; if($smarty->security && is_file($smarty->debug_tpl)) { $smarty->secure_dir[] = realpath($smarty->debug_tpl); } $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; } $_ldelim_orig = $smarty->left_delimiter; $_rdelim_orig = $smarty->right_delimiter; $smarty->left_delimiter = '{'; $smarty->right_delimiter = '}'; $_compile_id_orig = $smarty->_compile_id; $smarty->_compile_id = null; $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl); if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path)) { ob_start(); $smarty->_include($_compile_path); $_results = ob_get_contents(); ob_end_clean(); } else { $_results = ''; } $smarty->_compile_id = $_compile_id_orig; $smarty->left_delimiter = $_ldelim_orig; $smarty->right_delimiter = $_rdelim_orig; return $_results; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.get_include_path.php000066400000000000000000000017521237252063700240330ustar00rootroot00000000000000 Collabtive-2.0/include/internals/core.get_microtime.php000066400000000000000000000005501237252063700233570ustar00rootroot00000000000000 Collabtive-2.0/include/internals/core.get_php_resource.php000066400000000000000000000046431237252063700240740ustar00rootroot00000000000000trusted_dir; $smarty->_parse_resource_name($params, $smarty); /* * Find out if the resource exists. */ if ($params['resource_type'] == 'file') { $_readable = false; if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) { $_readable = true; } else { // test for file in include_path $_params = array('file_path' => $params['resource_name']); require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); if(smarty_core_get_include_path($_params, $smarty)) { $_include_path = $_params['new_file_path']; $_readable = true; } } } else if ($params['resource_type'] != 'file') { $_template_source = null; $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0]) && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0], array($params['resource_name'], &$_template_source, &$smarty)); } /* * Set the error function, depending on which class calls us. */ if (method_exists($smarty, '_syntax_error')) { $_error_funcc = '_syntax_error'; } else { $_error_funcc = 'trigger_error'; } if ($_readable) { if ($smarty->security) { require_once(SMARTY_CORE_DIR . 'core.is_trusted.php'); if (!smarty_core_is_trusted($params, $smarty)) { $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted'); return false; } } } else { $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable'); return false; } if ($params['resource_type'] == 'file') { $params['php_resource'] = $params['resource_name']; } else { $params['php_resource'] = $_template_source; } return true; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.is_secure.php000066400000000000000000000032361237252063700225150ustar00rootroot00000000000000security || $smarty->security_settings['INCLUDE_ANY']) { return true; } if ($params['resource_type'] == 'file') { $_rp = realpath($params['resource_name']); if (isset($params['resource_base_path'])) { foreach ((array)$params['resource_base_path'] as $curr_dir) { if ( ($_cd = realpath($curr_dir)) !== false && strncmp($_rp, $_cd, strlen($_cd)) == 0 && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { return true; } } } if (!empty($smarty->secure_dir)) { foreach ((array)$smarty->secure_dir as $curr_dir) { if ( ($_cd = realpath($curr_dir)) !== false) { if($_cd == $_rp) { return true; } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { return true; } } } } } else { // resource is not on local file system return call_user_func_array( $smarty->_plugins['resource'][$params['resource_type']][0][2], array($params['resource_name'], &$smarty)); } return false; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.is_trusted.php000066400000000000000000000024041237252063700227150ustar00rootroot00000000000000trusted_dir)) { $_rp = realpath($params['resource_name']); foreach ((array)$smarty->trusted_dir as $curr_dir) { if (!empty($curr_dir) && is_readable ($curr_dir)) { $_cd = realpath($curr_dir); if (strncmp($_rp, $_cd, strlen($_cd)) == 0 && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { $_smarty_trusted = true; break; } } } } } else { // resource is not on local file system $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3], array($params['resource_name'], $smarty)); } return $_smarty_trusted; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.load_plugins.php000066400000000000000000000105151237252063700232120ustar00rootroot00000000000000_plugins[$_type][$_name]; /* * We do not load plugin more than once for each instance of Smarty. * The following code checks for that. The plugin can also be * registered dynamically at runtime, in which case template file * and line number will be unknown, so we fill them in. * * The final element of the info array is a flag that indicates * whether the dynamically registered plugin function has been * checked for existence yet or not. */ if (isset($_plugin)) { if (empty($_plugin[3])) { if (!is_callable($_plugin[0])) { $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__); } else { $_plugin[1] = $_tpl_file; $_plugin[2] = $_tpl_line; $_plugin[3] = true; if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */ } } continue; } else if ($_type == 'insert') { /* * For backwards compatibility, we check for insert functions in * the symbol table before trying to load them as a plugin. */ $_plugin_func = 'insert_' . $_name; if (function_exists($_plugin_func)) { $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false); continue; } } $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name); if (! $_found = ($_plugin_file != false)) { $_message = "could not load plugin file '$_type.$_name.php'\n"; } /* * If plugin file is found, it -must- provide the properly named * plugin function. In case it doesn't, simply output the error and * do not fall back on any other method. */ if ($_found) { include_once $_plugin_file; $_plugin_func = 'smarty_' . $_type . '_' . $_name; if (!function_exists($_plugin_func)) { $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__); continue; } } /* * In case of insert plugins, their code may be loaded later via * 'script' attribute. */ else if ($_type == 'insert' && $_delayed_loading) { $_plugin_func = 'smarty_' . $_type . '_' . $_name; $_found = true; } /* * Plugin specific processing and error checking. */ if (!$_found) { if ($_type == 'modifier') { /* * In case modifier falls back on using PHP functions * directly, we only allow those specified in the security * context. */ if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) { $_message = "(secure mode) modifier '$_name' is not allowed"; } else { if (!function_exists($_name)) { $_message = "modifier '$_name' is not implemented"; } else { $_plugin_func = $_name; $_found = true; } } } else if ($_type == 'function') { /* * This is a catch-all situation. */ $_message = "unknown tag - '$_name'"; } } if ($_found) { $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true); } else { // output error $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__); } } } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.load_resource_plugin.php000066400000000000000000000041431237252063700247360ustar00rootroot00000000000000_plugins['resource'][$params['type']]; if (isset($_plugin)) { if (!$_plugin[1] && count($_plugin[0])) { $_plugin[1] = true; foreach ($_plugin[0] as $_plugin_func) { if (!is_callable($_plugin_func)) { $_plugin[1] = false; break; } } } if (!$_plugin[1]) { $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__); } return; } $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']); $_found = ($_plugin_file != false); if ($_found) { /* * If the plugin file is found, it -must- provide the properly named * plugin functions. */ include_once($_plugin_file); /* * Locate functions that we require the plugin to provide. */ $_resource_ops = array('source', 'timestamp', 'secure', 'trusted'); $_resource_funcs = array(); foreach ($_resource_ops as $_op) { $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op; if (!function_exists($_plugin_func)) { $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__); return; } else { $_resource_funcs[] = $_plugin_func; } } $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true); } } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.process_cached_inserts.php000066400000000000000000000046401237252063700252500ustar00rootroot00000000000000_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis', $params['results'], $match); list($cached_inserts, $insert_args) = $match; for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) { if ($smarty->debugging) { $_params = array(); require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $debug_start_time = smarty_core_get_microtime($_params, $smarty); } $args = unserialize($insert_args[$i]); $name = $args['name']; if (isset($args['script'])) { $_params = array('resource_name' => $smarty->_dequote($args['script'])); require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); if(!smarty_core_get_php_resource($_params, $smarty)) { return false; } $resource_type = $_params['resource_type']; $php_resource = $_params['php_resource']; if ($resource_type == 'file') { $smarty->_include($php_resource, true); } else { $smarty->_eval($php_resource); } } $function_name = $smarty->_plugins['insert'][$name][0]; if (empty($args['assign'])) { $replace = $function_name($args, $smarty); } else { $smarty->assign($args['assign'], $function_name($args, $smarty)); $replace = ''; } $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); if ($smarty->debugging) { $_params = array(); require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $smarty->_smarty_debug_info[] = array('type' => 'insert', 'filename' => 'insert_'.$name, 'depth' => $smarty->_inclusion_depth, 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time); } } return $params['results']; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.process_compiled_include.php000066400000000000000000000017631237252063700255740ustar00rootroot00000000000000_cache_including; $smarty->_cache_including = true; $_return = $params['results']; foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { $smarty->_include($_include_file_path, true); } foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) { $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', array(&$smarty, '_process_compiled_include_callback'), $_return); } $smarty->_cache_including = $_cache_including; return $_return; } ?> Collabtive-2.0/include/internals/core.read_cache_file.php000066400000000000000000000070241237252063700235700ustar00rootroot00000000000000force_compile) { // force compile enabled, always regenerate return false; } if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) { list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']]; return true; } if (!empty($smarty->cache_handler_func)) { // use cache_handler function call_user_func_array($smarty->cache_handler_func, array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); } else { // use local cache file $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); $params['results'] = $smarty->_read_file($_cache_file); } if (empty($params['results'])) { // nothing to parse (error?), regenerate cache return false; } $_contents = $params['results']; $_info_start = strpos($_contents, "\n") + 1; $_info_len = (int)substr($_contents, 0, $_info_start - 1); $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len)); $params['results'] = substr($_contents, $_info_start + $_info_len); if ($smarty->caching == 2 && isset ($_cache_info['expires'])){ // caching by expiration time if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) { // cache expired, regenerate return false; } } else { // caching by lifetime if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) { // cache expired, regenerate return false; } } if ($smarty->compile_check) { $_params = array('get_source' => false, 'quiet'=>true); foreach (array_keys($_cache_info['template']) as $_template_dep) { $_params['resource_name'] = $_template_dep; if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { // template file has changed, regenerate cache return false; } } if (isset($_cache_info['config'])) { $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true); foreach (array_keys($_cache_info['config']) as $_config_dep) { $_params['resource_name'] = $_config_dep; if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { // config file has changed, regenerate cache return false; } } } } $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); $smarty->_cache_info = $_cache_info; return true; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.rm_auto.php000066400000000000000000000043561237252063700222060ustar00rootroot00000000000000 $params['auto_base'], 'level' => 0, 'exp_time' => $params['exp_time'] ); require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); $_res = smarty_core_rmdir($_params, $smarty); } else { $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); if(isset($params['auto_source'])) { if (isset($params['extensions'])) { $_res = false; foreach ((array)$params['extensions'] as $_extension) $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']); } else { $_res = $smarty->_unlink($_tname, $params['exp_time']); } } elseif ($smarty->use_sub_dirs) { $_params = array( 'dirname' => $_tname, 'level' => 1, 'exp_time' => $params['exp_time'] ); require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); $_res = smarty_core_rmdir($_params, $smarty); } else { // remove matching file names $_handle = opendir($params['auto_base']); $_res = true; while (false !== ($_filename = readdir($_handle))) { if($_filename == '.' || $_filename == '..') { continue; } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']); } } } } return $_res; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.rmdir.php000066400000000000000000000026441237252063700216530ustar00rootroot00000000000000 keep root) * WARNING: no tests, it will try to remove what you tell it! * * @param string $dirname * @param integer $level * @param integer $exp_time * @return boolean */ // $dirname, $level = 1, $exp_time = null function smarty_core_rmdir($params, &$smarty) { if(!isset($params['level'])) { $params['level'] = 1; } if(!isset($params['exp_time'])) { $params['exp_time'] = null; } if($_handle = @opendir($params['dirname'])) { while (false !== ($_entry = readdir($_handle))) { if ($_entry != '.' && $_entry != '..') { if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { $_params = array( 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry, 'level' => $params['level'] + 1, 'exp_time' => $params['exp_time'] ); smarty_core_rmdir($_params, $smarty); } else { $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']); } } } closedir($_handle); } if ($params['level']) { return @rmdir($params['dirname']); } return (bool)$_handle; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.run_insert_handler.php000066400000000000000000000051401237252063700244150ustar00rootroot00000000000000debugging) { $_params = array(); $_debug_start_time = smarty_core_get_microtime($_params, $smarty); } if ($smarty->caching) { $_arg_string = serialize($params['args']); $_name = $params['args']['name']; if (!isset($smarty->_cache_info['insert_tags'][$_name])) { $smarty->_cache_info['insert_tags'][$_name] = array('insert', $_name, $smarty->_plugins['insert'][$_name][1], $smarty->_plugins['insert'][$_name][2], !empty($params['args']['script']) ? true : false); } return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5; } else { if (isset($params['args']['script'])) { $_params = array('resource_name' => $smarty->_dequote($params['args']['script'])); require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); if(!smarty_core_get_php_resource($_params, $smarty)) { return false; } if ($_params['resource_type'] == 'file') { $smarty->_include($_params['php_resource'], true); } else { $smarty->_eval($_params['php_resource']); } unset($params['args']['script']); } $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0]; $_content = $_funcname($params['args'], $smarty); if ($smarty->debugging) { $_params = array(); require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $smarty->_smarty_debug_info[] = array('type' => 'insert', 'filename' => 'insert_'.$params['args']['name'], 'depth' => $smarty->_inclusion_depth, 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); } if (!empty($params['args']["assign"])) { $smarty->assign($params['args']["assign"], $_content); } else { return $_content; } } } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.smarty_include_php.php000066400000000000000000000031021237252063700244150ustar00rootroot00000000000000 $params['smarty_file']); require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); smarty_core_get_php_resource($_params, $smarty); $_smarty_resource_type = $_params['resource_type']; $_smarty_php_resource = $_params['php_resource']; if (!empty($params['smarty_assign'])) { ob_start(); if ($_smarty_resource_type == 'file') { $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); } else { $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); } $smarty->assign($params['smarty_assign'], ob_get_contents()); ob_end_clean(); } else { if ($_smarty_resource_type == 'file') { $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); } else { $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); } } } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.write_cache_file.php000066400000000000000000000070441237252063700240110ustar00rootroot00000000000000_cache_info['timestamp'] = time(); if ($smarty->cache_lifetime > -1){ // expiration set $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime; } else { // cache will never expire $smarty->_cache_info['expires'] = -1; } // collapse nocache.../nocache-tags if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { // remove everything between every pair of outermost noache.../nocache-tags // and replace it by a single nocache-tag // this new nocache-tag will be replaced by dynamic contents in // smarty_core_process_compiled_includes() on a cache-read $match_count = count($match[0]); $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); $level = 0; $j = 0; for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { if ($results[$i] == $match[0][$j]) { // nocache tag if ($match[1][$j]) { // closing tag $level--; unset($results[$i]); } else { // opening tag if ($level++ > 0) unset($results[$i]); } $j++; } elseif ($level > 0) { unset($results[$i]); } } $params['results'] = implode('', $results); } $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; // prepend the cache header info into cache file $_cache_info = serialize($smarty->_cache_info); $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; if (!empty($smarty->cache_handler_func)) { // use cache_handler function call_user_func_array($smarty->cache_handler_func, array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); } else { // use local cache file if(!@is_writable($smarty->cache_dir)) { // cache_dir not writable, see if it exists if(!@is_dir($smarty->cache_dir)) { $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); return false; } $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR); return false; } $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); require_once(SMARTY_CORE_DIR . 'core.write_file.php'); smarty_core_write_file($_params, $smarty); return true; } } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.write_compiled_include.php000066400000000000000000000060721237252063700252460ustar00rootroot00000000000000caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;'; $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;'; preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', $params['compiled_content'], $_match_source, PREG_SET_ORDER); // no nocache-parts found: done if (count($_match_source)==0) return; // convert the matched php-code to functions $_include_compiled = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n"; $_compile_path = $params['include_file_path']; $smarty->_cache_serials[$_compile_path] = $params['cache_serial']; $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; $_include_compiled .= $params['plugins_code']; $_include_compiled .= "= 5.0) ? '_smarty' : 'this'; for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) { $_match =& $_match_source[$_i]; $source = $_match[4]; if ($this_varname == '_smarty') { /* rename $this to $_smarty in the sourcecode */ $tokens = token_get_all('\n"; $_params = array('filename' => $_compile_path, 'contents' => $_include_compiled, 'create_dirs' => true); require_once(SMARTY_CORE_DIR . 'core.write_file.php'); smarty_core_write_file($_params, $smarty); return true; } ?> Collabtive-2.0/include/internals/core.write_compiled_resource.php000066400000000000000000000020711237252063700254450ustar00rootroot00000000000000compile_dir)) { // compile_dir not writable, see if it exists if(!@is_dir($smarty->compile_dir)) { $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); return false; } $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR); return false; } $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true); require_once(SMARTY_CORE_DIR . 'core.write_file.php'); smarty_core_write_file($_params, $smarty); return true; } /* vim: set expandtab: */ ?> Collabtive-2.0/include/internals/core.write_file.php000066400000000000000000000027641237252063700226720ustar00rootroot00000000000000 $_dirname); require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); smarty_core_create_dir_structure($_params, $smarty); } // write to tmp file, then rename it to avoid file locking race condition $_tmp_file = tempnam($_dirname, 'wrt'); if (!($fd = @fopen($_tmp_file, 'wb'))) { $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt'); if (!($fd = @fopen($_tmp_file, 'wb'))) { $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); return false; } } fwrite($fd, $params['contents']); fclose($fd); if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) { // On platforms and filesystems that cannot overwrite with rename() // delete the file before renaming it -- because windows always suffers // this, it is short-circuited to avoid the initial rename() attempt @unlink($params['filename']); @rename($_tmp_file, $params['filename']); } @chmod($params['filename'], $smarty->_file_perms); return true; } /* vim: set expandtab: */ ?>Collabtive-2.0/include/js/000077500000000000000000000000001237252063700155055ustar00rootroot00000000000000Collabtive-2.0/include/js/5up.js000066400000000000000000000113351237252063700165570ustar00rootroot00000000000000/** * * @access public * @return void **/ function finisher(){ blindtoggle('form_file'); toggleClass('addfile','addfile-active','addfile'); toggleClass('add_file_butn','butn_link_active','butn_link'); toggleClass('sm_files','smooth','nosmooth'); changeFileview($('fileviewtype').value,$('folderparent').value); $("statusrow").setAttribute("style","display:none;"); $("fileInfo1").innerHTML = ""; systemMsg("fileadded"); } function checkCompat(){ try{ formDataChk = new FormData(); } catch(e) { formDataChk = false; } try{ xhrChk = new XMLHttpRequest(); } catch(e) { xhrChk = false; } if(xhrChk && formDataChk) { return true; } else { return false; } } function getSelectedOptions(oList) { var sdValues = []; for(var i = 1; i < oList.options.length; i++) { if(oList.options[i].selected == true) { sdValues.push(oList.options[i].value); } } return sdValues; } function html5up(theFiles,theInfoEl,theIndicator,theTarget) { //File upload element this.theFiles = document.getElementById(theFiles); //HTML Element where the file info / list is displayed this.infoEl = document.getElementById(theInfoEl); //script where the upload is sent this.theTarget = theTarget; //HTML Element where the upload progress is displayed indicator = document.getElementById(theIndicator); } //gets information about the files selected in theFiles and prints them to an HTML element html5up.prototype.fileInfo = function() { var theFiles = this.theFiles.files; //String to be written to the HTML element where the fileinfo is displayed var outstr = ""; outstr += "
        "; //loop through all the files from the file input field for(var i=0;i 1024 * 1024) { fileSize = (Math.round(theFiles[i].size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; } else { fileSize = (Math.round(theFiles[i].size * 100 / 1024) / 100).toString() + 'KB'; } //Write a list item and the filename into the file info outstr += "
      1. " + theFiles[i].name + "
      2. "; } } outstr += "
      "; //Write the file info to the HTML element this.infoEl.innerHTML = outstr; } //uploads files to the script specified in theTarget html5up.prototype.upload = function() { var theFiles = this.theFiles.files; var myData = new FormData(); var upfolder = $('upfolder').value; var sendtos = getSelectedOptions($('sendto')); myData.append("upfolder",upfolder); //Loop through the files and create an upload form object for(var i = 0;i //endcolor for close element flashing closeEndcolor = '#377814'; //endcolor for delete element flashing deleteEndcolor = '#c62424'; //various ajax functions function change(script,element) { var ajax = new Ajax.Updater({success: element},script,{method: 'get',evalScripts:true}); } function changeshow(script,element,theindicator) { var ajax = new Ajax.Updater({success: element},script,{method: 'get',evalScripts:true,onCreate:startWait(theindicator)}); } function changePost(script,element,pbody) { var ajax = new Ajax.Updater({success: element},script,{method:'post', postBody:pbody,evalScripts:true}); } function startWait(indic) { $(indic).style.display = 'block'; } function stopWait(indic) { $(indic).style.display = 'none'; } function deleteElement(theElement,theUrl) { new Ajax.Request(theUrl, { method: 'get', onSuccess:function(payload) { if (payload.responseText == "ok") { removeRow(theElement,deleteEndcolor); result = true; } } }); try { systemMsg("deleted"); } catch(e){} } function closeElement(theElement,theUrl) { new Ajax.Request(theUrl, { method: 'get', onSuccess: function(payload) { if (payload.responseText == "ok") { removeRow(theElement,closeEndcolor); } } }); try { systemMsg("closed"); } catch(e){} } function recolorRows(therow) { row = therow.options.rowid; var theTable = $(row).parentNode; tbodys = $$('#'+theTable.id +' tbody:not([id='+row+'])'); bodies = new Array(); tbodys.each(function(s) { if(s.style.display != 'none') { bodies.push(s); } } ); for(i=0;i"; } if(sortmode == "daysleft") { tbodies.sort(daysort); } else if(sortmode == "done") { tbodies.sort(done); } else if(sortmode == "project") { tbodies.sort(sortByProject); } else if(sortmode == "byuser") { tbodies.sort(sortByUser); } else { tbodies.sort(sortByTitle); } //$('jslog').innerHTML += "

      sorted:
      "; for(i=0;i"; } } function done(a,b){ var x = a.getAttribute("done"); var y = b.getAttribute("done"); var sortorder = b.getAttribute("sortorder"); //desc if(sortorder == "asc") { return y - x } else { //asc return x - y } } function daysort(a,b){ var x = a.getAttribute("daysleft"); var y = b.getAttribute("daysleft"); var sortorder = b.getAttribute("sortorder"); //desc if(sortorder == "asc") { return y - x } else { //asc return x - y } } function sortByTitle(a, b) { var x = a.title.toLowerCase(); var y = b.title.toLowerCase(); var sortorder = b.getAttribute("sortorder"); if(sortorder == "asc") { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); } else { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); } } function sortByProject(a, b) { var x = a.getAttribute("project"); var y = b.getAttribute("project"); var sortorder = b.getAttribute("sortorder"); if(sortorder == "asc") { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); } else { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); } } function sortByUser(a, b) { var x = a.getAttribute("theuser"); var y = b.getAttribute("theuser"); var sortorder = b.getAttribute("sortorder"); if(sortorder == "asc") { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); } else { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); } } function sortByDays(a, b) { var x = a.getAttribute("daysleft"); var y = b.getAttribute("daysleft"); var sortorder = b.getAttribute("sortorder"); if(sortorder == "asc") { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); } else { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); } } // accordion.js v2.0 // // Copyright (c) 2007 stickmanlabs // Author: Kevin P Miller | http://www.stickmanlabs.com // // Accordion is freely distributable under the terms of an MIT-style license. // // I don't care what you think about the file size... // Be a pro: // http://www.thinkvitamin.com/features/webapps/serving-javascript-fast // http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files // /*-----------------------------------------------------------------------------------------------*/ if (typeof Effect == 'undefined') throw("accordion.js requires including script.aculo.us' effects.js library!"); var accordion = Class.create(); accordion.prototype = { // // Setup the Variables // showAccordion : null, currentAccordion : null, duration : null, effects : [], animating : false, // // Initialize the accordions // initialize: function(container, options) { if (!$(container)) { throw(container+" doesn't exist!"); return false; } this.options = Object.extend({ resizeSpeed : 8, classNames : { toggle : 'accordion_toggle', toggleActive : 'accordion_toggle_active', content : 'accordion_content' }, defaultSize : { height : null, width : null }, direction : 'vertical', onEvent : 'click' }, options || {}); //this.duration = ((11-this.options.resizeSpeed)*0.15); this.duration = 0.3; var accordions = $$('#'+container+' .'+this.options.classNames.toggle); accordions.each(function(accordion) { Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false); if (this.options.onEvent == 'click') { accordion.onclick = function() {return false;}; } if (this.options.direction == 'horizontal') { var options = {width: '0px', display:'none'}; } else { var options = {height: '0px', display:'none'}; } // options.merge({display: 'none'}); this.currentAccordion = $(accordion.next(0)).setStyle(options); }.bind(this)); }, // // Activate an accordion // activate : function(accordion) { if (this.animating) { return false; } this.effects = []; this.currentAccordion = $(accordion.next(0)); this.currentAccordion.setStyle({ display: 'block' }); this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive); if (this.options.direction == 'horizontal') { this.scaling = $H({ scaleX: true, scaleY: false }); } else { this.scaling = $H({ scaleX: false, scaleY: true }); } if (this.currentAccordion == this.showAccordion) { this.deactivate(); } else { this._handleAccordion(); } }, // // Deactivate an active accordion // deactivate : function() { var options = $H({ duration: this.duration, scaleContent: false, transition: Effect.Transitions.sinoidal, queue: { position: 'end', scope: 'accordionAnimation' }, scaleMode: { originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight, originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth }, afterFinish: function() { this.showAccordion.setStyle({ height: 'auto', display: 'none' }); this.showAccordion = null; this.animating = false; }.bind(this) }); // options.merge(this.scaling); this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive); new Effect.Scale(this.showAccordion, 0, options.update(this.scaling).toObject()); }, // // Handle the open/close actions of the accordion // _handleAccordion : function() { var options = $H({ sync: true, scaleFrom: 0, scaleContent: false, transition: Effect.Transitions.sinoidal, scaleMode: { originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight, originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth } }); options.merge(this.scaling); this.effects.push( new Effect.Scale(this.currentAccordion, 100, options.update(this.scaling).toObject()) ); if (this.showAccordion) { this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive); options = $H({ sync: true, scaleContent: false, transition: Effect.Transitions.sinoidal }); options.merge(this.scaling); this.effects.push( new Effect.Scale(this.showAccordion, 0, options.update(this.scaling).toObject()) ); } new Effect.Parallel(this.effects, { duration: this.duration, queue: { position: 'end', scope: 'accordionAnimation' }, beforeStart: function() { this.animating = true; }.bind(this), afterFinish: function() { if (this.showAccordion) { this.showAccordion.setStyle({ display: 'none' }); } $(this.currentAccordion).setStyle({ height: 'auto' }); this.showAccordion = this.currentAccordion; this.animating = false; }.bind(this) }); } } if(typeof (Control)=="undefined"){Control={};}Control.Modal=Class.create();Object.extend(Control.Modal,{loaded:false,loading:false,loadingTimeout:false,overlay:false,container:false,current:false,ie:false,effects:{containerFade:false,containerAppear:false,overlayFade:false,overlayAppear:false},targetRegexp:/#(.+)$/,imgRegexp:/\.(jpe?g|gif|png|tiff?)$/,overlayStyles:{position:"fixed",top:0,left:0,width:"100%",height:"100%",zIndex:9998},overlayIEStyles:{position:"absolute",top:0,left:0,zIndex:9998},disableHoverClose:false,load:function(){if(!Control.Modal.loaded){Control.Modal.loaded=true;Control.Modal.ie=!(typeof document.body.style.maxHeight!="undefined");Control.Modal.overlay=$(document.createElement("div"));Control.Modal.overlay.id="modal_overlay";Object.extend(Control.Modal.overlay.style,Control.Modal["overlay"+(Control.Modal.ie?"IE":"")+"Styles"]);Control.Modal.overlay.hide();Control.Modal.container=$(document.createElement("div"));Control.Modal.container.id="modal_container";Control.Modal.container.hide();Control.Modal.loading=$(document.createElement("div"));Control.Modal.loading.id="modal_loading";Control.Modal.loading.hide();var _1=document.getElementsByTagName("body")[0];_1.appendChild(Control.Modal.overlay);_1.appendChild(Control.Modal.container);_1.appendChild(Control.Modal.loading);Control.Modal.container.observe("mouseout",function(_2){if(!Control.Modal.disableHoverClose&&Control.Modal.current&&Control.Modal.current.options.hover&&!Position.within(Control.Modal.container,Event.pointerX(_2),Event.pointerY(_2))){Control.Modal.close();}});}},open:function(_3,_4){_4=_4||{};if(!_4.contents){_4.contents=_3;}var _5=new Control.Modal(false,_4);_5.open();return _5;},close:function(_6){if(typeof (_6)!="boolean"){_6=false;}if(Control.Modal.current){Control.Modal.current.close(_6);}},attachEvents:function(){Event.observe(window,"load",Control.Modal.load);Event.observe(window,"unload",Event.unloadCache,false);},center:function(_7){if(!_7._absolutized){_7.setStyle({position:"absolute"});_7._absolutized=true;}var _8=_7.getDimensions();Position.prepare();var _9=(Position.deltaX+Math.floor((Control.Modal.getWindowWidth()-_8.width)/2));var _a=(Position.deltaY+((Control.Modal.getWindowHeight()>_8.height)?Math.floor((Control.Modal.getWindowHeight()-_8.height)/2):0));_7.setStyle({top:((_8.height<=Control.Modal.getDocumentHeight())?((_a!=null&&_a>0)?_a:"0")+"px":0),left:((_8.width<=Control.Modal.getDocumentWidth())?((_9!=null&&_9>0)?_9:"0")+"px":0)});},getWindowWidth:function(){return (self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0);},getWindowHeight:function(){return (self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0);},getDocumentWidth:function(){return Math.min(document.body.scrollWidth,Control.Modal.getWindowWidth());},getDocumentHeight:function(){return Math.max(document.body.scrollHeight,Control.Modal.getWindowHeight());},onKeyDown:function(_b){if(_b.keyCode==Event.KEY_ESC){Control.Modal.close();}}});Object.extend(Control.Modal.prototype,{mode:"",html:false,href:"",element:false,src:false,imageLoaded:false,ajaxRequest:false,initialize:function(_c,_d){this.element=$(_c);this.options={beforeOpen:Prototype.emptyFunction,afterOpen:Prototype.emptyFunction,beforeClose:Prototype.emptyFunction,afterClose:Prototype.emptyFunction,onSuccess:Prototype.emptyFunction,onFailure:Prototype.emptyFunction,onException:Prototype.emptyFunction,beforeImageLoad:Prototype.emptyFunction,afterImageLoad:Prototype.emptyFunction,autoOpenIfLinked:true,contents:false,loading:false,fade:false,fadeDuration:0.75,image:false,imageCloseOnClick:true,hover:false,iframe:false,iframeTemplate:new Template(""),evalScripts:true,requestOptions:{},overlayDisplay:true,overlayClassName:"",overlayCloseOnClick:true,containerClassName:"",opacity:0.3,zIndex:1000,width:null,height:null,offsetLeft:0,offsetTop:0,position:"absolute"};Object.extend(this.options,_d||{});var _e=false;var _f=false;if(this.element){_e=Control.Modal.targetRegexp.exec(this.element.href);_f=Control.Modal.imgRegexp.exec(this.element.href);}if(this.options.position=="mouse"){this.options.hover=true;}if(this.options.contents){this.mode="contents";}else{if(this.options.image||_f){this.mode="image";this.src=this.element.href;}else{if(_e){this.mode="named";var x=$(_e[1]);this.html=x.innerHTML;x.remove();this.href=_e[1];}else{this.mode=(this.options.iframe)?"iframe":"ajax";this.href=this.element.href;}}}if(this.element){if(this.options.hover){this.element.observe("mouseover",this.open.bind(this));this.element.observe("mouseout",function(_11){if(!Position.within(Control.Modal.container,Event.pointerX(_11),Event.pointerY(_11))){this.close();}}.bindAsEventListener(this));}else{this.element.onclick=function(_12){this.open();Event.stop(_12);return false;}.bindAsEventListener(this);}}var _13=Control.Modal.targetRegexp.exec(window.location);this.position=function(_14){if(this.options.position=="absolute"){Control.Modal.center(Control.Modal.container);}else{var xy=(_14&&this.options.position=="mouse"?[Event.pointerX(_14),Event.pointerY(_14)]:Position.cumulativeOffset(this.element));Control.Modal.container.setStyle({position:"absolute",top:xy[1]+(typeof (this.options.offsetTop)=="function"?this.options.offsetTop():this.options.offsetTop)+"px",left:xy[0]+(typeof (this.options.offsetLeft)=="function"?this.options.offsetLeft():this.options.offsetLeft)+"px"});}if(Control.Modal.ie){Control.Modal.overlay.setStyle({height:Control.Modal.getDocumentHeight()+"px",width:Control.Modal.getDocumentWidth()+"px"});}}.bind(this);if(this.mode=="named"&&this.options.autoOpenIfLinked&&_13&&_13[1]&&_13[1]==this.href){this.open();}},showLoadingIndicator:function(){if(this.options.loading){Control.Modal.loadingTimeout=window.setTimeout(function(){var _16=$("modal_image");if(_16){_16.hide();}Control.Modal.loading.style.zIndex=this.options.zIndex+1;Control.Modal.loading.update("");Control.Modal.loading.show();Control.Modal.center(Control.Modal.loading);}.bind(this),250);}},hideLoadingIndicator:function(){if(this.options.loading){if(Control.Modal.loadingTimeout){window.clearTimeout(Control.Modal.loadingTimeout);}var _17=$("modal_image");if(_17){_17.show();}Control.Modal.loading.hide();}},open:function(_18){if(!_18&&this.notify("beforeOpen")===false){return;}if(!Control.Modal.loaded){Control.Modal.load();}Control.Modal.close();if(!this.options.hover){Event.observe($(document.getElementsByTagName("body")[0]),"keydown",Control.Modal.onKeyDown);}Control.Modal.current=this;if(!this.options.hover){Control.Modal.overlay.setStyle({zIndex:this.options.zIndex,opacity:this.options.opacity});}Control.Modal.container.setStyle({zIndex:this.options.zIndex+1,width:(this.options.width?(typeof (this.options.width)=="function"?this.options.width():this.options.width)+"px":null),height:(this.options.height?(typeof (this.options.height)=="function"?this.options.height():this.options.height)+"px":null)});if(Control.Modal.ie&&!this.options.hover){$A(document.getElementsByTagName("select")).each(function(_19){_19.style.visibility="hidden";});}Control.Modal.overlay.addClassName(this.options.overlayClassName);Control.Modal.container.addClassName(this.options.containerClassName);switch(this.mode){case "image":this.imageLoaded=false;this.notify("beforeImageLoad");this.showLoadingIndicator();var img=document.createElement("img");img.onload=function(img){this.hideLoadingIndicator();this.update([img]);if(this.options.imageCloseOnClick){$(img).observe("click",Control.Modal.close);}this.position();this.notify("afterImageLoad");img.onload=null;}.bind(this,img);img.src=this.src;img.id="modal_image";break;case "ajax":this.notify("beforeLoad");var _1c={method:"post",onSuccess:function(_1d){this.hideLoadingIndicator();this.update(_1d.responseText);this.notify("onSuccess",_1d);this.ajaxRequest=false;}.bind(this),onFailure:function(){this.notify("onFailure");}.bind(this),onException:function(){this.notify("onException");}.bind(this)};Object.extend(_1c,this.options.requestOptions);this.showLoadingIndicator();this.ajaxRequest=new Ajax.Request(this.href,_1c);break;case "iframe":this.update(this.options.iframeTemplate.evaluate({href:this.href,id:"modal_iframe"}));break;case "contents":this.update((typeof (this.options.contents)=="function"?this.options.contents():this.options.contents));break;case "named":this.update(this.html);break;}if(!this.options.hover){if(this.options.overlayCloseOnClick&&this.options.overlayDisplay){Control.Modal.overlay.observe("click",Control.Modal.close);}if(this.options.overlayDisplay){if(this.options.fade){if(Control.Modal.effects.overlayFade){Control.Modal.effects.overlayFade.cancel();}Control.Modal.effects.overlayAppear=new Effect.Appear(Control.Modal.overlay,{queue:{position:"front",scope:"Control.Modal"},to:this.options.opacity,duration:this.options.fadeDuration/2});}else{Control.Modal.overlay.show();}}}if(this.options.position=="mouse"){this.mouseHoverListener=this.position.bindAsEventListener(this);this.element.observe("mousemove",this.mouseHoverListener);}this.notify("afterOpen");},update:function(_1e){if(typeof (_1e)=="string"){Control.Modal.container.update(_1e);}else{Control.Modal.container.update("");(_1e.each)?_1e.each(function(_1f){Control.Modal.container.appendChild(_1f);}):Control.Modal.container.appendChild(node);}if(this.options.fade){if(Control.Modal.effects.containerFade){Control.Modal.effects.containerFade.cancel();}Control.Modal.effects.containerAppear=new Effect.Appear(Control.Modal.container,{queue:{position:"end",scope:"Control.Modal"},to:1,duration:this.options.fadeDuration/2});}else{Control.Modal.container.show();}this.position();Event.observe(window,"resize",this.position,false);Event.observe(window,"scroll",this.position,false);},close:function(_20){if(!_20&&this.notify("beforeClose")===false){return;}if(this.ajaxRequest){this.ajaxRequest.transport.abort();}this.hideLoadingIndicator();if(this.mode=="image"){var _21=$("modal_image");if(this.options.imageCloseOnClick&&_21){_21.stopObserving("click",Control.Modal.close);}}if(Control.Modal.ie&&!this.options.hover){$A(document.getElementsByTagName("select")).each(function(_22){_22.style.visibility="visible";});}if(!this.options.hover){Event.stopObserving(window,"keyup",Control.Modal.onKeyDown);}Control.Modal.current=false;Event.stopObserving(window,"resize",this.position,false);Event.stopObserving(window,"scroll",this.position,false);if(!this.options.hover){if(this.options.overlayCloseOnClick&&this.options.overlayDisplay){Control.Modal.overlay.stopObserving("click",Control.Modal.close);}if(this.options.overlayDisplay){if(this.options.fade){if(Control.Modal.effects.overlayAppear){Control.Modal.effects.overlayAppear.cancel();}Control.Modal.effects.overlayFade=new Effect.Fade(Control.Modal.overlay,{queue:{position:"end",scope:"Control.Modal"},from:this.options.opacity,to:0,duration:this.options.fadeDuration/2});}else{Control.Modal.overlay.hide();}}}if(this.options.fade){if(Control.Modal.effects.containerAppear){Control.Modal.effects.containerAppear.cancel();}Control.Modal.effects.containerFade=new Effect.Fade(Control.Modal.container,{queue:{position:"front",scope:"Control.Modal"},from:1,to:0,duration:this.options.fadeDuration/2,afterFinish:function(){Control.Modal.container.update("");this.resetClassNameAndStyles();}.bind(this)});}else{Control.Modal.container.hide();Control.Modal.container.update("");this.resetClassNameAndStyles();}if(this.options.position=="mouse"){this.element.stopObserving("mousemove",this.mouseHoverListener);}this.notify("afterClose");},resetClassNameAndStyles:function(){Control.Modal.overlay.removeClassName(this.options.overlayClassName);Control.Modal.container.removeClassName(this.options.containerClassName);Control.Modal.container.setStyle({height:null,width:null,top:null,left:null});},notify:function(_23){try{if(this.options[_23]){return [this.options[_23].apply(this.options[_23],$A(arguments).slice(1))];}}catch(e){if(e!=$break){throw e;}else{return false;}}}});if(typeof (Object.Event)!="undefined"){Object.Event.extend(Control.Modal);}Control.Modal.attachEvents(); Collabtive-2.0/include/js/dtree.js000066400000000000000000000277221237252063700171600ustar00rootroot00000000000000 // Node object function Node(id, pid, name, url, title, target, icon, iconOpen, open, daysLeft) { this.id = id; this.pid = pid; this.name = name; this.url = url; this.title = title; this.target = target; this.icon = icon; this.daysLeft = daysLeft; this.iconOpen = iconOpen; this._io = open || false; this._is = false; this._ls = false; this._hc = false; this._ai = 0; this._p; }; // Tree object function dTree(objName) { this.config = { target : null, folderLinks : true, useSelection : true, useCookies : true, useLines : true, useIcons : true, useStatusText : false, closeSameLevel : false, inOrder : false } this.icon = { root : 'templates/standard/theme/standard/images/symbols/empty.gif', folder : 'templates/standard/theme/standard/images/symbols/folder.gif', folderOpen : 'templates/standard/theme/standard/images/symbols/folderopen.gif', node : 'templates/standard/theme/standard/images/symbols/page.gif', empty : 'templates/standard/theme/standard/images/symbols/empty.gif', line : 'templates/standard/theme/standard/images/symbols/line.gif', join : 'templates/standard/theme/standard/images/symbols/join.gif', joinBottom : 'templates/standard/theme/standard/images/symbols/joinbottom.gif', plus : 'templates/standard/theme/standard/images/symbols/plus.gif', plusBottom : 'templates/standard/theme/standard/images/symbols/plusbottom.gif', minus : 'templates/standard/theme/standard/images/symbols/minus.gif', minusBottom : 'templates/standard/theme/standard/images/symbols/minusbottom.gif', nlPlus : 'templates/standard/theme/standard/images/symbols/nolines_plus.gif', nlMinus : 'templates/standard/theme/standard/images/symbols/nolines_minus.gif' }; this.obj = objName; this.aNodes = []; this.aIndent = []; this.root = new Node(-1); this.selectedNode = null; this.selectedFound = false; this.completed = false; }; // Adds a new node to the node array dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open, daysLeft) { this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open, daysLeft); }; // Open/close all nodes dTree.prototype.openAll = function() { this.oAll(true); }; dTree.prototype.closeAll = function() { this.oAll(false); }; // Outputs the tree to the page dTree.prototype.toString = function() { var str = '
      \n'; if (document.getElementById) { if (this.config.useCookies) this.selectedNode = this.getSelected(); str += this.addNode(this.root); } else str += 'Browser not supported.'; str += '
      '; if (!this.selectedFound) this.selectedNode = null; this.completed = true; return str; }; // Creates the tree structure dTree.prototype.addNode = function(pNode) { var str = ''; var n=0; if (this.config.inOrder) n = pNode._ai; for (n; n'; } } if (node.url) { str += '
      '; str += node.name; if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += ''; str += '
  • '; if (node._hc) { str += '
    '; str += this.addNode(node); str += '
    '; } this.aIndent.pop(); return str; }; // Adds the empty and line icons dTree.prototype.indent = function(node, nodeId) { var str = ''; if (this.root.id != node.pid) { for (var n=0; n'; (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1); if (node._hc) { str += ''; } else str += ''; } return str; }; // Checks if a node has any children and if it is the last sibling dTree.prototype.setCS = function(node) { var lastId; for (var n=0; n0)){for(var b=0;b0)){for(var a=0;athis.maxLength)){return false}if(this.regexp){if(!_checkRegExp(this.regexp,this.value)){if(!this.required&&this.value){return false}if(this.required){return false}}else{return true}}if(this.equals){for(var i=0;ithis.maxValue)){return false}}}return true};Field.prototype._ValidateGroup=function(a){if(this.required&&this.values.length==0){return false}if(this.required&&this.min&&this.min>this.values.length){return false}if(this.required&&this.max&&this.max-1){strErrorTemp=strErrorTemp.replace("\\n","\n");idx=strErrorTemp.indexOf("\\n")}return strErrorTemp.replace("%FIELDNAME%",(b.realname)?b.realname:((a.id)?a.id:a.name))}function _parseBoolean(a){return !(!a||a==0||a=="0"||a=="false")}function _checkRegExp(b,a){switch(b){case"EMAIL":return((/^[\x21-\x39\x41-\x5a\x5e-\x7e]+@[\x21-\x39\x41-\x5a\x5e-\x7e]+(\.\w{2,5})+$/).test(a));case"JSVAL_RX_TEL":return((/^1?[\- ]?\(?\d{3}\)?[\- ]?\d{3}[\- ]?\d{4}$/).test(a));case"JSVAL_RX_PC":return((/^[a-z]\d[a-z] ?\d[a-z]\d$/i).test(a));case"JSVAL_RX_ZIP":return((/^\d{5}$/).test(a));case"JSVAL_RX_MONEY":return((/^\d+([\.]\d\d)?$/).test(a));case"JSVAL_RX_CREDITCARD":return(!isNaN(a));case"JSVAL_RX_POSTALZIP":if(a.length==6||a.length==7){return((/^[a-zA-Z]\d[a-zA-Z] ?\d[a-zA-Z]\d$/).test(a))}if(a.length==5||a.length==10){return((/^\d{5}(\-\d{4})?$/).test(a))}break;default:return(b.test(a))}};Collabtive-2.0/include/js/lytebox.php000066400000000000000000000677221237252063700177220ustar00rootroot00000000000000 Array.prototype.removeDuplicates=function(){for(i=0;ii;j--){if(this[i][0]==this[j][0]){this.splice(j,1);}}}};Array.prototype.empty=function(){for(var i=0;i<=this.length;i++){this.shift();}};String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"");};function LyteBox(){this.theme="grey";this.hideFlash=true;this.outerBorder=false;this.resizeSpeed=4;this.maxOpacity=80;this.navType=1;this.autoResize=true;this.doAnimations=true;this.borderSize=12;this.slideInterval=4000;this.showNavigation=true;this.showClose=true;this.showDetails=true;this.showPlayPause=true;this.autoEnd=true;this.pauseOnNextClick=false;this.pauseOnPrevClick=true;if(this.resizeSpeed>10){this.resizeSpeed=10;}if(this.resizeSpeed<1){resizeSpeed=1;}this.resizeDuration=(11-this.resizeSpeed)*0.15;this.resizeWTimerArray=new Array();this.resizeWTimerCount=0;this.resizeHTimerArray=new Array();this.resizeHTimerCount=0;this.showContentTimerArray=new Array();this.showContentTimerCount=0;this.overlayTimerArray=new Array();this.overlayTimerCount=0;this.imageTimerArray=new Array();this.imageTimerCount=0;this.timerIDArray=new Array();this.timerIDCount=0;this.slideshowIDArray=new Array();this.slideshowIDCount=0;this.imageArray=new Array();this.activeImage=null;this.slideArray=new Array();this.activeSlide=null;this.frameArray=new Array();this.activeFrame=null;this.checkFrame();this.isSlideshow=false;this.isLyteframe=false;this.ie=false;this.ie7=(this.ie&&window.XMLHttpRequest);this.initialize();}LyteBox.prototype.initialize=function(){this.updateLyteboxItems();var _2=this.doc.getElementsByTagName("body").item(0);if(this.doc.getElementById("lbOverlay")){_2.removeChild(this.doc.getElementById("lbOverlay"));_2.removeChild(this.doc.getElementById("lbMain"));}var _3=this.doc.createElement("div");_3.setAttribute("id","lbOverlay");_3.setAttribute((this.ie?"className":"class"),this.theme);if((this.ie&&!this.ie7)||(this.ie7&&this.doc.compatMode=="BackCompat")){_3.style.position="absolute";}_3.style.display="none";_2.appendChild(_3);var _4=this.doc.createElement("div");_4.setAttribute("id","lbMain");_4.style.display="none";_2.appendChild(_4);var _5=this.doc.createElement("div");_5.setAttribute("id","lbOuterContainer");_5.setAttribute((this.ie?"className":"class"),this.theme);_4.appendChild(_5);var _6=this.doc.createElement("div");_6.setAttribute("id","lbIframeContainer");_6.style.display="none";_5.appendChild(_6);var _7=this.doc.createElement("iframe");_7.setAttribute("id","lbIframe");_7.setAttribute("name","lbIframe");_7.style.display="none";_6.appendChild(_7);var _8=this.doc.createElement("div");_8.setAttribute("id","lbImageContainer");_5.appendChild(_8);var _9=this.doc.createElement("img");_9.setAttribute("id","lbImage");_8.appendChild(_9);var _a=this.doc.createElement("div");_a.setAttribute("id","lbLoading");_5.appendChild(_a);var _b=this.doc.createElement("div");_b.setAttribute("id","lbDetailsContainer");_b.setAttribute((this.ie?"className":"class"),this.theme);_4.appendChild(_b);var _c=this.doc.createElement("div");_c.setAttribute("id","lbDetailsData");_c.setAttribute((this.ie?"className":"class"),this.theme);_b.appendChild(_c);var _d=this.doc.createElement("div");_d.setAttribute("id","lbDetails");_c.appendChild(_d);var _e=this.doc.createElement("span");_e.setAttribute("id","lbCaption");_d.appendChild(_e);var _f=this.doc.createElement("div");_f.setAttribute("id","lbHoverNav");_8.appendChild(_f);var _10=this.doc.createElement("div");_10.setAttribute("id","lbBottomNav");_c.appendChild(_10);var _11=this.doc.createElement("a");_11.setAttribute("id","lbPrev");_11.setAttribute((this.ie?"className":"class"),this.theme);_11.setAttribute("href","#");_f.appendChild(_11);var _12=this.doc.createElement("a");_12.setAttribute("id","lbNext");_12.setAttribute((this.ie?"className":"class"),this.theme);_12.setAttribute("href","#");_f.appendChild(_12);var _13=this.doc.createElement("span");_13.setAttribute("id","lbNumberDisplay");_d.appendChild(_13);var _14=this.doc.createElement("span");_14.setAttribute("id","lbNavDisplay");_14.style.display="none";_d.appendChild(_14);var _15=this.doc.createElement("a");_15.setAttribute("id","lbClose");_15.setAttribute((this.ie?"className":"class"),this.theme);_15.setAttribute("href","#");_10.appendChild(_15);var _16=this.doc.createElement("a");_16.setAttribute("id","lbPause");_16.setAttribute((this.ie?"className":"class"),this.theme);_16.setAttribute("href","#");_16.style.display="none";_10.appendChild(_16);var _17=this.doc.createElement("a");_17.setAttribute("id","lbPlay");_17.setAttribute((this.ie?"className":"class"),this.theme);_17.setAttribute("href","#");_17.style.display="none";_10.appendChild(_17);};LyteBox.prototype.updateLyteboxItems=function(){var _18=(this.isFrame)?window.parent.frames[window.name].document.getElementsByTagName("a"):document.getElementsByTagName("a");for(var i=0;i<_18.length;i++){var _1a=_18[i];var _1b=String(_1a.getAttribute("rel"));if(_1a.getAttribute("href")){if(_1b.toLowerCase().match("lytebox")){_1a.onclick=function(){myLytebox.start(this,false,false);return false;};}else{if(_1b.toLowerCase().match("lyteshow")){_1a.onclick=function(){myLytebox.start(this,true,false);return false;};}else{if(_1b.toLowerCase().match("lyteframe")){_1a.onclick=function(){myLytebox.start(this,false,true);return false;};}}}}}};LyteBox.prototype.start=function(_1c,_1d,_1e){if(this.ie&&!this.ie7){this.toggleSelects("hide");}if(this.hideFlash){this.toggleFlash("hide");}this.isLyteframe=(_1e?true:false);var _1f=this.getPageSize();var _20=this.doc.getElementById("lbOverlay");var _21=this.doc.getElementsByTagName("body").item(0);_20.style.height=_1f[1]+"px";_20.style.display="";this.appear("lbOverlay",(this.doAnimations?0:this.maxOpacity));var _22=(this.isFrame)?window.parent.frames[window.name].document.getElementsByTagName("a"):document.getElementsByTagName("a");if(this.isLyteframe){this.frameArray=[];this.frameNum=0;if((_1c.getAttribute("rel")=="lyteframe")){var rev=_1c.getAttribute("rev");this.frameArray.push(new Array(_1c.getAttribute("href"),_1c.getAttribute("title"),(rev==null||rev==""?"width: 400px; height: 400px; scrolling: auto;":rev)));}else{if(_1c.getAttribute("rel").indexOf("lyteframe")!=-1){for(var i=0;i<_22.length;i++){var _25=_22[i];if(_25.getAttribute("href")&&(_25.getAttribute("rel")==_1c.getAttribute("rel"))){var rev=_25.getAttribute("rev");this.frameArray.push(new Array(_25.getAttribute("href"),_25.getAttribute("title"),(rev==null||rev==""?"width: 400px; height: 400px; scrolling: auto;":rev)));}}this.frameArray.removeDuplicates();while(this.frameArray[this.frameNum][0]!=_1c.getAttribute("href")){this.frameNum++;}}}}else{this.imageArray=[];this.imageNum=0;this.slideArray=[];this.slideNum=0;if((_1c.getAttribute("rel")=="lytebox")){this.imageArray.push(new Array(_1c.getAttribute("href"),_1c.getAttribute("title")));}else{if(_1c.getAttribute("rel").indexOf("lytebox")!=-1){for(var i=0;i<_22.length;i++){var _28=_22[i];if(_28.getAttribute("href")&&(_28.getAttribute("rel")==_1c.getAttribute("rel"))){this.imageArray.push(new Array(_28.getAttribute("href"),_28.getAttribute("title")));}}this.imageArray.removeDuplicates();while(this.imageArray[this.imageNum][0]!=_1c.getAttribute("href")){this.imageNum++;}}if(_1c.getAttribute("rel").indexOf("lyteshow")!=-1){for(var i=0;i<_22.length;i++){var _2a=_22[i];if(_2a.getAttribute("href")&&(_2a.getAttribute("rel")==_1c.getAttribute("rel"))){this.slideArray.push(new Array(_2a.getAttribute("href"),_2a.getAttribute("title")));}}this.slideArray.removeDuplicates();while(this.slideArray[this.slideNum][0]!=_1c.getAttribute("href")){this.slideNum++;}}}}var _2b=this.doc.getElementById("lbMain");_2b.style.top=(this.getPageScroll()+(_1f[3]/15))+"px";_2b.style.display="";if(!this.outerBorder){this.doc.getElementById("lbOuterContainer").style.border="none";this.doc.getElementById("lbDetailsContainer").style.border="none";}else{this.doc.getElementById("lbOuterContainer").style.borderBottom="";this.doc.getElementById("lbOuterContainer").setAttribute((this.ie?"className":"class"),this.theme);}this.doc.getElementById("lbOverlay").onclick=function(){myLytebox.end();return false;};this.doc.getElementById("lbMain").onclick=function(e){var e=e;if(!e){if(window.parent.frames[window.name]&&(parent.document.getElementsByTagName("frameset").length<=0)){e=window.parent.window.event;}else{e=window.event;}}var id=(e.target?e.target.id:e.srcElement.id);if(id=="lbMain"){myLytebox.end();return false;}};this.doc.getElementById("lbClose").onclick=function(){myLytebox.end();return false;};this.doc.getElementById("lbPause").onclick=function(){myLytebox.togglePlayPause("lbPause","lbPlay");return false;};this.doc.getElementById("lbPlay").onclick=function(){myLytebox.togglePlayPause("lbPlay","lbPause");return false;};this.isSlideshow=_1d;this.isPaused=(this.slideNum!=0?true:false);if(this.isSlideshow&&this.showPlayPause&&this.isPaused){this.doc.getElementById("lbPlay").style.display="";this.doc.getElementById("lbPause").style.display="none";}if(this.isLyteframe){this.changeContent(this.frameNum);}else{if(this.isSlideshow){this.changeContent(this.slideNum);}else{this.changeContent(this.imageNum);}}};LyteBox.prototype.changeContent=function(_2f){if(this.isSlideshow){for(var i=0;i«« || » »";object.style.display="none";}if(this.isLyteframe){var _31=myLytebox.doc.getElementById("lbIframe");var _32=this.frameArray[this.activeFrame][2];var _33=_32.split(";");for(var i=0;i<_33.length;i++){if(_33[i].indexOf("width:")>=0){var w=_33[i].replace("width:","");_31.width=w.trim();}else{if(_33[i].indexOf("height:")>=0){var h=_33[i].replace("height:","");_31.height=h.trim();}else{if(_33[i].indexOf("scrolling:")>=0){var s=_33[i].replace("scrolling:","");_31.scrolling=s.trim();}else{if(_33[i].indexOf("border:")>=0){}}}}}this.resizeContainer(parseInt(_31.width),parseInt(_31.height));}else{imgPreloader=new Image();imgPreloader.onload=function(){var _38=imgPreloader.width;var _39=imgPreloader.height;if(myLytebox.autoResize){var _3a=myLytebox.getPageSize();var x=_3a[2]-150;var y=_3a[3]-150;if(_38>x){_39=Math.round(_39*(x/_38));_38=x;if(_39>y){_38=Math.round(_38*(y/_39));_39=y;}}else{if(_39>y){_38=Math.round(_38*(y/_39));_39=y;if(_38>x){_39=Math.round(_39*(x/_38));_38=x;}}}}var _3d=myLytebox.doc.getElementById("lbImage");_3d.src=(myLytebox.isSlideshow?myLytebox.slideArray[myLytebox.activeSlide][0]:myLytebox.imageArray[myLytebox.activeImage][0]);_3d.width=_38;_3d.height=_39;myLytebox.resizeContainer(_38,_39);imgPreloader.onload=function(){};};imgPreloader.src=(this.isSlideshow?this.slideArray[this.activeSlide][0]:this.imageArray[this.activeImage][0]);}};LyteBox.prototype.resizeContainer=function(_3e,_3f){this.wCur=this.doc.getElementById("lbOuterContainer").offsetWidth;this.hCur=this.doc.getElementById("lbOuterContainer").offsetHeight;this.xScale=((_3e+(this.borderSize*2))/this.wCur)*100;this.yScale=((_3f+(this.borderSize*2))/this.hCur)*100;var _40=(this.wCur-this.borderSize*2)-_3e;var _41=(this.hCur-this.borderSize*2)-_3f;if(!(_41==0)){this.hDone=false;this.resizeH("lbOuterContainer",this.hCur,_3f+this.borderSize*2,this.getPixelRate(this.hCur,_3f));}else{this.hDone=true;}if(!(_40==0)){this.wDone=false;this.resizeW("lbOuterContainer",this.wCur,_3e+this.borderSize*2,this.getPixelRate(this.wCur,_3e));}else{this.wDone=true;}if((_41==0)&&(_40==0)){if(this.ie){this.pause(250);}else{this.pause(100);}}this.doc.getElementById("lbPrev").style.height=_3f+"px";this.doc.getElementById("lbNext").style.height=_3f+"px";this.doc.getElementById("lbDetailsContainer").style.width=(_3e+(this.borderSize*2)+(this.ie&&this.doc.compatMode=="BackCompat"&&this.outerBorder?2:0))+"px";this.showContent();};LyteBox.prototype.showContent=function(){if(this.wDone&&this.hDone){for(var i=0;i1)||(this.frameArray.length>1&&this.isLyteframe)){this.doc.getElementById("lbNavDisplay").style.display="";}else{this.doc.getElementById("lbNavDisplay").style.display="none";}this.doc.getElementById("lbClose").style.display="";this.doc.getElementById("lbDetails").style.display="";this.doc.getElementById("lbPause").style.display="none";this.doc.getElementById("lbPlay").style.display="none";}this.doc.getElementById("lbImageContainer").style.display=(this.isLyteframe?"none":"");this.doc.getElementById("lbIframeContainer").style.display=(this.isLyteframe?"":"none");try{this.doc.getElementById("lbIframe").src=this.frameArray[this.activeFrame][0];}catch(e){}}else{this.showContentTimerArray[this.showContentTimerCount++]=setTimeout("myLytebox.showContent()",200);}};LyteBox.prototype.updateDetails=function(){var _43=this.doc.getElementById("lbCaption");var _44=(this.isSlideshow?this.slideArray[this.activeSlide][1]:(this.isLyteframe?this.frameArray[this.activeFrame][1]:this.imageArray[this.activeImage][1]));_43.style.display="";_43.innerHTML=(_44==null?"":_44);this.updateNav();this.doc.getElementById("lbDetailsContainer").style.display="";_43=this.doc.getElementById("lbNumberDisplay");if(this.isSlideshow&&this.slideArray.length>1){_43.style.display="";_43.innerHTML=eval(this.activeSlide+1)+" / "+this.slideArray.length;this.doc.getElementById("lbNavDisplay").style.display=(this.navType==2&&this.showNavigation?"":"none");}else{if(this.imageArray.length>1&&!this.isLyteframe){_43.style.display="";_43.innerHTML=eval(this.activeImage+1)+" / "+this.imageArray.length;this.doc.getElementById("lbNavDisplay").style.display=(this.navType==2?"":"none");}else{if(this.frameArray.length>1&&this.isLyteframe){_43.style.display="";_43.innerHTML=eval(this.activeFrame+1)+" / "+this.frameArray.length;this.doc.getElementById("lbNavDisplay").style.display="";}else{this.doc.getElementById("lbNavDisplay").style.display="none";}}}this.appear("lbDetailsContainer",(this.doAnimations?0:100));};LyteBox.prototype.updateNav=function(){if(this.isSlideshow){if(this.activeSlide!=0){var _45=(this.navType==2?this.doc.getElementById("lbPrev2"):this.doc.getElementById("lbPrev"));_45.style.display="";_45.onclick=function(){if(myLytebox.pauseOnPrevClick){myLytebox.togglePlayPause("lbPause","lbPlay");}myLytebox.changeContent(myLytebox.activeSlide-1);return false;};}else{if(this.navType==2){this.doc.getElementById("lbPrev2_Off").style.display="";}}if(this.activeSlide!=(this.slideArray.length-1)){var _46=(this.navType==2?this.doc.getElementById("lbNext2"):this.doc.getElementById("lbNext"));_46.style.display="";_46.onclick=function(){if(myLytebox.pauseOnNextClick){myLytebox.togglePlayPause("lbPause","lbPlay");}myLytebox.changeContent(myLytebox.activeSlide+1);return false;};}else{if(this.navType==2){this.doc.getElementById("lbNext2_Off").style.display="";}}}else{if(this.isLyteframe){if(this.activeFrame!=0){var _47=this.doc.getElementById("lbPrev2");_47.style.display="";_47.onclick=function(){myLytebox.changeContent(myLytebox.activeFrame-1);return false;};}else{this.doc.getElementById("lbPrev2_Off").style.display="";}if(this.activeFrame!=(this.frameArray.length-1)){var _48=this.doc.getElementById("lbNext2");_48.style.display="";_48.onclick=function(){myLytebox.changeContent(myLytebox.activeFrame+1);return false;};}else{this.doc.getElementById("lbNext2_Off").style.display="";}}else{if(this.activeImage!=0){var _49=(this.navType==2?this.doc.getElementById("lbPrev2"):this.doc.getElementById("lbPrev"));_49.style.display="";_49.onclick=function(){myLytebox.changeContent(myLytebox.activeImage-1);return false;};}else{if(this.navType==2){this.doc.getElementById("lbPrev2_Off").style.display="";}}if(this.activeImage!=(this.imageArray.length-1)){var _4a=(this.navType==2?this.doc.getElementById("lbNext2"):this.doc.getElementById("lbNext"));_4a.style.display="";_4a.onclick=function(){myLytebox.changeContent(myLytebox.activeImage+1);return false;};}else{if(this.navType==2){this.doc.getElementById("lbNext2_Off").style.display="";}}}}this.enableKeyboardNav();};LyteBox.prototype.enableKeyboardNav=function(){document.onkeydown=this.keyboardAction;};LyteBox.prototype.disableKeyboardNav=function(){document.onkeydown="";};LyteBox.prototype.keyboardAction=function(e){var _4c=key=escape=null;_4c=(e==null)?event.keyCode:e.which;key=String.fromCharCode(_4c).toLowerCase();escape=(e==null)?27:e.DOM_VK_ESCAPE;if((key=="x")||(key=="c")||(_4c==escape)){myLytebox.end();}else{if((key=="p")||(_4c==37)){if(myLytebox.isSlideshow){if(myLytebox.activeSlide!=0){myLytebox.disableKeyboardNav();myLytebox.changeContent(myLytebox.activeSlide-1);}}else{if(myLytebox.isLyteframe){if(myLytebox.activeFrame!=0){myLytebox.disableKeyboardNav();myLytebox.changeContent(myLytebox.activeFrame-1);}}else{if(myLytebox.activeImage!=0){myLytebox.disableKeyboardNav();myLytebox.changeContent(myLytebox.activeImage-1);}}}}else{if((key=="n")||(_4c==39)){if(myLytebox.isSlideshow){if(myLytebox.activeSlide!=(myLytebox.slideArray.length-1)){myLytebox.disableKeyboardNav();myLytebox.changeContent(myLytebox.activeSlide+1);}}else{if(myLytebox.isLyteframe){if(myLytebox.activeFrame!=(myLytebox.frameArray.length-1)){myLytebox.disableKeyboardNav();myLytebox.changeContent(myLytebox.activeFrame+1);}}else{if(myLytebox.activeImage!=(myLytebox.imageArray.length-1)){myLytebox.disableKeyboardNav();myLytebox.changeContent(myLytebox.activeImage+1);}}}}}}};LyteBox.prototype.preloadNeighborImages=function(){if(this.isSlideshow){if((this.slideArray.length-1)>this.activeSlide){preloadNextImage=new Image();preloadNextImage.src=this.slideArray[this.activeSlide+1][0];}if(this.activeSlide>0){preloadPrevImage=new Image();preloadPrevImage.src=this.slideArray[this.activeSlide-1][0];}}else{if((this.imageArray.length-1)>this.activeImage){preloadNextImage=new Image();preloadNextImage.src=this.imageArray[this.activeImage+1][0];}if(this.activeImage>0){preloadPrevImage=new Image();preloadPrevImage.src=this.imageArray[this.activeImage-1][0];}}};LyteBox.prototype.togglePlayPause=function(_4d,_4e){if(this.isSlideshow&&_4d=="lbPause"){for(var i=0;icur)?img-cur:cur-img;if(_55>=0&&_55<=100){return 10;}if(_55>100&&_55<=200){return 15;}if(_55>200&&_55<=300){return 20;}if(_55>300&&_55<=400){return 25;}if(_55>400&&_55<=500){return 30;}if(_55>500&&_55<=600){return 35;}if(_55>600&&_55<=700){return 40;}if(_55>700){return 45;}};LyteBox.prototype.appear=function(id,_57){var _58=this.doc.getElementById(id).style;_58.opacity=(_57/100);_58.MozOpacity=(_57/100);_58.KhtmlOpacity=(_57/100);_58.filter="alpha(opacity="+(_57+10)+")";if(_57==100&&(id=="lbImage"||id=="lbIframe")){try{_58.removeAttribute("filter");}catch(e){}this.updateDetails();}else{if(_57>=this.maxOpacity&&id=="lbOverlay"){for(var i=0;i=100&&id=="lbDetailsContainer"){try{_58.removeAttribute("filter");}catch(e){}for(var i=0;i=_60)?(_60-_65):_61;}else{if(_65>_60){_65-=(_65-_61<=_60)?(_65-_60):_61;}}this.resizeWTimerArray[this.resizeWTimerCount++]=setTimeout("myLytebox.resizeW('"+id+"', "+_65+", "+_60+", "+_61+", "+(_64+0.02)+")",_64+0.02);if(parseInt(_63.style.width)==_60){this.wDone=true;for(var i=0;i=_69)?(_69-_6e):_6a;}else{if(_6e>_69){_6e-=(_6e-_6a<=_69)?(_6e-_69):_6a;}}this.resizeHTimerArray[this.resizeHTimerCount++]=setTimeout("myLytebox.resizeH('"+id+"', "+_6e+", "+_69+", "+_6a+", "+(_6c+0.02)+")",_6c+0.02);if(parseInt(_6d.style.height)==_69){this.hDone=true;for(var i=0;ithis.doc.body.offsetHeight){_70=this.doc.body.scrollWidth;yScroll=this.doc.body.scrollHeight;}else{_70=this.doc.getElementsByTagName("html").item(0).offsetWidth;yScroll=this.doc.getElementsByTagName("html").item(0).offsetHeight;_70=(_70_82){return;}}};if(window.addEventListener){window.addEventListener("load",initLytebox,false);}else{if(window.attachEvent){window.attachEvent("onload",initLytebox);}else{window.onload=function(){initLytebox();};}}function initLytebox(){myLytebox=new LyteBox();}Collabtive-2.0/include/js/mycalendar.js000066400000000000000000000266251237252063700201750ustar00rootroot00000000000000function strtotime(_1,_2){var i,_3,s,_4="",_5="";_4=_1;_4=_4.replace(/\s{2,}|^\s|\s$/g," ");_4=_4.replace(/[\t\r\n]/g,"");if(_4=="now"){return (new Date()).getTime()/1000;}else{if(!isNaN(_5=Date.parse(_4))){return (_5/1000);}else{if(_2){_2=new Date(_2*1000);}else{_2=new Date();}}}_4=_4.toLowerCase();var _6={day:{"sun":0,"mon":1,"tue":2,"wed":3,"thu":4,"fri":5,"sat":6},mon:{"jan":0,"feb":1,"mar":2,"apr":3,"may":4,"jun":5,"jul":6,"aug":7,"sep":8,"oct":9,"nov":10,"dec":11}};var _7=function(m){var _8=(m[2]&&m[2]=="ago");var _9=(_9=m[0]=="last"?-1:1)*(_8?-1:1);switch(m[0]){case "last":case "next":switch(m[1].substring(0,3)){case "yea":_2.setFullYear(_2.getFullYear()+_9);break;case "mon":_2.setMonth(_2.getMonth()+_9);break;case "wee":_2.setDate(_2.getDate()+(_9*7));break;case "day":_2.setDate(_2.getDate()+_9);break;case "hou":_2.setHours(_2.getHours()+_9);break;case "min":_2.setMinutes(_2.getMinutes()+_9);break;case "sec":_2.setSeconds(_2.getSeconds()+_9);break;default:var _a;if(typeof (_a=_6.day[m[1].substring(0,3)])!="undefined"){var _b=_a-_2.getDay();if(_b==0){_b=7*_9;}else{if(_b>0){if(m[0]=="last"){_b-=7;}}else{if(m[0]=="next"){_b+=7;}}}_2.setDate(_2.getDate()+_b);}}break;default:if(/\d+/.test(m[0])){_9*=parseInt(m[0],10);switch(m[1].substring(0,3)){case "yea":_2.setFullYear(_2.getFullYear()+_9);break;case "mon":_2.setMonth(_2.getMonth()+_9);break;case "wee":_2.setDate(_2.getDate()+(_9*7));break;case "day":_2.setDate(_2.getDate()+_9);break;case "hou":_2.setHours(_2.getHours()+_9);break;case "min":_2.setMinutes(_2.getMinutes()+_9);break;case "sec":_2.setSeconds(_2.getSeconds()+_9);break;}}else{return false;}break;}return true;};_3=_4.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(_3!=null){if(!_3[2]){_3[2]="00:00:00";}else{if(!_3[3]){_3[2]+=":00";}}s=_3[1].split(/-/g);for(i in _6.mon){if(_6.mon[i]==s[1]-1){s[1]=i;}}s[0]=parseInt(s[0],10);s[0]=(s[0]>=0&&s[0]<=69)?"20"+(s[0]<10?"0"+s[0]:s[0]+""):(s[0]>=70&&s[0]<=99)?"19"+s[0]:s[0]+"";return parseInt(this.strtotime(s[2]+" "+s[1]+" "+s[0]+" "+_3[2])+(_3[4]?_3[4]/1000:""),10);}var _c="([+-]?\\d+\\s"+"(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?"+"|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday"+"|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)"+"|(last|next)\\s"+"(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?"+"|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday"+"|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))"+"(\\sago)?";_3=_4.match(new RegExp(_c,"gi"));if(_3==null){return false;}for(i=0;i<_3.length;i++){if(!_7(_3[i].split(" "))){return false;}}return (_2.getTime()/1000);};function date(_d,_e){var _f=this,_10,f,_11=/\\?([a-z])/gi,_12,_13=function(n,c){if((n=n+"").length4||j<21?"th":{1:"st",2:"nd",3:"rd"}[j%10]||"th";},w:function(){return _10.getDay();},z:function(){var a=new Date(f.Y(),f.n()-1,f.j()),b=new Date(f.Y(),0,1);return Math.round((a-b)/86400000)+1;},W:function(){var a=new Date(f.Y(),f.n()-1,f.j()-f.N()+3),b=new Date(a.getFullYear(),0,4);return _13(1+Math.round((a-b)/86400000/7),2);},F:function(){return _14[6+f.n()];},m:function(){return _13(f.n(),2);},M:function(){return f.F().slice(0,3);},n:function(){return _10.getMonth()+1;},t:function(){return (new Date(f.Y(),f.n(),0)).getDate();},L:function(){return new Date(f.Y(),1,29).getMonth()===1|0;},o:function(){var n=f.n(),W=f.W(),Y=f.Y();return Y+(n===12&&W<9?-1:n===1&&W>9);},Y:function(){return _10.getFullYear();},y:function(){return (f.Y()+"").slice(-2);},a:function(){return _10.getHours()>11?"pm":"am";},A:function(){return f.a().toUpperCase();},B:function(){var H=_10.getUTCHours()*3600,i=_10.getUTCMinutes()*60,s=_10.getUTCSeconds();return _13(Math.floor((H+i+s+3600)/86.4)%1000,3);},g:function(){return f.G()%12||12;},G:function(){return _10.getHours();},h:function(){return _13(f.g(),2);},H:function(){return _13(f.G(),2);},i:function(){return _13(_10.getMinutes(),2);},s:function(){return _13(_10.getSeconds(),2);},u:function(){return _13(_10.getMilliseconds()*1000,6);},e:function(){throw "Not supported (see source code of date() for timezone on how to add support)";},I:function(){var a=new Date(f.Y(),0),c=Date.UTC(f.Y(),0),b=new Date(f.Y(),6),d=Date.UTC(f.Y(),6);return 0+((a-c)!==(b-d));},O:function(){var a=_10.getTimezoneOffset();return (a>0?"-":"+")+_13(Math.abs(a/60*100),4);},P:function(){var O=f.O();return (O.substr(0,3)+":"+O.substr(3,2));},T:function(){return "UTC";},Z:function(){return -_10.getTimezoneOffset()*60;},c:function(){return "Y-m-d\\Th:i:sP".replace(_11,_12);},r:function(){return "D, d M Y H:i:s O".replace(_11,_12);},U:function(){return _10.getTime()/1000|0;}};this.date=function(_15,_16){_f=this;_10=((typeof _16==="undefined")?new Date():(_16 instanceof Date)?new Date(_16):new Date(_16*1000));return _15.replace(_11,_12);};return this.date(_d,_e);};function makeDatepicker(m,y,div){theCal=new calendar(m,y);theCal.getDatepicker(div);};function makeCal(m,y,div){theCal=new calendar(m,y);theCal.getCal(div);};function calendar(_17,_18,_19){this.dayNames=["Mo","Di","Mi","Do","Fr","Sa","So"];this.monthNames=["Januar","Februar","M??rz","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"];this.keepEmpty=false;this.dateSeparator=".";this.relateTo="";this.dateFormat="d.m.Y";this.calendar=[];datobj=new Date();this.currmonth=datobj.getMonth();this.curryear=datobj.getFullYear();this.currday=datobj.getDate();if(_17>12){_17=1;_18=_18+1;}if(_17<1){_17=12;_18=_18-1;}this.month=_17-1;this.year=_18;this.daysInMonth=this.getDaysInMonth(this.month,this.year);this.daysLastMonth=this.getDaysInMonth(this.month-1,this.year);var _1a=new Date(this.year,this.month,1);this.startDay=_1a.getDay()-1;if(this.startDay<0)this.startDay+=7;var _1b=this.startDay+this.daysInMonth;this.weeksInMonth=Math.ceil(_1b/7);};calendar.prototype.getCal=function(_1c){var _1d="";var _1e=this.month;var _1f=this.month+2;_1d+="";_1d+=""+""+""+"";_1d+="";for(i=0;i"+this.dayNames[i]+"";}_1d+="";var _20=this.buildCal();for(j=0;j";for(i=0;i<7;i++){var _21=_20[j][i];if(_21>0&&_21<=this.daysInMonth){if(this.currmonth==this.month&&this.curryear==this.year&&this.currday==_21){_1d+="";}else{_1d+="";}}else{if(_21<1){_1d+="";}else{if(_21>this.daysInMonth){_1d+="";}}}}_1d+="";}_1d+="
    "+this.monthNames[this.month]+" "+this.year+"
    "+_21+""+_21+""+(this.daysLastMonth+_21)+""+(_21-this.daysInMonth)+"
    ";$(_1c).innerHTML=_1d;theMonths=this.monthNames;theDays=this.dayNames;keepEmpty=this.keepEmpty;dateSeparator=this.dateSeparator;theYear=this.year;$$("#"+_1c+" .cal .back a").each(function(_22){_22.onclick=function(){theCal=new calendar(_1e,theYear);theCal.monthNames=theMonths;theCal.dayNames=theDays;theCal.keepEmpty=keepEmpty;theCal.dateSeparator=dateSeparator;theCal.getCal(_1c);};});$$("#"+_1c+" .cal .next a").each(function(_23){_23.onclick=function(){internalCals=new calendar(_1f,theYear);internalCals.monthNames=theMonths;internalCals.dayNames=theDays;internalCals.keepEmpty=keepEmpty;internalCals.dateSeparator=dateSeparator;internalCals.getCal(_1c);};});};calendar.prototype.getDatepicker=function(_24){if(this.dateFormat=="m/d/Y"||this.dateFormat=="m/d/y"){this.dateSeparator="/";}var _25="";var _26=this.month;var _27=this.month+2;this.theDiv=_24;if(this.relateTo){$(this.relateTo).onfocus=function(){new Effect.Appear(_24,{duration:0.8});};}_25+="";_25+=""+""+""+"";_25+="";for(i=0;i"+this.dayNames[i]+"";}_25+="";var _28=this.buildCal();if(!this.keepEmpty&&!$(this.relateTo).value){if((this.month+1)<10){strMon="0"+(this.month+1);}else{strMon=this.month+1;}if(this.currday<10&&this.currday>0){strDay="0"+this.currday;}else{strDay=this.currday;}initStr2=strMon+"/"+strDay+"/"+this.curryear;var _29=strtotime(initStr2);$(this.relateTo).value=date(this.dateFormat,_29);}selectedVals=$(this.relateTo).value.split(this.dateSeparator);for(j=0;j";for(i=0;i<7;i++){var _2a=_28[j][i];strDay=_2a;if(_2a<10&&_2a>0){strDay="0"+_2a;}if((this.month+1)<10){strMon="0"+(this.month+1);}else{strMon=this.month+1;}dstring=strDay+this.dateSeparator+strMon+this.dateSeparator+this.year;dstring2=strMon+"/"+strDay+"/"+this.year;var _2b=strtotime(dstring2);var _2c=date(this.dateFormat,_2b);if(_2a>0&&_2a<=this.daysInMonth){if(this.currmonth==this.month&&this.curryear==this.year&&this.currday==_2a){_25+="";}else{if(this.month==(selectedVals[1]-1)&&this.year==selectedVals[2]&&selectedVals[0]==_2a){_25+="";}else{_25+="";}}}else{if(_2a<1){_25+="";}else{if(_2a>this.daysInMonth){_25+="";}}}}_25+="";}_25+="
    "+this.monthNames[this.month]+" "+this.year+"
    "+_2a+""+_2a+""+_2a+""+(this.daysLastMonth+_2a)+""+(_2a-this.daysInMonth)+"
    Close
    ";$(_24).innerHTML=_25;var _2d=this.monthNames;var _2e=this.dayNames;var _2f=this.keepEmpty;var _30=this.dateSeparator;var _31=this.year;var _32=this.relateTo;var _33=this.dateFormat;$$("#"+_24+" .cal .back a").each(function(_34){_34.onclick=function(){var _35=new calendar(_26,_31);_35.monthNames=_2d;_35.dayNames=_2e;_35.keepEmpty=_2f;_35.relateTo=_32;_35.dateSeparator=_30;_35.dateFormat=_33;_35.getDatepicker(_24);};});$$("#"+_24+" .cal .next a").each(function(_36){_36.onclick=function(){var _37=new calendar(_27,_31);_37.monthNames=_2d;_37.dayNames=_2e;_37.keepEmpty=_2f;_37.relateTo=_32;_37.dateSeparator=_30;_37.dateFormat=_33;_37.getDatepicker(_24);};});};calendar.prototype.showDatepicker=function(){};calendar.prototype.buildCal=function(){var _38=0;for(j=0;j 0) { if (m[0] == 'last') { diff -= 7; } } else { if (m[0] == 'next') { diff += 7; } } now.setDate(now.getDate() + diff); } } break; default: if (/\d+/.test(m[0])) { num *= parseInt(m[0], 10); switch (m[1].substring(0, 3)) { case 'yea': now.setFullYear(now.getFullYear() + num); break; case 'mon': now.setMonth(now.getMonth() + num); break; case 'wee': now.setDate(now.getDate() + (num * 7)); break; case 'day': now.setDate(now.getDate() + num); break; case 'hou': now.setHours(now.getHours() + num); break; case 'min': now.setMinutes(now.getMinutes() + num); break; case 'sec': now.setSeconds(now.getSeconds() + num); break; } } else { return false; } break; } return true; }; match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/); if (match != null) { if (!match[2]) { match[2] = '00:00:00'; } else if (!match[3]) { match[2] += ':00'; } s = match[1].split(/-/g); for (i in __is.mon) { if (__is.mon[i] == s[1] - 1) { s[1] = i; } } s[0] = parseInt(s[0], 10); s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + ''; return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10); } var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?'; match = strTmp.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i' if (match == null) { return false; } for (i = 0; i < match.length; i++) { if (!process(match[i].split(' '))) { return false; } } return (now.getTime() / 1000); } function date (format, timestamp) { // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) var that = this, jsdate, f, formatChr = /\\?([a-z])/gi, formatChrCb, // Keep this here (works, but for code commented-out // below for file size reasons) //, tal= [], _pad = function (n, c) { if ((n = n + '').length < c) { return new Array((++c) - n.length).join('0') + n; } return n; }, txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; formatChrCb = function (t, s) { return f[t] ? f[t]() : s; }; f = { // Day d: function () { // Day of month w/leading 0; 01..31 return _pad(f.j(), 2); }, D: function () { // Shorthand day name; Mon...Sun return f.l().slice(0, 3); }, j: function () { // Day of month; 1..31 return jsdate.getDate(); }, l: function () { // Full day name; Monday...Sunday return txt_words[f.w()] + 'day'; }, N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun] return f.w() || 7; }, S: function () { // Ordinal suffix for day of month; st, nd, rd, th var j = f.j(); return j > 4 || j < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[j % 10] || 'th'; }, w: function () { // Day of week; 0[Sun]..6[Sat] return jsdate.getDay(); }, z: function () { // Day of year; 0..365 var a = new Date(f.Y(), f.n() - 1, f.j()), b = new Date(f.Y(), 0, 1); return Math.round((a - b) / 864e5) + 1; }, // Week W: function () { // ISO-8601 week number var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3), b = new Date(a.getFullYear(), 0, 4); return _pad(1 + Math.round((a - b) / 864e5 / 7), 2); }, // Month F: function () { // Full month name; January...December return txt_words[6 + f.n()]; }, m: function () { // Month w/leading 0; 01...12 return _pad(f.n(), 2); }, M: function () { // Shorthand month name; Jan...Dec return f.F().slice(0, 3); }, n: function () { // Month; 1...12 return jsdate.getMonth() + 1; }, t: function () { // Days in month; 28...31 return (new Date(f.Y(), f.n(), 0)).getDate(); }, // Year L: function () { // Is leap year?; 0 or 1 return new Date(f.Y(), 1, 29).getMonth() === 1 | 0; }, o: function () { // ISO-8601 year var n = f.n(), W = f.W(), Y = f.Y(); return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9); }, Y: function () { // Full year; e.g. 1980...2010 return jsdate.getFullYear(); }, y: function () { // Last two digits of year; 00...99 return (f.Y() + "").slice(-2); }, // Time a: function () { // am or pm return jsdate.getHours() > 11 ? "pm" : "am"; }, A: function () { // AM or PM return f.a().toUpperCase(); }, B: function () { // Swatch Internet time; 000..999 var H = jsdate.getUTCHours() * 36e2, // Hours i = jsdate.getUTCMinutes() * 60, // Minutes s = jsdate.getUTCSeconds(); // Seconds return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3); }, g: function () { // 12-Hours; 1..12 return f.G() % 12 || 12; }, G: function () { // 24-Hours; 0..23 return jsdate.getHours(); }, h: function () { // 12-Hours w/leading 0; 01..12 return _pad(f.g(), 2); }, H: function () { // 24-Hours w/leading 0; 00..23 return _pad(f.G(), 2); }, i: function () { // Minutes w/leading 0; 00..59 return _pad(jsdate.getMinutes(), 2); }, s: function () { // Seconds w/leading 0; 00..59 return _pad(jsdate.getSeconds(), 2); }, u: function () { // Microseconds; 000000-999000 return _pad(jsdate.getMilliseconds() * 1000, 6); }, // Timezone e: function () { // Timezone identifier; e.g. Atlantic/Azores, ... // The following works, but requires inclusion of the very large // timezone_abbreviations_list() function. /* return this.date_default_timezone_get(); */ throw 'Not supported (see source code of date() for timezone on how to add support)'; }, I: function () { // DST observed?; 0 or 1 // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. // If they are not equal, then DST is observed. var a = new Date(f.Y(), 0), // Jan 1 c = Date.UTC(f.Y(), 0), // Jan 1 UTC b = new Date(f.Y(), 6), // Jul 1 d = Date.UTC(f.Y(), 6); // Jul 1 UTC return 0 + ((a - c) !== (b - d)); }, O: function () { // Difference to GMT in hour format; e.g. +0200 var a = jsdate.getTimezoneOffset(); return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4); }, P: function () { // Difference to GMT w/colon; e.g. +02:00 var O = f.O(); return (O.substr(0, 3) + ":" + O.substr(3, 2)); }, T: function () { // Timezone abbreviation; e.g. EST, MDT, ... // The following works, but requires inclusion of the very // large timezone_abbreviations_list() function. /* var abbr = '', i = 0, os = 0, default = 0; if (!tal.length) { tal = that.timezone_abbreviations_list(); } if (that.php_js && that.php_js.default_timezone) { default = that.php_js.default_timezone; for (abbr in tal) { for (i=0; i < tal[abbr].length; i++) { if (tal[abbr][i].timezone_id === default) { return abbr.toUpperCase(); } } } } for (abbr in tal) { for (i = 0; i < tal[abbr].length; i++) { os = -jsdate.getTimezoneOffset() * 60; if (tal[abbr][i].offset === os) { return abbr.toUpperCase(); } } } */ return 'UTC'; }, Z: function () { // Timezone offset in seconds (-43200...50400) return -jsdate.getTimezoneOffset() * 60; }, // Full Date/Time c: function () { // ISO-8601 date. return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb); }, r: function () { // RFC 2822 return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); }, U: function () { // Seconds since UNIX epoch return jsdate.getTime() / 1000 | 0; } }; this.date = function (format, timestamp) { that = this; jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) ); return format.replace(formatChr, formatChrCb); }; return this.date(format, timestamp); } function makeDatepicker(m,y,div) { theCal = new calendar(m,y); theCal.getDatepicker(div); } function makeCal(m,y,div) { theCal = new calendar(m,y); theCal.getCal(div); } function calendar(theMonth,theYear,options) { this.dayNames = ["Mo","Di","Mi","Do","Fr","Sa","So"]; this.monthNames = ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"]; this.keepEmpty = false; this.dateSeparator = "."; this.relateTo = ""; this.dateFormat = "d.m.Y"; this.calendar = []; datobj = new Date(); this.currmonth = datobj.getMonth(); this.curryear = datobj.getFullYear(); this.currday = datobj.getDate(); if(theMonth > 12) { theMonth = 1; theYear = theYear+1; } if(theMonth < 1) { theMonth = 12; theYear = theYear-1; } this.month = theMonth-1; this.year = theYear; this.daysInMonth = this.getDaysInMonth(this.month,this.year); this.daysLastMonth = this.getDaysInMonth(this.month-1,this.year); var firstDay = new Date(this.year, this.month, 1); this.startDay = firstDay.getDay()-1; if(this.startDay<0)this.startDay+=7; var tempDays = this.startDay + this.daysInMonth; this.weeksInMonth = Math.ceil(tempDays/7); } calendar.prototype.getCal = function(theDiv) { var theHtml = ""; var pmonth = this.month; var nmonth = this.month+2; theHtml += ""; theHtml += "" + "" + "" + ""; theHtml += ""; for(i=0;i" } theHtml += ""; var intMinithecal = this.buildCal(); for(j=0;j 0 && theDay <= this.daysInMonth) { if(this.currmonth == this.month && this.curryear == this.year && this.currday == theDay) { theHtml += ""; } else { theHtml += ""; } } else if(theDay < 1) { theHtml += ""; } else if(theDay > this.daysInMonth) { theHtml += ""; } } theHtml += ""; } theHtml += "
    " + this.monthNames[this.month] + " " + this.year + "
    "+ theDay + ""+ theDay + ""+(this.daysLastMonth+theDay)+""+(theDay-this.daysInMonth)+"
    "; $(theDiv).innerHTML = theHtml; theMonths = this.monthNames theDays = this.dayNames; keepEmpty = this.keepEmpty; dateSeparator = this.dateSeparator; theYear = this.year; $$("#"+theDiv+" .cal .back a").each ( function (item) { item.onclick = function() { theCal = new calendar(pmonth,theYear); theCal.monthNames = theMonths; theCal.dayNames = theDays; theCal.keepEmpty = keepEmpty; theCal.dateSeparator = dateSeparator; theCal.getCal(theDiv); } } ); $$("#"+theDiv+" .cal .next a").each ( function (item) { item.onclick = function() { internalCals = new calendar(nmonth,theYear); internalCals.monthNames = theMonths; internalCals.dayNames = theDays; internalCals.keepEmpty = keepEmpty; internalCals.dateSeparator = dateSeparator; internalCals.getCal(theDiv); } } ); } calendar.prototype.getDatepicker = function(theDiv) { if(this.dateFormat == "m/d/Y" || this.dateFormat == "m/d/y") { this.dateSeparator = "/"; } var theHtml = ""; var pmonth = this.month; var nmonth = this.month+2; this.theDiv = theDiv; if(this.relateTo) { $(this.relateTo).onfocus = function() { new Effect.Appear(theDiv,{duration:0.8}); } } theHtml += ""; theHtml += "" + "" + "" + ""; theHtml += ""; for(i=0;i" } theHtml += ""; var thecal = this.buildCal(); if(!this.keepEmpty && !$(this.relateTo).value) { if((this.month+1) < 10) { strMon = "0" + (this.month+1); } else { strMon = this.month+1; } if(this.currday < 10 && this.currday > 0) { strDay = "0" + this.currday; } else { strDay = this.currday; } //initStr = strMon + this.dateSeparator + strDay + this.dateSeparator + this.curryear; initStr2 = strMon + "/" + strDay + "/" + this.curryear; // var theIniStamp = Date.parse(initStr2)/1000; var theIniStamp = strtotime(initStr2); $(this.relateTo).value = date(this.dateFormat,theIniStamp); } selectedVals = $(this.relateTo).value.split(this.dateSeparator); for(j=0;j 0) { strDay = "0" + theDay; } if((this.month+1) < 10) { strMon = "0" + (this.month+1); } else { strMon = this.month+1; } dstring = strDay + this.dateSeparator + strMon + this.dateSeparator + this.year; dstring2 = strMon+ "/" + strDay + "/" + this.year; // var theStamp = Date.parse(dstring2)/1000; var theStamp = strtotime(dstring2); var dateString = date(this.dateFormat,theStamp); //dstring = strMon + "/" + strDay + "/" + this.year; if(theDay > 0 && theDay <= this.daysInMonth) { if(this.currmonth == this.month && this.curryear == this.year && this.currday == theDay) { theHtml += ""; } else if(this.month == (selectedVals[1]-1) && this.year == selectedVals[2] && selectedVals[0] == theDay) { theHtml += ""; } else { theHtml += ""; } } else if(theDay < 1) { theHtml += ""; } else if(theDay > this.daysInMonth) { theHtml += ""; } } theHtml += ""; } theHtml += "
    " + this.monthNames[this.month] + " " + this.year + "
    "+ theDay + ""+ theDay + ""+ theDay + ""+(this.daysLastMonth+theDay)+""+(theDay-this.daysInMonth)+"
    Close
    "; $(theDiv).innerHTML = theHtml; var theMonths = this.monthNames var theDays = this.dayNames; var keepEmpty = this.keepEmpty; var dateSeparator = this.dateSeparator; var theYear = this.year; var theRelate = this.relateTo; var theDateFormat = this.dateFormat; $$("#"+theDiv+" .cal .back a").each ( function (item) { item.onclick = function() { var internalCal = new calendar(pmonth,theYear); internalCal.monthNames = theMonths; internalCal.dayNames = theDays; internalCal.keepEmpty = keepEmpty; internalCal.relateTo = theRelate; internalCal.dateSeparator = dateSeparator; internalCal.dateFormat = theDateFormat; internalCal.getDatepicker(theDiv); } } ); $$("#"+theDiv+" .cal .next a").each ( function (item) { item.onclick = function() { var internalCal = new calendar(nmonth,theYear); internalCal.monthNames = theMonths; internalCal.dayNames = theDays; internalCal.keepEmpty = keepEmpty; internalCal.relateTo = theRelate; internalCal.dateSeparator = dateSeparator; internalCal.dateFormat = theDateFormat; internalCal.getDatepicker(theDiv); } } ); } calendar.prototype.showDatepicker = function() { } calendar.prototype.buildCal = function() { var counter = 0; for(j=0;j var Prototype={Version:"1.6.0.3",Browser:{IE:!!(window.attachEvent&&navigator.userAgent.indexOf("Opera")===-1),Opera:navigator.userAgent.indexOf("Opera")>-1,WebKit:navigator.userAgent.indexOf("AppleWebKit/")>-1,Gecko:navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")===-1,MobileSafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/)},BrowserFeatures:{XPath:!!document.evaluate,SelectorsAPI:!!document.querySelector,ElementExtensions:!!window.HTMLElement,SpecificElementExtensions:document.createElement("div")["__proto__"]&&document.createElement("div")["__proto__"]!==document.createElement("form")["__proto__"]},ScriptFragment:"]*>([\\S\\s]*?)<\/script>",JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){},K:function(a){return a}};if(Prototype.Browser.MobileSafari){Prototype.BrowserFeatures.SpecificElementExtensions=false}var Class={create:function(){var e=null,d=$A(arguments);if(Object.isFunction(d[0])){e=d.shift()}function a(){this.initialize.apply(this,arguments)}Object.extend(a,Class.Methods);a.superclass=e;a.subclasses=[];if(e){var b=function(){};b.prototype=e.prototype;a.prototype=new b;e.subclasses.push(a)}for(var c=0;c0){if(b=d.match(e)){a+=d.slice(0,b.index);a+=String.interpret(c(b));d=d.slice(b.index+b[0].length)}else{a+=d,d=""}}return a},sub:function(c,a,b){a=this.gsub.prepareReplacement(a);b=Object.isUndefined(b)?1:b;return this.gsub(c,function(d){if(--b<0){return d[0]}return a(d)})},scan:function(b,a){this.gsub(b,a);return String(this)},truncate:function(b,a){b=b||30;a=Object.isUndefined(a)?"...":a;return this.length>b?this.slice(0,b-a.length)+a:String(this)},strip:function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")},stripTags:function(){return this.replace(/<\/?[^>]+>/gi,"")},stripScripts:function(){return this.replace(new RegExp(Prototype.ScriptFragment,"img"),"")},extractScripts:function(){var b=new RegExp(Prototype.ScriptFragment,"img");var a=new RegExp(Prototype.ScriptFragment,"im");return(this.match(b)||[]).map(function(c){return(c.match(a)||["",""])[1]})},evalScripts:function(){return this.extractScripts().map(function(script){return eval(script)})},escapeHTML:function(){var a=arguments.callee;a.text.data=this;return a.div.innerHTML},unescapeHTML:function(){var a=new Element("div");a.innerHTML=this.stripTags();return a.childNodes[0]?(a.childNodes.length>1?$A(a.childNodes).inject("",function(b,c){return b+c.nodeValue}):a.childNodes[0].nodeValue):""},toQueryParams:function(b){var a=this.strip().match(/([^?#]*)(#.*)?$/);if(!a){return{}}return a[1].split(b||"&").inject({},function(e,f){if((f=f.split("="))[0]){var c=decodeURIComponent(f.shift());var d=f.length>1?f.join("="):f[0];if(d!=undefined){d=decodeURIComponent(d)}if(c in e){if(!Object.isArray(e[c])){e[c]=[e[c]]}e[c].push(d)}else{e[c]=d}}return e})},toArray:function(){return this.split("")},succ:function(){return this.slice(0,this.length-1)+String.fromCharCode(this.charCodeAt(this.length-1)+1)},times:function(a){return a<1?"":new Array(a+1).join(this)},camelize:function(){var d=this.split("-"),a=d.length;if(a==1){return d[0]}var c=this.charAt(0)=="-"?d[0].charAt(0).toUpperCase()+d[0].substring(1):d[0];for(var b=1;b-1},startsWith:function(a){return this.indexOf(a)===0},endsWith:function(a){var b=this.length-a.length;return b>=0&&this.lastIndexOf(a)===b},empty:function(){return this==""},blank:function(){return/^\s*$/.test(this)},interpolate:function(a,b){return new Template(this,b).evaluate(a)}});if(Prototype.Browser.WebKit||Prototype.Browser.IE){Object.extend(String.prototype,{escapeHTML:function(){return this.replace(/&/g,"&").replace(//g,">")},unescapeHTML:function(){return this.stripTags().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}})}String.prototype.gsub.prepareReplacement=function(b){if(Object.isFunction(b)){return b}var a=new Template(b);return function(c){return a.evaluate(c)}};String.prototype.parseQuery=String.prototype.toQueryParams;Object.extend(String.prototype.escapeHTML,{div:document.createElement("div"),text:document.createTextNode("")});String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);var Template=Class.create({initialize:function(a,b){this.template=a.toString();this.pattern=b||Template.Pattern},evaluate:function(a){if(Object.isFunction(a.toTemplateReplacements)){a=a.toTemplateReplacements()}return this.template.gsub(this.pattern,function(d){if(a==null){return""}var f=d[1]||"";if(f=="\\"){return d[2]}var b=a,g=d[3];var e=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;d=e.exec(g);if(d==null){return f}while(d!=null){var c=d[1].startsWith("[")?d[2].gsub("\\\\]","]"):d[1];b=b[c];if(null==b||""==d[3]){break}g=g.substring("["==d[3]?d[1].length:d[0].length);d=e.exec(g)}return f+String.interpret(b)})}});Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;var $break={};var Enumerable={each:function(c,b){var a=0;try{this._each(function(e){c.call(b,e,a++)})}catch(d){if(d!=$break){throw d}}return this},eachSlice:function(d,c,b){var a=-d,e=[],f=this.toArray();if(d<1){return f}while((a+=d)=a){a=e}});return a},min:function(c,b){c=c||Prototype.K;var a;this.each(function(e,d){e=c.call(b,e,d);if(a==null||ec?1:0}).pluck("value")},toArray:function(){return this.map()},zip:function(){var b=Prototype.K,a=$A(arguments);if(Object.isFunction(a.last())){b=a.pop()}var c=[this].concat(a).map($A);return this.map(function(e,d){return b(c.pluck(d))})},size:function(){return this.toArray().length},inspect:function(){return"#"}};Object.extend(Enumerable,{map:Enumerable.collect,find:Enumerable.detect,select:Enumerable.findAll,filter:Enumerable.findAll,member:Enumerable.include,entries:Enumerable.toArray,every:Enumerable.all,some:Enumerable.any});function $A(c){if(!c){return[]}if(c.toArray){return c.toArray()}var b=c.length||0,a=new Array(b);while(b--){a[b]=c[b]}return a}if(Prototype.Browser.WebKit){$A=function(c){if(!c){return[]}if(!(typeof c==="function"&&typeof c.length==="number"&&typeof c.item==="function")&&c.toArray){return c.toArray()}var b=c.length||0,a=new Array(b);while(b--){a[b]=c[b]}return a}}Array.from=$A;Object.extend(Array.prototype,Enumerable);if(!Array.prototype._reverse){Array.prototype._reverse=Array.prototype.reverse}Object.extend(Array.prototype,{_each:function(b){for(var a=0,c=this.length;a1?this:this[0]},uniq:function(a){return this.inject([],function(d,c,b){if(0==b||(a?d.last()!=c:!d.include(c))){d.push(c)}return d})},intersect:function(a){return this.uniq().findAll(function(b){return a.detect(function(c){return b===c})})},clone:function(){return[].concat(this)},size:function(){return this.length},inspect:function(){return"["+this.map(Object.inspect).join(", ")+"]"},toJSON:function(){var a=[];this.each(function(b){var c=Object.toJSON(b);if(!Object.isUndefined(c)){a.push(c)}});return"["+a.join(", ")+"]"}});if(Object.isFunction(Array.prototype.forEach)){Array.prototype._each=Array.prototype.forEach}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(c,a){a||(a=0);var b=this.length;if(a<0){a=b+a}for(;a"},toJSON:function(){return Object.toJSON(this.toObject())},clone:function(){return new Hash(this)}}})());Hash.prototype.toTemplateReplacements=Hash.prototype.toObject;Hash.from=$H;var ObjectRange=Class.create(Enumerable,{initialize:function(c,a,b){this.start=c;this.end=a;this.exclusive=b},_each:function(a){var b=this.start;while(this.include(b)){a(b);b=b.succ()}},include:function(a){if(a1&&!((a==4)&&this._complete)){this.respondToReadyState(this.transport.readyState)}},setRequestHeaders:function(){var e={"X-Requested-With":"XMLHttpRequest","X-Prototype-Version":Prototype.Version,Accept:"text/javascript, text/html, application/xml, text/xml, */*"};if(this.method=="post"){e["Content-type"]=this.options.contentType+(this.options.encoding?"; charset="+this.options.encoding:"");if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){e.Connection="close"}}if(typeof this.options.requestHeaders=="object"){var c=this.options.requestHeaders;if(Object.isFunction(c.push)){for(var b=0,d=c.length;b=200&&a<300)},getStatus:function(){try{return this.transport.status||0}catch(a){return 0}},respondToReadyState:function(a){var c=Ajax.Request.Events[a],b=new Ajax.Response(this);if(c=="Complete"){try{this._complete=true;(this.options["on"+b.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(b,b.headerJSON)}catch(d){this.dispatchException(d)}var f=b.getHeader("Content-type");if(this.options.evalJS=="force"||(this.options.evalJS&&this.isSameOrigin()&&f&&f.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))){this.evalResponse()}}try{(this.options["on"+c]||Prototype.emptyFunction)(b,b.headerJSON);Ajax.Responders.dispatch("on"+c,this,b,b.headerJSON)}catch(d){this.dispatchException(d)}if(c=="Complete"){this.transport.onreadystatechange=Prototype.emptyFunction}},isSameOrigin:function(){var a=this.url.match(/^\s*https?:\/\/[^\/]*/);return !a||(a[0]=="#{protocol}//#{domain}#{port}".interpolate({protocol:location.protocol,domain:document.domain,port:location.port?":"+location.port:""}))},getHeader:function(a){try{return this.transport.getResponseHeader(a)||null}catch(b){return null}},evalResponse:function(){try{return eval((this.transport.responseText||"").unfilterJSON())}catch(e){this.dispatchException(e)}},dispatchException:function(a){(this.options.onException||Prototype.emptyFunction)(this,a);Ajax.Responders.dispatch("onException",this,a)}});Ajax.Request.Events=["Uninitialized","Loading","Loaded","Interactive","Complete"];Ajax.Response=Class.create({initialize:function(c){this.request=c;var d=this.transport=c.transport,a=this.readyState=d.readyState;if((a>2&&!Prototype.Browser.IE)||a==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=String.interpret(d.responseText);this.headerJSON=this._getHeaderJSON()}if(a==4){var b=d.responseXML;this.responseXML=Object.isUndefined(b)?null:b;this.responseJSON=this._getResponseJSON()}},status:0,statusText:"",getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||""}catch(a){return""}},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){try{return this.getAllResponseHeaders()}catch(a){return null}},getResponseHeader:function(a){return this.transport.getResponseHeader(a)},getAllResponseHeaders:function(){return this.transport.getAllResponseHeaders()},_getHeaderJSON:function(){var a=this.getHeader("X-JSON");if(!a){return null}a=decodeURIComponent(escape(a));try{return a.evalJSON(this.request.options.sanitizeJSON||!this.request.isSameOrigin())}catch(b){this.request.dispatchException(b)}},_getResponseJSON:function(){var a=this.request.options;if(!a.evalJSON||(a.evalJSON!="force"&&!(this.getHeader("Content-type")||"").include("application/json"))||this.responseText.blank()){return null}try{return this.responseText.evalJSON(a.sanitizeJSON||!this.request.isSameOrigin())}catch(b){this.request.dispatchException(b)}}});Ajax.Updater=Class.create(Ajax.Request,{initialize:function($super,a,c,b){this.container={success:(a.success||a),failure:(a.failure||(a.success?null:a))};b=Object.clone(b);var d=b.onComplete;b.onComplete=(function(e,f){this.updateContent(e.responseText);if(Object.isFunction(d)){d(e,f)}}).bind(this);$super(c,b)},updateContent:function(d){var c=this.container[this.success()?"success":"failure"],a=this.options;if(!a.evalScripts){d=d.stripScripts()}if(c=$(c)){if(a.insertion){if(Object.isString(a.insertion)){var b={};b[a.insertion]=d;c.insert(b)}else{a.insertion(c,d)}}else{c.update(d)}}}});Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function($super,a,c,b){$super(b);this.onComplete=this.options.onComplete;this.frequency=(this.options.frequency||2);this.decay=(this.options.decay||1);this.updater={};this.container=a;this.url=c;this.start()},start:function(){this.options.onComplete=this.updateComplete.bind(this);this.onTimerEvent()},stop:function(){this.updater.options.onComplete=undefined;clearTimeout(this.timer);(this.onComplete||Prototype.emptyFunction).apply(this,arguments)},updateComplete:function(a){if(this.options.decay){this.decay=(a.responseText==this.lastText?this.decay*this.options.decay:1);this.lastText=a.responseText}this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency)},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options)}});function $(b){if(arguments.length>1){for(var a=0,d=[],c=arguments.length;a';delete c.name;return Element.writeAttribute(document.createElement(d),c)}if(!b[d]){b[d]=Element.extend(document.createElement(d))}return Element.writeAttribute(b[d].cloneNode(false),c)};Object.extend(this.Element,a||{});if(a){this.Element.prototype=a.prototype}}).call(window);Element.cache={};Element.Methods={visible:function(a){return $(a).style.display!="none"},toggle:function(a){a=$(a);Element[Element.visible(a)?"hide":"show"](a);return a},hide:function(a){a=$(a);a.style.display="none";return a},show:function(a){a=$(a);a.style.display="";return a},remove:function(a){a=$(a);a.parentNode.removeChild(a);return a},update:function(a,b){a=$(a);if(b&&b.toElement){b=b.toElement()}if(Object.isElement(b)){return a.update().insert(b)}b=Object.toHTML(b);a.innerHTML=b.stripScripts();b.evalScripts.bind(b).defer();return a},replace:function(b,c){b=$(b);if(c&&c.toElement){c=c.toElement()}else{if(!Object.isElement(c)){c=Object.toHTML(c);var a=b.ownerDocument.createRange();a.selectNode(b);c.evalScripts.bind(c).defer();c=a.createContextualFragment(c.stripScripts())}}b.parentNode.replaceChild(c,b);return b},insert:function(c,e){c=$(c);if(Object.isString(e)||Object.isNumber(e)||Object.isElement(e)||(e&&(e.toElement||e.toHTML))){e={bottom:e}}var d,f,b,g;for(var a in e){d=e[a];a=a.toLowerCase();f=Element._insertionTranslations[a];if(d&&d.toElement){d=d.toElement()}if(Object.isElement(d)){f(c,d);continue}d=Object.toHTML(d);b=((a=="before"||a=="after")?c.parentNode:c).tagName.toUpperCase();g=Element._getContentFromAnonymousElement(b,d.stripScripts());if(a=="top"||a=="after"){g.reverse()}g.each(f.curry(c));d.evalScripts.bind(d).defer()}return c},wrap:function(b,c,a){b=$(b);if(Object.isElement(c)){$(c).writeAttribute(a||{})}else{if(Object.isString(c)){c=new Element(c,a)}else{c=new Element("div",c)}}if(b.parentNode){b.parentNode.replaceChild(c,b)}c.appendChild(b);return c},inspect:function(b){b=$(b);var a="<"+b.tagName.toLowerCase();$H({id:"id",className:"class"}).each(function(f){var e=f.first(),c=f.last();var d=(b[e]||"").toString();if(d){a+=" "+c+"="+d.inspect(true)}});return a+">"},recursivelyCollect:function(a,c){a=$(a);var b=[];while(a=a[c]){if(a.nodeType==1){b.push(Element.extend(a))}}return b},ancestors:function(a){return $(a).recursivelyCollect("parentNode")},descendants:function(a){return $(a).select("*")},firstDescendant:function(a){a=$(a).firstChild;while(a&&a.nodeType!=1){a=a.nextSibling}return $(a)},immediateDescendants:function(a){if(!(a=$(a).firstChild)){return[]}while(a&&a.nodeType!=1){a=a.nextSibling}if(a){return[a].concat($(a).nextSiblings())}return[]},previousSiblings:function(a){return $(a).recursivelyCollect("previousSibling")},nextSiblings:function(a){return $(a).recursivelyCollect("nextSibling")},siblings:function(a){a=$(a);return a.previousSiblings().reverse().concat(a.nextSiblings())},match:function(b,a){if(Object.isString(a)){a=new Selector(a)}return a.match($(b))},up:function(b,d,a){b=$(b);if(arguments.length==1){return $(b.parentNode)}var c=b.ancestors();return Object.isNumber(d)?c[d]:Selector.findElement(c,d,a)},down:function(b,c,a){b=$(b);if(arguments.length==1){return b.firstDescendant()}return Object.isNumber(c)?b.descendants()[c]:Element.select(b,c)[a||0]},previous:function(b,d,a){b=$(b);if(arguments.length==1){return $(Selector.handlers.previousElementSibling(b))}var c=b.previousSiblings();return Object.isNumber(d)?c[d]:Selector.findElement(c,d,a)},next:function(c,d,b){c=$(c);if(arguments.length==1){return $(Selector.handlers.nextElementSibling(c))}var a=c.nextSiblings();return Object.isNumber(d)?a[d]:Selector.findElement(a,d,b)},select:function(){var a=$A(arguments),b=$(a.shift());return Selector.findChildElements(b,a)},adjacent:function(){var a=$A(arguments),b=$(a.shift());return Selector.findChildElements(b.parentNode,a).without(b)},identify:function(b){b=$(b);var c=b.readAttribute("id"),a=arguments.callee;if(c){return c}do{c="anonymous_element_"+a.counter++}while($(c));b.writeAttribute("id",c);return c},readAttribute:function(c,a){c=$(c);if(Prototype.Browser.IE){var b=Element._attributeTranslations.read;if(b.values[a]){return b.values[a](c,a)}if(b.names[a]){a=b.names[a]}if(a.include(":")){return(!c.attributes||!c.attributes[a])?null:c.attributes[a].value}}return c.getAttribute(a)},writeAttribute:function(e,c,f){e=$(e);var b={},d=Element._attributeTranslations.write;if(typeof c=="object"){b=c}else{b[c]=Object.isUndefined(f)?true:f}for(var a in b){c=d.names[a]||a;f=b[a];if(d.values[a]){c=d.values[a](e,f)}if(f===false||f===null){e.removeAttribute(c)}else{if(f===true){e.setAttribute(c,c)}else{e.setAttribute(c,f)}}}return e},getHeight:function(a){return $(a).getDimensions().height},getWidth:function(a){return $(a).getDimensions().width},classNames:function(a){return new Element.ClassNames(a)},hasClassName:function(a,b){if(!(a=$(a))){return}var c=a.className;return(c.length>0&&(c==b||new RegExp("(^|\\s)"+b+"(\\s|$)").test(c)))},addClassName:function(a,b){if(!(a=$(a))){return}if(!a.hasClassName(b)){a.className+=(a.className?" ":"")+b}return a},removeClassName:function(a,b){if(!(a=$(a))){return}a.className=a.className.replace(new RegExp("(^|\\s+)"+b+"(\\s+|$)")," ").strip();return a},toggleClassName:function(a,b){if(!(a=$(a))){return}return a[a.hasClassName(b)?"removeClassName":"addClassName"](b)},cleanWhitespace:function(b){b=$(b);var c=b.firstChild;while(c){var a=c.nextSibling;if(c.nodeType==3&&!/\S/.test(c.nodeValue)){b.removeChild(c)}c=a}return b},empty:function(a){return $(a).innerHTML.blank()},descendantOf:function(b,a){b=$(b),a=$(a);if(b.compareDocumentPosition){return(b.compareDocumentPosition(a)&8)===8}if(a.contains){return a.contains(b)&&a!==b}while(b=b.parentNode){if(b==a){return true}}return false},scrollTo:function(a){a=$(a);var b=a.cumulativeOffset();window.scrollTo(b[0],b[1]);return a},getStyle:function(b,c){b=$(b);c=c=="float"?"cssFloat":c.camelize();var d=b.style[c];if(!d||d=="auto"){var a=document.defaultView.getComputedStyle(b,null);d=a?a[c]:null}if(c=="opacity"){return d?parseFloat(d):1}return d=="auto"?null:d},getOpacity:function(a){return $(a).getStyle("opacity")},setStyle:function(b,c){b=$(b);var e=b.style,a;if(Object.isString(c)){b.style.cssText+=";"+c;return c.include("opacity")?b.setOpacity(c.match(/opacity:\s*(\d?\.?\d*)/)[1]):b}for(var d in c){if(d=="opacity"){b.setOpacity(c[d])}else{e[(d=="float"||d=="cssFloat")?(Object.isUndefined(e.styleFloat)?"cssFloat":"styleFloat"):d]=c[d]}}return b},setOpacity:function(a,b){a=$(a);a.style.opacity=(b==1||b==="")?"":(b<0.00001)?0:b;return a},getDimensions:function(c){c=$(c);var g=c.getStyle("display");if(g!="none"&&g!=null){return{width:c.offsetWidth,height:c.offsetHeight}}var b=c.style;var f=b.visibility;var d=b.position;var a=b.display;b.visibility="hidden";b.position="absolute";b.display="block";var h=c.clientWidth;var e=c.clientHeight;b.display=a;b.position=d;b.visibility=f;return{width:h,height:e}},makePositioned:function(a){a=$(a);var b=Element.getStyle(a,"position");if(b=="static"||!b){a._madePositioned=true;a.style.position="relative";if(Prototype.Browser.Opera){a.style.top=0;a.style.left=0}}return a},undoPositioned:function(a){a=$(a);if(a._madePositioned){a._madePositioned=undefined;a.style.position=a.style.top=a.style.left=a.style.bottom=a.style.right=""}return a},makeClipping:function(a){a=$(a);if(a._overflow){return a}a._overflow=Element.getStyle(a,"overflow")||"auto";if(a._overflow!=="hidden"){a.style.overflow="hidden"}return a},undoClipping:function(a){a=$(a);if(!a._overflow){return a}a.style.overflow=a._overflow=="auto"?"":a._overflow;a._overflow=null;return a},cumulativeOffset:function(b){var a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;b=b.offsetParent}while(b);return Element._returnOffset(c,a)},positionedOffset:function(b){var a=0,d=0;do{a+=b.offsetTop||0;d+=b.offsetLeft||0;b=b.offsetParent;if(b){if(b.tagName.toUpperCase()=="BODY"){break}var c=Element.getStyle(b,"position");if(c!=="static"){break}}}while(b);return Element._returnOffset(d,a)},absolutize:function(b){b=$(b);if(b.getStyle("position")=="absolute"){return b}var d=b.positionedOffset();var f=d[1];var e=d[0];var c=b.clientWidth;var a=b.clientHeight;b._originalLeft=e-parseFloat(b.style.left||0);b._originalTop=f-parseFloat(b.style.top||0);b._originalWidth=b.style.width;b._originalHeight=b.style.height;b.style.position="absolute";b.style.top=f+"px";b.style.left=e+"px";b.style.width=c+"px";b.style.height=a+"px";return b},relativize:function(a){a=$(a);if(a.getStyle("position")=="relative"){return a}a.style.position="relative";var c=parseFloat(a.style.top||0)-(a._originalTop||0);var b=parseFloat(a.style.left||0)-(a._originalLeft||0);a.style.top=c+"px";a.style.left=b+"px";a.style.height=a._originalHeight;a.style.width=a._originalWidth;return a},cumulativeScrollOffset:function(b){var a=0,c=0;do{a+=b.scrollTop||0;c+=b.scrollLeft||0;b=b.parentNode}while(b);return Element._returnOffset(c,a)},getOffsetParent:function(a){if(a.offsetParent){return $(a.offsetParent)}if(a==document.body){return $(a)}while((a=a.parentNode)&&a!=document.body){if(Element.getStyle(a,"position")!="static"){return $(a)}}return $(document.body)},viewportOffset:function(d){var a=0,c=0;var b=d;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;if(b.offsetParent==document.body&&Element.getStyle(b,"position")=="absolute"){break}}while(b=b.offsetParent);b=d;do{if(!Prototype.Browser.Opera||(b.tagName&&(b.tagName.toUpperCase()=="BODY"))){a-=b.scrollTop||0;c-=b.scrollLeft||0}}while(b=b.parentNode);return Element._returnOffset(c,a)},clonePosition:function(b,d){var a=Object.extend({setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0},arguments[2]||{});d=$(d);var e=d.viewportOffset();b=$(b);var f=[0,0];var c=null;if(Element.getStyle(b,"position")=="absolute"){c=b.getOffsetParent();f=c.viewportOffset()}if(c==document.body){f[0]-=document.body.offsetLeft;f[1]-=document.body.offsetTop}if(a.setLeft){b.style.left=(e[0]-f[0]+a.offsetLeft)+"px"}if(a.setTop){b.style.top=(e[1]-f[1]+a.offsetTop)+"px"}if(a.setWidth){b.style.width=d.offsetWidth+"px"}if(a.setHeight){b.style.height=d.offsetHeight+"px"}return b}};Element.Methods.identify.counter=1;Object.extend(Element.Methods,{getElementsBySelector:Element.Methods.select,childElements:Element.Methods.immediateDescendants});Element._attributeTranslations={write:{names:{className:"class",htmlFor:"for"},values:{}}};if(Prototype.Browser.Opera){Element.Methods.getStyle=Element.Methods.getStyle.wrap(function(d,b,c){switch(c){case"left":case"top":case"right":case"bottom":if(d(b,"position")==="static"){return null}case"height":case"width":if(!Element.visible(b)){return null}var e=parseInt(d(b,c),10);if(e!==b["offset"+c.capitalize()]){return e+"px"}var a;if(c==="height"){a=["border-top-width","padding-top","padding-bottom","border-bottom-width"]}else{a=["border-left-width","padding-left","padding-right","border-right-width"]}return a.inject(e,function(f,g){var h=d(b,g);return h===null?f:f-parseInt(h,10)})+"px";default:return d(b,c)}});Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(function(c,a,b){if(b==="title"){return a.title}return c(a,b)})}else{if(Prototype.Browser.IE){Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(function(c,b){b=$(b);try{b.offsetParent}catch(f){return $(document.body)}var a=b.getStyle("position");if(a!=="static"){return c(b)}b.setStyle({position:"relative"});var d=c(b);b.setStyle({position:a});return d});$w("positionedOffset viewportOffset").each(function(a){Element.Methods[a]=Element.Methods[a].wrap(function(f,c){c=$(c);try{c.offsetParent}catch(h){return Element._returnOffset(0,0)}var b=c.getStyle("position");if(b!=="static"){return f(c)}var d=c.getOffsetParent();if(d&&d.getStyle("position")==="fixed"){d.setStyle({zoom:1})}c.setStyle({position:"relative"});var g=f(c);c.setStyle({position:b});return g})});Element.Methods.cumulativeOffset=Element.Methods.cumulativeOffset.wrap(function(b,a){try{a.offsetParent}catch(c){return Element._returnOffset(0,0)}return b(a)});Element.Methods.getStyle=function(a,b){a=$(a);b=(b=="float"||b=="cssFloat")?"styleFloat":b.camelize();var c=a.style[b];if(!c&&a.currentStyle){c=a.currentStyle[b]}if(b=="opacity"){if(c=(a.getStyle("filter")||"").match(/alpha\(opacity=(.*)\)/)){if(c[1]){return parseFloat(c[1])/100}}return 1}if(c=="auto"){if((b=="width"||b=="height")&&(a.getStyle("display")!="none")){return a["offset"+b.capitalize()]+"px"}return null}return c};Element.Methods.setOpacity=function(b,e){function f(g){return g.replace(/alpha\([^\)]*\)/gi,"")}b=$(b);var a=b.currentStyle;if((a&&!a.hasLayout)||(!a&&b.style.zoom=="normal")){b.style.zoom=1}var d=b.getStyle("filter"),c=b.style;if(e==1||e===""){(d=f(d))?c.filter=d:c.removeAttribute("filter");return b}else{if(e<0.00001){e=0}}c.filter=f(d)+"alpha(opacity="+(e*100)+")";return b};Element._attributeTranslations={read:{names:{"class":"className","for":"htmlFor"},values:{_getAttr:function(a,b){return a.getAttribute(b,2)},_getAttrNode:function(a,c){var b=a.getAttributeNode(c);return b?b.value:""},_getEv:function(a,b){b=a.getAttribute(b);return b?b.toString().slice(23,-2):null},_flag:function(a,b){return $(a).hasAttribute(b)?b:null},style:function(a){return a.style.cssText.toLowerCase()},title:function(a){return a.title}}}};Element._attributeTranslations.write={names:Object.extend({cellpadding:"cellPadding",cellspacing:"cellSpacing"},Element._attributeTranslations.read.names),values:{checked:function(a,b){a.checked=!!b},style:function(a,b){a.style.cssText=b?b:""}}};Element._attributeTranslations.has={};$w("colSpan rowSpan vAlign dateTime accessKey tabIndex encType maxLength readOnly longDesc frameBorder").each(function(a){Element._attributeTranslations.write.names[a.toLowerCase()]=a;Element._attributeTranslations.has[a.toLowerCase()]=a});(function(a){Object.extend(a,{href:a._getAttr,src:a._getAttr,type:a._getAttr,action:a._getAttrNode,disabled:a._flag,checked:a._flag,readonly:a._flag,multiple:a._flag,onload:a._getEv,onunload:a._getEv,onclick:a._getEv,ondblclick:a._getEv,onmousedown:a._getEv,onmouseup:a._getEv,onmouseover:a._getEv,onmousemove:a._getEv,onmouseout:a._getEv,onfocus:a._getEv,onblur:a._getEv,onkeypress:a._getEv,onkeydown:a._getEv,onkeyup:a._getEv,onsubmit:a._getEv,onreset:a._getEv,onselect:a._getEv,onchange:a._getEv})})(Element._attributeTranslations.read.values)}else{if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1)?0.999999:(b==="")?"":(b<0.00001)?0:b;return a}}else{if(Prototype.Browser.WebKit){Element.Methods.setOpacity=function(a,b){a=$(a);a.style.opacity=(b==1||b==="")?"":(b<0.00001)?0:b;if(b==1){if(a.tagName.toUpperCase()=="IMG"&&a.width){a.width++;a.width--}else{try{var d=document.createTextNode(" ");a.appendChild(d);a.removeChild(d)}catch(c){}}}return a};Element.Methods.cumulativeOffset=function(b){var a=0,c=0;do{a+=b.offsetTop||0;c+=b.offsetLeft||0;if(b.offsetParent==document.body){if(Element.getStyle(b,"position")=="absolute"){break}}b=b.offsetParent}while(b);return Element._returnOffset(c,a)}}}}}if(Prototype.Browser.IE||Prototype.Browser.Opera){Element.Methods.update=function(b,c){b=$(b);if(c&&c.toElement){c=c.toElement()}if(Object.isElement(c)){return b.update().insert(c)}c=Object.toHTML(c);var a=b.tagName.toUpperCase();if(a in Element._insertionTranslations.tags){$A(b.childNodes).each(function(d){b.removeChild(d)});Element._getContentFromAnonymousElement(a,c.stripScripts()).each(function(d){b.appendChild(d)})}else{b.innerHTML=c.stripScripts()}c.evalScripts.bind(c).defer();return b}}if("outerHTML" in document.createElement("div")){Element.Methods.replace=function(c,e){c=$(c);if(e&&e.toElement){e=e.toElement()}if(Object.isElement(e)){c.parentNode.replaceChild(e,c);return c}e=Object.toHTML(e);var d=c.parentNode,b=d.tagName.toUpperCase();if(Element._insertionTranslations.tags[b]){var f=c.next();var a=Element._getContentFromAnonymousElement(b,e.stripScripts());d.removeChild(c);if(f){a.each(function(g){d.insertBefore(g,f)})}else{a.each(function(g){d.appendChild(g)})}}else{c.outerHTML=e.stripScripts()}e.evalScripts.bind(e).defer();return c}}Element._returnOffset=function(b,c){var a=[b,c];a.left=b;a.top=c;return a};Element._getContentFromAnonymousElement=function(c,b){var d=new Element("div"),a=Element._insertionTranslations.tags[c];if(a){d.innerHTML=a[0]+b+a[1];a[2].times(function(){d=d.firstChild})}else{d.innerHTML=b}return $A(d.childNodes)};Element._insertionTranslations={before:function(a,b){a.parentNode.insertBefore(b,a)},top:function(a,b){a.insertBefore(b,a.firstChild)},bottom:function(a,b){a.appendChild(b)},after:function(a,b){a.parentNode.insertBefore(b,a.nextSibling)},tags:{TABLE:["","
    ",1],TBODY:["","
    ",2],TR:["","
    ",3],TD:["
    ","
    ",4],SELECT:["",1]}};(function(){Object.extend(this.tags,{THEAD:this.tags.TBODY,TFOOT:this.tags.TBODY,TH:this.tags.TD})}).call(Element._insertionTranslations);Element.Methods.Simulated={hasAttribute:function(a,c){c=Element._attributeTranslations.has[c]||c;var b=$(a).getAttributeNode(c);return !!(b&&b.specified)}};Element.Methods.ByTag={};Object.extend(Element,Element.Methods);if(!Prototype.BrowserFeatures.ElementExtensions&&document.createElement("div")["__proto__"]){window.HTMLElement={};window.HTMLElement.prototype=document.createElement("div")["__proto__"];Prototype.BrowserFeatures.ElementExtensions=true}Element.extend=(function(){if(Prototype.BrowserFeatures.SpecificElementExtensions){return Prototype.K}var a={},b=Element.Methods.ByTag;var c=Object.extend(function(f){if(!f||f._extendedByPrototype||f.nodeType!=1||f==window){return f}var d=Object.clone(a),e=f.tagName.toUpperCase(),h,g;if(b[e]){Object.extend(d,b[e])}for(h in d){g=d[h];if(Object.isFunction(g)&&!(h in f)){f[h]=g.methodize()}}f._extendedByPrototype=Prototype.emptyFunction;return f},{refresh:function(){if(!Prototype.BrowserFeatures.ElementExtensions){Object.extend(a,Element.Methods);Object.extend(a,Element.Methods.Simulated)}}});c.refresh();return c})();Element.hasAttribute=function(a,b){if(a.hasAttribute){return a.hasAttribute(b)}return Element.Methods.Simulated.hasAttribute(a,b)};Element.addMethods=function(c){var h=Prototype.BrowserFeatures,d=Element.Methods.ByTag;if(!c){Object.extend(Form,Form.Methods);Object.extend(Form.Element,Form.Element.Methods);Object.extend(Element.Methods.ByTag,{FORM:Object.clone(Form.Methods),INPUT:Object.clone(Form.Element.Methods),SELECT:Object.clone(Form.Element.Methods),TEXTAREA:Object.clone(Form.Element.Methods)})}if(arguments.length==2){var b=c;c=arguments[1]}if(!b){Object.extend(Element.Methods,c||{})}else{if(Object.isArray(b)){b.each(g)}else{g(b)}}function g(k){k=k.toUpperCase();if(!Element.Methods.ByTag[k]){Element.Methods.ByTag[k]={}}Object.extend(Element.Methods.ByTag[k],c)}function a(m,l,k){k=k||false;for(var o in m){var n=m[o];if(!Object.isFunction(n)){continue}if(!k||!(o in l)){l[o]=n.methodize()}}}function e(m){var k;var l={OPTGROUP:"OptGroup",TEXTAREA:"TextArea",P:"Paragraph",FIELDSET:"FieldSet",UL:"UList",OL:"OList",DL:"DList",DIR:"Directory",H1:"Heading",H2:"Heading",H3:"Heading",H4:"Heading",H5:"Heading",H6:"Heading",Q:"Quote",INS:"Mod",DEL:"Mod",A:"Anchor",IMG:"Image",CAPTION:"TableCaption",COL:"TableCol",COLGROUP:"TableCol",THEAD:"TableSection",TFOOT:"TableSection",TBODY:"TableSection",TR:"TableRow",TH:"TableCell",TD:"TableCell",FRAMESET:"FrameSet",IFRAME:"IFrame"};if(l[m]){k="HTML"+l[m]+"Element"}if(window[k]){return window[k]}k="HTML"+m+"Element";if(window[k]){return window[k]}k="HTML"+m.capitalize()+"Element";if(window[k]){return window[k]}window[k]={};window[k].prototype=document.createElement(m)["__proto__"];return window[k]}if(h.ElementExtensions){a(Element.Methods,HTMLElement.prototype);a(Element.Methods.Simulated,HTMLElement.prototype,true)}if(h.SpecificElementExtensions){for(var j in Element.Methods.ByTag){var f=e(j);if(Object.isUndefined(f)){continue}a(d[j],f.prototype)}}Object.extend(Element,Element.Methods);delete Element.ByTag;if(Element.extend.refresh){Element.extend.refresh()}Element.cache={}};document.viewport={getDimensions:function(){var a={},b=Prototype.Browser;$w("width height").each(function(e){var c=e.capitalize();if(b.WebKit&&!document.evaluate){a[e]=self["inner"+c]}else{if(b.Opera&&parseFloat(window.opera.version())<9.5){a[e]=document.body["client"+c]}else{a[e]=document.documentElement["client"+c]}}});return a},getWidth:function(){return this.getDimensions().width},getHeight:function(){return this.getDimensions().height},getScrollOffsets:function(){return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop)}};var Selector=Class.create({initialize:function(a){this.expression=a.strip();if(this.shouldUseSelectorsAPI()){this.mode="selectorsAPI"}else{if(this.shouldUseXPath()){this.mode="xpath";this.compileXPathMatcher()}else{this.mode="normal";this.compileMatcher()}}},shouldUseXPath:function(){if(!Prototype.BrowserFeatures.XPath){return false}var a=this.expression;if(Prototype.Browser.WebKit&&(a.include("-of-type")||a.include(":empty"))){return false}if((/(\[[\w-]*?:|:checked)/).test(a)){return false}return true},shouldUseSelectorsAPI:function(){if(!Prototype.BrowserFeatures.SelectorsAPI){return false}if(!Selector._div){Selector._div=new Element("div")}try{Selector._div.querySelector(this.expression)}catch(a){return false}return true},compileMatcher:function(){var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m;if(Selector._cache[e]){this.matcher=Selector._cache[e];return}this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];while(e&&le!=e&&(/\S/).test(e)){le=e;for(var i in ps){p=ps[i];if(m=e.match(p)){this.matcher.push(Object.isFunction(c[i])?c[i](m):new Template(c[i]).evaluate(m));e=e.replace(m[0],"");break}}}this.matcher.push("return h.unique(n);\n}");eval(this.matcher.join("\n"));Selector._cache[this.expression]=this.matcher},compileXPathMatcher:function(){var f=this.expression,g=Selector.patterns,b=Selector.xpath,d,a;if(Selector._cache[f]){this.xpath=Selector._cache[f];return}this.matcher=[".//*"];while(f&&d!=f&&(/\S/).test(f)){d=f;for(var c in g){if(a=f.match(g[c])){this.matcher.push(Object.isFunction(b[c])?b[c](a):new Template(b[c]).evaluate(a));f=f.replace(a[0],"");break}}}this.xpath=this.matcher.join("");Selector._cache[this.expression]=this.xpath},findElements:function(a){a=a||document;var c=this.expression,b;switch(this.mode){case"selectorsAPI":if(a!==document){var d=a.id,f=$(a).identify();c="#"+f+" "+c}b=$A(a.querySelectorAll(c)).map(Element.extend);a.id=d;return b;case"xpath":return document._getElementsByXPath(this.xpath,a);default:return this.matcher(a)}},match:function(j){this.tokens=[];var o=this.expression,a=Selector.patterns,f=Selector.assertions;var b,d,g;while(o&&b!==o&&(/\S/).test(o)){b=o;for(var k in a){d=a[k];if(g=o.match(d)){if(f[k]){this.tokens.push([k,Object.clone(g)]);o=o.replace(g[0],"")}else{return this.findElements(document).include(j)}}}}var n=true,c,l;for(var k=0,h;h=this.tokens[k];k++){c=h[0],l=h[1];if(!Selector.assertions[c](j,l)){n=false;break}}return n},toString:function(){return this.expression},inspect:function(){return"#"}});Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:"/following-sibling::*",tagName:function(a){if(a[1]=="*"){return""}return"[local-name()='"+a[1].toLowerCase()+"' or local-name()='"+a[1].toUpperCase()+"']"},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:function(a){a[1]=a[1].toLowerCase();return new Template("[@#{1}]").evaluate(a)},attr:function(a){a[1]=a[1].toLowerCase();a[3]=a[5]||a[6];return new Template(Selector.xpath.operators[a[2]]).evaluate(a)},pseudo:function(a){var b=Selector.xpath.pseudos[a[1]];if(!b){return""}if(Object.isFunction(b)){return b(a)}return new Template(Selector.xpath.pseudos[a[1]]).evaluate(a)},operators:{"=":"[@#{1}='#{3}']","!=":"[@#{1}!='#{3}']","^=":"[starts-with(@#{1}, '#{3}')]","$=":"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']","*=":"[contains(@#{1}, '#{3}')]","~=":"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]","|=":"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{"first-child":"[not(preceding-sibling::*)]","last-child":"[not(following-sibling::*)]","only-child":"[not(preceding-sibling::* or following-sibling::*)]",empty:"[count(*) = 0 and (count(text()) = 0)]",checked:"[@checked]",disabled:"[(@disabled) and (@type!='hidden')]",enabled:"[not(@disabled) and (@type!='hidden')]",not:function(b){var j=b[6],h=Selector.patterns,a=Selector.xpath,f,c;var g=[];while(j&&f!=j&&(/\S/).test(j)){f=j;for(var d in h){if(b=j.match(h[d])){c=Object.isFunction(a[d])?a[d](b):new Template(a[d]).evaluate(b);g.push("("+c.substring(1,c.length-1)+")");j=j.replace(b[0],"");break}}}return"[not("+g.join(" and ")+")]"},"nth-child":function(a){return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",a)},"nth-last-child":function(a){return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",a)},"nth-of-type":function(a){return Selector.xpath.pseudos.nth("position() ",a)},"nth-last-of-type":function(a){return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",a)},"first-of-type":function(a){a[6]="1";return Selector.xpath.pseudos["nth-of-type"](a)},"last-of-type":function(a){a[6]="1";return Selector.xpath.pseudos["nth-last-of-type"](a)},"only-of-type":function(a){var b=Selector.xpath.pseudos;return b["first-of-type"](a)+b["last-of-type"](a)},nth:function(g,e){var h,j=e[6],d;if(j=="even"){j="2n+0"}if(j=="odd"){j="2n+1"}if(h=j.match(/^(\d+)$/)){return"["+g+"= "+h[1]+"]"}if(h=j.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(h[1]=="-"){h[1]=-1}var f=h[1]?Number(h[1]):1;var c=h[2]?Number(h[2]):0;d="[((#{fragment} - #{b}) mod #{a} = 0) and ((#{fragment} - #{b}) div #{a} >= 0)]";return new Template(d).evaluate({fragment:g,a:f,b:c})}}}},criteria:{tagName:'n = h.tagName(n, r, "#{1}", c); c = false;',className:'n = h.className(n, r, "#{1}", c); c = false;',id:'n = h.id(n, r, "#{1}", c); c = false;',attrPresence:'n = h.attrPresence(n, r, "#{1}", c); c = false;',attr:function(a){a[3]=(a[5]||a[6]);return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(a)},pseudo:function(a){if(a[6]){a[6]=a[6].replace(/"/g,'\\"')}return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(a)},descendant:'c = "descendant";',child:'c = "child";',adjacent:'c = "adjacent";',laterSibling:'c = "laterSibling";'},patterns:{laterSibling:/^\s*~\s*/,child:/^\s*>\s*/,adjacent:/^\s*\+\s*/,descendant:/^\s/,tagName:/^\s*(\*|[\w\-]+)(\b|$)?/,id:/^#([\w\-\*]+)(\b|$)/,className:/^\.([\w\-\*]+)(\b|$)/,pseudo:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,attrPresence:/^\[((?:[\w]+:)?[\w]+)\]/,attr:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/},assertions:{tagName:function(a,b){return b[1].toUpperCase()==a.tagName.toUpperCase()},className:function(a,b){return Element.hasClassName(a,b[1])},id:function(a,b){return a.id===b[1]},attrPresence:function(a,b){return Element.hasAttribute(a,b[1])},attr:function(b,c){var a=Element.readAttribute(b,c[1]);return a&&Selector.operators[c[2]](a,c[5]||c[6])}},handlers:{concat:function(d,c){for(var e=0,f;f=c[e];e++){d.push(f)}return d},mark:function(a){var d=Prototype.emptyFunction;for(var b=0,c;c=a[b];b++){c._countedByPrototype=d}return a},unmark:function(a){for(var b=0,c;c=a[b];b++){c._countedByPrototype=undefined}return a},index:function(a,d,g){a._countedByPrototype=Prototype.emptyFunction;if(d){for(var b=a.childNodes,e=b.length-1,c=1;e>=0;e--){var f=b[e];if(f.nodeType==1&&(!g||f._countedByPrototype)){f.nodeIndex=c++}}}else{for(var e=0,c=1,b=a.childNodes;f=b[e];e++){if(f.nodeType==1&&(!g||f._countedByPrototype)){f.nodeIndex=c++}}}},unique:function(b){if(b.length==0){return b}var d=[],e;for(var c=0,a=b.length;c0?[c]:[]}return $R(1,e).inject([],function(a,b){if(0==(b-c)%d&&(b-c)/d>=0){a.push(b)}return a})},nth:function(c,s,u,r,e){if(c.length==0){return[]}if(s=="even"){s="2n+0"}if(s=="odd"){s="2n+1"}var q=Selector.handlers,p=[],d=[],g;q.mark(c);for(var o=0,f;f=c[o];o++){if(!f.parentNode._countedByPrototype){q.index(f.parentNode,r,e);d.push(f.parentNode)}}if(s.match(/^\d+$/)){s=Number(s);for(var o=0,f;f=c[o];o++){if(f.nodeIndex==s){p.push(f)}}}else{if(g=s.match(/^(-?\d*)?n(([+-])(\d+))?/)){if(g[1]=="-"){g[1]=-1}var v=g[1]?Number(g[1]):1;var t=g[2]?Number(g[2]):0;var w=Selector.pseudos.getIndices(v,t,c.length);for(var o=0,f,k=w.length;f=c[o];o++){for(var n=0;n+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(c){a.push(c[1].strip())});return a},matchElements:function(f,g){var e=$$(g),d=Selector.handlers;d.mark(e);for(var c=0,b=[],a;a=f[c];c++){if(a._countedByPrototype){b.push(a)}}d.unmark(e);return b},findElement:function(b,c,a){if(Object.isNumber(c)){a=c;c=false}return Selector.matchElements(b,c||"*")[a||0]},findChildElements:function(e,g){g=Selector.split(g.join(","));var d=[],f=Selector.handlers;for(var c=0,b=g.length,a;c1)?f.unique(d):d}});if(Prototype.Browser.IE){Object.extend(Selector.handlers,{concat:function(d,c){for(var e=0,f;f=c[e];e++){if(f.tagName!=="!"){d.push(f)}}return d},unmark:function(a){for(var b=0,c;c=a[b];b++){c.removeAttribute("_countedByPrototype")}return a}})}function $$(){return Selector.findChildElements(document,$A(arguments))}var Form={reset:function(a){$(a).reset();return a},serializeElements:function(g,b){if(typeof b!="object"){b={hash:!!b}}else{if(Object.isUndefined(b.hash)){b.hash=true}}var c,f,a=false,e=b.submit;var d=g.inject({},function(h,j){if(!j.disabled&&j.name){c=j.name;f=$(j).getValue();if(f!=null&&j.type!="file"&&(j.type!="submit"||(!a&&e!==false&&(!e||c==e)&&(a=true)))){if(c in h){if(!Object.isArray(h[c])){h[c]=[h[c]]}h[c].push(f)}else{h[c]=f}}}return h});return b.hash?d:Object.toQueryString(d)}};Form.Methods={serialize:function(b,a){return Form.serializeElements(Form.getElements(b),a)},getElements:function(a){return $A($(a).getElementsByTagName("*")).inject([],function(b,c){if(Form.Element.Serializers[c.tagName.toLowerCase()]){b.push(Element.extend(c))}return b})},getInputs:function(g,c,d){g=$(g);var a=g.getElementsByTagName("input");if(!c&&!d){return $A(a).map(Element.extend)}for(var e=0,h=[],f=a.length;e=0}).sortBy(function(d){return d.tabIndex}).first();return a?a:c.find(function(d){return["input","select","textarea"].include(d.tagName.toLowerCase())})},focusFirstElement:function(a){a=$(a);a.findFirstElement().activate();return a},request:function(b,a){b=$(b),a=Object.clone(a||{});var d=a.parameters,c=b.readAttribute("action")||"";if(c.blank()){c=window.location.href}a.parameters=b.serialize(true);if(d){if(Object.isString(d)){d=d.toQueryParams()}Object.extend(a.parameters,d)}if(b.hasAttribute("method")&&!a.method){a.method=b.method}return new Ajax.Request(c,a)}};Form.Element={focus:function(a){$(a).focus();return a},select:function(a){$(a).select();return a}};Form.Element.Methods={serialize:function(a){a=$(a);if(!a.disabled&&a.name){var b=a.getValue();if(b!=undefined){var c={};c[a.name]=b;return Object.toQueryString(c)}}return""},getValue:function(a){a=$(a);var b=a.tagName.toLowerCase();return Form.Element.Serializers[b](a)},setValue:function(a,b){a=$(a);var c=a.tagName.toLowerCase();Form.Element.Serializers[c](a,b);return a},clear:function(a){$(a).value="";return a},present:function(a){return $(a).value!=""},activate:function(a){a=$(a);try{a.focus();if(a.select&&(a.tagName.toLowerCase()!="input"||!["button","reset","submit"].include(a.type))){a.select()}}catch(b){}return a},disable:function(a){a=$(a);a.disabled=true;return a},enable:function(a){a=$(a);a.disabled=false;return a}};var Field=Form.Element;var $F=Form.Element.Methods.getValue;Form.Element.Serializers={input:function(a,b){switch(a.type.toLowerCase()){case"checkbox":case"radio":return Form.Element.Serializers.inputSelector(a,b);default:return Form.Element.Serializers.textarea(a,b)}},inputSelector:function(a,b){if(Object.isUndefined(b)){return a.checked?a.value:null}else{a.checked=!!b}},textarea:function(a,b){if(Object.isUndefined(b)){return a.value}else{a.value=b}},select:function(c,f){if(Object.isUndefined(f)){return this[c.type=="select-one"?"selectOne":"selectMany"](c)}else{var b,d,g=!Object.isArray(f);for(var a=0,e=c.length;a=0?this.optionValue(b.options[a]):null},selectMany:function(d){var a,e=d.length;if(!e){return null}for(var c=0,a=[];c<\/script>");$("__onDOMContentLoaded").onreadystatechange=function(){if(this.readyState=="complete"){this.onreadystatechange=null;a()}}}})();Hash.toQueryString=Object.toQueryString;var Toggle={display:Element.toggle};Element.Methods.childOf=Element.Methods.descendantOf;var Insertion={Before:function(a,b){return Element.insert(a,{before:b})},Top:function(a,b){return Element.insert(a,{top:b})},Bottom:function(a,b){return Element.insert(a,{bottom:b})},After:function(a,b){return Element.insert(a,{after:b})}};var $continue=new Error('"throw $continue" is deprecated, use "return" instead');var Position={includeScrollOffsets:false,prepare:function(){this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},within:function(b,a,c){if(this.includeScrollOffsets){return this.withinIncludingScrolloffsets(b,a,c)}this.xcomp=a;this.ycomp=c;this.offset=Element.cumulativeOffset(b);return(c>=this.offset[1]&&c=this.offset[0]&&a=this.offset[1]&&this.ycomp=this.offset[0]&&this.xcomp0})._each(a)},set:function(a){this.element.className=a},add:function(a){if(this.include(a)){return}this.set($A(this).concat(a).join(" "))},remove:function(a){if(!this.include(a)){return}this.set($A(this).without(a).join(" "))},toString:function(){return $A(this).join(" ")}};Object.extend(Element.ClassNames.prototype,Enumerable);Element.addMethods();var Scriptaculous={Version:"1.8.2",require:function(a){document.write(''; } elseif ($encode == 'javascript_charcode') { $string = '' . $text . ''; for($x = 0, $y = strlen($string); $x < $y; $x++) { $ord[] = ord($string[$x]); } $_ret = "\n"; return $_ret; } elseif ($encode == 'hex') { preg_match('!^(.*)(\?.*)$!', $address, $match); if (!empty($match[2])) { trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.",E_USER_WARNING); return; } $address_encode = ''; for ($x = 0, $_length = strlen($address); $x < $_length; $x++) { if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) { $address_encode .= '%' . bin2hex($address[$x]); } else { $address_encode .= $address[$x]; } } $text_encode = ''; for ($x = 0, $_length = strlen($text); $x < $_length; $x++) { $text_encode .= '&#x' . bin2hex($text[$x]) . ';'; } $mailto = "mailto:"; return '' . $text_encode . ''; } else { // no encoding return '' . $text . ''; } } ?>Collabtive-2.0/include/plugins/function.math.php000066400000000000000000000055271237252063700220510ustar00rootroot00000000000000 * Name: math
    * Purpose: handle math computations in template * * @link http://www.smarty.net/manual/en/language.function.math.php {math} * (Smarty online manual) * @author Monte Ohrt * @param array $params parameters * @param Smarty_Internal_Template $template template object * @return string|null */ function smarty_function_math($params, $template) { static $_allowed_funcs = array( 'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, 'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true ,'tan' => true ); // be sure equation parameter is present if (empty($params['equation'])) { trigger_error("math: missing equation parameter",E_USER_WARNING); return; } $equation = $params['equation']; // make sure parenthesis are balanced if (substr_count($equation,"(") != substr_count($equation,")")) { trigger_error("math: unbalanced parenthesis",E_USER_WARNING); return; } // match all vars in equation, make sure all are passed preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match); foreach($match[1] as $curr_var) { if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) { trigger_error("math: function call $curr_var not allowed",E_USER_WARNING); return; } } foreach($params as $key => $val) { if ($key != "equation" && $key != "format" && $key != "assign") { // make sure value is not empty if (strlen($val)==0) { trigger_error("math: parameter $key is empty",E_USER_WARNING); return; } if (!is_numeric($val)) { trigger_error("math: parameter $key: is not numeric",E_USER_WARNING); return; } $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation); } } $smarty_math_result = null; eval("\$smarty_math_result = ".$equation.";"); if (empty($params['format'])) { if (empty($params['assign'])) { return $smarty_math_result; } else { $template->assign($params['assign'],$smarty_math_result); } } else { if (empty($params['assign'])){ printf($params['format'],$smarty_math_result); } else { $template->assign($params['assign'],sprintf($params['format'],$smarty_math_result)); } } } ?>Collabtive-2.0/include/plugins/function.paginate_first.php000066400000000000000000000050331237252063700241070ustar00rootroot00000000000000 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://www.phpinsider.com/php/code/SmartyPaginate/ * @copyright 2001-2005 New Digital Group, Inc. * @author Monte Ohrt * @package SmartyPaginate * @version 1.6-dev */ function smarty_function_paginate_first($params, &$smarty) { $_id = 'default'; $_attrs = array(); if (!class_exists('SmartyPaginate')) { $smarty->trigger_error("paginate_first: missing SmartyPaginate class"); return; } if (!isset($_SESSION['SmartyPaginate'])) { $smarty->trigger_error("paginate_first: SmartyPaginate is not initialized, use connect() first"); return; } foreach($params as $_key => $_val) { switch($_key) { case 'id': if (!SmartyPaginate::isConnected($_val)) { $smarty->trigger_error("paginate_first: unknown id '$_val'"); return; } $_id = $_val; break; default: $_attrs[] = $_key . '="' . $_val . '"'; break; } } if (SmartyPaginate::getTotal($_id) === false) { $smarty->trigger_error("paginate_first: total was not set"); return; } $_url = SmartyPaginate::getURL($_id); $_attrs = !empty($_attrs) ? ' ' . implode(' ', $_attrs) : ''; $_text = isset($params['text']) ? $params['text'] : SmartyPaginate::getFirstText($_id); $_url .= (strpos($_url, '?') === false) ? '?' : '&'; $_url .= SmartyPaginate::getUrlVar($_id) . '=1'; return '' . $_text . ''; } ?> Collabtive-2.0/include/plugins/function.paginate_last.php000066400000000000000000000053471237252063700237330ustar00rootroot00000000000000 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://www.phpinsider.com/php/code/SmartyPaginate/ * @copyright 2001-2005 New Digital Group, Inc. * @author Monte Ohrt * @package SmartyPaginate * @version 1.6-dev */ function smarty_function_paginate_last($params, &$smarty) { $_id = 'default'; $_attrs = array(); if (!class_exists('SmartyPaginate')) { $smarty->trigger_error("paginate_last: missing SmartyPaginate class"); return; } if (!isset($_SESSION['SmartyPaginate'])) { $smarty->trigger_error("paginate_last: SmartyPaginate is not initialized, use connect() first"); return; } foreach($params as $_key => $_val) { switch ($_key) { case 'id': if (!SmartyPaginate::isConnected($_val)) { $smarty->trigger_error("paginate_last: unknown id '$_val'"); return; } $_id = $_val; break; default: $_attrs[] = $_key . '="' . $_val . '"'; break; } } if (SmartyPaginate::getTotal($_id) === false) { $smarty->trigger_error("paginate_last: total was not set"); return; } $_url = SmartyPaginate::getURL($_id); //$_url = full_url(); $_total = SmartyPaginate::getTotal($_id); $_limit = SmartyPaginate::getLimit($_id); $_attrs = !empty($_attrs) ? ' ' . implode(' ', $_attrs) : ''; $_text = isset($params['text']) ? $params['text'] : SmartyPaginate::getLastText($_id); $_url .= (strpos($_url, '?') === false) ? '?' : '&'; $_url .= SmartyPaginate::getUrlVar($_id) . '='; $_url .= ($_total % $_limit > 0) ? $_total - ($_total % $_limit) + 1 : $_total - $_limit + 1; return '' . $_text . ''; } ?> Collabtive-2.0/include/plugins/function.paginate_middle.php000066400000000000000000000114421237252063700242170ustar00rootroot00000000000000 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://www.phpinsider.com/php/code/SmartyPaginate/ * @copyright 2001-2005 New Digital Group, Inc. * @author Monte Ohrt * @package SmartyPaginate * @version 1.6-dev */ function smarty_function_paginate_middle($params, &$smarty) { $_id = 'default'; $_prefix = '['; $_suffix = ']'; $_link_prefix = ''; $_link_suffix = ''; $_page_limit = null; $_attrs = array(); if (!class_exists('SmartyPaginate')) { $smarty->trigger_error("paginate_middle: missing SmartyPaginate class"); return; } if (!isset($_SESSION['SmartyPaginate'])) { $smarty->trigger_error("paginate_middle: SmartyPaginate is not initialized, use connect() first"); return; } foreach($params as $_key => $_val) { switch($_key) { case 'id': if (!SmartyPaginate::isConnected($_val)) { $smarty->trigger_error("paginate_middle: unknown id '$_val'"); return; } $_id = $_val; break; case 'prefix': $_prefix = $_val; break; case 'suffix': $_suffix = $_val; break; case 'link_prefix': $_link_prefix = $_val; break; case 'link_suffix': $_link_suffix = $_val; break; case 'page_limit'; $_page_limit = $_val; break; case 'format': break; default: $_attrs[] = $_key . '="' . $_val . '"'; break; } } if (!isset($_SESSION['SmartyPaginate'][$_id]['item_total'])) { $smarty->trigger_error("paginate_middle: total was not set"); return; } if(!isset($_page_limit) && isset($_SESSION['SmartyPaginate'][$_id]['page_limit'])) { $_page_limit = $_SESSION['SmartyPaginate'][$_id]['page_limit']; } $_url = $_SESSION['SmartyPaginate'][$_id]['url']; // $_url = full_url(); $_total = SmartyPaginate::getTotal($_id); $_curr_item = SmartyPaginate::getCurrentItem($_id); $_limit = SmartyPaginate::getLimit($_id); $_item = 1; $_page = 1; $_display_pages = 0; $_ret = ''; $_attrs = !empty($_attrs) ? ' ' . implode(' ', $_attrs) : ''; if(isset($_page_limit)) { // find halfway point $_page_limit_half = floor($_page_limit / 2); // determine what item/page we start with $_item_start = $_curr_item - $_limit * $_page_limit_half; if( ($_view = ceil(($_total - $_item_start) / $_limit)) < $_page_limit) { $_item_start -= ($_limit * ( $_page_limit - $_view )); } $_item = ($_item_start >= 1) ? $_item_start : 1; $_page = ceil($_item / $_limit); } while($_item <= $_total) { if(isset($params['format']) && $params['format'] == 'page') { $_text = $_prefix . $_page . $_suffix; } else { // $_text = $_prefix . $_item . '-'; // $_text .= ($_item + $_limit - 1 <= $_total) ? $_item + $_limit - 1 : $_total; // $_text .= $_suffix; //$_text = $_prefix . $_page . $_suffix; $_text = $_page . " "; } if($_item != $_curr_item) { $_this_url = $_url; $_this_url .= (strpos($_url, '?') == false) ? '?' : '&'; $_this_url .= SmartyPaginate::getUrlVar($_id) . '=' . $_item; $_ret .= $_link_prefix . '' . $_text . '' . $_link_suffix; } else { $_ret .= $_link_prefix . $_text . $_link_suffix; } $_item += $_limit; $_page++; $_display_pages++; if(isset($_page_limit) && $_display_pages == $_page_limit) break; } return $_ret; } ?> Collabtive-2.0/include/plugins/function.paginate_next.php000066400000000000000000000053501237252063700237400ustar00rootroot00000000000000 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://www.phpinsider.com/php/code/SmartyPaginate/ * @copyright 2001-2005 New Digital Group, Inc. * @author Monte Ohrt * @package SmartyPaginate * @version 1.6-dev */ function smarty_function_paginate_next($params, &$smarty) { $_id = 'default'; $_attrs = array(); if (!class_exists('SmartyPaginate')) { $smarty->trigger_error("paginate_next: missing SmartyPaginate class"); return; } if (!isset($_SESSION['SmartyPaginate'])) { $smarty->trigger_error("paginate_next: SmartyPaginate is not initialized, use connect() first"); return; } foreach($params as $_key => $_val) { switch($_key) { case 'id': if (!SmartyPaginate::isConnected($_val)) { $smarty->trigger_error("paginate_next: unknown id '$_val'"); return; } $_id = $_val; break; default: $_attrs[] = $_key . '="' . $_val . '"'; break; } } if (SmartyPaginate::getTotal($_id) === false) { $smarty->trigger_error("paginate_next: total was not set"); return; } $_url = SmartyPaginate::getURL($_id); //$_url = full_url(); $_attrs = !empty($_attrs) ? ' ' . implode(' ', $_attrs) : ''; if(($_item = SmartyPaginate::_getNextPageItem($_id)) !== false) { $_show = true; //$_text = isset($params['text']) ? $params['text'] : SmartyPaginate::getNextText($_id); $_text = ">>"; $_url .= (strpos($_url, '?') === false) ? '?' : '&'; $_url .= SmartyPaginate::getUrlVar($_id) . '=' . $_item; } else { $_show = false; } return $_show ? '' . $_text . '' : ''; } ?> Collabtive-2.0/include/plugins/function.paginate_prev.php000066400000000000000000000053631237252063700237420ustar00rootroot00000000000000 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://www.phpinsider.com/php/code/SmartyPaginate/ * @copyright 2001-2005 New Digital Group, Inc. * @author Monte Ohrt * @package SmartyPaginate * @version 1.6-dev */ function smarty_function_paginate_prev($params, &$smarty) { $_id = 'default'; $_attrs = array(); if (!class_exists('SmartyPaginate')) { $smarty->trigger_error("paginate_prev: missing SmartyPaginate class"); return; } if (!isset($_SESSION['SmartyPaginate'])) { $smarty->trigger_error("paginate_prev: SmartyPaginate is not initialized, use connect() first"); return; } foreach($params as $_key => $_val) { switch($_key) { case 'id': if (!SmartyPaginate::isConnected($_val)) { $smarty->trigger_error("paginate_prev: unknown id '$_val'"); return; } $_id = $_val; break; default: $_attrs[] = $_key . '="' . $_val . '"'; break; } } if (SmartyPaginate::getTotal($_id) === false) { $smarty->trigger_error("paginate_prev: total was not set"); return; } $_url = SmartyPaginate::getURL($_id); // $_url = full_url(); $_attrs = !empty($_attrs) ? ' ' . implode(' ', $_attrs) : ''; if(($_item = SmartyPaginate::_getPrevPageItem($_id)) !== false) { $_show = true; //$_text = isset($params['text']) ? $params['text'] : SmartyPaginate::getPrevText($_id); $_text = "<<"; $_url .= (strpos($_url, '?') === false) ? '?' : '&'; $_url .= SmartyPaginate::getUrlVar($_id) . '=' . $_item; } else { $_show = false; } return $_show ? '' . $_text . '' : ''; } ?> Collabtive-2.0/include/plugins/modifier.capitalize.php000066400000000000000000000053151237252063700232110ustar00rootroot00000000000000 * Name: capitalize
    * Purpose: capitalize words in the string * * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }} * * @param string $string string to capitalize * @param boolean $uc_digits also capitalize "x123" to "X123" * @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa" * @return string capitalized string * @author Monte Ohrt * @author Rodney Rehm */ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false) { if (Smarty::$_MBSTRING) { if ($lc_rest) { // uppercase (including hyphenated words) $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET ); } else { // uppercase word breaks $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\2'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $string); } // check uc_digits case if (!$uc_digits) { if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { foreach($matches[1] as $match) { $upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0])); } } } $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\3'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $upper_string); return $upper_string; } // lowercase first if ($lc_rest) { $string = strtolower($string); } // uppercase (including hyphenated words) $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string); // check uc_digits case if (!$uc_digits) { if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { foreach($matches[1] as $match) { $upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0])); } } } $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string); return $upper_string; } ?>Collabtive-2.0/include/plugins/modifier.date_format.php000066400000000000000000000043221237252063700233460ustar00rootroot00000000000000 * Name: date_format
    * Purpose: format datestamps via strftime
    * Input:
    * - string: input date string * - format: strftime format for output * - default_date: default date if $string is empty * * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual) * @author Monte Ohrt * @param string $string input date string * @param string $format strftime format for output * @param string $default_date default date if $string is empty * @param string $formatter either 'strftime' or 'auto' * @return string |void * @uses smarty_make_timestamp() */ function smarty_modifier_date_format($string, $format=null, $default_date='', $formatter='auto') { if ($format === null) { $format = Smarty::$_DATE_FORMAT; } /** * Include the {@link shared.make_timestamp.php} plugin */ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') { $timestamp = smarty_make_timestamp($string); } elseif ($default_date != '') { $timestamp = smarty_make_timestamp($default_date); } else { return; } if($formatter=='strftime'||($formatter=='auto'&&strpos($format,'%')!==false)) { if (DS == '\\') { $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S'); if (strpos($format, '%e') !== false) { $_win_from[] = '%e'; $_win_to[] = sprintf('%\' 2d', date('j', $timestamp)); } if (strpos($format, '%l') !== false) { $_win_from[] = '%l'; $_win_to[] = sprintf('%\' 2d', date('h', $timestamp)); } $format = str_replace($_win_from, $_win_to, $format); } return strftime($format, $timestamp); } else { return date($format, $timestamp); } } ?>Collabtive-2.0/include/plugins/modifier.debug_print_var.php000066400000000000000000000066141237252063700242410ustar00rootroot00000000000000 * Name: debug_print_var
    * Purpose: formats variable contents for display in the console * * @author Monte Ohrt * @param array|object $var variable to be formatted * @param integer $depth maximum recursion depth if $var is an array * @param integer $length maximum string length if $var is a string * @return string */ function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40) { $_replace = array("\n" => '\n', "\r" => '\r', "\t" => '\t' ); switch (gettype($var)) { case 'array' : $results = 'Array (' . count($var) . ')'; foreach ($var as $curr_key => $curr_val) { $results .= '
    ' . str_repeat(' ', $depth * 2) . '' . strtr($curr_key, $_replace) . ' => ' . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); $depth--; } break; case 'object' : $object_vars = get_object_vars($var); $results = '' . get_class($var) . ' Object (' . count($object_vars) . ')'; foreach ($object_vars as $curr_key => $curr_val) { $results .= '
    ' . str_repeat(' ', $depth * 2) . ' ->' . strtr($curr_key, $_replace) . ' = ' . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); $depth--; } break; case 'boolean' : case 'NULL' : case 'resource' : if (true === $var) { $results = 'true'; } elseif (false === $var) { $results = 'false'; } elseif (null === $var) { $results = 'null'; } else { $results = htmlspecialchars((string) $var); } $results = '' . $results . ''; break; case 'integer' : case 'float' : $results = htmlspecialchars((string) $var); break; case 'string' : $results = strtr($var, $_replace); if (Smarty::$_MBSTRING) { if (mb_strlen($var, Smarty::$_CHARSET) > $length) { $results = mb_substr($var, 0, $length - 3, Smarty::$_CHARSET) . '...'; } } else { if (isset($var[$length])) { $results = substr($var, 0, $length - 3) . '...'; } } $results = htmlspecialchars('"' . $results . '"'); break; case 'unknown type' : default : $results = strtr((string) $var, $_replace); if (Smarty::$_MBSTRING) { if (mb_strlen($results, Smarty::$_CHARSET) > $length) { $results = mb_substr($results, 0, $length - 3, Smarty::$_CHARSET) . '...'; } } else { if (strlen($results) > $length) { $results = substr($results, 0, $length - 3) . '...'; } } $results = htmlspecialchars($results); } return $results; } ?>Collabtive-2.0/include/plugins/modifier.escape.php000066400000000000000000000164101237252063700223220ustar00rootroot00000000000000 * Name: escape
    * Purpose: escape string for output * * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual) * @author Monte Ohrt * @param string $string input string * @param string $esc_type escape type * @param string $char_set character set, used for htmlspecialchars() or htmlentities() * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities() * @return string escaped input string */ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) { static $_double_encode = null; if ($_double_encode === null) { $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>='); } if (!$char_set) { $char_set = Smarty::$_CHARSET; } switch ($esc_type) { case 'html': if ($_double_encode) { // php >=5.3.2 - go native return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); } else { if ($double_encode) { // php <5.2.3 - only handle double encoding return htmlspecialchars($string, ENT_QUOTES, $char_set); } else { // php <5.2.3 - prevent double encoding $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); $string = htmlspecialchars($string, ENT_QUOTES, $char_set); $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); return $string; } } case 'htmlall': if (Smarty::$_MBSTRING) { // mb_convert_encoding ignores htmlspecialchars() if ($_double_encode) { // php >=5.3.2 - go native $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); } else { if ($double_encode) { // php <5.2.3 - only handle double encoding $string = htmlspecialchars($string, ENT_QUOTES, $char_set); } else { // php <5.2.3 - prevent double encoding $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); $string = htmlspecialchars($string, ENT_QUOTES, $char_set); $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); return $string; } } // htmlentities() won't convert everything, so use mb_convert_encoding return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set); } // no MBString fallback if ($_double_encode) { return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); } else { if ($double_encode) { return htmlentities($string, ENT_QUOTES, $char_set); } else { $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); $string = htmlentities($string, ENT_QUOTES, $char_set); $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); return $string; } } case 'url': return rawurlencode($string); case 'urlpathinfo': return str_replace('%2F', '/', rawurlencode($string)); case 'quotes': // escape unescaped single quotes return preg_replace("%(? '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', ' '<\/')); case 'mail': if (Smarty::$_MBSTRING) { require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php'); return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string); } // no MBString fallback return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string); case 'nonstd': // escape non-standard chars, such as ms document quotes $return = ''; if (Smarty::$_MBSTRING) { require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php'); foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) { if ($unicode >= 126) { $return .= '&#' . $unicode . ';'; } else { $return .= chr($unicode); } } return $return; } $_length = strlen($string); for ($_i = 0; $_i < $_length; $_i++) { $_ord = ord(substr($string, $_i, 1)); // non-standard char, escape it if ($_ord >= 126) { $return .= '&#' . $_ord . ';'; } else { $return .= substr($string, $_i, 1); } } return $return; default: return $string; } } ?>Collabtive-2.0/include/plugins/modifier.regex_replace.php000066400000000000000000000030301237252063700236610ustar00rootroot00000000000000 * Name: regex_replace
    * Purpose: regular expression search/replace * * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php * regex_replace (Smarty online manual) * @author Monte Ohrt * @param string $string input string * @param string|array $search regular expression(s) to search for * @param string|array $replace string(s) that should be replaced * @return string */ function smarty_modifier_regex_replace($string, $search, $replace) { if(is_array($search)) { foreach($search as $idx => $s) { $search[$idx] = _smarty_regex_replace_check($s); } } else { $search = _smarty_regex_replace_check($search); } return preg_replace($search, $replace, $string); } /** * @param string $search string(s) that should be replaced * @return string * @ignore */ function _smarty_regex_replace_check($search) { // null-byte injection detection // anything behind the first null-byte is ignored if (($pos = strpos($search,"\0")) !== false) { $search = substr($search,0,$pos); } // remove eval-modifier from $search if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); } return $search; } ?>Collabtive-2.0/include/plugins/modifier.replace.php000066400000000000000000000015021237252063700224710ustar00rootroot00000000000000 * Name: replace
    * Purpose: simple search/replace * * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual) * @author Monte Ohrt * @author Uwe Tews * @param string $string input string * @param string $search text to search for * @param string $replace replacement text * @return string */ function smarty_modifier_replace($string, $search, $replace) { if (Smarty::$_MBSTRING) { require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php'); return smarty_mb_str_replace($search, $replace, $string); } return str_replace($search, $replace, $string); } ?>Collabtive-2.0/include/plugins/modifier.spacify.php000066400000000000000000000013711237252063700225200ustar00rootroot00000000000000 * Name: spacify
    * Purpose: add spaces between characters in a string * * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual) * @author Monte Ohrt * @param string $string input string * @param string $spacify_char string to insert between characters. * @return string */ function smarty_modifier_spacify($string, $spacify_char = ' ') { // well… what about charsets besides latin and UTF-8? return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY)); } ?>Collabtive-2.0/include/plugins/modifier.truncate.php000066400000000000000000000041371237252063700227120ustar00rootroot00000000000000 * Name: truncate
    * Purpose: Truncate a string to a certain length if necessary, * optionally splitting in the middle of a word, and * appending the $etc string or inserting $etc into the middle. * * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual) * @author Monte Ohrt * @param string $string input string * @param integer $length length of truncated text * @param string $etc end string * @param boolean $break_words truncate at word boundary * @param boolean $middle truncate in the middle of text * @return string truncated string */ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) { if ($length == 0) return ''; if (Smarty::$_MBSTRING) { if (mb_strlen($string, Smarty::$_CHARSET) > $length) { $length -= min($length, mb_strlen($etc, Smarty::$_CHARSET)); if (!$break_words && !$middle) { $string = preg_replace('/\s+?(\S+)?$/' . Smarty::$_UTF8_MODIFIER, '', mb_substr($string, 0, $length + 1, Smarty::$_CHARSET)); } if (!$middle) { return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc; } return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . mb_substr($string, - $length / 2, $length, Smarty::$_CHARSET); } return $string; } // no MBString fallback if (isset($string[$length])) { $length -= min($length, strlen($etc)); if (!$break_words && !$middle) { $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1)); } if (!$middle) { return substr($string, 0, $length) . $etc; } return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2); } return $string; } ?> Collabtive-2.0/include/plugins/modifiercompiler.cat.php000066400000000000000000000012311237252063700233570ustar00rootroot00000000000000 * Name: cat
    * Date: Feb 24, 2003
    * Purpose: catenate a value to a variable
    * Input: string to catenate
    * Example: {$var|cat:"foo"} * * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat * (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_cat($params, $compiler) { return '('.implode(').(', $params).')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.count_characters.php000066400000000000000000000016601237252063700261450ustar00rootroot00000000000000 * Name: count_characteres
    * Purpose: count the number of characters in a text * * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_count_characters($params, $compiler) { if (!isset($params[1]) || $params[1] != 'true') { return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[0] . ', $tmp)'; } if (Smarty::$_MBSTRING) { return 'mb_strlen(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')'; } // no MBString fallback return 'strlen(' . $params[0] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.count_paragraphs.php000066400000000000000000000012731237252063700261560ustar00rootroot00000000000000 * Name: count_paragraphs
    * Purpose: count the number of paragraphs in a text * * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php * count_paragraphs (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_count_paragraphs($params, $compiler) { // count \r or \n characters return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.count_sentences.php000066400000000000000000000014151237252063700260130ustar00rootroot00000000000000 * Name: count_sentences * Purpose: count the number of sentences in a text * * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php * count_sentences (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_count_sentences($params, $compiler) { // find periods, question marks, exclamation marks with a word before but not after. return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[0] . ', $tmp)'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.count_words.php000066400000000000000000000017551237252063700251710ustar00rootroot00000000000000 * Name: count_words
    * Purpose: count the number of words in a text * * @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_count_words($params, $compiler) { if (Smarty::$_MBSTRING) { // return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)'; // expression taken from http://de.php.net/manual/en/function.str-word-count.php#85592 return 'preg_match_all(\'/\p{L}[\p{L}\p{Mn}\p{Pd}\\\'\x{2019}]*/' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)'; } // no MBString fallback return 'str_word_count(' . $params[0] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.default.php000066400000000000000000000014631237252063700242430ustar00rootroot00000000000000 * Name: default
    * Purpose: designate default value for empty variables * * @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_default ($params, $compiler) { $output = $params[0]; if (!isset($params[1])) { $params[1] = "''"; } array_shift($params); foreach ($params as $param) { $output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)'; } return $output; } ?>Collabtive-2.0/include/plugins/modifiercompiler.escape.php000066400000000000000000000117231237252063700240570ustar00rootroot00000000000000 * Name: escape
    * Purpose: escape string for output * * @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual) * @author Rodney Rehm * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_escape($params, $compiler) { static $_double_encode = null; if ($_double_encode === null) { $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>='); } try { $esc_type = smarty_literal_compiler_param($params, 1, 'html'); $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET); $double_encode = smarty_literal_compiler_param($params, 3, true); if (!$char_set) { $char_set = Smarty::$_CHARSET; } switch ($esc_type) { case 'html': if ($_double_encode) { return 'htmlspecialchars(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . var_export($double_encode, true) . ')'; } else if ($double_encode) { return 'htmlspecialchars(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } case 'htmlall': if (Smarty::$_MBSTRING) { if ($_double_encode) { // php >=5.2.3 - go native return 'mb_convert_encoding(htmlspecialchars(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . var_export($double_encode, true) . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')'; } else if ($double_encode) { // php <5.2.3 - only handle double encoding return 'mb_convert_encoding(htmlspecialchars(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } } // no MBString fallback if ($_double_encode) { // php >=5.2.3 - go native return 'htmlentities(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . var_export($double_encode, true) . ')'; } else if ($double_encode) { // php <5.2.3 - only handle double encoding return 'htmlentities(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } case 'url': return 'rawurlencode(' . $params[0] . ')'; case 'urlpathinfo': return 'str_replace("%2F", "/", rawurlencode(' . $params[0] . '))'; case 'quotes': // escape unescaped single quotes return 'preg_replace("%(? "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", " "<\/" ))'; } } catch(SmartyException $e) { // pass through to regular plugin fallback } // could not optimize |escape call, so fallback to regular plugin if ($compiler->tag_nocache | $compiler->nocache) { $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php'; $compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape'; } else { $compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php'; $compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape'; } return 'smarty_modifier_escape(' . join( ', ', $params ) . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.from_charset.php000066400000000000000000000014321237252063700252670ustar00rootroot00000000000000 * Name: from_charset
    * Purpose: convert character encoding from $charset to internal encoding * * @author Rodney Rehm * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_from_charset($params, $compiler) { if (!Smarty::$_MBSTRING) { // FIXME: (rodneyrehm) shouldn't this throw an error? return $params[0]; } if (!isset($params[1])) { $params[1] = '"ISO-8859-1"'; } return 'mb_convert_encoding(' . $params[0] . ', "' . addslashes(Smarty::$_CHARSET) . '", ' . $params[1] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.indent.php000066400000000000000000000013461237252063700241000ustar00rootroot00000000000000 * Name: indent
    * Purpose: indent lines of text * * @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_indent($params, $compiler) { if (!isset($params[1])) { $params[1] = 4; } if (!isset($params[2])) { $params[2] = "' '"; } return 'preg_replace(\'!^!m\',str_repeat(' . $params[2] . ',' . $params[1] . '),' . $params[0] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.lower.php000066400000000000000000000013741237252063700237500ustar00rootroot00000000000000 * Name: lower
    * Purpose: convert string to lowercase * * @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual) * @author Monte Ohrt * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_lower($params, $compiler) { if (Smarty::$_MBSTRING) { return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ; } // no MBString fallback return 'strtolower(' . $params[0] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.noprint.php000066400000000000000000000006571237252063700243140ustar00rootroot00000000000000 * Name: noprint
    * Purpose: return an empty string * * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_noprint($params, $compiler) { return "''"; } ?>Collabtive-2.0/include/plugins/modifiercompiler.string_format.php000066400000000000000000000011421237252063700254670ustar00rootroot00000000000000 * Name: string_format
    * Purpose: format strings via sprintf * * @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_string_format($params, $compiler) { return 'sprintf(' . $params[1] . ',' . $params[0] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.strip.php000066400000000000000000000015221237252063700237540ustar00rootroot00000000000000 * Name: strip
    * Purpose: Replace all repeated spaces, newlines, tabs * with a single space or supplied replacement string.
    * Example: {$var|strip} {$var|strip:" "}
    * Date: September 25th, 2002 * * @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_strip($params, $compiler) { if (!isset($params[1])) { $params[1] = "' '"; } return "preg_replace('!\s+!" . Smarty::$_UTF8_MODIFIER . "', {$params[1]},{$params[0]})"; } ?>Collabtive-2.0/include/plugins/modifiercompiler.strip_tags.php000066400000000000000000000013751237252063700250000ustar00rootroot00000000000000 * Name: strip_tags
    * Purpose: strip html tags from text * * @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_strip_tags($params, $compiler) { if (!isset($params[1])) { $params[1] = true; } if ($params[1] === true) { return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})"; } else { return 'strip_tags(' . $params[0] . ')'; } } ?>Collabtive-2.0/include/plugins/modifiercompiler.to_charset.php000066400000000000000000000014241237252063700247470ustar00rootroot00000000000000 * Name: to_charset
    * Purpose: convert character encoding from internal encoding to $charset * * @author Rodney Rehm * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_to_charset($params, $compiler) { if (!Smarty::$_MBSTRING) { // FIXME: (rodneyrehm) shouldn't this throw an error? return $params[0]; } if (!isset($params[1])) { $params[1] = '"ISO-8859-1"'; } return 'mb_convert_encoding(' . $params[0] . ', ' . $params[1] . ', "' . addslashes(Smarty::$_CHARSET) . '")'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.unescape.php000066400000000000000000000023301237252063700244140ustar00rootroot00000000000000 * Name: unescape
    * Purpose: unescape html entities * * @author Rodney Rehm * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_unescape($params, $compiler) { if (!isset($params[1])) { $params[1] = 'html'; } if (!isset($params[2])) { $params[2] = '\'' . addslashes(Smarty::$_CHARSET) . '\''; } else { $params[2] = "'" . $params[2] . "'"; } switch (trim($params[1], '"\'')) { case 'entity': case 'htmlall': if (Smarty::$_MBSTRING) { return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')'; } return 'html_entity_decode(' . $params[0] . ', ENT_NOQUOTES, ' . $params[2] . ')'; case 'html': return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)'; case 'url': return 'rawurldecode(' . $params[0] . ')'; default: return $params[0]; } } ?>Collabtive-2.0/include/plugins/modifiercompiler.upper.php000066400000000000000000000013231237252063700237450ustar00rootroot00000000000000 * Name: lower
    * Purpose: convert string to uppercase * * @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_upper($params, $compiler) { if (Smarty::$_MBSTRING) { return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ; } // no MBString fallback return 'strtoupper(' . $params[0] . ')'; } ?>Collabtive-2.0/include/plugins/modifiercompiler.wordwrap.php000066400000000000000000000030521237252063700244600ustar00rootroot00000000000000 * Name: wordwrap
    * Purpose: wrap a string of text at a given length * * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual) * @author Uwe Tews * @param array $params parameters * @return string with compiled code */ function smarty_modifiercompiler_wordwrap($params, $compiler) { if (!isset($params[1])) { $params[1] = 80; } if (!isset($params[2])) { $params[2] = '"\n"'; } if (!isset($params[3])) { $params[3] = 'false'; } $function = 'wordwrap'; if (Smarty::$_MBSTRING) { if ($compiler->tag_nocache | $compiler->nocache) { $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php'; $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap'; } else { $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php'; $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap'; } $function = 'smarty_mb_wordwrap'; } return $function . '(' . $params[0] . ',' . $params[1] . ',' . $params[2] . ',' . $params[3] . ')'; } ?>Collabtive-2.0/include/plugins/outputfilter.trimwhitespace.php000066400000000000000000000066231237252063700250670ustar00rootroot00000000000000.*?#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) { foreach ($matches as $match) { $store[] = $match[0][0]; $_length = strlen($match[0][0]); $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@'; $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length); $_offset += $_length - strlen($replace); $_store++; } } // Strip all HTML-Comments // yes, even the ones in {/literal} {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addfolder.tpl000066400000000000000000000024171237252063700217150ustar00rootroot00000000000000

    {#addfolder#}

    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addmessageform.tpl000066400000000000000000000047611237252063700227560ustar00rootroot00000000000000

    {#addmessage#}

    {*Attach*}
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addmilestone.tpl000066400000000000000000000072061237252063700224420ustar00rootroot00000000000000{if $showhtml|default == "yes"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" milestab="active"}

    {#addmilestone#}

    {/if}

    {#addmilestone#}

    {*block_in_wrapper end*} {if $showhtml|default == "yes"}
    {*Miles END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if} Collabtive-2.0/templates/standard/addmymessage.tpl000066400000000000000000000105311237252063700224300ustar00rootroot00000000000000

    {#addmessage#}

    {*Attach*} {*Add*}
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addmytask.tpl000066400000000000000000000057721237252063700217610ustar00rootroot00000000000000

    {#addtask#}

    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addmytask_index.tpl000066400000000000000000000056531237252063700231460ustar00rootroot00000000000000

    {#addtask#}

    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addproject.tpl000066400000000000000000000066101237252063700221070ustar00rootroot00000000000000

    {#addproject#}

    {section name=user loop=$users}

    {/section}
    {if $myprojects == "1"} {else} {/if}
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addroles.tpl000066400000000000000000000157131237252063700215710ustar00rootroot00000000000000

    {#addrole#}

    {#add#}
    {#edit#}
    {#delete#}
    {#close#}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#close#}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#close#}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#answer#}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#view#}
    {#permissionread#}
    {#add#}
    {#edit#}
    {#delete#}
    {#chat#}
    {#administration#}
    {if $myprojects|default == "1"} {else} {/if}
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addtask.tpl000066400000000000000000000075441237252063700214120ustar00rootroot00000000000000

    {#addtask#}

    {if $lists[list].ID != ""} {else} {/if}
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/addtaskform.tpl000066400000000000000000000100621237252063700222630ustar00rootroot00000000000000{if $showhtml != "no"} {include file="header.tpl" jsload = "ajax" jsload1 = "tinymce" } {include file="tabsmenue-project.tpl" taskstab = "active"}
    {/if}

    {#addtask#}

    {*block_in_wrapper end*} {if $showhtml != "no"}
    {*Tasks END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/addtasklist.tpl000066400000000000000000000024441237252063700223000ustar00rootroot00000000000000

    {#addtasklist#}

    Collabtive-2.0/templates/standard/addtimetracker.tpl000066400000000000000000000074011237252063700227520ustar00rootroot00000000000000
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/adduserform.tpl000066400000000000000000000043371237252063700223070ustar00rootroot00000000000000
    {if $projects} {*only show this block if there are any projects to choose*}
    {section name=project loop=$projects}
    {/section}
    {/if}
    {#cancel#}
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/adduserproject.tpl000066400000000000000000000020341237252063700230020ustar00rootroot00000000000000
    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/admin.tpl000066400000000000000000000004451237252063700210600ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"}

    {#administration#}

    {*required object for focus cells*} {include file="admin_top.tpl"}
    {*Content_left end*} {include file="footer.tpl"} Collabtive-2.0/templates/standard/admin_top.tpl000066400000000000000000000010161237252063700217350ustar00rootroot00000000000000 Collabtive-2.0/templates/standard/admincustomers.tpl000066400000000000000000000140211237252063700230200ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-admin.tpl" customertab="active"}
    {literal} {/literal}

    {#administration#}/ {#customeradministration#}

    {if $userpermissions.customers.add|default} {/if}

    {#customerlist#}

    {*Add Customer*}
    {section name=cust loop=$allcust} {*Color-Mix*} {if $smarty.section.cust.index % 2 == 0} {else} {/if} {/section}
    {#customer#} {#phone#} {#email#}
      {$allcust[cust].phone} {$allcust[cust].email} {if $userpermissions.customers.edit} {/if} {if $userpermissions.customers.del} {/if}
    {#contactperson#}: {$allcust[cust].contact} {#address#}: {$allcust[cust].address}
    {#cellphone#}: {$allcust[cust].mobile} {$allcust[cust].zip} {$allcust[cust].city}
    {#url#}: {$allcust[cust].url} {$allcust[cust].country}
    {*Customers End*}
    {*smooth end*}
    {if $userpermissions.admin.add|default} {#addcustomer#} {/if}
    {*block END*} {*Donecustomers End*} {literal} {/literal}
    {*Customers END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/admindeluserform.tpl000066400000000000000000000043721237252063700233330ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="tabsmenue-admin.tpl" usertab="active"}

    {#deleteuser#}/ {$user.name}

    {#deleteform#}

    {section name=proj loop=$projects}

    {$projects[proj].name}

    {/section}
    {*required ... do not delete this row*}
    {*block_in_wrapper end*}
    {*User END*}
    {*content-left-in END*}
    {*Content_left end*} {include file="sidebar-a.tpl"} {include file="footer.tpl"} Collabtive-2.0/templates/standard/adminprojects.tpl000066400000000000000000000334751237252063700226430ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-admin.tpl" projecttab="active"}
    {literal} {/literal}

    {#administration#}/ {#projectadministration#}

    {if $userpermissions.projects.add} {/if}

    {#openprojects#}

    {*Add Project*}
    {section name=opro loop=$opros|default} {*Color-Mix*} {if $smarty.section.opro.index % 2 == 0} {else} {/if} {/section}
    {#project#} {#done#} {#daysleft#}  
    {if $userpermissions.projects.del} {/if}
    {$opros[opro].done}%
    {$opros[opro].daysleft}   {if $userpermissions.projects.edit} {/if} {if $userpermissions.projects.del} {/if}
    {$opros[opro].desc}

    {#user#}:

    {*inwrapper End*}

    {*assign users*} {#adduser#}:

    {*assign users end*}
    {*Projects End*} {*Doneprojects*} {*doneblock end*}
    {*smooth end*}
    {if $userpermissions.projects.add} {#addproject#} {/if} {#closedprojects#}
    {*block END*} {*Doneprojects End*} {literal} {/literal}
    {*Projects END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/adminusers.tpl000066400000000000000000000170461237252063700221470ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="tabsmenue-admin.tpl" usertab="active"}
    {literal} {/literal}

    {#administration#}/ {#useradministration#}

    {if $userpermissions.admin.add} {#adduser#} {/if}

    {#useradministration#}

    {*Add User*} {if $userpermissions.admin.add} {/if}
    {*place for tool under ne title-icon*}
    {*place for header-informations*}
    {*inwrapper End*}
    {*content_in_wrapper_in End*}
    {*content_in_wrapper End*}
    {*place for whatever*}
    {$langfile.page|default} {paginate_prev} {paginate_middle} {paginate_next}
    {*nosmooth End*}
    {if $userpermissions.admin.add} {#adduser#} {/if}
    {*block_files End*}
    {* Roles *} {include file = "rolesadmin.tpl"} {* Roles End *}
    {if $userpermissions.admin.add} {#addrole#} {/if}
    {*block END*} {literal} {/literal}
    {*User END*}
    {*content-left-in END*} {*Content_left end*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/assignform.tpl000066400000000000000000000011411237252063700221320ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" title=""}

    {$user.name}'s {#projects#}

    {section name=proj loop=$projects}
    {/section}
    {include file="footer.tpl"} Collabtive-2.0/templates/standard/calbody.tpl000066400000000000000000000232711237252063700214070ustar00rootroot00000000000000 {* Calender head area *} {* Localized days *} {section name=week loop=$weeks} {* Iterate days of current week *} {section name=day loop=$weeks[week]} {if $weeks[week][day].currmonth == 1} {* Hightlight today *} {if $thism == $m and $thisy == $y and $thisd == $weeks[week][day].val} {/section} {* Day End *} {/section} {* Week End *}
    {* Localized month & year *} {$mstring} {$y}
    {$langfile.monday} {$langfile.tuesday} {$langfile.wednesday} {$langfile.thursday} {$langfile.friday} {$langfile.saturday} {$langfile.sunday}
    {$weeks[week][day].val} {else} {$weeks[week][day].val} {/if} {else} {$weeks[week][day].val} {/if} {* Only output tasks/milestones if the day belongs to the current month *} {if $weeks[week][day].currmonth == 1}
    {* Milestones *} {if $weeks[week][day].milesnum > 0} {literal} {/literal} {literal} {/literal} {/if} {* Milestones End *} {* Tasks *} {if $weeks[week][day].tasksnum > 0} {literal} {/literal} {literal} {/literal} {/if} {* Tasks End *}
    {* Calcontent End *} {/if}
    {*loading indicator off*} {literal} {/literal}Collabtive-2.0/templates/standard/calbody_project.tpl000066400000000000000000000251201237252063700231300ustar00rootroot00000000000000 {* Calender Head Area *} {* Days *} {section name=week loop=$weeks} {* Days of Current Week*} {section name=day loop=$weeks[week]} {if $weeks[week][day].currmonth == 1} {* Hightlight Today *} {if $thism == $m and $thisy == $y and $thisd == $weeks[week][day].val} {/section} {* Day End *} {/section} {* Week End *}
    {* Localized Month & Year *} {$mstring} {$y}
    {$langfile.monday} {$langfile.tuesday} {$langfile.wednesday} {$langfile.thursday} {$langfile.friday} {$langfile.saturday} {$langfile.sunday}
    {$weeks[week][day].val} {else} {$weeks[week][day].val} {/if} {else} {$weeks[week][day].val} {/if} {* Options Menu *} {if $weeks[week][day].currmonth == 1} {/if} {* only output tasks/milestones if the day belongs to the current month *} {if $weeks[week][day].currmonth == 1}
    {* Milestones *} {if $weeks[week][day].milesnum > 0} {/literal} {/if} {*Tasks*} {if $weeks[week][day].tasksnum > 0}
    {* Calendar Content End*} {/if} {* Tasks End *} {/if}
    {* Loading Indicator Off *} {literal} {/literal}Collabtive-2.0/templates/standard/deassignuserform.tpl000066400000000000000000000035201237252063700233450ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="tabsmenue-project.tpl" userstab="active"}

    {#deassignuser#}/ {$user.name}

    {#deleteform#}

    {$project.name}

    {*block_in_wrapper end*}
    {* user END *}
    {* content-left-in END *}
    {* content-left End *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} Collabtive-2.0/templates/standard/editcustomer.tpl000066400000000000000000000106301237252063700224740ustar00rootroot00000000000000{if $async == "yes"} {literal} {/literal} {/if}

    {$langfile.editcustomer}

    {* block_in_wrapper END *} Collabtive-2.0/templates/standard/editfileform.tpl000066400000000000000000000034001237252063700224330ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" filestab="active"}

    {$file.title|truncate:30:"...":true}

    {#editfile#}

    {* block_in_wrapper END *}
    {* content_left END *} {include file="footer.tpl"}Collabtive-2.0/templates/standard/editform.tpl000066400000000000000000000127531237252063700216060ustar00rootroot00000000000000{if $showhtml != "no"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" projecttab="active"}

    {$project.name}

    {/if} {if $async|default == "yes"} {literal} {/literal} {/if}

    {$langfile.editproject}

    {*block_in_wrapper end*} {if $showhtml != "no"}
    {*Projects END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/editmessageform.tpl000066400000000000000000000074061237252063700231520ustar00rootroot00000000000000{if $showhtml != "no"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" msgstab="active"}

    {$message.name}

    {/if} {if $async == "yes"} {literal} {/literal} {/if}

    {#editmessage#}

    {if $showhtml == "no"} {/if}
    {*block_in_wrapper end*} {if $showhtml != "no"}
    {* Msgs END *}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/editmilestone.tpl000066400000000000000000000104161237252063700226340ustar00rootroot00000000000000{if $showhtml|default != "no"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" milestab="active"}

    {#editmilestone#}

    {/if}
    {if $showhtml|default == "no"}

    {#editmilestone#}

    {else}

     

    {/if}
    {if $showhtml|default == "no"} {/if}
    {*block_in_wrapper end*} {if $showhtml|default != "no"}
    {* Miles END *}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/editsettings.tpl000066400000000000000000000040111237252063700224670ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" } {include file="tabsmenue-admin.tpl" settingstab="active"}
    {literal} {/literal}

    {#administration#}/ {#systemadministration#}

    {#systemadministration#}

    {include file="settings_system.tpl"}
    {* block_system END *}

    {#email#}

    {include file="settings_email.tpl"}
    {* Block END *}
    {* neutral END *}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/edittask.tpl000066400000000000000000000175301237252063700216030ustar00rootroot00000000000000{if $showhtml != "no"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" taskstab="active"}

    {$task.title|truncate:30:"...":true}

    {/if} {if $async == "yes"} {literal} {/literal} {/if}

    {$langfile.edittask}

    {* block_in_wrapper END *} {if $showhtml != "no"}
    {* tasks END *}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/edittasklist.tpl000066400000000000000000000060011237252063700224660ustar00rootroot00000000000000{if $showhtml != "no"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" taskstab="active"}

    {$tasklist.name|truncate:30:"...":true}

    {/if}

    {#edittasklist#}

    {* block_in_wrapper END *} {if $showhtml != "no"}
    {* tasks END *}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/edittrackform.tpl000066400000000000000000000115541237252063700226310ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" timetab="active"}

    {$track.username} ({$track.hours})

    {#edittimetracker#}

    {* block_in_wrapper END *}
    {* timetrack END *}
    {* content-left-in END *}
    {* content_left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} Collabtive-2.0/templates/standard/edituseradminform.tpl000066400000000000000000000255601237252063700235160ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="tabsmenue-admin.tpl" usertab="active"}

    {#edituser#}/ {$user.name}

    {if $user.avatar != ""}
    {else} {if $user.gender == "f"}
    {else}
    {/if} {/if}
    {* block END *}
    {* message END *}
    {literal} {/literal}
    {* UserWrapper END *}
    {* user END *}
    {* content-left-in END *}
    {* content_left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/edituserform.tpl000066400000000000000000000233611237252063700225020ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="tabsmenue-user.tpl" edittab="active"}

    {#edituser#}/ {$user.name}

    {if $user.avatar != ""}
    {else} {if $user.gender == "f"}
    {else}
    {/if} {/if}
    {* block END *}
    {* message END *}
    {literal} {/literal}
    {*UserWrapper End*}
    {* user END *}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/error.tpl000066400000000000000000000004471237252063700211230ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="footer.tpl"} Collabtive-2.0/templates/standard/fileview.tpl000066400000000000000000000132731237252063700216050ustar00rootroot00000000000000 {section name=fold loop=$folders} {literal} {/literal} {/section} Collabtive-2.0/templates/standard/fileview2.tpl000066400000000000000000000117421237252063700216660ustar00rootroot00000000000000 {section name=fold loop=$folders} {literal} {/literal} {/section} Collabtive-2.0/templates/standard/fileview_list.tpl000066400000000000000000000116141237252063700226350ustar00rootroot00000000000000{config_load file='lng.conf' section="strings" scope="global"} {section name=folder loop=$folders} {*Color-Mix*} {if $smarty.section.folder.index % 2 == 0} {else} {/if} {/section} {section name=file loop=$files} {*Color-Mix*} {if $smarty.section.file.index % 2 == 0} {else} {/if} {literal} {/literal} {/section}
    {#name#} {#uploaded#} {#filesize#}
    {if $folders[folder].name != ""} {$folders[folder].name|truncate:100:"...":true} {/if} {$folders[folder].description|truncate:30:"...":true} {if $userpermissions.files.del} {/if}
    {*if $files[file].imgfile == 1} {$files[file].name} {else} {$files[file].name} {/if*} {$files[file].name} {$files[file].name|truncate:75:"...":true} {$files[file].addedstr} / {$files[file].userdata.name} {$files[file].size} kB
    {section name=fold loop=$folders} {literal} {/literal} {/section} Collabtive-2.0/templates/standard/filterreport.tpl000066400000000000000000000055021237252063700225100ustar00rootroot00000000000000

    {#filterreport#}

    {*block_in_wrapper end*} Collabtive-2.0/templates/standard/filtertracker.tpl000066400000000000000000000072701237252063700226340ustar00rootroot00000000000000

    {#filterreport#}

    {if $userpermissions.admin.add}
    {else} {/if}
    {* block_in_wrapper END *} Collabtive-2.0/templates/standard/flashchart.tpl000066400000000000000000000001241237252063700221010ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {$flashstr} {include file="footer.tpl"} Collabtive-2.0/templates/standard/footer.tpl000066400000000000000000000004711237252063700212650ustar00rootroot00000000000000 {* contentwrapper END *} {* sitebody END *} Collabtive-2.0/templates/standard/header.tpl000066400000000000000000000100311237252063700212100ustar00rootroot00000000000000{config_load file='lng.conf' section = "strings" scope="global" } {$title} @ {$settings.name} {if $stage != "project" and $loggedin|default} {elseif $stage == "project" and $loggedin} {/if} {if $loggedin} {/if} {if $jsload|default == "ajax"} {literal} {/literal} {/if} {if $jsload2 == "chat"} {literal} {/literal} {/if} {if $jsload3 == "lightbox"} {/if} {if $jsload1 == "tinymce"} {literal} {/literal} {/if} {if $showheader != "no"} {include file="header_main.tpl"} {/if} Collabtive-2.0/templates/standard/header_main.tpl000066400000000000000000000044611237252063700222260ustar00rootroot00000000000000
    Collabtive-2.0/templates/standard/index.tpl000066400000000000000000000553511237252063700211050ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce" jsload3="lightbox" stage="index"} {include file="tabsmenue-desk.tpl" desktab="active"}
    {* Display system messages *} {literal} {/literal} {if $isUpdated|default} {include file="updateNotify.tpl"}
    {/if}

    {#desktop#}

    {* Projects *} {if $projectnum > 0}

    {#myprojects#}

    {* Add project *}
    {section name=project loop=$myprojects} {*Color-Mix*} {if $smarty.section.project.index % 2 == 0} {else} {/if} {/section}
    {#project#} {#done#} {#daysleft#}  
    {if $userpermissions.projects.close} {/if}
    {$myprojects[project].done}%
    {$myprojects[project].daysleft}   {if $userpermissions.projects.edit} {/if} {if $userpermissions.projects.del} {/if}
    {$myprojects[project].desc}
    {if $userpermissions.projects.add} {#addproject#} {/if}
    {* block END *}
    {* smooth END *}
    {* projects END *} {/if} {* Projects END *} {* Tasks *} {if $tasknum > 0}

    {#mytasks#}

    {section name=task loop=$tasks} {*Color-Mix*} {if $smarty.section.task.index % 2 == 0} {else} {/if} {/section}
    {#task#} {#project#} {#daysleft#}  
    {if $userpermissions.tasks.close} {/if} {$tasks[task].pname|truncate:30:"...":true} {$tasks[task].daysleft}   {if $userpermissions.tasks.edit} {/if} {if $userpermissions.tasks.del} {/if}
    {$tasks[task].text|nl2br}
    {if $userpermissions.tasks.add} {#addtask#} {/if}
    {*block END*}
    {* Smooth end *}
    {*tasks END*} {/if} {* Tasks END *} {* Milestones *} {if $tasknum}

    {#calendar#}

    {* block END *}
    {* miles END *} {* milestons END *} {/if} {* Messages *} {if $msgnum > 0}

    {#mymessages#}

    {section name=message loop=$messages} {*Color-Mix*} {if $smarty.section.message.index % 2 == 0} {else} {/if} {/section}
    {#message#} {#project#} {#by#} {#on#}
    {if $userpermissions.messages.close} {/if} {$messages[message].pname|truncate:20:"...":true} {$messages[message].username|truncate:20:"...":true} {$messages[message].postdate} {if $userpermissions.messages.edit} {/if} {if $userpermissions.messages.del} {/if}
    {if $messages[message].avatar != ""}
    {else} {if $messages[message].gender == "f"}
    {else}
    {/if} {/if}
    {$messages[message].text|nl2br}
    {* MILESTONE and TAGS *} {if $messages[message].tagnum > 1 or $messages[message].milestones[0] != ""}
    {* MESSAGES-MILESTONES *} {if $messages[message].milestones[0] != ""}

    {#milestone#}: {$messages[message].milestones.name}

    {/if} {* MESSAGES-TAGS *} {if $messages[message].tagnum > 1}

    {#tags#}: {section name=tag loop=$messages[message].tagsarr} {$messages[message].tagsarr[tag]}, {/section}

    {/if} {/if} {* MESSAGES-FILES *} {if $messages[message].files[0][0] > 0}

    {#files#}:

    {*inwrapper End*}
    {/if}
    {*div messages end*}
    {* block END *}
    {* messages END *} {/if} {literal} {/literal}
    {* block index end*}
    {* content-left-in END *}
    {* content-left END *} {include file="sidebar-a.tpl"} {include file="footer.tpl"} Collabtive-2.0/templates/standard/install1.tpl000066400000000000000000000135531237252063700215230ustar00rootroot00000000000000{include file="header.tpl" title="$title" showheader="no"}

    {#installcollabtive#}

    1. {#installerconditions#}

    {#installerchecksconditions#}
    {if $phpver >= 5.2} {else} {/if} {if $configfile == 1} {else} {/if} {if $filesdir == 1} {else} {/if} {if $templatesdir == 1} {else} {/if} {if $is_mbstring_enabled} {else} {/if}
    {#condition#}: {#status#}:
    PHP 5.2OKNot OK
    (PHP {$phpver} - {#phpversion#})
    config.php {#iswritable#}OKNot OK
    {#makefilewritable#}
    files {#iswritable#}OKNot OK
    {#makedirwritable#}
    templates_c {#iswritable#}OKNot OK
    {#makedirwritable#}
    {#mb_string_enabled#}OKNot OK
    {#enable_mb_string#}
    {if $configfile >= 666 and $phpver >= 5.1 and $templatesdir == 1 and $filesdir == 1 and $is_mbstring_enabled}

    2. {#db#}

    {#insertdbaccessdata#}
    {#clickcontinue#}
    {else}
    {#correctfaults#} {/if}
    {* install END *} Collabtive-2.0/templates/standard/install2.tpl000066400000000000000000000022541237252063700215200ustar00rootroot00000000000000{include file="header.tpl" title="install" showheader="no"}

    {#installcollabtive#}

    {#installstep#} 3

    {#createadmin#}


    {* install END *} Collabtive-2.0/templates/standard/install3.tpl000066400000000000000000000020461237252063700215200ustar00rootroot00000000000000{include file="header.tpl" title="install" showheader="no"}

    Installation Status

    {#installsuccess#}

    Congratulations! Collabtive is now running on your server.

    As a next step, you could extend the functionality of your installation with plugins.
    They enable you to easily adapt Collabtive to your workflow.
    {* install END *} Collabtive-2.0/templates/standard/log.tpl000066400000000000000000000104101237252063700205420ustar00rootroot00000000000000
    {if $userpermissions.admin.add} {/if}

    {#activity#}

    {section name=logitem loop=$log} {*Color-Mix*} {if $smarty.section.logitem.index % 2 == 0} {else} {/if} {/section}
    {#action#} {#user#}
    {if $log[logitem].type == "tasklist"} {elseif $log[logitem].type == "user"} {elseif $log[logitem].type == "task"} {elseif $log[logitem].type == "projekt"} {elseif $log[logitem].type == "milestone"} {elseif $log[logitem].type == "message"} {elseif $log[logitem].type == "file"} {elseif $log[logitem].type == "folder"} {elseif $log[logitem].type == "track"} {/if}
    {$log[logitem].name|truncate:55:"...":true}
    {#was#} {if $log[logitem].action == 1} {#added#} {elseif $log[logitem].action == 2} {#edited#} {elseif $log[logitem].action == 3} {#deleted#} {elseif $log[logitem].action == 4} {#opened#} {elseif $log[logitem].action == 5} {#closed#} {elseif $log[logitem].action == 6} {#assigned#} {elseif $log[logitem].action == 7} {#deassigned#} {/if} {$log[logitem].datum}
    {$log[logitem].username|truncate:25:"...":true}
    {paginate_prev} {paginate_middle} {paginate_next}
    {*block end*}
    Collabtive-2.0/templates/standard/login.tpl000066400000000000000000000037321237252063700211020ustar00rootroot00000000000000{include file="header.tpl" title="Login" showheader="no" jsload="ajax"} Collabtive-2.0/templates/standard/menu-project.tpl000066400000000000000000000063421237252063700224020ustar00rootroot00000000000000
    {#description#} {#daysleft#} {#status#}
    {* accordion END *}
    {* table_Body END *}
    {* status END *} {literal} {/literal}Collabtive-2.0/templates/standard/message.tpl000066400000000000000000000407571237252063700214260ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce" jsload3="lightbox"} {include file="tabsmenue-project.tpl" msgstab="active"}
    {literal} {/literal}

    {$message.title|truncate:40:"...":true}

    {* Add Reply *} {if $userpermissions.messages.close} {/if} {* Edit Message *} {if $userpermissions.messages.edit} {/if}
    {if $message.avatar != ""}
    {else} {if $message.gender == "f"}
    {else}
    {/if} {/if}

    {$message.endstring} / {$message.username|truncate:20:"...":true}

    {$message.text}
    {if $message.tagsarr[0] != "" or $message.milestones[0] != ""}
    {* Milestones *} {if $message.milestones[0] != ""}

    {#milestone#}: {$message.milestones.name}

    {/if} {*Tags*} {if $message.tagsarr[0] != ""}

    {#tags#}: {section name = tag loop=$message.tagsarr} {$message.tagsarr[tag]} {/section}

    {/if} {/if} {*Files*} {if $message.files[0][0] > 0}
    {#files#}: {*inwrapper End*} {/if}
    {*message End*}
    {*nosmooth End*}
    {*descript End*} {* ANSWERS *} {if $replies > 0}
    {if $userpermissions.messages.close} {#answer#} {/if}

    {#replies#}

    {*Add Reply*} {if $userpermissions.messages.close} {/if}
    {section name=reply loop=$replies} {*Color-Mix*} {if $smarty.section.reply.index % 2 == 0} {else} {/if} {/section}
    {#message#} {#on#} {#by#}
    {$replies[reply].title|truncate:20:"...":true}
    {$replies[reply].postdate} {$replies[reply].username|truncate:20:"...":true} {if $userpermissions.messages.edit} {/if} {if $userpermissions.messages.del} {/if}
    {if $replies[reply].avatar != ""}
    {else} {if $replies[reply].gender == "f"}
    {else}
    {/if} {/if}
    {$replies[reply].text|nl2br}
    {*MESSAGETAGS*} {if $replies[reply].tagsarr[0] != ""}

    {#tags#}: {section name = tag loop=$replies[reply].tagsarr} {$replies[reply].tagsarr[tag]} {/section}

    {/if} {*MESSAGEFILES*} {if $replies[reply].files[0][0] > 0}
    {#files#}:
    {*inwrapper End*} {/if}
    {*nosmooth End*}
    {*block End*} {literal} {/literal}
    {/if} {*if REPLY End*}
    {*MSGs END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/milescal.tpl000066400000000000000000000075371237252063700215720ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload3 = "lightbox" showheader="no"} {section name = day loop=$timestr} {/section} {section name=tag loop=$timeline1} {/section} {section name=day loop=$timeline2} {/section} {section name=day loop=$timeline3} {/section} {section name=day loop=$timeline4} {/section}
    {$timestr[day]}
    {$timeline1[tag].tagstr}

    {if $timeline1[tag].milestone.ID > 0}{$timeline1[tag].milestone.name|truncate:30:"...":true}
    {literal} {/literal} {/if}

    {$timeline2[day].tagstr}

    {if $timeline2[day].milestone.ID > 0}{$timeline2[day].milestone.name|truncate:30:"...":true}
    {literal} {/literal} {/if}

    {$timeline3[day].tagstr}

    {if $timeline3[day].milestone.ID > 0}{$timeline3[day].milestone.name|truncate:30:"...":true}
    {literal} {/literal} {/if}

    {$timeline4[day].tagstr}

    {if $timeline4[day].milestone.ID > 0}{$timeline4[day].milestone.name|truncate:30:"...":true}
    {literal} {/literal} {/if}

    Collabtive-2.0/templates/standard/mileslist.tpl000066400000000000000000000063571237252063700220050ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload3 = "lightbox" showheader="no"}
    {#milestone#} {#due#} {#daysleft#}
      {section name=stone loop=$milestones} {*Color-Mix*} {if $smarty.section.stone.index % 2 == 0}
    • {else}
    • {/if}
      {$milestones[stone].fend} {$milestones[stone].daysleft}
      {*Accordeon_Toggle End*}
      {$milestones[stone].desc} {section name=task loop=$milestones[stone].tasks} {if $smarty.section.task.first == TRUE}

      {#tasklists#}: {/if} {$milestones[stone].tasks[task].name} {if $smarty.section.task.last == FALSE},{/if} {/section} {section name=msg loop=$milestones[stone].messages} {if $smarty.section.msg.first == TRUE}
      {#messages#}: {/if} {$milestones[stone].messages[msg].title} {if $smarty.section.msg.last == FALSE},{/if} {/section}
      {*Accordion_Content End*}
      {*Focus End*}
      {*Marker End*}
    • {/section}
    {*Accordion End*}
    {*Table_Body End*}
    {*required ... do not delete this row*}
    {*milehead end*} {literal} {/literal} Collabtive-2.0/templates/standard/milestone.tpl000066400000000000000000000155141237252063700217720ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax"} {include file="tabsmenue-project.tpl" milestab = "active"}

    {$milestone.name}

    {*Edit Milestone*} {if $userpermissions.milestones.edit} {/if}
    {*Description*}

    {#description#}

    {$milestone.desc}
    {*Tasklists*} {if $milestone.tasklists[0][0]}

    {#tasklists#}

    {*inwrapper End*} {/if} {*Messages*} {if $milestone.messages[0][0]}

    {#messages#}

    {*inwrapper End*} {/if}
    {*nosmooth End*}
    {*Miles END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/mileview1.tpl000066400000000000000000000034361237252063700216750ustar00rootroot00000000000000 {section name = day loop=$timestr} {/section} {section name=tag loop=$timeline1} {if $smarty.section.tag.index % 2 == 0} {if $timeline1[tag].tagstr == $today} {literal} {/literal} {/if} {/section}
    {$timestr[day]}
    {else} {/if} {else} {/if} {$timeline1[tag].tagstr} {if $timeline1[tag].milestone.ID > 0}

    {$timeline1[tag].milestone.name|truncate:30:"...":true}

    Collabtive-2.0/templates/standard/mileview2.tpl000066400000000000000000000060141237252063700216710ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload3 = "lightbox" showheader="no"} {section name = day loop=$timestr} {/section} {section name=tag loop=$timeline1} {if $smarty.section.tag.index % 2 == 0} {if $timeline1[tag].tagstr == $today} {/section} {section name=day loop=$timeline2} {if $smarty.section.day.index % 2 == 0} {if $timeline2[day].tagstr == $today} {/section}
    {$timestr[day]}
    {else} {/if} {else} {/if} {$timeline1[tag].tagstr}

    {if $timeline1[tag].milestone.ID > 0} {$timeline1[tag].milestone.name|truncate:30:"...":true}
    {literal} {/literal} {/if}

    {else} {/if} {else} {/if} {$timeline2[day].tagstr} {if $timeline2[day].milestone.ID > 0}

    {$timeline2[day].milestone.name|truncate:30:"...":true}

    {literal} {/literal} {/if}
    {*required ... do not delete this row*}
    {*block_in_wrapper end*}
    Collabtive-2.0/templates/standard/mymessages.tpl000066400000000000000000000303741237252063700221510ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload1="tinymce" jsload3 = "lightbox"} {include file="tabsmenue-desk.tpl" msgstab = "active"}
    {literal} {/literal}

    {#mymessages#}

    {section name= project loop=$myprojects}
    {*Add Message*}
    {section name=message loop=$myprojects[project].messages} {*Color-Mix*} {if $smarty.section.message.index % 2 == 0} {else} {/if} {/section}
    {#message#} {#replies#}   {#by#} {#on#}
    {if $userpermissions.messages.close}{/if} {if $myprojects[project].messages[message].replies > 0} {$myprojects[project].messages[message].replies} {else} {$myprojects[project].messages[message].replies} {/if}   {$myprojects[project].messages[message].username|truncate:20:"...":true} {$myprojects[project].messages[message].postdate} {if $userpermissions.messages.edit} {/if} {if $userpermissions.messages.del} {/if}
    {if $myprojects[project].messages[message].avatar != ""}
    {else} {if $myprojects[project].messages[message].gender == "f"}
    {else}
    {/if} {/if}
    {$myprojects[project].messages[message].text}
    {*MILESTONE and TAGS*} {if $myprojects[project].messages[message].tagnum > 1 or $myprojects[project].messages[message].milestones[0] != ""}
    {*MESSAGES-MILESTONES*} {if $myprojects[project].messages[message].milestones[0] != ""}

    {#milestone#}: {$myprojects[project].messages[message].milestones.name}

    {/if} {*MESSAGES-TAGS*} {if $myprojects[project].messages[message].tagnum > 1}

    {#tags#}: {section name = tag loop=$myprojects[project].messages[message].tagsarr} {$myprojects[project].messages[message].tagsarr[tag]}, {/section}

    {/if} {/if} {*MESSAGES-FILES*} {if $myprojects[project].messages[message].files[0][0] > 0}

    {#files#}:

    {*inwrapper End*}
    {/if}
    {*MESSAGES END*}
    {*smooth End*}
    {if $userpermissions.messages.add} {#addmessage#} {/if}
    {*block END*}
    {literal} {/literal} {/section}
    {*Msgs END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/myprojects.tpl000066400000000000000000000200031237252063700221570ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload1 = "tinymce"} {include file="tabsmenue-desk.tpl" projectstab = "active"}
    {if $newproject == 1} {#projectwasadded#} {/if} {if $editproject == 1} {#projectwasedited#} {/if} {if $delproject == 1} {#projectwasdeleted#} {/if} {if $openproject == 1} {#projectwasopened#} {/if} {if $closeproject == 1} {#projectwasclosed#} {/if} {if $assignproject == 1} {#projectwasassigned#} {/if} {if $deassignproject == 1} {#projectwasdeassigned#} {/if}

    {#myprojects#}

    {*Projects*}
    {if $userpermissions.projects.add} {/if}

    {#openprojects#}

    {*Add Project*}
    {section name=project loop=$myprojects} {*Color-Mix*} {if $smarty.section.project.index % 2 == 0} {else} {/if} {/section}
    {#project#} {#done#} {#daysleft#}  
    {if $userpermissions.projects.add}{/if}
    {$myprojects[project].done}%
    {$myprojects[project].daysleft}   {if $userpermissions.projects.edit} {/if} {if $userpermissions.projects.del} {/if}
    {$myprojects[project].desc}
    {*Projects End*} {*Doneprojects*} {*doneblock end*}
    {*smooth end*}
    {if $userpermissions.projects.add} {#addproject#} {/if} {#closedprojects#}
    {*block END*} {*Doneprojects End*} {literal} {/literal}
    {*projects END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/mytasks.tpl000066400000000000000000000305531237252063700214660ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload1 = "tinymce"} {include file="tabsmenue-desk.tpl" taskstab = "active"}
    {literal} {/literal}

    {#mytasks#}

    {section name=project loop=$myprojects} {if $myprojects[project].tasknum}
    {if $userpermissions.tasks.add} {#addtask#} {/if}

    {$myprojects[project].name|truncate:80:"...":true}

    {*Add Task*} {if $userpermissions.tasks.add > 0} {/if}
    {if $myprojects[project].tasknum > 0} {section name=task loop=$myprojects[project].tasks} {*Color-Mix*} {if $smarty.section.task.index % 2 == 0} {else} {/if} {/section} {else} {/if}
    {#tasks#} {#tasklist#} {#daysleft#}  
    {if $userpermissions.tasks.close}{/if} {$myprojects[project].tasks[task].list|truncate:23:"...":true} {$myprojects[project].tasks[task].daysleft}   {if $userpermissions.tasks.edit} {/if} {if $userpermissions.tasks.del} {/if}
    {$myprojects[project].tasks[task].text|nl2br}
    {#notasks#}
    {*Tasks donetasks*} {*done_block End*}
    {*smooth End*} {*Add Task*}
    {if $userpermissions.tasks.add} {#addtask#} {/if} {#donetasks#}
    {*Add Task End*}
    {*block END*}
    {literal} {/literal} {/if} {/section} {if $tasknum < 1} {#notasks#}
    {/if}
    {*tasks END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/newcal.tpl000066400000000000000000000035531237252063700212440ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" } aaa

    {if $weeks[week][day].tasksnum > 0}
    {section name = task loop=$weeks[week][day].tasks} {$weeks[week][day].tasks[task].title}
    {/section}
    {literal} {/literal} {/if}
    {*Content_left end*} {literal} {/literal} {include file="footer.tpl"}Collabtive-2.0/templates/standard/project.tpl000066400000000000000000000256221237252063700214420ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" stage="project" jsload1="tinymce"} {include file="tabsmenue-project.tpl" projecttab="active"}
    {literal} {/literal}

    {$project.name|truncate:45:"...":true}/ {#overview#}

    {$done}%
    {*Edit Task*} {if $userpermissions.projects.edit} {/if}
    {*Projects END*}
    {*Miles tree*} {if $tree[0][0] > 0}

    {#projecttree#}


    {*block end*}
    {*block in wrapper end*}
    {*Tree end*} {/if} {*Milestones*}

    {#calendar#}

    Loading ...

    {*block End*}
    {*miles End*} {*Milestons END*} {*Timetracker*} {if $userpermissions.timetracker.add}
    {include file="addtimetracker.tpl" }
    {*block end*}
    {*timetrack end*} {/if} {*Timetracker End*} {*Activity Log*}
    {include file="log.tpl" }
    {*Activity Log End*}
    {*nosmooth End*} {*block dashboard end*}
    {literal} {/literal}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl" showcloud="1"} {literal} {/literal} {include file="footer.tpl"} Collabtive-2.0/templates/standard/projectfiles.tpl000066400000000000000000000145671237252063700224730ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload3 = "lightbox" } {include file="tabsmenue-project.tpl" filestab = "active"}
    {literal} {/literal}

    {$projectname|truncate:45:"...":true}/ {#files#}

    {#addbutton#}
    {*at two items*} {if $userpermissions.files.add} {#addfile#} {#addfolder#} {/if}

    {#rootdir#}

    {*Add Folder*} {if $userpermissions.files.add} {/if} {*Add File*} {if $userpermissions.files.add} {/if}
    {*change to fileview_list.tpl for list style view*}
    {*include file = "fileview.tpl"*}
    {*content_in_wrapper_in End*}
    {*content_in_wrapper End*}
    {$filenum} {#files#}
    {*nosmooth End*}
    {if $userpermissions.files.add} {#addfile#} {#addfolder#} {/if}
    {*block_files End*}
    {*Files END*}
    {*content-left-in END*}
    {*content-left END*} {literal} {/literal} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/projectmembers.tpl000066400000000000000000000142731237252063700230150ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax"} {include file="tabsmenue-project.tpl" userstab="active"}
    {literal} {/literal}

    {$projectname|truncate:45:"...":true}/ {#members#}

    {if $userpermissions.projects.edit} {#adduser#} {/if}

    {#members#}

    {*Add User*} {if $userpermissions.projects.edit} {/if}
    {*place for tool under ne title-icon*}
    {*place for header-informations*}
    {*inwrapper End*}
    {*content_in_wrapper_in End*}
    {*content_in_wrapper End*}
    {*place for whatever*}
    {$langfile.page} {paginate_prev} {paginate_middle} {paginate_next}
    {*nosmooth End*}
    {if $userpermissions.projects.edit} {#adduser#} {/if}
    {*block_files End*}
    {*User END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/projectmessages.tpl000066400000000000000000000261211237252063700231650ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload1="tinymce" jsload3 = "lightbox"} {include file="tabsmenue-project.tpl" msgstab = "active"}
    {literal} {/literal}

    {$projectname|truncate:45:"...":true}/ {#messages#}

    {if $userpermissions.messages.add} {#addmessage#} {/if}

    {#messages#}

    {*Add Message*}
    {section name=message loop=$messages} {*Color-Mix*} {if $smarty.section.message.index % 2 == 0} {else} {/if} {/section}
    {#message#} {#replies#}   {#by#} {#on#}
    {if $userpermissions.messages.close} {/if} {if $messages[message].replies > 0} {$messages[message].replies} {else} {$messages[message].replies} {/if}   {$messages[message].username|truncate:20:"...":true} {$messages[message].postdate} {if $userpermissions.messages.edit} {/if} {if $userpermissions.messages.del} {/if}
    {if $messages[message].avatar != ""}
    {else} {if $messages[message].gender == "f"}
    {else}
    {/if} {/if}
    {$messages[message].text}
    {*MILESTONE and TAGS*} {if $messages[message].tagnum > 1 or $messages[message].milestones[0] != ""}
    {*MESSAGES-MILESTONES*} {if $messages[message].milestones[0] != ""}

    {#milestone#}: {$messages[message].milestones.name}

    {/if} {*MESSAGES-TAGS*} {if $messages[message].tagnum > 1}

    {#tags#}: {section name = tag loop=$messages[message].tagsarr} {$messages[message].tagsarr[tag]}, {/section}

    {/if} {/if} {*MESSAGES-FILES*} {if $messages[message].files[0][0] > 0}

    {#files#}:

    {*inwrapper End*}
    {/if}
    {*div messages end*}
    {*smooth End*}
    {if $userpermissions.messages.add} {#addmessage#} {/if}
    {*block END*}
    {*Msgs END*}
    {*content-left-in END*}
    {*content-left END*} {literal} {/literal} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/projectmilestones.tpl000066400000000000000000000542301237252063700235420ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" milestab = "active"}
    {literal} {/literal}

    {$projectname|truncate:45:"...":true}/ {#milestones#}

    {*Milestones*}
    {if $userpermissions.milestones.add} {#addmilestone#} {/if}

    {#milestones#}

    {*Add Milestone*} {if $userpermissions.milestones.add} {/if}
    {#milestone#} {#due#} {#daysleft#}  
    {*late Miles*} {if $countlate > 0}
    {#latestones#}
    {section name=latestone loop=$latemilestones} {if $smarty.section.latestone.index % 2 == 0} {else} {/if} {/section}
    {if $userpermissions.milestones.close} {/if} {$latemilestones[latestone].fend} -{$latemilestones[latestone].dayslate}   {if $userpermissions.milestones.edit} {/if} {if $userpermissions.milestones.del} {/if}
    {$latemilestones[latestone].desc}
    {*toggleblock End*} {/if} {*late Miles End*} {*new Miles*}
    {#currentmiles#}
    {section name=stone loop=$milestones} {if $smarty.section.stone.index % 2 == 0} {else} {/if} {/section}
    {if $userpermissions.milestones.close} {/if} {$milestones[stone].fend} {$milestones[stone].dayslate}   {if $userpermissions.milestones.edit} {/if} {if $userpermissions.milestones.del} {/if}
    {$milestones[stone].desc} {*Tasklists*} {if $milestones[stone].tasklists[0][0]}

    {#tasklists#}

    {*inwrapper End*} {/if}
    {*toggleblock End*}{*new Miles End*} {if $upcomingcount > 0} {*Upcoming miles*}
    Upcoming milestones
    {section name=ustone loop=$upcomingStones} {if $smarty.section.ustone.index % 2 == 0} {else} {/if} {/section}
    {if $userpermissions.milestones.close} {/if} {$upcomingStones[ustone].startstring} - {$upcomingStones[ustone].endstring} {$upcomingStones[ustone].dayslate}   {if $userpermissions.milestones.edit} {/if} {if $userpermissions.milestones.del} {/if}
    {$upcomingStones[ustone].desc} {*Tasklists*} {if $upcomingStones[ustone].tasklists[0][0]}

    {#tasklists#}

    {*inwrapper End*} {/if}
    {*toggleblock End*} {/if} {*Upcoming miles end*} {*finished Miles*} {*done_block End*}
    {*smooth End*}
    {if $userpermissions.milestones.add > 0} {#addmilestone#} {/if} {#donemilestones#}
    {*block End*} {literal} {/literal}
    {*Miles END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/projecttasks.tpl000066400000000000000000000452501237252063700225070ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload1 = "tinymce" } {include file="tabsmenue-project.tpl" taskstab = "active"}
    {*System Message*} {literal} {/literal}{*/System Message*}

    {$projectname|truncate:45:"...":true}/ {#tasklists#}

    {if $userpermissions.tasks.add} {/if} {if $userpermissions.tasks.add} {*Add Tasklist*} {/if} {*Add Tasklist END*} {*Tasks*} {if $lists[0][0]} {section name=list loop=$lists}
    {if $userpermissions.tasks.close} {#close#} {/if} {if $userpermissions.tasks.edit} {#edit#} {/if} {if $userpermissions.tasks.del} {#delete#} {/if} {if $userpermissions.tasks.add} {#addtask#} {/if}

    {$lists[list].name|truncate:70:"...":true}

    {*Add Task*} {if $userpermissions.tasks.add} {/if}
    {section name=task loop=$lists[list].tasks} {*Color-Mix*} {if $smarty.section.task.index % 2 == 0} {else} {/if} {literal} {/literal} {/section}
    {#tasks#} {#user#} {#daysleft#}  
    {if $userpermissions.tasks.close} {/if} {section name=theusers loop=$lists[list].tasks[task].users} {$lists[list].tasks[task].users[theusers].name|truncate:30:"...":true} {/section} {$lists[list].tasks[task].daysleft}   {if $userpermissions.tasks.edit} {/if} {if $userpermissions.tasks.del} {/if}
    {$lists[list].tasks[task].text|nl2br}
    {*Tasks donetasks*} {*done_block End*}
    {*smooth End*}
    {if $userpermissions.tasks.add} {#addtask#} {/if} {#donetasks#}
    {*block END*}
    {/section} {*Tasks End*} {/if} {*if $lists[0][0]*} {if !$lists[0][0] and !$oldlists[0][0]} {#notasklists#} {/if}
    {*Tasks END*}
    {*content-left-in END*}
    {*content-left END*} {* current tasklists end*} {*right sidebar*} {include file="sidebar-a.tpl"} {if $oldlists[0][0]} {*only show the block if there are closed tasklists*} {*Done Tasklists*}
    {*closed tasklists*}

    {$projectname|truncate:45:"...":true}/ {#donetasklists#}

    {* Closed tasklists *}
    {section name = oldlist loop=$oldlists} {*Color-Mix*} {if $smarty.section.oldlist.index % 2 == 0} {else} {/if} {/section}
    {#tasklist#}
    {if $userpermissions.tasks.close}{/if} {$oldlists[oldlist].daysleft} {if $userpermissions.tasks.del} {/if}
    {$oldlists[oldlist].desc|nl2br}
    {*dones End*}
    {*block End*}
    {literal} {/literal}
    {*Tasks END*}
    {*content-left-in END*}
    {*content-left END*} {/if} {*Done Tasklists End*} {include file="footer.tpl"}Collabtive-2.0/templates/standard/replyform.tpl000066400000000000000000000132661237252063700220140ustar00rootroot00000000000000{if $showhtml != "no"} {include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" msgstab="active"}

    {$message.name}

    {/if} {if $async == "yes"} {literal} {/literal} {/if}

    {#answer#}

    {*Attach*}
    {if $showhtml == "no"} {if $reply != "a"} {/if} {/if} {if $reply == "a"} {/if}
    {*block_in_wrapper end*} {if $showhtml != "no"}
    {*Msgs END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"} {/if}Collabtive-2.0/templates/standard/resetpassword.tpl000066400000000000000000000025311237252063700226730ustar00rootroot00000000000000{include file="header.tpl" title="Reset Password" showheader="no" jsload = "ajax"} Collabtive-2.0/templates/standard/rolesadmin.tpl000066400000000000000000000262161237252063700221310ustar00rootroot00000000000000

    {#roles#}

    {*Add Roles*} {section name=role loop=$roles} {*Color-Mix*} {if $smarty.section.role.index % 2 == 0} {else} {/if} {/section}
    {#name#}
    {* Permissions for projects *}
    {#add#}
    {#edit#}
    {#delete#}
    {#close#}
    {* Permissions for milestones *}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#close#}
    {* Permissions for tasks *}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#close#}
    {* Permissions for messages, close = reply *}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {#answer#}
    {* Permissions for files *}
    {#view#}
    {#add#}
    {#edit#}
    {#delete#}
    {* Permissions for timetracker, read = read other's entries *}
    {#view#}
    {#permissionread#}
    {#add#}
    {#edit#}
    {#delete#}
    {#chat#}
    {#administration#}
    Collabtive-2.0/templates/standard/search.tpl000066400000000000000000000114411237252063700212330ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload3="lightbox"} {include file="tabsmenue-desk.tpl"}

    {#search#}

    {#results#} ({$num})

    {*place for tool under ne title-icon*}
    {*place for header-informations*}
    {*inwrapper End*}
    {*content_in_wrapper_in End*}
    {*content_in_wrapper End*}
    {*place for whatever*}
    {*block_tags End*}
    {*Neutral END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/search_modal.tpl000066400000000000000000000022071237252063700224070ustar00rootroot00000000000000

    {#search#}

    {literal} {/literal}Collabtive-2.0/templates/standard/settings_email.tpl000066400000000000000000000041741237252063700230020ustar00rootroot00000000000000
    {*block_in_wrapper end*}
    {*admin end*}Collabtive-2.0/templates/standard/settings_system.tpl000066400000000000000000000057051237252063700232400ustar00rootroot00000000000000
    {*block_in_wrapper end*}Collabtive-2.0/templates/standard/sidebar-a.tpl000066400000000000000000000064561237252063700216270ustar00rootroot00000000000000
    {*Search*} {*Search End*} {*Calendar*} {* theCal.dayNames = ["{#monday#}","{#tuesday#}","{#wednesday#}","{#thursday#}","{#friday#}","{#saturday#}","{#sunday#}"];

    {#calendar#}

    Calendar End*} {*Tag Cloud*} {if $showcloud|default == "1"} {if $cloud|default != ""}

    {#tags#}

    {$cloud}
    {/if} {/if} {*Tag Cloud End*} {*Quickfinder*} {if $openProjects[0].ID > 0}

    {#myprojects#}

    {/if} {*Onlinelist*} {literal} {/literal}
    Collabtive-2.0/templates/standard/tabsmenue-admin.tpl000066400000000000000000000013061237252063700230360ustar00rootroot00000000000000Collabtive-2.0/templates/standard/tabsmenue-desk.tpl000066400000000000000000000002401237252063700226700ustar00rootroot00000000000000
    Collabtive-2.0/templates/standard/tabsmenue-project.tpl000066400000000000000000000027711237252063700234230ustar00rootroot00000000000000
    Collabtive-2.0/templates/standard/tabsmenue-user.tpl000066400000000000000000000031231237252063700227230ustar00rootroot00000000000000
      {if $user.gender == "f"} {if $userid == $user.ID}
    • {#myaccount#}
    • {else}
    • {/if} {if $userpermissions.admin.add and $userid != $user.ID}
    • {#edit#}
    • {elseif $userid == $user.ID}
    • {#edit#}
    • {/if} {else} {if $userid == $user.ID}
    • {#myaccount#}
    • {else}
    • {/if} {if $userpermissions.admin.add and $userid != $user.ID}
    • {#edit#}
    • {elseif $userid == $user.ID}
    • {#edit#}
    • {/if} {/if}
    Collabtive-2.0/templates/standard/tag.tpl000066400000000000000000000114661237252063700205500ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload3 = "lightbox" } {include file="tabsmenue-desk.tpl" }

    {#tags#}

    {$thetag}

    {*place for tool under ne title-icon*}
    {*place for header-informations*}
    {*inwrapper End*}
    {*content_in_wrapper_in End*}
    {*content_in_wrapper End*}
    {*place for whatever*}
    {*block_tags End*}
    {*Neutral END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/task.tpl000066400000000000000000000052141237252063700207310ustar00rootroot00000000000000{include file="header.tpl" jsload="ajax" jsload1="tinymce"} {include file="tabsmenue-project.tpl" taskstab="active"}

    {$task.title|truncate:40:"...":true}

    {*Edit Task*} {if $userpermissions.tasks.edit} {/if}

    {#description#}

    {$task.text}
    {*Tasks END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/tasklist.tpl000066400000000000000000000266711237252063700216370ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" jsload1 = "tinymce" } {include file="tabsmenue-project.tpl" taskstab = "active"}
    {literal} {/literal}

    {$tasklist.name|truncate:40:"...":true}

    {*Edit Tasklist*} {if $userpermissions.tasks.edit} {/if}
    {if $userpermissions.tasks.add} {#addtask#} {/if}

    {#newtasks#}

    {*Add Task*} {if $userpermissions.tasks.add} {/if}
    {if $tasklist.tasknum > 0} {section name=task loop=$tasks} {*Color-Mix*} {if $smarty.section.task.index % 2 == 0} {else} {/if} {/section} {else} {/if}
    {#tasks#} {#user#} {#daysleft#}  
    {if $userpermissions.tasks.close}{/if} {$tasks[task].user|truncate:23:"...":true} {$tasks[task].daysleft}   {if $userpermissions.tasks.edit} {/if} {if $userpermissions.tasks.del} {/if}
    {$tasks[task].text|nl2br}
    {#notasks#}
    {*Tasks donetasks*} {if $tasklist.donetasknum > 0}
    {#donetasks#}
    {section name=donetask loop=$donetasks} {if $smarty.section.donetask.index % 2 == 0} {else} {/if} {/section} {*Tasks donetasks END*}
    {if $userpermissions.tasks.close}{/if} {$donetasks[donetask].user|truncate:23:"...":true} {$donetasks[donetask].daysleft}   {if $userpermissions.tasks.edit} {/if} {if $userpermissions.tasks.del} {/if}
    {$donetasks[donetask].text|nl2br}
    {*toggleblock End*}
    {*done_block End*} {/if} {*If if $tasklist.donetasknum > 0*}
    {*smooth End*} {*Add Task*}
    {if $userpermissions.tasks.add} {#addtask#} {/if} {if $tasklist.donetasknum > 0} {#donetasks#} {/if}
    {*Add Task End*}
    {*nosmooth End*}
    {*block END*}
    {literal} {/literal}
    {*Tasks END*}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/theme/000077500000000000000000000000001237252063700203465ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/000077500000000000000000000000001237252063700216505ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/css/000077500000000000000000000000001237252063700224405ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/css/calendar.css000066400000000000000000000076211237252063700247310ustar00rootroot00000000000000/* CALENDAR */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Calendar JS/DOM v3.0 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (C) 2005-07 by Michael Loesler, http://derletztekick.de + + + + + + This program is free software; you can redistribute it and/or modify + + it under the terms of the GNU General Public License as published by + + the Free Software Foundation; either version 2 of the License, or + + (at your option) any later version. + + + */ html, body { font-family:Arial, helvetica, sans-serif; } /* Fuer IE in IE-FIX */ div#calendar { } div#calendar table thead th{ font-weight: bold; font-size: 12px; text-align: center; background-color: #cedbec; padding: 2px; border-bottom: 1px #8b9dba solid; } div#calendar table thead th.weekday{ font-weight: normal; font-size: 11px; text-align: center; background-color: #e7edf4; border: solid #e7edf4 1px; border:none; } div#calendar table tbody td{ font-weight: normal; font-size: 11px; padding: 2px 5px 2px 5px; color: #0E224B; text-align: right; border: solid #e7edf4 1px; border-width: 0 0 1px 1px; background: white; } div#calendar table tbody td.weekend{ color: rgb(198,36,36); } div#calendar table tbody td.today{ background: #c4d5e3; } div#calendar table{ /*border-collapse: collapse;*/ padding:0; border-spacing: 0; border-width: 0 0 1px 1px; } div.calendar table th{ font-weight: bold; font-size: 12px; text-align: center; background-color: .cedbec; padding: 2px; border-bottom: 1px .8b9dba solid; } div.calendar table th.weekday{ font-weight: normal; font-size: 11px; text-align: center; background-color: .e7edf4; border: solid .e7edf4 1px; border:none; } div.calendar table td{ font-weight: normal; font-size: 11px; padding: 2px 5px 2px 5px; color: .0E224B; text-align: right; border: solid .e7edf4 1px; border-width: 0 0 1px 1px; background: white; } div.calendar table td.weekend{ color: rgb(198,36,36); } div.calendar table td.today{ background: .c4d5e3; } div.calendar table{ /*border-collapse: collapse;*/ padding:0; border-spacing: 0; border-width: 0 0 1px 1px; } /* DATEPICKER */ div.datepicker { position: absolute; text-align: center; border: 1px #8b9dba solid; font-family: arial; } div.datepicker-header { font-size: 11px; font-weight: bold; background: #cedbec; border-bottom:1px solid #8b9dba; padding: 2px; } div.datepicker-footer { font-size: 10px; background: #cedbec; border-top:1px solid #8b9dba; cursor: pointer; text-align: center; padding: 2px; } div.datepicker-calendar { font-size: 10px; background:#e7edf4; padding: 2px; text-align: center; } div.datepicker-calendar table { font-size: 10px; border: 0px; margin: 0px; padding: 0px; text-align: center; background:#e7edf4; } div.datepicker-calendar table tr { border: 1px white solid; margin: 0px; padding: 0px; } div.datepicker-calendar table td { font-size: 11px; border: solid #e7edf4 1px; border-width: 0 0 1px 1px; padding: 2px 4px 2px 4px; margin: 0px; text-align: center; background:white; } div.datepicker-calendar table td:hover, div.datepicker-calendar table td.outbound:hover, div.datepicker-calendar table td.today:hover { background: #e9eff4; cursor: pointer; } div.datepicker-calendar table td.wday { border: solid #e7edf4 1px; border-width: 0 0 1px 1px; background: #e7edf4; cursor: text; } div.datepicker-calendar table td.outbound { opacity:.4; filter:alpha(opacity=40); -moz-opacity:.4; } div.datepicker-calendar table td.today { background: #c4d5e3; } Collabtive-2.0/templates/standard/theme/spring/css/dtree.css000066400000000000000000000005171237252063700242600ustar00rootroot00000000000000 .dtree { white-space: nowrap; } .dtree img { border: 0px; vertical-align: middle; } .dtree a.node, .dtree a.nodeSel { white-space: nowrap; padding: 1px 2px 1px 2px; } .dtree a.node:hover, .dtree a.nodeSel:hover { text-decoration: underline; } .dtree a.nodeSel { background-color: #c0d2ec; } .dtree .clip { overflow: hidden; }Collabtive-2.0/templates/standard/theme/spring/css/export.css000066400000000000000000000130301237252063700244700ustar00rootroot00000000000000.export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: ; font-size: 12px; background: ; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: ; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: ; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: ; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: ; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: ; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: ; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: ; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: ; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: ; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; }Collabtive-2.0/templates/standard/theme/spring/css/lytebox.css000066400000000000000000000051771237252063700246520ustar00rootroot00000000000000#lbOverlay { position: fixed; top: 0; left: 0; z-index: 99998; width: 100%; height: 500px; } #lbOverlay.grey { background-color: #000000; } #lbMain { position: absolute; left: 0; width: 100%; z-index: 99999; text-align: center; line-height: 0; } #lbMain a img { border: none; } #lbOuterContainer { position: relative; background-color: #fff; width: 200px; height: 200px; margin: 0 auto; } #lbOuterContainer.grey { border: 3px solid #FFFFFF; } #lbDetailsContainer { font: 10px Verdana, Helvetica, sans-serif; background-color: #fff; width: 100%; line-height: 1.4em; overflow: auto; margin: 0 auto; } #lbDetailsContainer.grey { border: 3px solid #FFFFFF; border-top: none; } #lbImageContainer, #lbIframeContainer { padding: 10px; } #lbLoading { position: absolute; top: 45%; left: 0%; height: 32px; width: 100%; text-align: center; line-height: 0; background: url(../images/symbols/loading.gif) center no-repeat; } #lbHoverNav { position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 1025; } #lbImageContainer>#lbHoverNav { left: 0; } #lbHoverNav a { outline: none; } #lbPrev { width: 49%; height: 100%; background: transparent url(../images/symbols/blank.gif) no-repeat; display: block; left: 0; float: left; } #lbPrev.grey:hover, #lbPrev.grey:visited:hover { background: url(../images/symbols/prev.gif) left 15% no-repeat; } #lbNext { width: 49%; height: 100%; background: transparent url(../images/symbols/blank.gif) no-repeat; display: block; right: 0; float: right; } #lbNext.grey:hover, #lbNext.grey:visited:hover { background: url(../images/symbols/next.gif) right 15% no-repeat; } #lbPrev2, #lbNext2 { text-decoration: none; font-weight: bold; } #lbPrev2.grey, #lbNext2.grey, #lbSpacer.grey { color: #333333; } #lbPrev2_Off, #lbNext2_Off { font-weight: bold; } #lbPrev2_Off.grey, #lbNext2_Off.grey { color: #CCCCCC; } #lbDetailsData { padding: 0 10px; } #lbDetailsData.grey { color: #333333; } #lbDetails { width: 60%; float: left; text-align: left; } #lbCaption { display: block; font-weight: bold; } #lbNumberDisplay { float: left; display: block; padding-bottom: 1.0em; } #lbNavDisplay { float: left; display: block; padding-bottom: 1.0em; } #lbClose {display:block; width: 17px; height: 22px; float: right; margin-bottom: 1px; position:relative; top:-4px;} #lbClose.grey { background: url(../images/symbols/closelabel.gif) no-repeat; } #lbPlay { width: 64px; height: 28px; float: right; margin-bottom: 1px; } #lbPlay.grey { background: url(../images/symbols/play.png) no-repeat; } #lbPause { width: 64px; height: 28px; float: right; margin-bottom: 1px; } #lbPause.grey { background: url(../images/symbols/pause_grey.png) no-repeat; }Collabtive-2.0/templates/standard/theme/spring/css/style_form.css000066400000000000000000000136201237252063700253370ustar00rootroot00000000000000form.main { display:block; margin:0; font-family: Arial, helvetica, sans-serif; font-size:9pt; line-height:normal; padding:0; } form.main .row { clear:both; } form.main .row-butn-top { /* Button top on forms */ clear:both; height: 38px; } form.main .row-butn-bottom { /* Button bottom on forms */ clear:both; padding: 12px 0 0 0; } form fieldset { display:block; border:none; padding:0; margin:0; } form.main label { width:140px; height:25px; float:left; padding-top:4px; font-weight: bold; } form.main label:hover { cursor: pointer ; } form.main input { float: left; margin-bottom: 6px; width: 307px; height: 17px; padding: 3px 3px 0px 3px; border: 1px solid; font-family: Arial, helvetica, sans-serif; font-size: 9pt; } /* in Userprofile */ .userwrapper form.main label { height: auto; padding: 0; } .userwrapper form.main input, .userwrapper form.main select { margin: 0; } /* ## LOGIN - Form ################################ */ .login form { width: 200px; margin: 0 auto 0 auto; font-weight: bold; text-align: left; } .login form .row { height: 38px; } .login form label { float: left; display: block; width: 34px; height: 23px; margin-right: 1px; background-position: 0 0; background-prepeat: no-repeat; } #username, #pass { color: #598a31; } .login .username { background: url(../images/login-user.png); } .login .pass { background: url(../images/login-pass.png); } .login .keep, login .keep-active { background: url(../images/login-keeplogged.png); } .login .keep-active { background: url(../images/login-keeplogged.png) no-repeat -68px 0; } .login label:hover { background-position: -34px 0; cursor: pointer; } .login label.keep-active:hover { background-position: -102px 0; } .login form input, .login form label.keep span, .login form label.keep-active span { float: left; width: 153px; height: 19px; padding: 4px 6px 0 6px; border: none; font-size: 12px; background: #efefef; /*url(../images/input-bg-a.png) repeat-x 0 0;*/ } .login form label.keep span, .login form label.keep-active span { margin: 0 0 0 35px; background: #efefef; /*url(../images/login-logged-butn.png) repeat-x 0 0;*/ } .login form label.keep:hover span, .login form label.keep-active:hover span { background-position: 0 -23px; } #stay { visibility: hidden; } .loginbutn { border: none; margin: 0 84px 0 84px; width: 32px; height: 32px; background: url(../images/login-butn.png) repeat-x 0 0; outline: none; } .loginbutn:hover { background: url(../images/login-butn.png); background-position: -32px 0; cursor: pointer; } /* ## SEARCH - Form (Sidebar)) ############################### */ #search { position: relative; margin: 0; background: #598A31; } #search .row .text, #choices ul { float: left; width:137px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: #efefef; color: #6daa3b; margin-right: 1px; } #search button { width: 34px; height: 23px; background: url(../images/search-butn-side.png) no-repeat 0 0; float: left; margin: 0; -webkit-border-radius: 0px; border-radius: 0px; } #search button:hover { background-position: 0 -23px; } #choices ul { /* Autocompleter */ width: 184px; height: auto; max-height: 300px; overflow-y: auto; overflow-x: hidden; float:left; padding: 0 0 1px 0; } #choices li { width: 180px; height: 31px; line-height: 31px; background: #f8faf9; margin-top: 1px; padding: 2px; float:left; } #choices li:hover { cursor:pointer; background-position: 0 -36px; } #choices li img { float:left; margin:2px 0 2px 0; } #indicator1 { position: absolute; top:0; left: 150px; width: 34px; height: 23px; background: #3c556f; } #indicator1 img { margin: 3px 9px 0 9px; } /* ## BUTTON ############################### */ button, button.inner, button.inner-active { border: none; font-family: Arial, helvetica, sans-serif; float: left; height: 22px; line-height: 22px; color: #fff; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 5px 0 0; padding-top: 0px; padding-bottom: 1px; /*padding: 2px 0 3px 0;*/ white-space: nowrap; background: #384e67; } button:hover { cursor: pointer; background: #001e40; } button[disabled] { opacity:.6; filter:alpha(opacity=60); } button[disabled]:hover { background: #384e67; } form.main select { width: 315px; height: 22px; border: 1px solid; float: left; margin-bottom: 6px; padding: 2px 0 0 0; font-family: Arial, helvetica, sans-serif; font-size: 9pt; } #acc-tracker form.main select#ttask{ height: 150px; } form.main option { background:#fff; } #blaform div button, #resetpasswordform fieldset div div button { background: #efefef; color: #cb6e68; } /* ## FILES ############################### */ .fileinput { position: relative; float: left; width: 315px; } .fileinput table { width: 315px; } .block .fileinput table td, .blockwrapper .fileinput table td { padding: 0; border: none; height: 24px; } .block .fileinput table td.choose, .blockwrapper .fileinput table td.choose { width: 10%; padding: 0 0 0 13px; } .faux { position: absolute; top: 0px; left: 0px; z-index: 1; } .fileinput button { margin: 0px 0 0 0; float: right; } form.main input.file { position: relative; filter: alpha(opacity: 0); opacity: 0; z-index: 2; height: 25px; } form.main input.text-file { width: 100%; margin: 0; } form.main textarea { width: 307px; height:90px; font-size:9pt; padding:2px 3px 2px 3px; background:#fff; border:1px solid; font-family:Arial, helvetica, sans-serif; margin-bottom:6px; } form.main .checkbox{ width:auto; float:left; margin: 1px 25px 0 0; border:none; } form.main .radio{ float:left; width: auto; border:none; position: relative; top: 6px; margin: 0; } form.main .input_error { border-color: #8a3630; color: #8a3630; } /* ## Editor ## start */ form.main .row .editor { float: left; margin-bottom:6px; border: 1px solid #000; } /* ## Editor ## end */ Collabtive-2.0/templates/standard/theme/spring/css/style_iefix.css000066400000000000000000000007561237252063700255060ustar00rootroot00000000000000#sitebody { min-height:100%; } * html #sitebody { height:100%; } #contentwrapper { width: 980px; margin: 0 auto 26px auto; /* same as footer-height (for IE 7) */ } /*# Form Button # */ .butn button { height:24px; line-height:21px; padding:0 8px 0px 3px; overflow:visible; width:auto; } /*# UL LI Tables # */ .content_left ul li{ float:left; } /*# Calender # */ div#calendar table{ border-collapse: collapse; } /* Datepicker */ .datepick .picker { width: 187px; top: -239px; }Collabtive-2.0/templates/standard/theme/spring/css/style_main.css000066400000000000000000001471521237252063700253300ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Froehner ## URL: http://www.visional-arts.de ## Color Scheme: Eva Kiszka */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#598a31; background:#e5e7e6; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: #6daa3b ; color: #fff; } ::-moz-selection { background: #6daa3b; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color: #8a3630; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-in { background: #598a31; } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background: #cb6e68; font-weight: bold; color: #fff; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: #fff; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: #98ce6c; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: #598a31; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: #98ce6c; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: #598a31; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images/main-admin-c.png) no-repeat 0 0; } #mainmenue .submen li.customer-settings a { background: url(../images/main-admin-d.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: #98ce6c; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: #fff; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: #fff; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #598a31; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #598a31; } .content-right-in a:hover { color: #6daa3b; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images/color-a.png) repeat 0 0; padding: 11px; color: #598a31; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #598a31; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #598a31; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ .export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: #6daa3b; font-size: 12px; background: #fff; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: #fff; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: #598a31; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: #598a31; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: #598a31; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: #598a31; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: #598a31; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: #598a31; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: #598a31; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: #598a31; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; } /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: #fff; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: #d1f0b5; } .cal td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: #fff; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: #fff; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: #d1f0b5; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: #fff; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: #598a31; background: #d1f0b5; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: #8a3630; background: url(../images/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images/next-side-user.png); } .user .datepick td.back a { background-image: url(../images/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images/next-side-files.png); } .files .datepick td.back a { background-image: url(../images/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { float: left; position: relative; } #onlinelist li { width: 184px; clear: both; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #598a31; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #6daa3b; } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: #fff; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted #fff; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: #fff; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 585px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 585px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in ul, .descript ul { list-style-type: disc; padding-left: 40px; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid #fff; border-bottom: 1px solid #fff; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: #82c24d; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images/symbols/tab-projects.png); } ul.tabs li.customers a { background-image: url(../images/symbols/tab-customers.png); } ul.tabs li.tasks a { background-image: url(../images/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: #6daa3b; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: #6daa3b; color: #598a31; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: #6daa3b; color: #598a31; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: #6daa3b; } #modal_overlay.useroverlay { background: #bacfa8; } #modal_overlay.tasksoverlay { background: #bacfa8; } #modal_overlay.milesoverlay { background: #bacfa8; } #modal_container .inmodal { background: #fff; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid #fff; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: #fff; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: #F7FCF2; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: #F7FCF2; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: #98ce6c; } .statusbar_b .complete { height: 8px; background: #98ce6c; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid #fff; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid #fff; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid #fff; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid #fff; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid #fff; padding: 12px 9px 18px 9px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 230px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 176px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: #598a31; } .projects thead { background: #f8faf9; } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: #f7f9f8; } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: #e5e7e6; } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: #f5f7f6; } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: #598a31; color: #598a31; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: #598a31; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: #6daa3b; border-color: #bacfa8; } .projects .datepick td.wrong { color: #bacfa8; } .projects h1 span a { border-color: #598a31; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: #bacfa8; color: #598a31; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: #6daa3b; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: #598a31; } .tasks thead { background: #f8faf9; } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: #f7f9f8; } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: #e5e7e6; } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: #f5f7f6; } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: #598a31; color: #598a31; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: #598a31; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: #bacfa8; } .task h1 span a { border-color: #598a31; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: #bacfa8; color: #598a31; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: #6daa3b; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: #598a31; } .msgs thead { background: #f8faf9; } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: #f7f9f8; } .msgs .color-a, .msgs .statuswrapper li { background: #e5e7e6; } .msgs .color-b { background: #f5f7f6; } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: url(../images/tables-projects-bg-c.png); } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: #598a31; color: #598a31; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: #bacfa8; } .msgs h1 span a { border-color: #598a31; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: #bacfa8; color: #598a31; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: #6daa3b; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: #598a31; } .user thead, .user .contenttitle { background: #f8faf9; } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: #f7f9f8; } .user .color-a, .user .staterow { background: #e5e7e6; } .user .color-b, .user .content_in_wrapper { background: #f5f7f6; } .user .color-a ul.files table, .user .color-b ul.files table { background: url(../images/tables-projects-bg-c.png); } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: #598a31; color: #598a31; } .user h1 span, .user h1 span a, .user .inmenue a span { color: #bacfa8; } .user h1 span a { border-color: #598a31; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: #bacfa8; color: #598a31; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: #6daa3b; } /* USER PROFILE */ .user .export-main { background-image: url(../images/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: #e5e7e6; border-right: 1px solid #fff; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: #598a31; } .neutral thead, .neutral .contenttitle { background: #f8faf9; } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: #f7f9f8; } .neutral .color-a, .neutral .staterow { background: #e5e7e6; } .neutral .color-b, .neutral .content_in_wrapper { background: #f5f7f6; } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: url(../images/tables-projects-bg-c.png); } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: #598a31; color: #598a31; } .neutral h1 span, .neutral h1 span a { color: #bacfa8; } .neutral h1 span a { border-color: #598a31; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: #bacfa8; color: #598a31; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: #6daa3b; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: #598a31; } .timetrack thead { background: #f8faf9; } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: #f7f9f8; } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: #e5e7e6; } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: #f5f7f6; } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: url(../images/tables-projects-bg-c.png); } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: #598a31; color: #598a31; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: #598a31; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: #bacfa8; } .timetrack h1 span a { border-color: #598a31; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: #bacfa8; color: #598a31; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: #6daa3b; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: #598a31; } .miles thead, .miles .calhead th { background: #f8faf9; } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: #f7f9f8; } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: #e5e7e6; } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: #f5f7f6; } .miles .color-a ul.files table, .miles .color-b ul.files table { background: url(../images/tables-projects-bg-c.png); } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: #598a31; color: #598a31; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: #598a31; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: #bacfa8; } .miles h1 span a, .miles .content-spacer-b { border-color: #598a31; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: #bacfa8; color: #598a31; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: #6daa3b; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: #598a31; } .files thead, .files .contenttitle { background: #f8faf9; } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: #f7f9f8; cursor:move; } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: #e5e7e6; } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: #f5f7f6; } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: #598a31; color: #598a31; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: #598a31; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: #bacfa8; } .files h1 span a { border-color: #598a31; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: #bacfa8; color: #598a31; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: #6daa3b; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images/butn-reply.png); } a.butn_reply_active { display: block; width: 100%; height: 27px; background: url(../images/butn-reply.png) no-repeat 4px -20px; } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 4px; } a.tool_edit_active { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 -22px; } a.tool_del { background-image: url(../images/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: #8a3630; } .marker-today, .marker-today a { color: #598a31; } .green, .green a { color: #598a31; border-color: #598a31; background-color:#d1f0b5; } .red, .red a { color: #8a3630; border-color: #8a3630; background-color:#e8dbdb; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images/infowin_green.png) repeat; } .info_in_yellow { background: url(../images/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #598a31; } .footer a { color: #598a31; } /* ## Footer ## end ## */Collabtive-2.0/templates/standard/theme/spring/css/style_main.php000066400000000000000000001644031237252063700253250ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Froehner ## URL: http://www.visional-arts.de ## Color Scheme: Eva Kiszka */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#598a31; background:#e5e7e6; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: ; color: #fff; } ::-moz-selection { background: ; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color: ; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-in { background: #598a31; } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background: #cb6e68; font-weight: bold; color: ; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: ; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: ; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: #598a31; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: ; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: #598a31; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images/main-admin-c.png) no-repeat 0 0; } #mainmenue .submen li.customer-settings a { background: url(../images/main-admin-d.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: ; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: ; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: #fff; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #598a31; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #598a31; } .content-right-in a:hover { color: #6daa3b; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images/color-a.png) repeat 0 0; padding: 11px; color: #598a31; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #598a31; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #598a31; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ .export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: ; font-size: 12px; background: ; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: ; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: ; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: ; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: ; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: ; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: ; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: ; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: ; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: ; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; } /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: ; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: #d1f0b5; } .cal td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: ; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: ; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: ; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: ; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: ; background: #d1f0b5; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: ; background: url(../images/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images/next-side-user.png); } .user .datepick td.back a { background-image: url(../images/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images/next-side-files.png); } .files .datepick td.back a { background-image: url(../images/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { float: left; position: relative; } #onlinelist li { width: 184px; clear: both; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #598a31; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #6daa3b; } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: ; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted ; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: ; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 585px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 585px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in ul, .descript ul { list-style-type: disc; padding-left: 40px; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid ; border-bottom: 1px solid ; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: #82c24d; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images/symbols/tab-projects.png); } ul.tabs li.customers a { background-image: url(../images/symbols/tab-customers.png); } ul.tabs li.tasks a { background-image: url(../images/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: ; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: ; color: ; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: ; color: ; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: ; } #modal_overlay.useroverlay { background: ; } #modal_overlay.tasksoverlay { background: ; } #modal_overlay.milesoverlay { background: ; } #modal_container .inmodal { background: ; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid ; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: ; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: #F7FCF2; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: #F7FCF2; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: #98ce6c; } .statusbar_b .complete { height: 8px; background: #98ce6c; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid ; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid ; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid ; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid ; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid ; padding: 12px 9px 18px 9px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 230px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 176px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: ; } .projects thead { background: ; } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: ; } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: ; } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: ; } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: ; color: ; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: ; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: ; border-color: ; } .projects .datepick td.wrong { color: ; } .projects h1 span a { border-color: ; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: ; color: ; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: ; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: ; } .tasks thead { background: ; } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: ; } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: ; } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: ; } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: ; color: ; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: ; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: ; } .task h1 span a { border-color: ; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: ; color: ; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: ; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: ; } .msgs thead { background: ; } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: ; } .msgs .color-a, .msgs .statuswrapper li { background: ; } .msgs .color-b { background: ; } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: ; } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: ; color: ; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: ; } .msgs h1 span a { border-color: ; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: ; color: ; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: ; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: ; } .user thead, .user .contenttitle { background: ; } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: ; } .user .color-a, .user .staterow { background: ; } .user .color-b, .user .content_in_wrapper { background: ; } .user .color-a ul.files table, .user .color-b ul.files table { background: ; } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: ; color: ; } .user h1 span, .user h1 span a, .user .inmenue a span { color: ; } .user h1 span a { border-color: ; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: ; color: ; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: ; } /* USER PROFILE */ .user .export-main { background-image: url(../images/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: ; border-right: 1px solid ; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: ; } .neutral thead, .neutral .contenttitle { background: ; } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: ; } .neutral .color-a, .neutral .staterow { background: ; } .neutral .color-b, .neutral .content_in_wrapper { background: ; } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: ; } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: ; color: ; } .neutral h1 span, .neutral h1 span a { color: ; } .neutral h1 span a { border-color: ; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: ; color: ; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: ; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: ; } .timetrack thead { background: ; } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: ; } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: ; } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: ; } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: ; } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: ; color: ; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: ; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: ; } .timetrack h1 span a { border-color: ; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: ; color: ; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: ; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: ; } .miles thead, .miles .calhead th { background: ; } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: ; } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: ; } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: ; } .miles .color-a ul.files table, .miles .color-b ul.files table { background: ; } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: ; color: ; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: ; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: ; } .miles h1 span a, .miles .content-spacer-b { border-color: ; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: ; color: ; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: ; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: ; } .files thead, .files .contenttitle { background: ; } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: ; cursor:move; } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: ; } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: ; } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: ; color: ; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: ; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: ; } .files h1 span a { border-color: ; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: ; color: ; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: ; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images/butn-reply.png); } a.butn_reply_active { display: block; width: 100%; height: 27px; background: url(../images/butn-reply.png) no-repeat 4px -20px; } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 4px; } a.tool_edit_active { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 -22px; } a.tool_del { background-image: url(../images/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: ; } .marker-today, .marker-today a { color: ; } .green, .green a { color: ; border-color: ; background-color:; } .red, .red a { color: ; border-color: ; background-color:; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images/infowin_green.png) repeat; } .info_in_yellow { background: url(../images/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #598a31; } .footer a { color: #598a31; } /* ## Footer ## end ## */Collabtive-2.0/templates/standard/theme/spring/images/000077500000000000000000000000001237252063700231155ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/acc-open-b.png000066400000000000000000000005721237252063700255330ustar00rootroot00000000000000PNG  IHDR R$tEXtSoftwareAdobe ImageReadyqe<IDATx1 0cp\z+(]]"NP@;8{ktqI6A!^%$N))>19s #Mc8Vhf djצƨjVC&&Ƀ7̑Oڒ-Cwq~7w:yvS, W.!XfqzGg2[gNꓧXk.sڐ%_GL5RE5REh!ZC^`\&=%(L5RE5RECr|IENDB`Collabtive-2.0/templates/standard/theme/spring/images/acc-open.png000066400000000000000000000004611237252063700253110ustar00rootroot00000000000000PNG  IHDR R$tEXtSoftwareAdobe ImageReadyqe<IDATxb\fd`.(8ċA,i@jEn!!!a<,*H1} #HւvQ0 `b3sVTT 2'k9[+@s Un!BU f)mJDF[̈́f :@vA-DRȕ"F*$1sѬ!?s0|fٜTIENDB`Collabtive-2.0/templates/standard/theme/spring/images/add-files.png000066400000000000000000000026211237252063700254540ustar00rootroot00000000000000PNG  IHDRP3qYtEXtSoftwareAdobe ImageReadyqe<3IDATx]lTOl7%YZ)_6/ZCPih!xDEoE0J4 e^Z^@T뀎)Hd]˚&n?νv$|_sϹEOΰϠӅQ uAhBfPGهm]5Y 7oo l0b(ˎBZ#,;g:]k32&F@3&JpCrl%vZ뢙oW ݐwiK8Y+ٍ%ujSxS9QBZ@Z)v1ЄHlRL)3 =bnw1+ѕ҅%ct4+҅@NLi z|^ g+&D};{x<@4HG?:-I;c;`xx~?<~tc̻xw;acQ\/^e3k7~9vY7 FLH|[1%KRxV,' OnwtسPJϖB F}#JʹxKQ'/UK2}[HQ;laVEo|bXu'B],˴7Rm㓂 chԱy(c4nj)b嗯\չeEjl @`wyՕ|Qܞr!:jQȹJ|:ˣ*jVp箕voN;nQ6g!\U>jIYM{h\Hnl $-@EgEp8ƴ՝pnuc?u ": ƒ :>oc>=|e:XQ K7kH:ݴ(Suw-Z`$>uϑ`.eX``NZS cȗ(MAߞ>wO]}4za|#1ԃkQW7#u|I.KKIxϿT' >xX雚1 !T3xS֪Fwp8Jl?\0ږW[  8I4I[-d0-JŬ Id6rSV OYګ/8s[ nB/IO-ZlL(t.8rMs+CR)jUEhSt `0uAU}gQ~h`9H&e,oBULhy*c^ PLk:?K客IENDB`Collabtive-2.0/templates/standard/theme/spring/images/adds.png000066400000000000000000000004541237252063700245410ustar00rootroot00000000000000PNG  IHDR3u3tEXtSoftwareAdobe ImageReadyqe<IDATxb?]vbi y ĻYDP(CB` 01PPe0aDHaxs4iPOT2ȰM@B@7 df4Bra5\7$ۃ2 Qf s` Hн`DbXÌáIJf=/(4? z24יIENDB`Collabtive-2.0/templates/standard/theme/spring/images/autocomplete-bg-a.png000066400000000000000000000001661237252063700271330ustar00rootroot00000000000000PNG  IHDRH7B-tEXtSoftwareAdobe ImageReadyqe<IDATxb1 -b ?_bIENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-files.png000066400000000000000000000004111237252063700265410ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbOa؀؂ 17 j ր F6$i,fS@ b'@o`_@|f #t>M `?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 HH ȢIENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-miles.png000066400000000000000000000004111237252063700265500ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbl`؀؂ 17 j ր F6$i,fS@ b'@o`_@|fGut>M `?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 ĕIENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-msgs.png000066400000000000000000000004021237252063700264100ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbLMc؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-neutral.png000066400000000000000000000004021237252063700271110ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbc؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 ߴʓ\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-projects.png000066400000000000000000000004051237252063700272730ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb/,a؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNš8?bK@<T] Wvd蒕@Oqye7k\\)Ȧ` )5zzIENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-tasks.png000066400000000000000000000004021237252063700265640ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb4*c؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 _stIENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-timetrack.png000066400000000000000000000004111237252063700274220ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbwe؀؂ 17 j ր F6$i,fS@ b'@o`_@|fet>M `?.ĀJNG^lIz>K3Ļ@IAȪ%+ n ⹸SMpS ~IENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side-user.png000066400000000000000000000004021237252063700264150ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb ύb؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 8IENDB`Collabtive-2.0/templates/standard/theme/spring/images/back-side.png000066400000000000000000000003141237252063700254430ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<nIDATxb? 2X$XY%X&F6$) %YLP'A; (23vTr%ـ$(517$X5k Wn6 : Iе0~dh1FIENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-bg-side.png000066400000000000000000000001661237252063700261060ustar00rootroot00000000000000PNG  IHDR.sjtEXtSoftwareAdobe ImageReadyqe<IDATxb1Е!IENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-check.png000066400000000000000000000006611237252063700256510ustar00rootroot00000000000000PNG  IHDR(tEXtSoftwareAdobe ImageReadyqe<SIDATxbYf  9xBA^@j? ^Man@| 6" rjD ď` e @,$@M1 ~Pb1jTA`r#)hB].$6  *r Nx% Y@0P[@IP rI8+"Y5z8Mh7_i@ [0'QPVI⟸ X7Wm /0z({+A ^/;>d 3P 6jبa3arh>Z=#2ԩ O0@IENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-del.png000066400000000000000000000010131237252063700253300ustar00rootroot00000000000000PNG  IHDR(νtEXtSoftwareAdobe ImageReadyqe<IDATx+Da3n%YPv(QH)ʎvK(rll( e5)e+Sr)6V%y}lNsu l˲J![jWT9*,C?\4MX ?^(wC1=q <ɐ C$=24:M:)ÃMsba 4G6xq!|$(u .=yIt( B^;g=kwe2 v u5傭ZR!u x?1ZjO:"4K9P/3h4F-/uU<%XP֬t{gO<Ep9e*!ר&^@qGNzOrHNrJ$k!K}…$s.nYqִW`4ꈃhIENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-edit.png000066400000000000000000000012241237252063700255150ustar00rootroot00000000000000PNG  IHDR(νtEXtSoftwareAdobe ImageReadyqe<6IDATxϋa̸jEŃAQ?@ʈy@)Ùخ1-QО˛d(bWF[Нrٲ,J_FGr i.{IENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-notok.png000066400000000000000000000007051237252063700257250ustar00rootroot00000000000000PNG  IHDR ,sRGBbKGD pHYs  tIME;~EIDAT8ҿKa{0hpph 7E J EgMD  ¥Q\DA%.w!*45t[ ߻ܵ9y9Z-\zm0=c?vc_pcs\+ ;Xs 8wc)ޏPͱ$"p7*>b %ȖBO ln N zx|J5qn*!JXk}K!a=1MwE`XFM;M+]:Ni`$ѬLW+FlGm}?2EbY:IENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-ok.png000066400000000000000000000006421237252063700252040ustar00rootroot00000000000000PNG  IHDRmJsRGBbKGD pHYs  tIME XE!"IDAT8ӿ+Qu/I ,, An&ժ`-hڕ@B_˹:}~o7|yޝW.IaMAٖ3h$Zq!E .m?CF-uBFB`G Jdg茴 ,\y銴nDtR 2~iXJQ)T]bT8 ؍)F=xXЛ1)"[5:wy׻kXMiט[٨ fPΚVd K=#I53IENDB`Collabtive-2.0/templates/standard/theme/spring/images/butn-reply.png000066400000000000000000000005251237252063700257260ustar00rootroot00000000000000PNG  IHDR(tEXtSoftwareAdobe ImageReadyqe<IDATx @ElZ%hx` &IgO2E'1f7yN]<45N%@5yJ^ b4@;AJDӈ tg/`)*yNp+8@d_ٸOLh؉נ ,amU,d'W%5p 520DZc=iJ&T":oF=l7KLDTKIENDB`Collabtive-2.0/templates/standard/theme/spring/images/chat.png000066400000000000000000000005461237252063700245470ustar00rootroot00000000000000PNG  IHDRJetEXtSoftwareAdobe ImageReadyqe<IDATx엿 0"v1b|#QG; EBХr\i>r_XJDF-Pa[UUqT|G*J@OuVR_d*!7EJf\|##dձ2w *j:氱V@BcP`(Ft sA`l3"wU0fW'6!h]=}%GD@{hJ7I'2zw SG,s `l37b\ /wH3wIENDB`Collabtive-2.0/templates/standard/theme/spring/images/closemodalwin.png000066400000000000000000000013331237252063700264630ustar00rootroot00000000000000PNG  IHDR8;9tEXtSoftwareAdobe ImageReadyqe<}IDATxOQƧ3m qQ`#M#ܹ_bBH\ $l *PX[-7̴YItfns9\=y%wt mE)hK@-"Txi 5Q;=. t݆.C%3h hn;yD ^.8M.t/a5WaȴmhOֳ*b,t"k4L$hEix~* }7y&f00gYcf? 7újf r(ZIshˆK -'Є@U[g>Qudf_Kir Mif+%V mf`,etn71a폟Vva:`T":WO覺_z#hČyjlZ8{EV]H*д,[7ѮCcЌW>lقpyHfτʰ)9z8}>굜6Gt^,A/b`ʣ,?ן5nK(Ú֓  [1uDm#JʴÅ$ؐ LvQ`'4n呛`m-{n͚1Abt#KDM~UQBr#i$m˶Ti **l*4/ŨMԪj)@cu7lYoYkٙ{g׎5t4;=s~<=k_,ʅ4Crؽ$ h63#dl?'$*dDH1^-d0nLn+ҽ= ,`fN-%B )#Эm9AlNfZn '89B r06 ݺFW $J.gdƃ#2hdLPdyA!iO('RQo`-Mgf.."Yd#&$_$ vrOŦ{ HJZ!KV_t!\#:J|! 4-=cyHu=Ʀ~X垥tsDh BY/Tz=C5$@ZD+ M?tH!y%]# he#$UgF,N0e@ARk,cjnFpE%!aՆ+5tX*3(cI|P6Ssc&wE*y1!Af0#㎀umJ*v6M,!PKVb}2^i<Ҿ$E~y\2!]HR-Ҋ8gĖs\kT{wSc$ib _N>%(YR?7&MO54#c6^}$4XS$ Y2Xd,sHvP7XcmE5;Of0C]#D*O/lq,g;B -{YIK"|rsDj$HFR2Ib5&wXe.[XaŹ%VV8Cl&]lJH0۰e(Lcy;JYUHYWcBw (\t-du1:Yݧ*A_ZGRqornR3Ȟ%B }&o/ g-ADZЊڤg' AV;6rCٰ|W=̹;鿣Xrϛ]+.nVgD^IB,v露b ?|]q/,N1W''D2bx=mTnjIqZcWG]9ف ~c~^#bź,x f/Y[">] -iYg%%RInH-U [i2|[Aw~7oVm@Bg[v͑Ecw 'xV|ʟK$H"]!"^[EACRa;R4xp0 m,G}ZĎܸ-*R |b ImɌz"1e茻16 ^nHXmu߾ha-+#e~gsO@M:1i>8^8WPa{RXq+U!"!C禆Hm8V7i3%>"Or4Ě&O<|McׯYw _Vybߟ3b7?>d̉W!Ɖ.|rB##@,UBVm$qs5i5Sy^x$$omnu:K}j|yTlӦHִMd`zVHTc%f5۵L-XՖ$i+?Dj^ "ZrBkN& V=wY#a"'P z2ɢy+Q”Tk9&No6>+)qOH_/22D&ܨ'XfnwZXώB߭ Ģbrdbc~ 'Nɀ\ XSB3 1@lYk?Lchw:pn^euAk3 _a}mDRibz2C"O>[;u(pDX"CFf9.qNbWdz/D9O IENDB`Collabtive-2.0/templates/standard/theme/spring/images/export-msgs.png000066400000000000000000000051621237252063700261170ustar00rootroot00000000000000PNG  IHDRv3B2tEXtSoftwareAdobe ImageReadyqe< IDATx\}p\*&B*`` 2f# 2SZ upZ'w38u%І1g$JifETb#$޳7ݼyyHl<= `õm=qNJu-Qq)T2c1x?c>~¸1m;s#l3@˸Oz#5+[_``Ο ڶh~nN@XGǽfsfSߜf,e|Bǘfn v4Ʌ0>Mn[=&ݱEiKOl?vГ㎖3b8wIjD]H~C On(98ad="7и^A ?(뎠!Ezq5t1Vz'=(IăD yn +Ft3n☛$A$< 1dnǴ>78FFOm+c;Ulj3@t"O-uST0CXQ tPcb,r_smrуUL)m"*7DUU.,UX DYt1%w \<5j $?&X'-?i9fȸ,6,i-*1\O!8lʈu9LR- mqo|cnL.6Ec'B ?H*uFodJl'sh봨\FXF>XXuw7 Zm3m I+Ȓ "nNb9G!A|5}d5[A(B])p=$*@UЃDL↸iGct~w7s)M3QqMkD )6X4*N=+R\ 7"}1JKrńB%:5n?7*8kMU '*OiKPH%xA!U\K$Pdk[>y\wq:utXԎ^ctơBlmzm!]mv~3pĥw.xq8ǵFmR*<>߂y#/lya 6 Nxc/?;ߝyPǍ2,Tqy _q{@7;߮x[ޚ_hld`LIc"'\!G.tmgiy|@;W]1vqo .,)n#|~`tƕ}&Q$9!|3Y\qzH@W\qjt.Oi\BUS|0t@1֬XVErry_WW]#GKA4@zD.O)3^3kÐ Z #FyN6b3+g@=pضzX^ F8$;?~K !Y((ůjTi|~ZƧX<֡@cg͑p0t̩٥vNlڕ.k CfXx3#C7@X+Ý4蕧Q/= -5쌹=$f\EBN%MQJ@Jc{HwzD[q}kHN9~iUƣݩz_aTRAfSlj*R'B58؄^-# }%}fN(y9h]]'DU,R=QZzYW}Q-pJOBK>D+TY R+fNPDJThIXu^4wż K Nt%~] Khl^KOgCj۩Uo' ܵSdlֺ#r!IENDB`Collabtive-2.0/templates/standard/theme/spring/images/export-tasks-headline.png000066400000000000000000000042231237252063700300370ustar00rootroot00000000000000PNG  IHDR_3ztEXtSoftwareAdobe ImageReadyqe<5IDATx[klU/RG[M& KH $ !QIiB`Diń$J4*-(e@.tk-)Ҳ]ﶇqv:dNevf;s9]O$QTR$Р /F۹EA$Z;1 @XO _ =hF[O7I>pNqs{@@@sNGU[O "!gvjr:r2ZLpkVĮ"maǪ"79C<dލDL-D%*p8!awR`YPy ϵC~FN!#0FF9 `/F^(PbdGc%Կ$YAm&].wA%MGpӡ3 z4d˘C/DXBy7a3B (hd3|Ixј@QM$rCh䂩pԍ^M :NZGB4i1=C,;]VFA0OC;y(%CƼ!v}EL@Ofm}:0&Fi -idXH¬F>M=̫g 2@v2<ڇ |r|ئ}Wr(9pf;./'5>xdγLz}BNs5ԭ'ݬtP+xJdKKK+..s?2֟Yϯ?0`+:>^ ~=Hį%Z;~]JbpjϧV ™yZWkO )po6)CoNXYbvx"NN7*_ VЊ`rWDm\12A~yvJ`l퐏󡉶tQB-C-_((.^/im/L`ͱQ N>Fb @u6uI/ i|"֧mR`@5FU+P"'&/ՌNڕT *CC;jA?m*zy%ٿbcѓgXHK] )?"4̇3a*."4@Ľ}8Y…ЩW-8M):/XTH?cZ2(#),?3QP0SXKZl80+L:Fue9ʪ׶IX\Er0 WJ35"k;RJoqU>eʤ Pqߡ;oZWm$000^­opg Ju]oYxv.~U0}s nY#/-Yܻg^:!ϱ"` ܇:#x$ΪTW*{0*:5bOF"JNةs~:;pF}Qx$Jsmh A>UIS2'SB"b@f@͌70alc=fṳz~iQ(n+z a>=O91~y `sr]DDITq%/3>In}6ݱhOO<F?"qC+2dN$N.!?&F'QJ%{,NFX?Y|M4Wbn)Z1^AiNR$^FI畨@!bD/.+IO"`@ǁ<KQ]cb|'1w3Ν0J4u v08[<ͣ:C q3]U%"[ݲH CQ!gS~ZOZ?z`2\' P(B[,۬xv2W1ݹ@'^X-֝K(T 0&ya G^<6/l OFcz7uXNj2,֌&=kim߯y~ -';k7K|_}e|tgN#C (2>θX0>xݢ0iJ \~4nM0x23~xgA[V1l!I:) Kh;dU16#YpG:| w=u_èx̅w>[>>qBv ~?J0(_ [i6H=C=q&~oTw.]Qu \4$?r%=~WuZn?m:+Z5,]5HkVY:Q.d=ol:K12TQ,uKJf%k0,)5B< % IBN-2>5cnj_cꍑ3Xl\7MCMI?/`g˫&D.mn]juz/ar[f?[RHDun\4:>q<-v+ ~{a,eOOן;W+B c8IКV=b-pQb2ZtSq AW4^=󪡸\EYoi'q;Z;j+ypB/:;ԉ 9m=I[,7j0fc5۵Fb VܱI =\׬ 0g‚ŷüR1BD:r8`{hcvEBtz-k) C3#akWkcDbS4ug > \JAcvSl]r ]czm8DX@ PŽ gxQ:Wՠi|ɧU B\:Tt†8kȊc툚hoPy".mJIB i!8m qD  kwױ9- DcځS N$= G@id Bzm4O{_{خu VrvIENDB`Collabtive-2.0/templates/standard/theme/spring/images/export-vcard.png000066400000000000000000000026311237252063700262430ustar00rootroot00000000000000PNG  IHDRZ25tEXtSoftwareAdobe ImageReadyqe<;IDATxZhU&6M:6$Sl/*E@!fUpbg9D&fP2e)FܤJ]lmRkm,^ۙܽ{7~サsmkm.k/FPHtãm!kH0"}I ٦$g:5*o7NQg0' bJР't8^eGd=y9:D^eE hB[țhmeIG4r;D}B/I ;Qie! E9:dZBO.2R/M5Aq g'IE9J=F69x "{TR;0Frp'oB!R]<U1+O ~E1d{]1S=$'Gh=n)."UJSD$_Rp>IXwQ 1Un~=1 B%A,g0' Lۨ.(3[n7Pxt5XG;b\vAM}qī#7G"~_sOPKUJ<(%޹ݟuJe{ hޝx$Eh[kMX9<3IP ` Nw;F/unW+k8+!aGS=@gƘH[D%rQ6Xj% Hn?GGN\/B4J̰h.V,rNV.k6~%]b78QϞl^p#_0>/o}.Lu^agk>,*q>0WGF,O t ~t(~4h`.ƽm]scC-}iti <L`Rn6}ďCW+(lf?9ix9ADBi0 ~S28]ݏq*.J~ȹ2E@7d90ʫ\s,'~.~-9zo!n,Wcizq)uα>܏(ΰcmecƿqc"7c9;:V#d}_xpa75DP_\wGIENDB`Collabtive-2.0/templates/standard/theme/spring/images/favicon.ico000066400000000000000000000015761237252063700252470ustar00rootroot00000000000000h(   S-Q-Q-Q-Q-R-Q-Z7$vW5[7$Q-Q-Q-R-S-R-T.S.S.S.eC*lAS.xX6zxX6S.S.S.T.T.T.U/ T/ U/ U/ MzM˵iz˵imBU/ T/ T/ V/ V/ V0!V0!_:&V0 nC|||||NV0 V0!V0 W0!W0!X1!X1!}Űp΃ى{zM|[:zMa;'X1!X1!X1!Y1!Y1!Z2"Y2"gFޗޗнc=)kH1sPkH1Y2"Y2"Z2"Y2"[2"[2"[3#[3#nI4mI3jLל_D[3#[3#[3#\3#\3#]4$tėĖ]4$˹­]4$˹s]4$]4$]4$^4$^4$^5%fǟө^5%ıͽqL8Ƞyz߳h^5%_5%`6%`6%iA/ƅdNrM9ֲֲoW˧|XC`6%a6&a7&a7&|ͰjC1a7&}YEa7&jC1Ͱ¥a7&b7'b7'b7'зͶkC2uN=fSkC2c7(c7'd8(c8'c8'c8'sac8'c8'c8'd8(d8(f8)d9(d8(d9'°禌{¯¯iWd9(d8(e8)e8)e9)f9)f9)e9(e9(nE4iYe9(iYiYe9(e9(f9)f9)f9)f:)f9)f9)f9)f9)e9(e9(e9(e9(e9(e9(f9)f9)f9)f9)f:)f:)Collabtive-2.0/templates/standard/theme/spring/images/files/000077500000000000000000000000001237252063700242175ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/files/application-illustrator.png000066400000000000000000000124001237252063700316070ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X]IDATx͙ tƟ!DcI R%f%T[Dj+JRS'5OfRTy*THdLy}'9wַ-ϻ_Diwpy篫u<QT T)lwҨQM^WqbR|/)1ˎՎ5pc8;-J![]F}tmvVFQ_ [ ~"~hA+uAhM]}u(N7s _#2w/`}=ɞ^go?Y$'U:P%7;@.|wgCk8T@Ȩkph! -~`Xbm0LvM5YXGVxcoF՞ܟO%<YiԉZڃ`lEsԚZׁ"R )D %Ժ}F?TG+\B]]7h$0(Q ನ-ZyQ1fǧ`Urna~zE/\L]ox= R r%vcjvm?4P=' ɝaH`_ PɟĸAk`)J S+E:M:F"UrY;BNAG!%N 57C'kzq1 >l8l檙o׸\qIP)qq24&;AL$Elyh `@ +A:t1uU9*9C2OL j'ES-}BDhOCʊ.ѧn`#vԖf:-'yڈKb:( O)(4}[[ZZH#h=ćԋz> 62mzÇ@z`aؿpKgIȇ)Cr9u [5l()O y xn@;k  XOT[g1 tSo}%h)ZfHJP_ *](C1Z!k<^ dW^J%TDKOOO;R (jRuF q<__졎s3SkzFSWʞOSua>zROxWNvbx^N;Xp"k oi"W&L.Li;-pijg\˸Ǹ ݫ.O$ <yl  J6`OutpaVs˜;@ u`' Ԗ(< JV@"ϕJ@p}FT X!VD 4ʀFW7o1tO>> Hgu:_Rf \)Ю?AT7L7 pq3Yrsod3pđi5qP 0DB !Ia1UG ' p6flA-vnj:(J;vѹn/At r,* - jڥKpU\8ŸYAZx>gn%vG Xre[S`4o`Eho(Ef@g8XlM2lO 䍘1֡B G,8kc>r7H2?P=*xeqj+;^v)}.rgGWTWj0{z*n)SjM^1X̀%⡫!TjQkUGzzUA2S:ͭo4a#@ G>h4HoQ&r;1F`3x=XC}6`ޒ}2Z9 8N:z_]._V2ZzHe v]եC%/G}f, KpYgkr2p'q @SMBBFϋ 7#Z `9"c!`Xmo(+2[/"Z :AW)ڍ HB]0P}n]2L2{ bUpϢ8j@ogPMC! *|xp`TS= ׇ_Ώ\Q? rWCt m m+D@+*}{{@{W~qe3Ic 2 3t_!L)~ѹ@)~ c i: Pn>+B/Շ}Bw_g ^w}oWͿ;ǫ:ϚgmvnmN c+kr.EԒ%[ѳ8 `/@7'gc.O .8U &@L\=༪bySPғpLvD;fjP&Nj MW7UWm?#m5"d࠹qL켪rokP(ځ Dr#?l v;e 1A@kU:0uFwcwc1@^ԝ~ğ"OD2Q"':Hk<(ϜTw`]RAڻ]t@D"^8n5b Lj yZO'TI;!wBGߐ (wm/xAU<o пedU=׼5զM=RV[ÁmpImv`jz[fUHKGpJp퀯h( e'yPc,fh/Q;̟*x{G-ZzOi+e#PEqpV4~Mu?4z{!)=6n@Ʒvb[m @2tqnvha:P>{YwǺpy2LJ_15G1ubI3\_Fa0 "(_`ۃ$ q@k`[e{&zʟWW#`n#ы5`;e!bK{kDY%hFR?8iI$@yh@Xɇ? ZxLA ]7@Xް|=h5W(|/24qwaHZ9q%rrSԹsa'p)@l.W@@gta@U;A,0L]9P[zm zzB.{!2'O3g0`d^d7+y?Xj[T؜:+wJ x$ylHFSϼ&zMƟz~Q(#0xG`od^ֻ̌[X¯KBm] q=m鶥q|RDw~"ZNBZO5!37´3/։zg̓wxkǗV+F,3g_Zi[*l̟R˜_0|MWMWLinYŖ3 14pߣR~_nuwE:>2 ty.OU(_0,YfzA^%BhtpDp [KEۼ)@~yFv*L4U''TSscklkhI$Sږ3|fϨ| z<:'2 lɿ@k Wftz5o 7p8lET]rKG 6~>uPyx+79 V #+N@w1NhPYko+O.ߕ]wrT;3vFL],9ˮp# P ;-zN[C-nņ_t Uj_e'</c@FC"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-javascript.png000066400000000000000000000030661237252063700314010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[oEv^{}K'1 %!REj+Th/Tx ~gxPQJU(S'i(;{㜣VSc"$'L(0 0C=`P$x$xtp$KsS 0v6Zv, 9 i;y`ZM3Oǂv0W X.D\A0MaA$9 +1@!h jA?VQ(PC@k76r]lb``@s4oRd2qmLNNbvvt}h4022¾BzŢ|KDB,IdRݝ@7a)e$B CҶyj@Sqi+lxaeeJcc@\?"q@0 X,,Bj2_ű%DsI),dB; "Hp%piŚUsxċ1Ir-pdlQ8& Su&,|1$KjmW) 3mbů#*OWϠCc?rikLYTWD]7VaBO 80B~!l@JS¹x V9C%R>D^ nVJ\.N~yds,: k) N(q# V K $/J)XWjH د!ۗa,Hr'lŒ &a"(ymc$J%i:&,3)-\.##W`ceD7%!d? :{mD ֩WWWi Rz(Go H `fs 7D̔TTBЀxqDH`[|hυ{wc{#">=@WoaHؠcr_|!P/)w0{LL2Z:x=a[/DZ699NWC} q=[uOo3D2mxqqKRlY)J'*sv409`}<۷X ЗUP:%0e X\rkkkX@*e]wofzzCKFܕ-wCuܘD[ܨqixZ.s[tfkSdqF .Àg"$Ȉ俪w,rF0zv?_H.]zr;t CBb|(w ϟ?xCw8tgΞ=.HjԒ(k$]%4x$ώ{QG U5IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-msword.png000066400000000000000000000030431237252063700305410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIo[U8C3IJ EZBbZXPʤl邲A@l/@ @tQqrR'q'8ߑoڴye8ѽ>~~ιׯRc.1`R& ]P4y=s'a#6\%t1:Um̭+\ߪ&@Ey/ u'Õ_w-n @1˭0VEEw O4|/ 1_+t{νroʀe59h[l_&x|AiL's^b gKcH"9d4c6&SJ/Js (@ ALA8 w@6\jgcuأ%xr_}W- L d; w7φp._&G VސtV6l»n7?nXdjd|qx::(k;s9+cw#@|Ws ;D==zT r8B갽 ^nX]]E Б= 8ǦpX8#S,a~~t%133׫/..M pC3mYHc9ɐxDBDZ0緶Z*")%ly6evW3, mhjjBkk+~7;;gIBctsssw҄qِ56ҙ U͗L&޽{$Y U1sV(8&W 477k#~q>GVVV $g:T guօ&6˜`)QYL'iCC{$iN1$xֹS(z{{ eg)97攗@< |1I92s:Ccb%C08hUgeW/H]ƬK@)}S{jY :鬯q捫f%@hr6|IS@pR:S8هOL`o%#QFIB_Z z/Ԃ??b%t+H} oZOc,'9^Jl{*y u؉@3TM/fcO8`BNAtr N lφgz;-^>%ko9Ug$x3NUh|27?߇L6|S?O~Uvcd' V5o=G.9WO h$212r;yQ^H ޿%Xh\7H$[<֣xFk;|F|QsN_L6yɆ9whaQIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-octet-stream.png000066400000000000000000000114451237252063700316420ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZݶS۷؈77·s't]s@N@%or}r7<ĝ$~_fFM3G.iRx XMN*J́mJ~& Ey}s`:ٽ?…Ȝ8\< õJ͛Q~M߽͛ ]g,>#m{^f:*u+41κrK"J+\먔JjBe^skh ^^ sP?|Hk@M pb^]GF WĦ#C" ƈ0RD4{ PQj,LOܺk(qGeQd'&sq\ \}*,`0TJsD }H$pgyBb7xqAɦ*!*$QIb@Ezp8\E(vt؂1 HD1 .t:zfҜt ˜;|{P쵐mخ͟5(ϝE|V" ձmZ-@HQ[NRFV3eYp #2'A@`_x)eSLLHߘiB|rrcb8ꄥůD0@2[MqsVeU"0yHBmC5&$cyD a;kwP'3UGukp"bQkZg}}}4 ӃBrlPzO f6^)D U}bkk[:(0&9wwr "`z\./U"B[yQ\ZZ ⵐSٌgɞAu.Jֿ:OߗQ @IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-pgp-keys.png000066400000000000000000000036351237252063700307740ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-pgp-signature.png000066400000000000000000000067061237252063700320240ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X #IDATxݘy8"KII2-ZUP2nȒ)cI*Z$4-;c .TsC̔QJz59\}|}?&lV9t3;qomn!_|]ML>c н=*v/knB.@ux-*GUejxxOc62YƏM$ԘzmYR/T k23/8bb@MU~siBvLP>tށޗݖIqwkzzz irEwN7 tcqEJB{^H`P_)aOZw\ԊY;x@G ё  Ɔ:1ۜ5@]^N^^((B2 ) Cج=thHteI]uuu^**jYM3j8IFRKRGؙ,tzxNݒe'-Hց wBv>y;AP_EHTK;fZZ7Mi"ΣZGjjũEjjj> 栭]@fbF opcc5+;$'$CC5=Mׯ]?COCe*N$+:\ڠ5=pߟ=(i.Grl|q@Hh3V@_ٕ@YahÄSORA>֡HJ~6V=/>(>;6U6@H`a_M0Gmb{tQՇZ:A\7N sp\Hm@ N8Ǝa0Ƿb)FvY8JTl3%^ w§! D?pƻ*{ rVJ cwEq0P?c<*f"1nXԒ ƧQAePzB$Bf.?9h7԰ԕ ~pzw3x6>k3Z 0aee]0qX[a.4و_p^6騺^WT~i>s:S7Jj!IQQ<[&ox.ːKn,P2WR+j1afRclnbPs@UF$vaY#?NSSV4Rsi,ż%H?HG"CCq۬S9HI lDp %DRoh+돟Sq;0pCCm4!OA 4szz٧%2»‹Dm:vr<ѝK,laܦѳ1[cMx|-TGd^^ʟ?KHyxw7:9BZW:Vb%9*N`|@p4afu8 Pf~]B[o`'bxGxGxz˿NBÒ yJmB;D~myh:j~yrRG*h8 1 ƚOZ(qpECujuj_5NlPӿػ!wWL`6^h@md9ckVdE) W8w;gb ]|y̽_3BW6_I(6LjcҳH21Q\qϹsҾ;|wX[ZnrihH\x4ѱkg !ZRg.;qDS*bt:r->!6y PĀ8a$Oxayy3W]= `|bkWW]]CHƍu7R{іZ4zI/xN9/[{1&Ęk[[Z^z+Ljd\x xL|>+6oLL!2 .y^چ L$LW@؆ՙ 2r%y>_|>fMmzQ0-`8E)OI __ *D _Zrmm}%WӧݧԜnBT?11 J+"4jD!P~_A6WwcZ:j082vfb6z]pw.Z.e.e g+.{]ss6Ϝvo}730!EsUO֦C}SƦZj$>-tvAO{p>fXX*cKӏ|s@4&f gYϒ] 0Z rҌ" +xvEBB`$/$ZGD?a]FM=(4G<:1>,a z#Ac1L1g22evSuJEi҆WO2j5Rn+r~,iMCtL..35"#XV3ZƆ jE#jژ_HR MqFLާ8[^̶W^a~ncW{yRuj}MGtذة*Sݨ'x&2ՂKH/D'H=s[mI zO4VڒHJG3'\#LeP^(±xzrjG1K=z\j%C,=|ɰ0i)]b?-X#"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-pkcs7-mime.png000066400000000000000000000036351237252063700312110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-pkcs7-signature.png000066400000000000000000000067061237252063700322650ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X #IDATxݘy8"KII2-ZUP2nȒ)cI*Z$4-;c .TsC̔QJz59\}|}?&lV9t3;qomn!_|]ML>c н=*v/knB.@ux-*GUejxxOc62YƏM$ԘzmYR/T k23/8bb@MU~siBvLP>tށޗݖIqwkzzz irEwN7 tcqEJB{^H`P_)aOZw\ԊY;x@G ё  Ɔ:1ۜ5@]^N^^((B2 ) Cج=thHteI]uuu^**jYM3j8IFRKRGؙ,tzxNݒe'-Hց wBv>y;AP_EHTK;fZZ7Mi"ΣZGjjũEjjj> 栭]@fbF opcc5+;$'$CC5=Mׯ]?COCe*N$+:\ڠ5=pߟ=(i.Grl|q@Hh3V@_ٕ@YahÄSORA>֡HJ~6V=/>(>;6U6@H`a_M0Gmb{tQՇZ:A\7N sp\Hm@ N8Ǝa0Ƿb)FvY8JTl3%^ w§! D?pƻ*{ rVJ cwEq0P?c<*f"1nXԒ ƧQAePzB$Bf.?9h7԰ԕ ~pzw3x6>k3Z 0aee]0qX[a.4و_p^6騺^WT~i>s:S7Jj!IQQ<[&ox.ːKn,P2WR+j1afRclnbPs@UF$vaY#?NSSV4Rsi,ż%H?HG"CCq۬S9HI lDp %DRoh+돟Sq;0pCCm4!OA 4szz٧%2»‹Dm:vr<ѝK,laܦѳ1[cMx|-TGd^^ʟ?KHyxw7:9BZW:Vb%9*N`|@p4afu8 Pf~]B[o`'bxGxGxz˿NBÒ yJmB;D~myh:j~yrRG*h8 1 ƚOZ(qpECujuj_5NlPӿػ!wWL`6^h@md9ckVdE) W8w;gb ]|y̽_3BW6_I(6LjcҳH21Q\qϹsҾ;|wX[ZnrihH\x4ѱkg !ZRg.;qDS*bt:r->!6y PĀ8a$Oxayy3W]= `|bkWW]]CHƍu7R{іZ4zI/xN9/[{1&Ęk[[Z^z+Ljd\x xL|>+6oLL!2 .y^چ L$LW@؆ՙ 2r%y>_|>fMmzQ0-`8E)OI __ *D _Zrmm}%WӧݧԜnBT?11 J+"4jD!P~_A6WwcZ:j082vfb6z]pw.Z.e.e g+.{]ss6Ϝvo}730!EsUO֦C}SƦZj$>-tvAO{p>fXX*cKӏ|s@4&f gYϒ] 0Z rҌ" +xvEBB`$/$ZGD?a]FM=(4G<:1>,a z#Ac1L1g22evSuJEi҆WO2j5Rn+r~,iMCtL..35"#XV3ZƆ jE#jژ_HR MqFLާ8[^̶W^a~ncW{yRuj}MGtذة*Sݨ'x&2ՂKH/D'H=s[mI zO4VڒHJG3'\#LeP^(±xzrjG1K=z\j%C,=|ɰ0i)]b?-X#"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-postscript.png000066400000000000000000000024201237252063700314360ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE b_`bacddeebdedeeefffgrv}}~__!!__""~~++,,--KKOO99@@ᨨ㨨蝝'tRNS $'(+/189::;<>?F67IDATxmjAsn̘I ѨWJ@to !D+.(Q!FD4AHH2{I%v~uOW7mPJ@چ8V1|XC <@s'b +)`!4Ɗo7$ !DM0Ԁ҂5BPxBϯD@͟Ի~Wdh,P #@Xvb٧ctRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-rss+xml.png000066400000000000000000000021601237252063700306300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxOh\U&$E4ik@].DӅX(7J[ BKEucD*6شD:q6:I23)"q| 8Ѕ83{=s{s$,6RS01WRJٚ[jl}3Q07釬Q^S1ܼ}*/ZO~W>}XXZ@qV=>هo=4<"A%p>Itc`@KObphMY< 0InkTބ   1y0BMF@XD6z0 0Q9@Q ":hQ[#E@Y/ h\%C D˚B]%uҙTOn2aa(1} l[-[u 7 YM`C5Yת^%@1 C,5bV.EnB~|mC56 Ȥ  [{l} z_Ν0:9Xug @Q8* ÍK:"%̕8~ = ,DlN"Uԥh,<{ACR$wtgͷRʀ&=m5AHg&{7i" ͝n9E=yjSx'z`hD;]'AϞ 2AH@-<8f@ _U/}AXz5 $kkQ^ԺmpUTbXhX>sZ7WVU&vQQh}@ۗgvZY"5#Z.=jsB*#0#^k}8<8DӖE Xɷc_Xn|t2Vl7j]čy.2'GD & -'pBvRL;n/ە^IIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-rtf.png000066400000000000000000000027431237252063700300270ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.ms-access.png000066400000000000000000000025611237252063700316760ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IPLTE xxx}}}ֳ'tRNS $'(+/189::;<>?F0PgIDATxmNSAtW(  BD !!F+}/ h/54* У3vW&̗u1bq*p :Ub" &bF(7,0 ZК@xgHT:D!U=W!#@):%;ş RYoo.u :0VF)}pRW$z%&2ue%nˈ|#;ǭ!BYha8' Qʀ:ql_ 2aEtgMLZn_"Z'w [{2 eWRqvDD}Bn<"T[oA7$&XB7y^Si=e-;NA37x?'=kx|¾ fV*=umJBՀKyy$P)|hƇ0lu)n} @0yC=h[FHۣ&˪qaf#IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.ms-excel.png000066400000000000000000000026031237252063700315320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKOdUy3Ûf4YeD3+WY111.0I\ ݻQL!m*Ts{o|S{: XZ j!2 5g'NJ&4qpM}7浆j!S.H\t5u }W" O߹X \mܸz6LMu)Oj>!vqKco7yJ~{K>ԥ[fZ(ћ 8S\qsS-3qaogMzV{PA@C5AL)mJ.Y``paY.X%4_Sx.+bdP/Hqhx@쐱i $sj[k3گM y`UbD0lR U[*M^ŗP Up{eƐ5uNctDW@5޹a ù0/TmTSfBdjмZ4Mm%áR*B?4,^$yEai~xx\ǽJ!/Tf b.&jBGGeGRyr}2Djq vkCHGR;Ԯ.\@CǀSRF1&ȼ?tww$@/%HAz߹̝ f[[ \v_j8\=~ +܉FՅR,kR TbT@4wfM p,@ew6O3cǐ3gTmD $&k7fgAeг7o|ڠLX\/o^ TvuX'[KKE8r&mvtTr-SU@O"Bc͌qR aQ: ..~xᰘ˹UVR+liQ@PmۤQؒUE]V:w{l T.ccdddRٗRgYfoC@-ᮭaa!6988!c8D"hg299UZH]&HlपAݑ$>[[[E~ @kƳ Plg,-, H gVEm_]0nX.#?J*@Ev)P9' ."܆4Q u?: cccf'sgs ,E?#x>޵f8`nӪ}ûe8IENDB`application-vnd.oasis.opendocument.chart.png000066400000000000000000000031251237252063700346530ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵKlTUyvfBiI)C[jR B `7(F6;,YXX F1!$KK-VJi>0;370Co<9}s8LI2f\=v ּyV-D"tM!=q(?,7Ϛ(TxZ P0h+rY.e{ӭ"su $E)/ x^8 oѾ9+NE!=q5؁z"yj@ 0d KuWYP  $s UOpud'xjs[%0qv_V7TŨC* 6/cq. Uf.~ HmR)"M1i_mmJgLp<$O N $/AQF@ɗrYLA42O~R!fzqWj-WpH1f"!R1Oun@;ւdS`$qYs%9MJo7`&zޗf"͸߉㡡ٯw8vд UվH= b@/uThG5TzcPIe @ /_=g۾ޫ$Pvyt sa;LrdEͧe.].c+**p\  vuu} d2/$p=ZZZlU*~rcU:0lUUΝAlޜ I8;|'0,iBE ODgIXL&R(ݵkGx* BvdDy"ów8uqlVB O^{V;w~(od)P­ܾ}]1N 2? 烨q͡|70"H.kX& 64@B{YIENDB`application-vnd.oasis.opendocument.database.png000066400000000000000000000025611237252063700353210ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IPLTE xxx}}}ֳ'tRNS $'(+/189::;<>?F0PgIDATxmNSAtW(  BD !!F+}/ h/54* У3vW&̗u1bq*p :Ub" &bF(7,0 ZК@xgHT:D!U=W!#@):%;ş RYoo.u :0VF)}pRW$z%&2ue%nˈ|#;ǭ!BYha8' Qʀ:ql_ 2aEtgMLZn_"Z'w [{2 eWRqvDD}Bn<"T[oA7$&XB7y^Si=e-;NA37x?'=kx|¾ fV*=umJBՀKyy$P)|hƇ0lu)n} @0yC=h[FHۣ&˪qaf#IENDB`application-vnd.oasis.opendocument.formula.png000066400000000000000000000031371237252063700352220ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe ĩ"q@ܠ pJzhPT*q8A R%mR֎ݸqx=-I}ge "=|xA.={fL3ng)^8/q} hB7 :*z%LYlb4lDnQVMmsc0VU b"22 ,f˂T"WA!WQ$rȥ: e&Q %`xK =d%TTb#OGj5 GJÎPnN`- 0I9bRVƠRYg˵A6; xn?.cO:q⮇‹>|4+O:985'I^k{5VZ*v;ORPJis)1Fz1՝8| SQsDT(@ݮU,?Šhyyyٚw,HnYkR8 bq-Y-jM-q>Zzk%N湗s.:W9M J+++TUk!Yk;O?uF&?PXv̍vߚo3?\w]mh\lp%RېT7sH Bِ^,r\DyQor2K @o>qDi *Tx*0N=z8:b4Y<VdpL!6F'>kB8749##*жe04^:YԼ^uyJ{P(HsH0>>")vo뀜{~wn]0I`/ >=ou}N5>.L#k(ȹZ^el!+W>5 ]a1 .H;\fŋx,zq'fp9sS5K=1 rC/ `ƺ4fXLQ#4 FR) w12h xlT2P5Ct(a1tMٙ u"!W UV&puL2KKCUSM&2u`w_oASiUpCz3ELtO~լ4!in)q6 õb^V5,}%̳,2LȺhimE,]`#nh`큡uԕ4"F/!t T*s(HX^^N2͖9W8zm8;i acc;/Xa}𲽘xdoXú'֘'0%%zF;3<8y@ uا/ HbkfhLLL<4s.<UE 5EY?0,fyFlLfyL *&$7`7}CIENDB`application-vnd.oasis.opendocument.image.png000066400000000000000000000024521237252063700346360ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<:PLTE 9-;( E/ I/I;#N2NG9PF2R3^<`>b@ bN/kDke[mf\oMofXrKtNuL wb@xL xo`xskyqfzrf|xozp{nwxyZ y_ c RæƞɟѺ'tRNS $'(+/189::;<>?F0P/IDATxm=kQsGb!uBtEh\ vZXK/kbgcK$DB%ffv ;L8 )Ef'2%)7HECnз)/"-PE0Kp\È YHų'` 9a=.nӼ+N]"d#0mih3{39PVJ&nBPCR/VS7%@WY~pT&b,a[bte&ԯ^-?$y,cwi^j'A F5s ۋ/\@1"yu/з "[AI5[= +-:(lֺ &H_A*8A)W Rm@@dsr`{] [HW!RBv)#026IENDB`application-vnd.oasis.opendocument.presentation-template.png000066400000000000000000000024131237252063700400750ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKoU=NGDDj〒böHHH"!ʢ ~Bac]~D TyTj7c^ 3M=pOwFs=}߽c#hS.@ D*4K?=ƾy}6ΐb$?Q|먐T9jQXl~ei}lp45%7 0L&Cς_GLj8d0yx\x\FWe^D@6"'ພ8*v8YS8Ry)H&@3  |WAQIB]ceeQضu!'4Y<,, \w@RyiB5CnG;LEh4[xOJp!*2|q"=o_H3Rt:L@qbQ<60!\ȍxO=BĵQV155L&Hq:{Z{ H#$,:;w(kmފHul0EaܾjctI&N76`̣;.=G~wBr^sV|`U(,`Z LO))~l--пK*q:;!lCY[{al>{w$7tdu[tWP|-dmkɻ@`v~(maW >`^ Zo_\dl]ITb D}X̉ p2NGG0 !=!7 W |&ʁt)8=_gLږ$ `}Ejwl۬9UՁV4i/^\MIVd`$8oq\G}^JG0qVsM*""dW"7HS.~Y^~ı6+r!<3yݰ'5/<یۊ0AD!A~㼓;aƠ+.@" ͢\.o~N?;yB7$*333?xDZe*H Q" E؟Sqc1ڌ-KT@X%F=‡vh耨W/۶uXW;b} #_Ko4 #fJE!,' u}zz5LMM3 ]l[J%,@сcu\\2Q#d[.1ZKȽ\\?!y" ۸(NXDEܡ2E~ͷ8:H̍ m z:;e|zB*C ȯ}GQd`rܠIАt<|?xa:3{{'#?*oN( &$+ӝ̛!p ʙN.3 ܻ9, <'ֆ$m{;KK0t`O7o(KnfĻw}e;\Вe4ZnƑ~VATH;tNŠѻwi΋PBn%{UG`:F99 ܁ :''09pd޹x@?-Zn+R" Z_K9b*%Xӧ#SS!`&K]Ua&\AnkG$ ǰo@4Qʙ3RkO8PINjf~~kr"QfLE"Y%$9s`gg-/sk$N'̌7b ̳8_vwwPٳžMτdMbETP~aaK:'  H$I/H)493@x7C+ޟ8Dͨ1M9U zWG _I E4Dϩg ha-bd "\N7[IENDB`application-vnd.oasis.opendocument.spreadsheet-template.png000066400000000000000000000023031237252063700376670ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE _װdݸef໡fgɽhh¨kпŒÌ‹Ǝ9(tRNS $'(+/189::;<>?FIDATxmKnAa{ǀ8A=^#p .#@ [XۉQ~ݣZjA⮨ E|U%lx'B@,\!4Q l/cyO?Bϼ੐0>K{_Բp?څSpHDXXy H@’Zk2#Sb">DZteEkIĥ:رg; IcCtشg鎝TDT1A(z3=2C 3ۀ]ݟ̡ ȴa974[puoY.fC7ꪜTy%eJ>rn 2#0)0yckq`UFQ%>)>8\l .oh٠??&֐Ơj|??3:`nPdᨈ_oy9 Ynh 9=T-uڑFq"Qe% )bIENDB`application-vnd.oasis.opendocument.spreadsheet.png000066400000000000000000000023321237252063700360600ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8?F0PIDATxe]O`sv[>At:xa2N4^_O !F@%mL9nv>5]:?M'$3pT: @= FDIWxbs*@7w:IBDN>E$0 ڠұw^dE80q^tjs%"_f [3 DM ͌$r\\wmk5yrow ?%l~@R8Ez៤li8A ]P%vX/2ޑA<4֬mxy9s5dYv:vEpK$u*a)oj* xis@a#dmUNcX%uQ*iPv8֞LAL;Fx8ZP\K40THՖQ˲pr1}FSBךTknSLI8`vf] 0u-$e.-mK{3e 06cfxasx ֒PQVy^U3ZJ{0JBWzɀm'@@qibĔ(󪭙U6--$ۀ˅]AoIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.rn-realmedia.png000066400000000000000000000027751237252063700323670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.stardivision.calc.png000066400000000000000000000025121237252063700334330ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE pppuuu꟟שּׂΰް龾`='tRNS $'(+/189::;<>?F0PjIDATxmMOPs 0Â(`ٻw`Ԙs1DIgD 23 N{ ]pŚ#{V'oӫF' mPR hJwpO$@ VLUguBb`LE;@Xjzл6EY$ lNxl,Fw¢얷T. &ϙg + * 0T{*dėI4rLpC@"Y`T!PFlX 9BqĪ# b`J(Gb2a6 L q؄Xs MmȅߒfD4kC]-9~q+2`aF:߻Zk6l7n@$XT]k{N=58 #:}iۣl"fBCN]֖_5d#}h" Z/d\O/j@ BZ}~Oډ? ij;~(pZ!$+p+oIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.stardivision.draw.png000066400000000000000000000030321237252063700334640ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.sun.xml.calc.png000066400000000000000000000025261237252063700323260ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<+PLTE ݰз龾ꌴ뗹똻z슲쐶쑷쒷쒸쓸킮햺z'tRNS $'(+/189::;<>?F0PjIDATxm=oPsnԉJ[:t mNJ UEX@ #(02 !DB+Mm'vQb,?yϹĄN$#@s(R7[Y A潠lu2hDA?q YEc\FbIS BU0aennhg̈>@WrCߠO`V@M$07ʌ 4W gK2%D 3Jthe}@TfFGL4\SSaM1]#Vf3(1q7RD%YV uG9e()*8p(J[0lU6tRye)T"'JȆ6 VQ'eX :_UQʷ7Q3p7]I_syAj/l5p]|Y[ vj֚oYFm#bCޯyՏ'[ E}2|susdC҆zލ  N] ~hBqQ4Bt%i{~-BDL>X]cwBIENDB`application-vnd.sun.xml.calc.template.png000066400000000000000000000025121237252063700340540ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<CPLTE _ݰзd깠effg齣h龤h¨kпŒÌ‹Ǝꌴ뗹똻z슲쐶쑷쒷쒸쓸킮햺'tRNS $'(+/189::;<>?F0PFIDATxmInAWf%7H >`8`'qd,X 9`{p*wuEI_@pVI!E8r pJ e`dxqh601抴A\H'8Y@U*;.1vhHbe58fm XnS {ѯ7[S#rV';lC#V0P+SV~}`o}Qr?꜄SV'b2=*^*7W-^z@Ek>eKMbWꡏ"Pu&mF&hP\Rjd Pp&wդ1t!|9ky4fgPvD\teF=3+% :_ ?\'sWfb<[fPn6$d ~&!r`ZOdwi@J X2T=Mz~%ȁE4oD^(NQ0!K"?ޅ IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-vnd.sun.xml.draw.png000066400000000000000000000030321237252063700323520ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`application-vnd.sun.xml.draw.template.png000066400000000000000000000030321237252063700341050ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-7z-compressed.png000066400000000000000000000034521237252063700322010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-ace.png000066400000000000000000000034521237252063700302270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-applix-spreadsheet.png000066400000000000000000000107501237252063700333000ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-arc.png000066400000000000000000000034521237252063700302440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-archive.png000066400000000000000000000023611237252063700311160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-arj.png000066400000000000000000000034521237252063700302530ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-awk.png000066400000000000000000000031611237252063700302560ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񯯰^_`abcd d e hghjklmnqr r!t#y,y*z,z-{.|1~45~3Ά@ΈDЊFЊGыGґSԕYՙ^כaםdןiעo؟hآmإs١lڥqڧuڬڭۭܩxܬ}ܰݭᵊḐ῞㻔㻕áĢȪɪɬɪ˯ͲԾӻӼѸӻԼս{'tRNS $'(+/189::;<>?F0PIDATxm_qbhrFȕ3rE!h+aDÄ\˙3h[M[|oc|7 |]k^}|Y AM`;$kox!lp Jah4fΓ0D<9pEԭSf(z {,ȧ*U*Vm@ZOHnPwTk =ai4Qr9EQZehͺ:l'>×; 'VH3 drn'`lAX=;  w %"/ȝ .eɬ 0PY'A/K*AWIo8y`[uĸ/i+wVCgΒAC><#ތR \t}:6boеC>R>t?!rWC5VI16c 6Ϡ<TC}pwEIwG1|A~Q87+C.E 8਷J'\bi4;$ӧ:d3@o@7 pbBk,fL*V(tqVJo ޖbgL ND'Dulb"i1KQY~yV\W%wnm>@zvqXԲC_ڵhB| ݨG ss4IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-bittorrent.png000066400000000000000000000026051237252063700316720ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWMoE}=3@A@p ā#B"倄DrO8!$H"x"ǎb{?磻y3&=UlwWU]{)4 Z#"&74ĕ(#_ZEhZL||xt[exs"i^(Nf5vKK/I$'A`!^p4tb%1q.@ #I]Th- Vs2a09[y_hn+!ow#d [ fG8D(Vi2nVB<kI(X Ҝ'М",!'ڣKhӰ!š$uD"lh8np (2$DF A v^]Ql(:l4ZpFI$(vPDFD%*^sLx-K ў}*@@JJCTb$UKZK @?A3e8vC["paUpGFU@_'1Rz{>- jSRs0t oE:b;?)hDT5}B^a4z3x|wK7DGn]4b /X?Ե~%WF kBUZkE :?H yq'< _DS'/qd!N|'PR Uȝ5Aso+å’$Wx>fSW 205Rp~9b:½{wCgLHJ)+[,XHK 8Ghts}IG>u(. hBJ֡OoCԑl1Tcz8x !m"CMpLuʳ!x S>Dac?Te)b>coo6[ܳބF <œ}l6'9s 5LNɄ __`:`gxw/wq<0*g?׮](dyrOc86 >;~$SnOߋI4vW{5ᆳ'g5|1_,~ gsPj<H7"zWaͧp8|7_(ԨЋ>mv`pm#8ytFS(XcR%8ɿ4y[""2 1$evƬNDn})IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-bzdvi.png000066400000000000000000000121351237252063700306130ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙itTU}N )I') "* n" 2 8WAP0 dJM}wj껮wٶdz'*I  #–aWsgG{a>m"B >|#a [v!7®SMa;l@ pCSK}˗{Wm-5"0}4%}mm [A{J<+^s誮8'A/AAt`CA ]@kt+ ^ AI? L̒' /)|E>ϻL͡ /L`'&qbҩ[}v3?îvj՚U?;ŠV@H?oDM ƍ2{u[\6=rc hOhP Dme7fbzԚo<&?zeyiK]톊tϓM 07nM c~ȟ8];vWG'~8q")Y..5卸fk:?8=c+VLFΏ*ƒw`M~[OztH.IޜrTo B ml(ZL(jYd$(\T0V50bA(\ܫ8 s7vqN. Anz{+y/y2 .®0cU*[红?\j$R$Q ]=*VC٢'߃&{QT?>~; o_ҿW.6k~Ww.ecK-Aw魡ڻԄ_=j}I!]vի/[SaW[]w"j׌O@?^? D6X'3Y@3y1 ǵ^ZIb "QD(( X/)K\=~ж*oX(d?{PRCm?z ojcK]}# @E8 t{ $mu8+62020)(;*ڠ3 &o\1q(u.2g5+κN(ܖ}ʀn/W./=% 5^7(K(н2.Xm%)ARs[@ɈƂ"g`3zz9f@CCcPK0Oíc >SQQ-QI"pGo2a@W\esb4Iq~G~m"Rus3'HAz#Fu]fcȫv: 'bV(@G5qkpr#T*C|xC`4"_d'{L-YoMkwyEf: p*E|!#P,Psv*ɿ?4 G6ʺ_v|nw|xg7M6E_Dq)ү3>^Z_}*= >1ǨλΘ֙+gAyAPϳ*oәū@1?s@,%&(\h utуj=8/΀;3󎀾)seg< ->`3JG~QC.x'hNl)=Yqt?7!uocp௾ ӄi dC)1N< 3' 2Lsū 5ʻq;΃IzycF]*U㾈Sǽ|1jF̷{!i|/D7/f;㑱.uo̷hTWʋ]1꺨3y>GЬxU5Ғ4L%)sxZjHM leDE58ǜl쎙qEDt߈O!G٨~.w4؃Poz "s\[%OS"%ln ż~3*sXt0L/+aֿ T@;@$W|! ҄9`MQh֚> Q&U1`jVk:!zњbrU .ljAQ\ Q,  o /A@HuAظN1d*bx'b1_eLd߂H7Ժ>^$S@Ѝ;3b+KebGC7X[Zv<zx05o)5 W)3.ٖs@vn9QݭdEmهζ?[b{9\nW\   [@DQpM`Q9 XijfR41ԂQAp;6̾En5[78$%&EɍmBLjjY`Yḙ8z.ۧP_)&jH.N;7_BpPh&fj* u3"^UknCs!0.n{o`!ȖLUץw׃mrzqvƔi5+׬ZrO_dӢFY UYzHR 7aFF{ $R4ٛ P+LmXժG^Wb  Wˑ_d:N?AFFy0Sͼ7Ks>?SɆ*)Q@%J_ңgI/\r˭o+HF%l2JFe)k"k1h^& XLJW uHB'u |#|}alqvMEWqyͬa2A#ތ{s&ۇ]>cwumoxnù ;[n9h%/VJ40nt|VKk5LJl+ZA%wW|e%B3F[]eޑrW[I>jJy3 6EEyERugNͿh+J/]KPJۼf%۱ {/s_?w\mmε΅΅c1٘ ח\~ c~kĤMEޚRsgʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-bzip.png000066400000000000000000000030111237252063700304320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-cd-image.png000066400000000000000000000027531237252063700311500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<hIDATxڵoG3{-N@KDQ_ZJ}C)-O:łn`lRVe 6޹kRE:@@e-.fe>x6Cy?'U)1F#r#ɩ O6OTPZM8~}2! "TbAv"%-U_9+> scWs 0S)Z۞E7 7>Ziwyh!bݝHzadMP(9yek§)UC6%)^=ajF7J0!ɑZ@ \@<@sm NǍ+@2Uڻf$F8Ή^B_E1?awlLH]Qr=6Y"jrvLl.YujQ_q1 +[䮝+g.L&pyR%GuDhl."x&Zs ڃr5S܅qn>HuӘd@LӮ"2&OX+bS>yNꉅ35i<ͤ~C`־'sQ=@ɦl;20NwQr&v H@Sȯc @.!M:zg?@ qFzd#&18(g6qd:y)zŗ,gj6ښ{SnlluE! MGϬ;Rč!ulq]$ fZWVVݻCz  E8.p"ժΝ; ~:'H1R[n} ,ɾ > { ?es_T>a~9∁k!O(P6FY^HܜeDRIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-cda.png000066400000000000000000000032301237252063700302200ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵ[l\G3s;*4Q_Z '4&ZWxEЧB} U7 ϷNn8''Na)lmHiLdD}B¶ B[\~w::?2):^rz:CBĶ1n@y'p}@`z̋s }~ B4Ci_4Qfƭ{YƊ4ҲiyK2,mT2C pf6M2"#G̪إ3MPhGn̥l1(oi D<VJg?EPA[ j鴳}H[F (q/8qSOdN$V6N j ֛HA]';+銫4QF8;eR $BYm~We')!!SG/:k4ArZOvB""jY<%dzf(4LW+tXDajfXr5[8|Oro(+$UJ :lg _W)̞n|oû୛k!~0 d> Q:Z&ֺO'\+-{p1:$3?%9 ]Ao8fZNZի/'lƧon?^}\K7=㌃Hq#'C9++.]-`Gk0{dP=hڏ[lNr~zA}>;/<ϳ~9)Y^^.E`Ո܄}\ǥ,oq==b _=&O?%7kkk+W| e=R1O5=h=R$[[[lll$uuܹs,,,RZZZ{T>=s:A~^__/...>_V5m0YvFŋnviJ!Af{`7))e_6L R Z8 > 7C 5!s>tfP?)IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-compress.png000066400000000000000000000030111237252063700313210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-compressed-tar.png000066400000000000000000000030341237252063700324230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[Eܝ}eѨ#!QI@b|D$$11Dd僘>B|#D ,,ٙ~W4‡=s9uު"[z*z>m4yQMFiVަMḰ/?ygOdW{[<Z& lF.̖skh>t(T0O < ڿkT!$к "t-锎RB6X&W+v Xy׽?M8 80K. ebp虨:-$<[Yts,6>!cD"T@OOo mXfG6 & px!%XUx_ZX Srƽ =:שl9obA(uH5Ds"<?EApL-h*@pԉ11U~H8.8.#.Z6#i;$w>\hMEhU B%3 ĵ5 @B. Ռc9gYo,}iK%ɛ:Bp\ (F}៑' !9Bp^L ".sLZ5K!T輣w: YxczXԞ_ E!x̓"C3DZ2пs#|9xo$A6c]Fǧ``ƒ`G-\<){ӟ,@XŮVxǂUqueUsWP[@QOiLނ,qDpq,@f)YhK3ܲbb^L! =;gPW'NԈ>.)|Haʮm&`xd6- Zs4EH47qQLx Ҍ$@Ҩ Ŀw pHq 3,_A8 NrONY޲ADߤ0)r35hrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-cue.png000066400000000000000000000120301237252063700302430ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XuIDATx͙ pTev H$KXDPA gDP #숢8"ʨ3A$lCCʹE5zU*u[i~gP_g{^oѪ *6X#{CTw<ڼ SM-WLɪK>`E?\~r#(~s;{<#X= a WwIC* |UխZrR %BMl tn鏳뿴"*F_ttqw|"~~C S%.N[g@ Z+fԯ9 cTHIuZ ƌѩ8%-Dznm1e84Mif._nٹ6 lZ} "|[=PpWp:m1}rA艈F_x+rc9ȟd6NMwҷ]{99 h` RAgirhcYy [eVwd+jݬw`JVz@HJVg/}\^h1gImLUgMx{{KͳJV!iV yU=gΜxjʀxWTXY( dP`s#Cls<FtĶ={n;5`tA"XΕ`t!bbmv6 *ƞo>DWӺ[u*s(kk5K7kw~z;*--)qh x^mh1N: [4!I lژcAt-(?J8}z&{;@֫㮎O~E!zW} PmBTߖͲ(O\*ȷRڈCBu>w`6$xǖ畟};"ႴO׃Oֿ+?X ̱".:<ѕ' ǶODHQkxf*VOCa%a?ĵ8!ͥ&*pʍL@ptI^0^1^S}8@qENJ05t~FǚYB03/엊?뾙SjBvn̊(9Y}{Tۧ잛u騿EAt dclK//9ǂ_{AkeK mG2*h@ 2,T]]mfk1 ys|u*f-99+Tw<@i-:Z:8jsw%NuOr8_X (@d.XF!ws-F2]A>6BP%oI88&.N*zl DEԻ1Lkڧy28={3T1fx!|)4eWY֫&g:JMH?~KlV2*5`vqLG#WܶG7_4iȰbP@D@Le_K4Pڈ*1g$x&m/ 5Yq=:j{e{gMdO^+p{7%ow+A֛aa`ZrM)x`e䄄]:ւgL*ϋ}`:L[͵? ^=_r;Hx9^>Ole|yn/?]^ EDohMh=Mpz\-_ kFa pda`~0Zsm3g{sIjgAŢT.59/l-1\YYӬ q==_>#͆‚j]L< ~IZ}n745mxf.u~{-aDeu}!e p*0yŬ]])>tXmtOUJZC/&Nx~GtX| Ì`)fל9Ws;+^TOP}o@Eٛ q$(FpA`ooҺ?p: !sKπYa_":GZK.Zqx|ܢz|ioyTsTW0%KIbzssR1[* meu6o mZ߇ӕOͷjCKmXU\/P>*p*lncZhCgn;???!nIgWB Dhj.,\zWц}>d]i_+-1[B~/LtAVLO#qHm+vqۡOo~v_HzIQ⼹[frus# !G.SKs`+d̗V}޹Uׅ;P sXPtlϱP}6wԕP1e;j!m?ju-N!uY)ϛ8kڮKS3cf}%Az|zR cgLqC8SjQ~B)W#=٦=4;1@>7?B/CFQulsMj6m*mFP!Y<*Tê]C -yϛ`dY'vOq>zG5 3/m_bYe}/}I\e%*+p+xCZZAH(XbJ*Ii+L Jjx40L~_}} C+W_Q# XDwY_#52[ԡuQK5>uϴ=lwIrKN;hѪ >!q!RvlJ4hpqqIÒ.}>>r_uKͱށYmc٨gc ܣpfV) <;,7*p(pȲgLkye{l٨fr-ZZJeT~| [ E r׮6ZǦ L;CSua ]#7A{ǷJY^j8Y T  F Z2DFpqm{jC檭S^ڷזOzmI݃vN6PoNnWP[_-6û܆ҝ=o6L nنq l< 7=#c"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-deb.png000066400000000000000000000030371237252063700302300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxWklTE>sna*B IDD1c"QGL#?R_jhLD?bL 5 "H HKҖ>g33ٲ ~{v͙sδDsftuuFP/Sh`F69mڴ݌8omk(1iG c9- , J)X)(5q\qέ;?yt6gy]=D29aB.{PLJ”,*\}P_Xp9(0k98" _E(׈߉i‚7_y]/\LPiiJh&5Pku^Wv.X-5z$NA ν,]Č<CHEo`#M22Ve847N5ww]pvj;fy̝ P9m q a[t2U5=+z=a55zq>͏O{;`FC =} 7F!oI7UQҹEs=>{X1xa,^%<~Tfm^!W@hAXy>|wwq68r';\Θ/ ذvI=|xcajXAD,R8|{pix ϵ8etѫ+wup>=NȪ́y^eEx^ kW-(WAbE[r>2Wq`~>@1.[L݂L_作p|FF&k$WFd]ڲ#δDD!#@:n٣W*?86ƭ(`MD䠀e?Cy0=W FkwP,i.:a$]r:D)EI"H%7g.˘ptR=X;i $ &9:Egdt_!TM=B pkCH+˪cBp-b m_Kt RIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-designer.png000066400000000000000000000025361237252063700313010ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sPLTE nnnpppz{z¾ƿ8'tRNS $'(+/189::;<>?F>B*IDATxmнkSa7M֠[A R$RPI.VpRJ'ŵ9ChBSHȹMnj.Ϗ+6D$tY 1C%yr[ahiy\( a2`b=<"\ڀ,uAW";^(1)ޏ&f_z o!WZ- CtA[w gUBq <ߝY,yuUD|8T0 H0qf=zx{27¡À7Sm]wqpD\" T H ٕ[ tTmQۦ??V m[1\>eV/gg\vG$8ۺYYrfr4w+DuNl~?({;M`sofl64mX][Zl >h b[A}Ui nS 6]7dWM;33on.N x?;}s*vS{fZ;yyiq(3aD%{qC e;{LX-|S-Nsr0Cw%M|o`Xϕ\ ϑGKO}8|ANk@<;:?48{nidXz(O!6`|![me\HD0!cLxRsV,,#^'N,R-""6!l hwmq1PD@"ffİmu|*/dDǢ>7YUnfBW01PE7Eb|{!aBǏժUWk9ukVr9tm(J^I:: Ux5Nᤷa+܆Ll 5 z8n<9v. &,TloˆU^$s# t̖-R,2y#ԃ/gDl|pXUMm:,wgOWQSPA +;U|~N,]HȰ A:``%xE^-qX4!Q6GYM<6 $n>iag"≈"r =w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-executable-script.png000066400000000000000000000033011237252063700331130ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<>IDATxڽWMLTW3 QbbL+"6 iu4M4j-E 6WMݔEaacEC#A-tCd`p&3`Zwa紴4JxYH_ؘ0yΝ;~)g$=k=tP\mkkkɓ'[,wܹ^yzp{{sssM؊)..;x`3VCCC+#Go߾x>/--)6BmrNNN2CZyfIcccWDtUyykCd?\؊^/<}UzI8Vi5JU'''=!gr@y&/Cpƍ?X VۭS-[0S=qDeW/$XXXM )pOy^ml6YWW) 5˚^u)}5ڵAt-0=H8++ ٟ ]6XVVMi ˉ ccc WGGG/,tDd<-HCzEfF0̙3fpeq@jar*k*~8y䧫_r䣔``(3è%Z{n.)dH%«݋?}- $@ t8&HEk8,6>>@KWa>@>uS ؠ8Đx#R/ι2,Yj/nȍ2 Z = Q oݺ5d><|"Q1{t}DoR  neb^AgiۚJllRTUXH8B[Pư`Jʜd b ϸ2U\ɳ~jt9::z.8!771"IA̍4Hj&&G Vuuux{)ƫ4-ajÒ;w|800jZ| m@x5&5(yUfDj>s Q}B-~-o~)=?X60Dmh[WV;pl!uJH6dR"x#NYnQQe &R pXQ$^+nPKKKF:[XIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-executable.png000066400000000000000000000022551237252063700316200ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<,IDATxڝU]hU>sofl64mX][Zl >h b[A}Ui nS 6]7dWM;33on.N x?;}s*vS{fZ;yyiq(3aD%{qC e;{LX-|S-Nsr0Cw%M|o`Xϕ\ ϑGKO}8|ANk@<;:?48{nidXz(O!6`|![me\HD0!cLxRsV,,#^'N,R-""6!l hwmq1PD@"ffİmu|*/dDǢ>7YUnfBW01PE7Eb|{!aBǏժUWk9ukVr9tm(J^I:: Ux5Nᤷa+܆Ll 5 z8n<9v. &,TloˆU^$s# t̖-R,2y#ԃ/gDl|pXUMm:,wgOWQSPA +;U|~N,]HȰ A:``%xE^-qX4!Q6GYM<6 $n>iag"≈"r ?F67IDATxmлkQs;3kV!A$ةu,bgoc#&" ;%3iԨ yϽfnyH)8{.uPhi+&t܉;CQBzf rh) @.@H Kh'dqP?@BIi[WbdqZJdG%`YK̚<X 8?{lr}kasE1%;u嫨fCYkZ h櫽U?_"m$ Ltk8~'SrxZHȦ(O?ΫCSnU|u/4(kk'l4Dnl'+E*1cח%e Ӹkg~\鍡hGa:Nz[r;vHNm;.|!m/6AR$v /]jo/,q7%(h{Gà A9$ k'3eHІʻ I(E dA0F96`IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-font-bdf.png000066400000000000000000000023261237252063700311750ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-font-otf.png000066400000000000000000000023541237252063700312330ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE AAAEEELLLPPPYYYZZZ```aaabbbcccdddeeejjjmmmnnnqqquuuwwwxxxyyyzzz{{{~~~S'tRNS $'(+/189::;<>?F67IDATU2(*"rP+J;1,L| /Xjg@023 gޮՐ }ШS1qO5UR%H`vav:j)I^Ii:~mRuxѫ<]*A=~"qtt-dw 2<7lt@gC.m|vAvǿA%ߝ^%_\h~vUjJp*5p}R)z_@/~|e+4*0UAInOUt@ժĞ  TU% C@ hTIx4ه1 DΒw1hU뭕}n}CE݅ywrzp3ζ}[ L?spӀ{MGO>|v Hb?}ZAۭ/zt |4@sb hM#4|thM`\m4vuvy=EIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-font-pcf.png000066400000000000000000000023261237252063700312120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-font-snf.png000066400000000000000000000023261237252063700312300ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-font-ttf.png000066400000000000000000000023541237252063700312400ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE AAAEEELLLPPPYYYZZZ```aaabbbcccdddeeejjjmmmnnnqqquuuwwwxxxyyyzzz{{{~~~S'tRNS $'(+/189::;<>?F67IDATU2(*"rP+J;1,L| /Xjg@023 gޮՐ }ШS1qO5UR%H`vav:j)I^Ii:~mRuxѫ<]*A=~"qtt-dw 2<7lt@gC.m|vAvǿA%ߝ^%_\h~vUjJp*5p}R)z_@/~|e+4*0UAInOUt@ժĞ  TU% C@ hTIx4ه1 DΒw1hU뭕}n}CE݅ywrzp3ζ}[ L?spӀ{MGO>|v Hb?}ZAۭ/zt |4@sb hM#4|thM`\m4vuvy=EIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-font-type1.png000066400000000000000000000024241237252063700315030ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE 999;;;<<?F67IDATxmлkQs;3kV!A$ةu,bgoc#&" ;%3iԨ yϽfnyH)8{.uPhi+&t܉;CQBzf rh) @.@H Kh'dqP?@BIi[WbdqZJdG%`YK̚<X 8?{lr}kasE1%;u嫨fCYkZ h櫽U?_"m$ Ltk8~'SrxZHȦ(O?ΫCSnU|u/4(kk'l4Dnl'+E*1cח%e Ӹkg~\鍡hGa:Nz[r;vHNm;.|!m/6AR$v /]jo/,q7%(h{Gà A9$ k'3eHІʻ I(E dA0F96`IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-gnumeric.png000066400000000000000000000107501237252063700313070ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSm"B >|#a [v!7®SMa;l@ pCSK}˗{Wm-5"0}4%}mm [A{J<+^s誮8'A/AAt`CA ]@kt+ ^ AI? L̒' /)|E>ϻL͡ /L`'&qbҩ[}v3?îvj՚U?;ŠV@H?oDM ƍ2{u[\6=rc hOhP Dme7fbzԚo<&?zeyiK]톊tϓM 07nM c~ȟ8];vWG'~8q")Y..5卸fk:?8=c+VLFΏ*ƒw`M~[OztH.IޜrTo B ml(ZL(jYd$(\T0V50bA(\ܫ8 s7vqN. Anz{+y/y2 .®0cU*[红?\j$R$Q ]=*VC٢'߃&{QT?>~; o_ҿW.6k~Ww.ecK-Aw魡ڻԄ_=j}I!]vի/[SaW[]w"j׌O@?^? D6X'3Y@3y1 ǵ^ZIb "QD(( X/)K\=~ж*oX(d?{PRCm?z ojcK]}# @E8 t{ $mu8+62020)(;*ڠ3 &o\1q(u.2g5+κN(ܖ}ʀn/W./=% 5^7(K(н2.Xm%)ARs[@ɈƂ"g`3zz9f@CCcPK0Oíc >SQQ-QI"pGo2a@W\esb4Iq~G~m"Rus3'HAz#Fu]fcȫv: 'bV(@G5qkpr#T*C|xC`4"_d'{L-YoMkwyEf: p*E|!#P,Psv*ɿ?4 G6ʺ_v|nw|xg7M6E_Dq)ү3>^Z_}*= >1ǨλΘ֙+gAyAPϳ*oәū@1?s@,%&(\h utуj=8/΀;3󎀾)seg< ->`3JG~QC.x'hNl)=Yqt?7!uocp௾ ӄi dC)1N< 3' 2Lsū 5ʻq;΃IzycF]*U㾈Sǽ|1jF̷{!i|/D7/f;㑱.uo̷hTWʋ]1꺨3y>GЬxU5Ғ4L%)sxZjHM leDE58ǜl쎙qEDt߈O!G٨~.w4؃Poz "s\[%OS"%ln ż~3*sXt0L/+aֿ T@;@$W|! ҄9`MQh֚> Q&U1`jVk:!zњbrU .ljAQ\ Q,  o /A@HuAظN1d*bx'b1_eLd߂H7Ժ>^$S@Ѝ;3b+KebGC7X[Zv<zx05o)5 W)3.ٖs@vn9QݭdEmهζ?[b{9\nW\   [@DQpM`Q9 XijfR41ԂQAp;6̾En5[78$%&EɍmBLjjY`Yḙ8z.ۧP_)&jH.N;7_BpPh&fj* u3"^UknCs!0.n{o`!ȖLUץw׃mrzqvƔi5+׬ZrO_dӢFY UYzHR 7aFF{ $R4ٛ P+LmXժG^Wb  Wˑ_d:N?AFFy0Sͼ7Ks>?SɆ*)Q@%J_ңgI/\r˭o+HF%l2JFe)k"k1h^& XLJW uHB'u |#|}alqvMEWqyͬa2A#ތ{s&ۇ]>cwumoxnù ;[n9h%/VJ40nt|VKk5LJl+ZA%wW|e%B3F[]eޑrW[I>jJy3 6EEyERugNͿh+J/]KPJۼf%۱ {/s_?w\mmε΅΅c1٘ ח\~ c~kĤMEޚRsg b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-gzpostscript.png000066400000000000000000000033701237252063700322510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<uIDATxڵWOTwsy<(", *Ʀ!тƤj[æ&hMiMh+kւ*4 <<ܞs¥35I~\}j(%`3,tX,8=i" Qu  zv_ɽy?'Kx{vR),..+`ʝv>`YPH TlZT!|YYP,VN|1 HZn#$~@9CTxu"\u&09`^.E(&bQBN`۩a\,Q4*p;8=x`~oofhn"4 xT!X?\8?ٜ[ QIC7^Jr8`em)Q! !x$H?F)[p8xlBR 'Nx}Ob͋H(JPÙ(aF~3u@f0f% Ek׋&@/dHj6ǢKaJJ IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-java-applet.png000066400000000000000000000033231237252063700317000ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PIDATxڵWKoUlόv켓6N!TD!*m)EFb #B)R%TRRWK&MbKJm8ɽ{|3q#)cS\pn??ɳ[d\>?m3u4¡9wugi0LsPpӣj `<;Yݼf'♻é' Po?61$W* 8RŹZz%~xVOA ?E ||$T148 GW36GoE8LzJEz-xB+]xmP©P,05sUlHv/fxs0Z@G}!tG:Tŀ; rL qIXgd %|-GdтV^qӇN@o7PV9 Okp膁M%$H~AYf~dtjAb[L&ܛpy0t$ê´HЇhЏ5`%و*>g 4hS>IcmW#R oDv@N#/WX`n"::kkãP\.qz/Z繱P%|IXE.7ds͛-=>r CQĻI$pK#>}7`uEtP"Q:g_E2+bkk Í kDda_eh8sB }O IʹLضͤ $hK+R[ЫXj6N ʚ Ԃ,-Qiy.keTt a!6p dittb@Jw, ViF Z}6 A,-GH01^\4QÅ|ۇ`0(~@&$ $̶-D@ƙcd2L˺9a*oٖU 1Ax.~JmcttPaYLU4#w3:1HBv7rq x+ 䀊x?`!C h/f`N"}( wW\̦5|ddD;%*q큍H2Kc4FI-^Úkoog.Hh{wn&ٰvuuP(p21(X__;UWYYR Ä~|ll1D@"b(:N2SSSi)insEpD˜h"Rw/+b8&''yD,5"< K}2;+%ֶY…4.Ц~pU ʭ&q s5H&'\tf Ԓ_6E7iC. 2IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-java-archive.png000066400000000000000000000030521237252063700320330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lUϜn[XhKi D( &(#I BFBjAQ o@/J/`YBms;gϙÌt0!s:FplЗ/<$s]\Ims_v\5ܗ˾*`hVRƹxS٩oذuΈ20Vb 0,7+r.5ԾJDx) 8IO #D - T cVWhe q;Ule/˞"1 Sb0ElSHC0؂mMȅD )' M3^Q~ aڕ$' b1I0¬V aƴI;:2 :QK[AJSi8uG? q |X!YC>S`{Z)OmKsܙS`\ڹ/s#w¶vF7_a6S`Ϩ;*|YDH a+Ric\\8k"<:H&>{$V<-zߗ\˲iUꀉru+*AbZ@%l0.}"$x^-F!e|IcytqvQԒ$ْ$$SE3I8 Kkt6͂ z)rXok@L@!n`AsH&wT@=F,iӧx 2*\I0B876w1>} T<*I uM@1kmOpev/LBfɊxO.SKs> 5u*$P>YPk3 2[5 D"!u$ĸTI1 >rjUe> AǦwƫ4b&}*l6rL/p8K>D@Uc#-Uq5+ KruՍME$8*|ZB.{ 4MV2ȥw.c|bd5rI(sUi0\e5LgAMu^Xf#ѳb%8 h\8vKّOOOKNi+`DXeaxxXd, F`-}0Q!&ϐкrֻ%%pCy'&{(IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-javascript.png000066400000000000000000000032671237252063700316510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<4IDATxڵW]L[ev?EÕWKL1;F/4ƟhLvX Å~dȘ2M6m&tP R -=Ү(ɓssysx@o6#! 5Cl j6 C0D0B(FxtD$H4 N-#O`Xi\k x3 ܇jλЪTBގ6( }}thS)7^YDBAlx+ & Fny]r% :"R099 rkM|/... C~6wa8B1猤Oi"2x$]Hr$FlaL $"I:7\9sǎ~0~9(E{QH@ϟ\EybOPNJy@OBW&%(}ywǣ᫱DJMא}ԍ̿sr9GSmM"Ѕ ?%ǃᤃ%kZQ׳@Vx\NA wY(T!wxp q~_ao m"ĕo.ݟ *$&% ́f]hiE(yAܺu!9ꉭ+a8=K"0< -8OJ~}}}0;1r"px?]PW0پszg'#b1FWWW}Ze 4_{2(fff#Z r|/Ih۷,'l$+@c9o7,Yuy_k|?~M@Y>3b',} &a2//\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-kgetlist.png000066400000000000000000000025741237252063700313310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIlUfǞfEJ %,ŤJ b\8 RTD/ZU 4%FRocیgi< vͼlٲ,@@dTv3H;1A `5)}[ν:cW$IPGA(9M/d.CįmUraw+d<N/(<׮+ <:%> QUr{[@(g7Љk/__Rb&Xΰ]#{wH`2f֐9JKZ Mtu0-tu4(Wb: ԙgmm~^ cuE z6i}x{9[ȒHX$sK'FDmN/𾦠D;M'"_mHN Z>L@&q!s|B dH;)ȻP_z^dsHA R0M,tSU!d@W'9$֗fR}} :]~P0a&P2=,Ip?on|ˤ{ Wx3NP!l"2x0L)OnXy>I.H؟eLTvF18>>^,Tv "(HKCq}~{06Õ.xV]Sx8SO߅tNXpR$d O>fFz9ЄKg?Fxn`qq@nqa]׹7"~vv藸8z[r Ԍi2r=sڇzӼ MMT.s0C42"l&''~'ٓǞ@ב܁^œx(_i Ս顡W$Ioѓg$> v<c|xh|DSSS<`ȵzR=ϯ} o `Bdsss###/&b}-Jrf'"`||`@,T534wspEC{@QND*cjhSιXE" `Bdqx^N'ۧOE}T²$2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-krita.png000066400000000000000000000027061237252063700306120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  y |!"&')2$;(R96S:7T;7W><[DAdMKkhlWTvca u|-- BךΜԣЩɬзɿ%Ӣ֨)ܵߢ྾!!⽽纺齽ﶶz'tRNS $'(+/189::;<>?F0PSIDATxmMhAߛ|y Q"DHRR)ED$GE QjE$-?^4_Mv7fH; aRR8nV]j [Xc! dc7E@*h 0 &:PMnB8Rq410 D$202t@Iu=u lr@D hBLqB@ZgH NvN-ud(`HًfxKj3t?kg#Kɡjt6^Niɟ G%zuXpLD~qr,a1? F[_U;9J|P؟:VΩݾRm0r~GZsM;6(JH>݃}7h0MQt̏XW,MMY3O|cIW[79) ߨv}vfZP?i~V+WLȕF-0`5ׇЬ{(_ڇgqSDIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-kvtml.png000066400000000000000000000016651237252063700306400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<2IDATXoG?onQG"%%Q*T$P$: Frr:8r9 D|ֳRvlNF|3߷O3A,`5 ϭB"x lH^ۈH؉CEUmvV1\p!"#)д'"jH@Sxz?ZLh'Yiu',pqNLw%G 8MbInvl5 b5T*@$^ Gp&jÈ7KpM0f//_P 0lJ_ONV\9Q] =}W7<|뷋_٩&0ySjx06 LĔP f|iڇ?@ _G=2xPy5U>d_ 68Z4Tl8(R J9LtO:Թ"T9t`FcL)#GCJ5v(1qY666X[[ZZpq&Z0XkJتCH6gΞVvff*df+t&=Bu/"w$I1VzRV_a=ha׌ғ0 /v DV\*Lj{}εoRIZT<!+0b-9(z& 7[]TIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-lha.png000066400000000000000000000034521237252063700302430ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-lzma-compressed-tar.png000066400000000000000000000023611237252063700333660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-lzop.png000066400000000000000000000030111237252063700304520ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-m4.png000066400000000000000000000024531237252063700300170ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE j['tRNS $'(+/189::;<>?F llIDATxm=OAvn' /+ cޘX'`Z; BLL,+Bz޺;337 LvO2dh'}1*m61DƠ-zN"0 "e\[# !Œ'  626h++r&1TD@5ߧ9c l0 LOoz1VNE ʕjǽmUv `_ |(a:wE2(0y9o9D1;M? 6[Z _-~ @gDĆ]{"N,hF/FP ֲߤӻ0Y{ *<G` XctzhVD`ݳ1Zk75첌?~D1dR2`GDrX@x`odH`0,1F:h_IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-marble.png000066400000000000000000000034731237252063700307440ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs^tIME 2ʫxIDATxڵW[o\W23g34--/)?(!">O'*** j(MI|̹ͷl+Pfoַ屇s;73E[֣uk8~u0(JxY|΍>37sҨF^!-?@F$\<:*4(K ܺ23|=đZ"1?p.s#YdtV`Ц9ǔR ::yvjb{kZyg_#sF>ɬhR7(E# 0,+"CxhXUi3ІMJ Utgei1Sy,3\&66g}U0| bJѕƩ?NXeL};E+$VѾm:M;b8rt03H7`?>k1:;'qYqG&N- ԏrCe3«@w?->|(AoiZaoo>y*JKᜎiƅOcܺ{oEZ_ifSa\)ϝ/րp9`%h',S%Vsb}c, (~}xwHzj3jtk/-XTي2ۡ0 |v8v`iO='Ծڀ+SkH#i2 ȲK@g2 a?Q(5,׳¸Y~7ԇã F@^J+ihnc*3xf+ [Na jIZkW}kw+pJ@! Y-vA"KlDb#1t93+WcpA$I0Ќ|hcpkx?AIWjǃw  Y2ҮvtRBbիB\ku:Iq؟a L^qY⥫u -E]Z`sˠ,`&9=tݐj1j`&D G4BVʬ@ ӧ$NKP y9d ˀ+:|X 7xb`^ qasW" :-i -NdR)RF{}V1ƏZEYdskrǎLkE٪B(o,W#팩}Uޯ4( iK0rXxjtL'S,*<}"y m7 `Z͐g*/ .JԬATC(A':@,QzVqU)A~`f  i B8׮'3%EQ" Y2~F7߼K)rb v3tbr4dRG'N@b?鏿[ogӴv/?켾;K +ĊIGIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-mimearchive.png000066400000000000000000000025771237252063700317770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[OcU(--V.R:*L)d$18Nݿ$dˋјh(a LePti-\keX;!}ioΠp-6jF?Qz%eAuMMM}5222 QSS^=Vwvv}J߀u:/kIItuuuU|rp+W$̫%=\*VM Z5) 2{ k(W$J'eΤNailthxa28mb#"B ߎ@{hS|烞+ܡJG5$1vFd*`aMFf7?b7Gww^|Wrpv/oXNn$pr9= L8 Վ&\cv,.a*cjV`N~D9vy`2Cvqzz*-F@ss s` |Mq(q-m#k?*J|*q4=2V&ĊHf]EjǴ]'''dچWF# l!DpZ:E6Ϫ&*(|N~l4d"x(kK1Ykl\<צ@):QR;)%&<`<&UBff^d2<*8ߖ9UD{: 6^dBň{K%y "U?|w? JDMp ]EXTפvUd2u_p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-ms-dos-executable.png000066400000000000000000000034771237252063700330270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڽW[LW] rQ40[Q.j,MLmSkڠ1B,1Р!M+}H<Tj@E~_a]}ZVVࠠ Yȉ'9r*AѣGvҒW^d|R:::zoݺu~|| SAyyyi`g~3g^ ^gn߾0 xřB:ccct:\JJJ4١={) Ru΍7ZEnA@|Gd6677O .8BƱ$--BZT/զԡ!m.22RygG`0 իWAӃ58>-˗/' x?33#r޽d,aaa?ԔhZC!!! m>44Ty5559bp\9Ñn/^ 0{@ɽ_Zvm$(%da !jdՑ/hRR {4|rwqq u1=a:ŋA{ccc@ 3,K*Uԓ= `Hi)Z~oKKKOˆeXe bTpx)m z`$AytAn Ufxݺk~qe W@z8*:Δw|Ϋ1?ϑr'tHwxt;Ζ$;+[,f{J7Jzzթ 6LMfW]& '1YԴV'y ---K zAay+7(nd _<ˈ{z,P5q9Ώ~,A4a@Җː![U^:Lឌ܆YF 7w:?jS<[r`//v'8mȒ:'L&Y^R8$ yGpVbav^Sm䂐f|&cGwE"$GyJHkBI"333_&z$uME'.̓42@Fl{\l߸pJ*`%30*&oM(p% Qc 6.K&nܺv¸pE\*+BhPKj1-t3};=m[nHgνϽ4 8xYט2q}gWų[[ɭVmF99sM?n>P[ bW`WvW9-n|<Q8'Nh@ѯ#^#Z" SEN m{n T<+r 5fZ\Z8lͤellly@X*c ;A[- 600q9cc4^ <^ 73gзo3Ȉ)[048J%2^pLY]>@&ZT[ %ӵ5%ðer#3Wz8/H U(;o#?='0-UN7%𢧧GeX,Z hoG>KMma:uo!r8|>E0.Hf (EV+ Q`6j4hzco.1'O}eqvBh5/0niqu K?"5%hD&T:* ɴ.H9ù>8Zb{R`Z۶@2Rp)_yggS /bҰdݲxaԥz\0qeaEXlEd2DAբ4Cxc%F ʾ'>( ttt3NЖs%n o/!u0H 300Nt&x,UOpvT*EZX^ghTx__2;nHT*;4^`TEfZC{Ŀگ!B}NMM5!!~<񺺺 Q"```j!d7m$"(WL?>8r(A.luѶ nώ@;1芁۷n1C} 2@Vxo獙L&J6eYE >y1Gܐञer>Yc8}>뤣Jlyf/ GA?x}ҮZkzz)qx3].7Ok*8.^s1Y`ֺxl/+++i,{ٳg0'k{20;;ˬXםL4d<' >388NG5C[N`:5]&( *KEO.B4_4ऐbM 'jitk5oH$ur<2("P!dU f,[_޿t+V$ Moq<-;VL FlC#96>Z4+$\A$o$]s $T9Y,ɇ&7eL$ cH "N$ fuǩt!.̓Y8tFT~R>F]*Ӹm:tGGaqIsss p2(eq?Вe 1zLK T(a. yWl!e\毞>-,4[[_]PyRǛ#܏~8pf;6K#%;P~mXs"WjDc8K5u|ɑ ]zHOktQUI9:.ģ$5 /' xk1&./ ǒJzGhaG]c f$JQ!qPht_Ld`(*dN[涺}Nf _͑$")^"DK{IMyrR(rИ߶o=vuLivSFWjW$)q-0w MFrUXwN:i6 T*nPTJ\AvAnjA,ɲP WtDT#hO}GX':\Ok{hw*yոs"C-t(2_q3:Aw  զ -xۈ5kft6.h%89mv=QYM)O) ĐrU{5qIp-rth}޹~2Ȇ5b6V1BσYޜ>Y$a<:YϥOrW`44oqt򍬐v\K䂝 nR45Nt6dj%xir\#YFT%4J}J+c)VZ0{\cx1 09 lf+@Ym9-; X}Dn ?p܅XY`{|oĂ2r[C= p;鸣]os0Cj0!U8}u  jnԎ OH/ $9/@ƳFc-qkRa>;?5ŽV9>r;s\Pj"mE;9A^5 o[v +{4p$K.ek<ۭBL)=\BS e%+ch %`k\^_^-YU?51!YI3OY@ŝVuސ2i`|&씍.C/n dNiyL=z<,`!/hƀ̓we p;o- =aSovgCZfʋ겺RmT wd5o|$S+S@>Jm`-锁X`4Ӂ xt~ odsTjn0/Bnx>*N(7hYNxL 0X @ P2PmA3OYHWH{ _YI߫8k5i]`IvN[ԢAeXSDsbUicMB})`+2 p3O2RN6TӠz"OZH5#wcQՠC!BZ 2OWɛ _-1'i$?{-z1 lT0/lw*|^^_*Cb7WWW-epux40bE%$~M [aW¡5/Ν/n:֟ }B8>ѐ0ʔsASMKUb?5>hVsüd^7 xy3JJ$=]#fvR2 ( MA2\ݨOm`)> *r2k8T n8G-^<ɷ Ǭ5E% ra!GYE} FL>O0_=-WǸFHOȃǯ\ )CFO}V g$QRS~}F8 xP)Vj0v)AEoB6{{YĭR!uQ ;vG[ֲ#w8woAU'W\=;yylpdpTp;;u!/Khc/_a38cqf+2;7;C[؁]ѡ3;B}<*/yG5<f;3Y9191`W3J/]R977a*[fmk̼s~/}f"g̊+dsa{}M>lAJ S]NrOCgrArH$U M ID⌍o1f@ ɜ_>}P63 JrEA.:s;QE*,h]ƢoR^ZrCƽ5nָ6`^eSwݲX 6*^A/Y`ͷ w׃wa86^ Tҙ=ܱ uE"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-object.png000066400000000000000000000114451237252063700307460ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZ b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-pem-key.png000066400000000000000000000036351237252063700310510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-perl.png000066400000000000000000000032221237252063700304340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoTUs93s˔NoR,J "(`c|??D /UӖr)- mgڹ3=ǽLw2t$JV>gﳾo}{}񸮋62+M0ǭ\6ܧcu`I\:~@Y^Yn[0£_fU|>a<@lƲkbTde^/f(UjDc1zi>߶̿i@< 3֞Jm7 Cg9=N4&2Pl<@LdZJmm]]rL"'T#H$O4=(0XKuFa> )v3E\˥,H\WKvͦ9we*`S\dj4Mȭh۶M~~٫(8+ ѻk6bQ@@ZZ|10`PL7%8n7I& تZr1"&49 cC*~{o t>DAhFT\PAZöʨLv f(Fa)`;!LuN0 ;LGjHi̝eY 9VsYS]dg<`;u g$++Qf#A)k5*wyU6y ^AeX` yYY.9,#3 'K$UidQDU /Q(Ufwos7D#AJ1>~#'lP]|+J ")@)R@P6k2Sw)V-NN߲^ff(iAfbJX`r'hBξƶ-^, Co@^?6Uaf:Kn.G.p&ƯI7W; +%uE@ p-A>9mmz@ |\ڡ?DDjH[2wdj[W@I^J!3J(dQ:%OLɖ\pѻ^a-~9~TWS!*`cXt!Xgߖ_ <(R͏#q Ɉ =t:#}k\LWX\` <4*6dn^a`װGKHuݹs0 [CRZ^ (eqҖ~]BNΎ sـݩӧO dULk;tvW? $䒱|?E%ógd2O4d$gBYzʈr" 昞Ν?0+ &-n2-hDEŋ(ո-e[\\ ]yϞ={FM7ښcccm\ m-5ƶifx;@yEܝfTmq ^XfO* *z>i?`[th8a7IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-php.png000066400000000000000000000034251237252063700302660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWilTUf{3әδ{-K R@ق R, hܐDYpCM, iefZ>Ng:73K Ϩ9ᄍ~Y9L&Et$G,QU C }HTu7Tbe^2R)L& ^EYdW 6/z=Ӗf"hD2D~^B0V+~X<C͆4yf# !77yo,A)ݤe7"''' ,tg`T Me P$X$=HYG^{צNʮN@ǪF)D"q X4.Ͱ Ph ʱ0(v(FtubAd2Dco` )őWhBsCxG#"q#J(-wBov)U6━j?Z\cn6(2*<Oc=s8M}Qt2 a%eD45a+}鬒@h8ǐ/GVFOOz=3&Osg@e/]ƸD ߠiDEy%^ LN[~/a%l۵ rBlߺW;/nƎW/Ag+=m z{fmIx5J0z:0YGl_9n鳿@{^:-F}ttqՌu oM?`Gcښ}r PBo0|!{ByDHRϢfCwO;[QHDŸY0 ˹9G4"{A^)RW{\T^$Lp@Ņ gOJ`9t5ݴuKv"%vcv~!7&Vż+,AqX I[6K!BLm'hi=J,^@lpkd,mБ[ JFz0MS)~TW E:Q"@`؋X)6}ohYS lH0Is ߜ:jB)$R}m;v = DbmhllW_A]ԆUّc bXJ?zQ;^*@xn*F=8u bg?ؐxze9U0`T=l\+W.M"0r|r[]hX&(Ƹ-YՅ^3Z[mmm^J?f͈AʤT~R swwQE \iӲ.Y94 ۰ah]\)r<0{JQfn~c(L"Pp802;}Y;-˗?*ͣ4_H$&NS '(krN:HHvSv"]DN~OBUHd >6_ϹF썇IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-plasma.png000066400000000000000000000117141237252063700307540ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X)IDATx͙ pTU}f& $B"8e4N#ACM)( Ű( 8Ą%aIط N~j*/53T}U}~?A-<ܯ~0kVhSeKj2detHh2B 1L/J# #!Q| 3J 2CDޤ@DN򆈼D@@DEˠ"!"݇j<"$Q1KbyMަ|~Ee^W 9㧿S=\r磝t/M٧yA-M4, X=hbWXޕNҝNoFH[f\pc*] IR/IvOY//~6" l}sup7+|qiu"NeRgKXZ +`W X$= ztL3D{ GW7 yROu@EzD|S9lǢ%w (`N N%o~yum Up+fs},켫ߡs $߷ %.lB+1>gZ۰_;&_dB;#u{ckK!fb:`1̶k=+$A؞u^O]]/#hG]]_Y+;Ŵ7ŠQb:喝"fSv"uiFo\yͶD[> xl8.{/~Rƭ ,jHoeb3!iֆE  jDA!˔̺]nRjڄI֒[8hnfDԐR rKPZ~^Q={F"SfՌv? ~5;"q">>=.O<}2Μ2q}d=FybחB$?v \p=HwcՌj$"`8V^9b:ډTF,r]Z(c} ~jL iw\rI`4[tq?6):8?a[%eUhv] f C -zM\k<^zrCw^,7Uqӭ)q?&EA֙SDdXڅ|A;vru"]mkpg_+0}ƚLU/^_NxmH~J~wJS2+~=B\KAWIט/t¡Ֆ_GMY-w1Qڢt >/#)fKMq?UԂ}M F?;>~fk4rHiLX=« ||Lo"b/l3*w|( ?ڪOA>܋4oq_u'Oep@@mxԓ ǵ6vu*zPrX.a] {p8?K i3FٕFΦ׵F .U6#}nihߠWŦ>9^/a)θ|M ]5`j]Bցo+"ggt0fܿb)'2H1чӧ`gP.W+d,k'l0K@!F!4f"RE q9wvD93OEG[3MGG/JM^۸ZAGMcԟe#~ o?uȞv{dgD{!S"DF|(˨v+S~R-"Uv iZ(Jr }%>w_C)SP-EMϻWh䏻sawn pm_(⾁na)`ޗ"V`&s_(DJFbuCyi< !oy oDYz"»`j ILz$8NmקXM9[c䝸ȬK,N]C1|&Z8J vaH~ &e\ѮCGR5͝6֪Տh-vi4~~~TY[צ.`yr6D M sO31eBi/@za*`(!uC{?;-n>s vSkGE `2ֵK<|/z-tDg;fT$Ǻ?uw2]>'JrѦM\߆f{kk,PM:9:^ٝ x򆈵xT! ȸ^}"m9W(J RnyHQ^U^p=LAqloQ]~} 4jh'|S \MYytZK/_ͫʳ5z4'*':'6jQsS)1&\+4?<-slK#y֩8Νhg4ϖ} B' qers5V)SrEι|6v*To{()K~Oq'Ź=|lҵQ%s5L,6; ߙblbbGlDttss$P.B`R tu:TN^ILUCaZq^+[4Zs7.r~'mK.<_w+EC XiBLP%;oDFQǨ]>w8MGB`4vH6즞Q[;]>>CQ@ _"Knn__F{zڥfv}6Kz(PqE3Wd.Ͼx,8Xcl3SZioPWg 588pv; y"PH&VwFH*BUM{U_U-MHXfZfX89|.3ygQgpvµ{'t{zBO Dt4Ǿ~&[/7p%_9ǔpW+y!!T}K{Q5^B}!\±JN5e[xo3Rdraqۛ<6O8yd0Oyw!2$][n~+:`1׍q#Z x6C>&b`!;GBxqyZQ#N_z{[6s~bn@npnG76lh}/m?N<ƴBџk/g rM'55:e֛a}"5k׌Ѭ"  ]Qw *Mh"*DBvX!i"f" %sBlL;/W۶vv^ZaզUL˝@og! lS_Yܘ%DR o^!yWd 3? C') ~M$"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-python-bytecode.png000066400000000000000000000114451237252063700326150ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZ@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-rpm.png000066400000000000000000000030671237252063700302770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lUΜn[b)ZlU|@DH$%45B">hbPmPPnQFMBJt\ϙ vh*2! p(p!(#×(]3UMٖW}t$l,q,v"4 Plvz'>qE;u<ՕdA6ڦ][Y2x|6_u[b(roYcCFuzdL8v>^ LA#)ʉ SOWghP@rH2lہx!R1qP(,]U|oZfru17{1s kѼ\D<k$VﻅR5MG\T ?" +Kȍi |Qgbr 6&q3 3y苦?fSHP fD  㚚,@SLmcf)/=ut0{o򦅙Y ã&{°cIS0=[/ |u,5% 7Ef k/=%ƱdM(IVXY >pXu*l:$M]GP@ `L̠r"E| =a]Š Y"eDM[ Tt,[4C#6X2O*Q,ۊΝGuH.C7I$"pfl vP_lіe6ᅕKBt?NdY|(t啋Ey2K.C:Mv\ih_ӆIi3g7t]/#eb\܈D33Al`?zu]6:2*m)8 *'+h6<ʦ"S h<~iwׄƼk% H%GDE1I LnCL.&JB\mt_wNxYbq "(N[.l`YT>R\LxȽ ,& PN1z0 $X O(:G"%#vWpVCfqC AbA98dL&!קyA|x 0j-Gx D>EytIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-ruby.png000066400000000000000000000032621237252063700304570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org</IDATxڵKlW~ǞW'f E@ JtB*HD.j) $*!eE!PgA$13wΗL<3̱swZsh 4tMK؅s< מѠH <~r= Î"! }{qrv? #(ƒ H ǒOtElggfU: "zȏ靍;I H!ccc?`tt*ri=WBJz}H%tK.Y^^&,]eownZ8F nhj4 0c Fq<@\?33c=@$FCZb_d]dq|6*u ^|/ #XrTɷOZm-jwi`۪p_Nvb"ՆynJj06en]\$\\8حq?q'Ȅ5y#O( ɡ6w{@v4yƍ?ˆ$qʄXJ\&吮 zכd <63FyyVPg9Y*xؐ%&C m~!Gs8 :BaS ʽ |"{us<6) 8G'~) # Ƿ-4^2DF4lw``+6DkdV굗)}uf&7K&V$9B#IpjLg_tJDbNm }x! YI$$v"q@DHBW,JNX'u6|bF*y%Ye0ȳVBDJAmD06IccQ {ShxH5FzgbX%4u#]{n̙erD{>29Z,P|ѳ%K4;adsk@t:ߧy.ĵ8v_0X/Rhm3ޯVVa>Qn߾yҥ瀲z[LV jffT.lpid7uW e`} mR.陞.۝!"0X,tZ+jaaaʕ+_nVPkRf~hm5677nF^1w^zls8gΜM=Zv8mlmmز_|ZPgi8^z=msfgg 27N4Ly昕0NJi !!p|W@Lg+=Cчlb_*@d>csPpIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-sharedlib.png000066400000000000000000000114451237252063700314350ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZZO4R& ɢڐ a{Ff3J{{~~CN!S? ҀSBi??C)@9L%*?N@YVasX !E9#1K"5bvc (xUJRP{Bq"@WǏ199\EdrFn}d{‚fvR|jj Lpxx8L1uy\#c|k/~ p}4&zZ6Ȁ+WK899JB$ w9 Q86ӹc`qm[rW *h4p̾7oc>˨=qnPf#Q> h<(sدSgRW˗~9\'D㽽=0~@;ݝ5?.Bxe_C? ^w]_ؑ@dg]@ +OO6 FqgW@mǯ ߗwS{aTĄ|lszȃA ~B7j? P0wapZa||VJemnn-4x#.ȍr[r~{/k fff/T8(}BZ .-*Iۿ]`&¢QȧEWҮXdYسlPB𽈯h:T$)GInC/J;VP1٩T*/D| Ni aGXnK.&L?<3 IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-shockwave-flash.png000066400000000000000000000027751237252063700325730ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-siag.png000066400000000000000000000107501237252063700304210ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-tarz.png000066400000000000000000000034521237252063700304570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-tgif.png000066400000000000000000000025171237252063700304310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoEǿÎc;8v'o F E IR!P)\ʿ7np+AP )@HB4Mm8u굳kv6YkD꓾z3~޼7?6eY7Idrj&1MI}B.NJ< lH:Tp ؾwou;"HӶܑ($ n@7j#Y pý l4ؖHFyjaT+y=3 /˼q^<~}Ýw]Lm 5TUa304k ;{EA $!53muy b |`p4V̾w-?$)8nؾU$AK!Sŝ_^6Vk(K{k-!Rm- T:c1ʈri_(ݰmyH JVt]g W J$S!8{،cF_ZwrS]5Ryj?lArK `Dk%t=}NL؋ %2@X G˸t'pn;HБQ![D7ÕBzh;s%x>& fnZT=^p/L5'-|_.׫w'C8J_ZuRn `BMY&ƭk%}|ϟM#oMp wmؑ2 7ߑgc(~b2=xL-7~/Uq\]E؁{8 &3`;~ݖzhl4svXXX:+LloUU H B|E",MMM ǾeF+oy ^{?`XiXhj\4 l? CI-89ՎSڝg6s,7QTX L:ER"qo3ܞX ڢ Niߜycgg o~ f,g9\&C%`Ҿ499*oCGYH ٻn-//_%iK>pS\?3H$C>Y%xeIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-trash.png000066400000000000000000000032641237252063700306210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<1IDATxڭWklTEnmKKxqQSi 4(1@SLԘQ!#"򐠩6AK)hv˾ ۭp._gf2wΜs^0 ( #ɚqN1'3!ެ{ 16f-,~ml. w}4K 0 AVZ$8%$4JsI.CoG hsG,!ITLI؏,XT%x"吞+9^3R`6%`{y9Q阇4!F`S<^D60]3_AEb\noX>4 X WwU#~o$$9XbkZ\x~NT3Nt%TaQV ^t KIE&cisWh~|ux~S&a7P?bFb#I# 1Jad26 a-C-n1.`")Bf)ȕb`_ kyN1ҝB0Bj-8/RNBR Ŧw7w̚]p/!dya+Q{Zf2b8ObuMCeNXF LJՠ>Y':ӹJ EvGȷR40B]?V5(s?~F9KȱH2g4Z@wϕTg !w%}uB$"z ǺjqxC_/{A4S RkI; ΅{t[[8i6 hKtLQYbF{kD)_bŒ@(/B{OƊHFKbx?'/_S4Cwc`xlB<~/.8J<"X ETD:Eb0bCE린)("n6^^i6NI2PCF:uS'cp؃ˮoWPV<"k$J]$\qtBA\r5Wo[vH" M M7=W"omQw<-UXl yדk9fܯYm Gط*ݾ<xf_GOnx<=sm3L)t-~ IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-troff-man.png000066400000000000000000000022161237252063700313650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org< IDATxڵWMkF=Hm^^RPmV!t -$RJVǦPڟMdh.J_ea*  ιgxd( Q,Ϙ5HLD;~N,#96?IM&pǶY)ҵVi1("X?GQiQʜjR}p%0,CRh0djQXxq` PPm5ڠ<` 4 1  " z@]h"d_t^I$`dB%+x>Vx' K*dUSڊ 8B>Hha hǞ(`)"X"Pل.Q@ Cw -7B` lL¹eD zbLhs ,yxԌ@i1H d*7z ;'BSibR.!Qbh4nN8C\vn瀐d6QpKzP>?)azfc{{xa ],s>( |" NȒWx>c4o6xxxȫxH))JHW&3~NGd+B=yY{u||| ]ل3a$,2L!ߜ.$5; dk& A2 ! }QJ)熀*oLp_{xA{qY҄?uhyqIw+ּ9Z>e?3+Yzzz_ *Q\^^KT7v{#xIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-tzo.png000066400000000000000000000034521237252063700303130ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-wmf.png000066400000000000000000000020511237252063700302620ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-zerosize.png000066400000000000000000000013641237252063700313510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<qIDATxڵAo1zCО{(!Nmo (BFTv3V&kE"dɌ1e@z+g4ߤ?݃Z>EYal?<o$a #(EYaNJ9wk--=DI cE4־ Dv{j{ouR[Pʲ>1#AYZ\.nj0Nǽ^? w,O}aX``>c4T+07)ЪnFfikLS#b8~? >6>3 sOh 8q۽㩝׍\)?"};ΧL&/`_R#x{ysKxLkfIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-x-zoo.png000066400000000000000000000034521237252063700303060ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-xhtml+xml.png000066400000000000000000000026651237252063700311670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<2IDATxڵoe9lwm#RP%FJ4"^(M^y\z?`4zxgT6RGj[3;ϯN44Ml{;;]]A _j׀Z1B*H/#+J^%B .FGC4+@7Pñl% SUC(+<Q~=&(bD̥V$sN Y$q~1Cͷ@P`pb{E M:Yc'%Q "G!%_z,3ZuIk%lWxIt];'~D|zǛ%wl3y*/mh斘)V5%E//Y=h: ʷsܓ'UIᦆ,K+L_x۟8 'џտ&f)v~,V.ZU.B7ks'|j]%N@h]F,M N[‘/*P@R.0ٹ#JW8G+_A/I MRoE[0xL&er1rBa _BhR))"/j_zO7T0-d*cEee~v&/@8L73ynu ye٢eu)Kᬦ0\ݣ,yGɼւ"PYҝm}A͍9~.VRRpbL >CSen]r|l*Wn8nG+P{ juf[xSs;f Tg=\G` iqg>g_* ꃪ#'s@C(i7,yLoFZS-7+ʱZWyL<B<2kV>2@lBiYy79™へ G6ǥ4s!||!jk2xf uV}4DBR4m'B Ds8@,[e"B ٚK3Ty277,\.NS/@<5{wʃMbjj62OH`lԂD0@B r1M3{WBƆ!%> [qi|gg{KKK M۶Wq~M|9OFrN: +_@A%  iX 8}E`B$.0aƫlf'O 4'GJIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-xml.png000066400000000000000000000021661237252063700300330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵVMlD}{IDZ*B@" !Ís{ʱ-QAphZHYIXdƛ5ifǣ}kG))TQ6nz?oט+AQ g}nNJ Yp]RE3mm@Ïa'bBhsŝG^>fGcM#}l&#nžnINT${4` H3My%`q)eP|qg%wvs-b-L̼l]a{30 rі4 8^g݄܆8vH]"<e[ \Ft{@3 PBx}hl; J=@Jxy0" Ϟ@(_xSOJ`_"0<9C%NC\opЁ)8;֍w.} !_; xg!8҅3`hQ**YxGhC8x_G`g[6::i-$v2^rWxqZXXKoC(f3ljXJVY.O?(b܎׺iIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-xsd.png000066400000000000000000000033731237252063700300320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<xIDATxڵ[lgw9ilYuk-kGĶT-J׍ .Av*'1 i&RGiLӒl9:cI68vbr2+[i{?!RB hW>eׁ8B@Vi 0%ǶADe{Q%4@*pN$> .U *PuMqXo`. Qk-Hj\ZV|u E7.x{LNtnᏑLn\)^넦 `rmUǙLsd7h0igo>$5v}a'jDWq睭>ϗ\>ywخON#>yB0uORR35Ube񱱱3g|yaaX\)^ WRʕ Dʶ>}eBx=(J{zzN+;_@iH)ke^qLӔǎ0,Up@ p?  8z<`mU9_$ kIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-xslt+xml.png000066400000000000000000000033731237252063700310220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<xIDATxڵ[lgw9ilYuk-kGĶT-J׍ .Av*'1 i&RGiLӒl9:cI68vbr2+[i{?!RB hW>eׁ8B@Vi 0%ǶADe{Q%4@*pN$> .U *PuMqXo`. Qk-Hj\ZV|u E7.x{LNtnᏑLn\)^넦 `rmUǙLsd7h0igo>$5v}a'jDWq睭>ϗ\>ywخON#>yB0uORR35Ube񱱱3g|yaaX\)^ WRʕ Dʶ>}eBx=(J{zzN+;_@iH)ke^qLӔǎ0,Up@ p?  8z<`mU9_$ kIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/application-zip.png000066400000000000000000000034521237252063700300340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-aac.png000066400000000000000000000027151237252063700265550ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-ac3.png000066400000000000000000000024711237252063700264760ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE  rx"')-:#@?F678IDATxeAk@즻jk(-z&?xxś?SPҳ/wVA(JvtwIf٤N7Bx_2! cH]d=%)@^YN@5R Q@ V'(e= sDq&v8} Q@!PK@?<B=H@@#( *y0v׀n1yboUt(RrnOAYnP]_u8& `]$Gq=9Y|mȈ3֬|3Hsۄ˂fY ZV,wW&2I/<nq2h7s$qu7ı 6u9ݷ/ QZsUӸTVNwcMD Ơgf]u{}; |4c~Ba PD9&/ʦ'nIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-basic.png000066400000000000000000000027151237252063700271120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-midi.png000066400000000000000000000023761237252063700267560ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<{IDATxڵWMoU=36hD I$]d(B ! EeEfb nPDQJ"S$ 3v7s޽۶!PYv )Hrc!?&o+/Y@Y(I=+EG 8ї~BhO.&)| wvMe[dkPpқN5]sv~_uK߿g^DL;0 |< rY+H$9_ ",򽆗nìp{( N_3z`}Y/UջR&x:^p8 > `Iʦn# #,Qř~>6,`nn+++F*X,5LNN"NcbbΉ8]~}}|NPh2>ݸ"y4׊<2E@V*'zMm̓D#i^i߿ #@2p81k2̌L&8HU 9b(777Q՜:#ν.}A*eeHprr#iox /m3f% 3CP(w޸'Imii}1wWWtwI03$)B|RGAn ."f& 5sLz@lF~j܄<\,6Dc'gggz7_CRXs*"9$OAIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-mp4.png000066400000000000000000000027151237252063700265310ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-mpeg.png000066400000000000000000000027151237252063700267610ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-prs.sid.png000066400000000000000000000023761237252063700274160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<{IDATxڵWMoU=36hD I$]d(B ! EeEfb nPDQJ"S$ 3v7s޽۶!PYv )Hrc!?&o+/Y@Y(I=+EG 8ї~BhO.&)| wvMe[dkPpқN5]sv~_uK߿g^DL;0 |< rY+H$9_ ",򽆗nìp{( N_3z`}Y/UջR&x:^p8 > `Iʦn# #,Qř~>6,`nn+++F*X,5LNN"NcbbΉ8]~}}|NPh2>ݸ"y4׊<2E@V*'zMm̓D#i^i߿ #@2p81k2̌L&8HU 9b(777Q՜:#ν.}A*eeHprr#iox /m3f% 3CP(w޸'Imii}1wWWtwI03$)B|RGAn ."f& 5sLz@lF~j܄<\,6Dc'gggz7_CRXs*"9$OAIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-vnd.rn-realaudio.png000066400000000000000000000027151237252063700312010ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-vnd.rn-realvideo.png000066400000000000000000000027751237252063700312140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-adpcm.png000066400000000000000000000125701237252063700273620ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-aiff.png000066400000000000000000000125701237252063700272030ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-flac+ogg.png000066400000000000000000000027151237252063700277530ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-flac.png000066400000000000000000000027641237252063700272070ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k [ {    !"$&'%() )*!-"."."/#3166848!9">;?@3EEIDLELEP>P&RRSLTHUNVAWIW'Z0^N_U`Wg\nnoaoUqksTwcwfxdxb{W}ikjƊwɐ˒ϦϾչా׻{v'tRNS $'(+/189::;<>?F67`IDATxeMkQsLL,IR!VeqB.ܸp%#HK.nqѪP+*R*Kivd3;;p/s /K`%HrwbY`DPC_ݐ;=B&LR+ҹbs@) !L0c\( RR\QݑrhJd`rtZv%J3}iY7tɗ }P0 D@hazAz7ՠqRq`ps}cgϺ"{q3chV֊bZ}8ZCor aL)* RO1 'ڙL@de̒ wb Ѕ^ GZk= jw5dz=_!1v2&Sfk,zk4ޘg \#]KX)7WqTü1_33?Gf~x%JP6;Q$=7L-SxFBnC* e@FS{uI~)}8~z9^JNGW\]m1SFWz\RX x$%H< laX^xFi:0N/Xb(IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-generic.png000066400000000000000000000027151237252063700277120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-matroska.png000066400000000000000000000027151237252063700301170ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-mod.png000066400000000000000000000027151237252063700270550ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-monkey.png000066400000000000000000000027641237252063700276040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k [ {    !"$&'%() )*!-"."."/#3166848!9">;?@3EEIDLELEP>P&RRSLTHUNVAWIW'Z0^N_U`Wg\nnoaoUqksTwcwfxdxb{W}ikjƊwɐ˒ϦϾչా׻{v'tRNS $'(+/189::;<>?F67`IDATxeMkQsLL,IR!VeqB.ܸp%#HK.nqѪP+*R*Kivd3;;p/s /K`%HrwbY`DPC_ݐ;=B&LR+ҹbs@) !L0c\( RR\QݑrhJd`rtZv%J3}iY7tɗ }P0 D@hazAz7ՠqRq`ps}cgϺ"{q3chV֊bZ}8ZCor aL)* RO1 'ڙL@de̒ wb Ѕ^ GZk= jw5dz=_!1v2&Sfk,zk4ޘg \#]KX)7WqTü1_33?Gf~x%JP6;Q$=7L-SxFBnC* e@FS{uI~)}8~z9^JNGW\]m1SFWz\RX x$%H< laX^xFi:0N/Xb(IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-mp2.png000066400000000000000000000027151237252063700267740ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-mpegurl.png000066400000000000000000000027151237252063700277510ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-ms-asx.png000066400000000000000000000027151237252063700275060ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-ms-wma.png000066400000000000000000000027151237252063700274770ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-musepack.png000066400000000000000000000027151237252063700301060ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-pn-realaudio-plugin.png000066400000000000000000000027151237252063700321520ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-scpls.png000066400000000000000000000027151237252063700274220ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-speex+ogg.png000066400000000000000000000027721237252063700301750ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE   !# $!!%%%&##&&&'''(((***+++---/,,///111444665666888999<::<<<@@@AAAGEEGGGHHHJGGLLKMMMOOOSQQTRRTTTVTTVVVWWWXYWYWWZZZ[\Z]]\]]]]^\__^``^baabbbecceeeggghigiiikkkmmmooopqpqppsrrssstutvwwwwwxxwyyyzzyz{y{{{"'tRNS $'(+/189::;<>?F67WIDATxeMhA{3IK,m F EHA֋7ҫ^{= jA/E{hA"P$iiuwٝq߬ɦ,7${h!nBWؗ$AD&Syǡ(R 9: "!W zz݁Y`rz_$2.H} hn%=Fd`" W+9?x vyV !ܣ\}8'/]: xpi,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/audio-x-wav.png000066400000000000000000000125701237252063700270730ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/encrypted.png000066400000000000000000000036351237252063700267310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-bmp.png000066400000000000000000000030321237252063700265610ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-cgm.png000066400000000000000000000030321237252063700265510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-fax-g3.png000066400000000000000000000030321237252063700270700ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-gif.png000066400000000000000000000030321237252063700265500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-jp2.png000066400000000000000000000030321237252063700264760ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-jpeg.png000066400000000000000000000030321237252063700267300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-png.png000066400000000000000000000030321237252063700265670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-svg+xml-compressed.png000066400000000000000000000033651237252063700315510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<rIDATxڵ[le3ve)[l)\M(>@Л&M4/&F}%>hb|0'1x kmD (x[vCtw;;lu%(8K?fiz @چp;K*yp@‚D"{ Y2jn1y @T dP305 0 1gbFX&@6V(I^*?]6_y,6z)U)? UwP砃Cj_FqjbK}x pp2?w):NM7I9uP˷pt ^Ug# Rncp n2/&UGT 1xS(j*y< .1d{jˎjjY0"_eY3&bpb[+03 +-@Ym1Ԕ2dB@ITw@7a4%<ĺ7[l`:wNĭf)E!h&)ęlEw{Xhd: a /U̶Lґ`A2WdYo}UU!6HC X_~MAtҾ\|*r!U01{/ޅG[X]AX_WG, j>=WT@.L&(xvv<N Gޫi*P)A<pQA0 ;ذvA ؽњa&f5S$Pdm-} a$Krq&'Τ:S2ӥiXJAa{ /) l*F&,)<MՐJWJw)X(0;?g|cc~ d29-RvZ R:$`*/$A$XtɳFa.Q$n< "gPqLЪ#@_c{ SMQQkY) 0>?qmrAT Qp08xGĥKhZ^gGO%j,-926)lH܄Eub+-j#>S(z΍j_-͈S>a۾fԤvڭ^$.Z*Af݃ŕKW\15^Cwũ)۷o/!ư·8јfnOeU 32";p~:z-~ хJH4l{Dv'1@o% ,ge}4[D'*|VbEk K¸>4Q`>:6:IoA x*t6tҘ̢d vlڎ@؎logftvu`t%X?$Rg&OO*0i\_œߤ'A},IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-svg+xml.png000066400000000000000000000024251237252063700274030ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkUMd7IS$MIV*Q0DDՊՋ" *^^"XA EV`mmvn23;,'CFox93}K)E(+`&TpoL @Z`q$VhW' eLlCÃY`- W8n%E1 nUuD`ik 1V1%qZ&\t-ׄm*1%-(ݨ02k5l{mYe 7 ?prq!ㇳxkx+A>Y䇙[tibc 6 pQ_>8=G>( FGQeNg|ze9}ُm7{!Am|tZ.~>6R6҉mK:r] /@+V=%T0xtK'Y&'mKs%[k)*_ !Q8oPR1HO&fO^wo=MFE7Wʮ~6#_h?'m$[^.?Wꏚ' \;-$6{ n-;haS2f.ҝ !r[jY}0]-4ܨ='m׻7Pq=ikbpT5sIP R*t `Ξ4F/Knšry^Z@tx+KRຮ8b0$, lct)?,c1q hZpȵࣨag,υ OskHb0kQsi%‚>>R[[Q /wHeŕn1eIC.1<Lp'K-ڻݯtѻY8 e˫ߡT;zKBA/AKK KGy.r&/4:H.ӵ=[,/a kݫ OPJ0@%cAF ^*L S)s@l`3RH "sO p<mSOIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-tiff.png000066400000000000000000000030321237252063700267330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-applix-graphics.png000066400000000000000000000030321237252063700313430ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-dcraw.png000066400000000000000000000030321237252063700273500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-dds.png000066400000000000000000000030321237252063700270220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-eps.png000066400000000000000000000024251237252063700270440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkUMd7IS$MIV*Q0DDՊՋ" *^^"XA EV`mmvn23;,'CFox93}K)E(+`&TpoL @Z`q$VhW' eLlCÃY`- W8n%E1 nUuD`ik 1V1%qZ&\t-ׄm*1%-(ݨ02k5l{mYe 7 ?prq!ㇳxkx+A>Y䇙[tibc 6 pQ_>8=G>( FGQeNg|ze9}ُm7{!Am|tZ.~>6R6҉mK:r] /@+V=%T0xtK'Y&'mKs%[k)*_ !Q8oPR1HO&fO^wo=MFE7Wʮ~6#_h?'m$[^.?Wꏚ' \;-$6{ n-;haS2f.ҝ !r[jY}0]-4ܨ='m׻7Pq=ikbpT5sIP R*t `Ξ4F/Knšry^Z@tx+KRຮ8b0$, lct)?,c1q hZpȵࣨag,υ OskHb0kQsi%‚>>R[[Q /wHeŕn1eIC.1<Lp'K-ڻݯtѻY8 e˫ߡT;zKBA/AKK KGy.r&/4:H.ӵ=[,/a kݫ OPJ0@%cAF ^*L S)s@l`3RH "sO p<mSOIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-exr.png000066400000000000000000000030321237252063700270460ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-fits.png000066400000000000000000000030321237252063700272150ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-generic.png000066400000000000000000000030321237252063700276640ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-hdr.png000066400000000000000000000030321237252063700270250ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-ico.png000066400000000000000000000030321237252063700270220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-jng.png000066400000000000000000000030321237252063700270260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-msod.png000066400000000000000000000030321237252063700272120ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-pcx.png000066400000000000000000000030321237252063700270420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-photo-cd.png000066400000000000000000000030321237252063700277650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-png.png000066400000000000000000000030321237252063700270340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-portable-bitmap.png000066400000000000000000000030321237252063700313320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-portable-graymap.png000066400000000000000000000030321237252063700315160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-portable-pixmap.png000066400000000000000000000030321237252063700313540ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-psd.png000066400000000000000000000030321237252063700270360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-rgb.png000066400000000000000000000030321237252063700270220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-tga.png000066400000000000000000000030321237252063700270230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-vnd.trolltech.qpicture.png000066400000000000000000000020511237252063700326710ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-xbitmap.png000066400000000000000000000030321237252063700277140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-xcf.png000066400000000000000000000030321237252063700270300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-xfig.png000066400000000000000000000020511237252063700272050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/image-x-xpixmap.png000066400000000000000000000030321237252063700277360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/inode-directory.png000066400000000000000000000012471237252063700300310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<$IDATX;OTQڏsy@E+576Xmlvv,lV6Z[NbAabHhh@` s>BDp(tU'ُÈEJ.; ^JPt*}~yQ>^^&O%5 Տj͉3zekf<3=!ߗ^VU .XQ|ڏ G1L*6 ̿|xcOSMޯ[2m>te2Ud1fT5e2V5;yޅPdJV[2L;`":*Kn#6!FLU14P%mL|B&%RLN4M. LJd)f"O6´/ #<}scOt(g.@I 2"Ǯin̴tpiڠ+n),;@Y?=/ABWgBoDETfIQN,]NO:}SVV*cW1S[=\ X\m~]V^4n_FCbObd>EgvEkWl('myo5o|p=ht4|zZ/:gSNߛrߝޟࡷޡ ᢹ⣺⤹ߤॻᦻ়⧼᧼㨽㨾᫿㭡sr#V1 'tRNS $'(+/189::;<>?F67IDATxmKOQ\N\h j .&$]w.L.L(D(Phvfzj[Bg8sw( %b8'8 k*`0@_e@Y@S켥5t*Xy;SJbhZ95?:ȹRoz?-e}_*  X2SiP`̠`t]j "n!>HJʫa[D_0gNƕC#3.L ̓ad L3:qzH `F7"3Ii5P#~KT.4͞r );nIA )DHńO3o+^˸ɓ( 7,PDlYEIzWt I'zVz &ZH)p!e;Y P.CR89@SE\UIJ3m[ɘ0* V" 8M5qHИaR5rہȪOͨ X TwJQiۖͧǥ%T>o,UpX~t=w)hU|$kpHpgW|xngl"&j4 }ѫ t<#G҉( IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/message-rfc822.png000066400000000000000000000025771237252063700273700ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[OcU(--V.R:*L)d$18Nݿ$dˋјh(a LePti-\keX;!}ioΠp-6jF?Qz%eAuMMM}5222 QSS^=Vwvv}J߀u:/kIItuuuU|rp+W$̫%=\*VM Z5) 2{ k(W$J'eΤNailthxa28mb#"B ߎ@{hS|烞+ܡJG5$1vFd*`aMFf7?b7Gww^|Wrpv/oXNn$pr9= L8 Վ&\cv,.a*cjV`N~D9vy`2Cvqzz*-F@ss s` |Mq(q-m#k?*J|*q4=2V&ĊHf]EjǴ]'''dچWF# l!DpZ:E6Ϫ&*(|N~l4d"x(kK1Ykl\<צ@):QR;)%&<`<&UBff^d2<*8ߖ9UD{: 6^dBň{K%y "U?|w? JDMp ]EXTפvUd2u_p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO 98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/odf.png000066400000000000000000000125121237252063700254760ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxڵytTնvU%bhToVDDPzA #H'G H!#8$jޮ /Q5֯kxF}Md[2He]Ĕ]BYtgX{{gֶ-ݤecZY8v U ȷ,";+C!ߋjl_}дSǜx}wgs7M?4ü̠2-LĜg)cڪ)vZaOՓv]GLyo[xLaFkr~U_t{/$}ͼMo.';N7{\ʾ=}i^]\ŕ}z$837ͨ%LLuPBBXaGc)i7ƦMv L L Z3~!,^)(̑R)pޢF[ߝ:YյH $z/|bn[X}'t__8k-)j7'Yf%7ּ@y [2H*e$iTq][vI+,3-ᰪ!%^f[کt$isU ={,_RL,i!ij곏@لV_\^#@:$\,H9V?T{عwjl.U_P{/W('BKSj?mׁƠCIE^ N(xN&4SUC1gBN>[46ol_p@m?ufDA^Β%|j3p|#GrB;O]cYқ*^Jl[`wsܽbQˎp6Zdz?"#:n' :i&t\?$ff56Xl%sYeRLolRhF-M:IL jP\7d e9@֨n]PQn@H!,GK1f9Є@K z6-ܟ6Z*49gYi`=yoO.e/CϽ|b`J ({ w:;z4L#;WA%`R]ؼBs9|.:@mVk%R3# L'T^-/m6|Zֱ/f*9rU 11W(p:rk(uhu;GϾǔӏ4߈aN)gN_}禍Vո'r{M|詽V.'C:H,xt%@a(+e'З $["GUXryV<R5()$jQ]I3w!~g8d}P7FHZ3\ԗ嬈{1jWQU2畬Z &1fA{H[ڃ) 9/& TUP- TK22D ꉁ= lb+;@zțRmҌvmTO;먴ыDer}\oKYd`p6)9|6@\po1IfYsR[fef[h wĹ^RYXp.L[2Bf:DKǛ> Qr%Ts7\AKY J ,;gV rP&?o3x9Y9}[a,y\W3=SDxgQ[DzX =f?K!×e; o?# zgCTBl+pMMwb$$e(lg7@^x8o@doU$, Ua!,[Ar5 p/ȿ_k(YL³?$(OFNwgLo  >zY NM{dEK;t'SG 4u]HK=`:s\M|DopyG K)2X#ջVRR(K<@QJл _+Y hz\0=C }OGf MR) zN+ <l!TJZ&j8 գB?f$D,tCz)%A `p룦8D;bm{w{艡z9r)N7?s8#\q]@I)`KhHKi.M.edNG41q۟;V{ǺŝgE3/@U 3 y-CHyth (CX Hwg3@<w \p4fDhd='KSr>]G%t =*Q3]ww \PA@_ ^P9mR9\ =AVaa q]'?"FPDJV&\H0bN?gLUS´]Fq~ AL;s>H)O@ZK7\rc[ C1!I#>^I._FC+ O[e.}qA/4r;M]>P/'4Tgl*yxz#0G= E]^yu0It҄@,ECP^w{@&ӚzgB`STrBvAx_gUTQWλD9w`m)$TYϹPtnfmjn wyNˇN;Y2eҀtepC4 =]Yz[ lJhmڸh~f8#o*HM6NtS=zЌ:p8{`;؝\gv:gρǝ{<}4rMȻk33ޝ”)w&y'~>Z1RBFA`ڄC@-GH.M l.5XcTV"| XjH\gЇ >evܢMg|:^n}n]5֏hO3f]B{xz[<|~QEQӇM)YꏩS?.f3Rf.x[i|։`':zZIȯ Twt* IKpoSzR zX$P|R6 UOrK=u [/+dZjOMΙ ]{ujf뚯}ܬ;.}~F׊)NNHLx) ?{ $S VPY>dLPU-hIG9rYv8Aih~r@e& _:Rg.#\W :^/>S1= ;AYmEvLvX]_U7æˋ0n-N6iwM%PC7Mt#?kЮ*sp`!_3ۄZ@&H P l&7l zf9j.˚Nd}=xv{wnPW^_e}%[n1شauD @\QX YRnfhּD ƛ[fBd5a>1C0r?8T )CY2. A.c\w)Ko?gWfEk2ꋳo& K4zʿuz:Ajy/׳&ҥg {{xzց2OH2;e-! & &H+\R:E/e9sz.eWz{s^#玟oY1k\3xۿK*\عY|ˇv393ί;e|f4͟! k!{r_t WrzwZ3g)3g_0v b.T*#6n`ܠO }g<52k ǝnA8h5"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/package-x-generic.png000066400000000000000000000023611237252063700302010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-calendar.png000066400000000000000000000026461237252063700274700ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-csv.png000066400000000000000000000023561237252063700265100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |||}}}~~~Gʢ'tRNS $'(+/189::;<>?F0P,IDATxmӿo@%iJ*J%@RRta,L쌝X!D0tEC$Q"J؎Ϲ#g;Dd?> !6RH4CCr9>1B$% }x @4 C\@]n$DR$r(Z9UEX#>s0u dC-k{Ij_ A.,ymހ)W q&?/Pp d˅05zGC-~> (4GNn}ăI pVlJUlvw4JwOTB{|* k^]gg1 #]n^J.ƩrB9}@yʥ-, wG^t̏[2| J* Tb:b /FkhTLˍV1kJYu,Gb{) 繳ze[0RBM5D% ݌,`hg09p5) 70E ~IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-directory.png000066400000000000000000000017661237252063700277250ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sIDATxڵWMkQ=4_%RbJ؅.B.EmEJ诐R".QZK6LީFF饇7o&}3M&1u!U,&)MYJŖ#&J"*rW&'' ~Ća DIMMM]E@HBd-@?񠏞`Br=P@@xjw0m5_w庀 XFmdAAEuN-Qnj 9x\Nj_:yڽf;0K29w;4LSljײn4ޝK։x ٔ|V#! FS׹M.$"ׁmrвluNŇNrA h9x}.<Lk/py:W81Z.QxlbtAe&-ܸr. C!t=j!O'&Ay;~k;cm(d=D`[EPZ.lB%*9[񰤋N[0r!m;H@=`[!G_¡%|0(Bv8+"BK_V*}&F˲nvTā݋!a&n6h4"jZ 0Nzi"H #˱#|J"@~Bs0;;aaͅ^o+Q "w)dars~~gDUT~{9P#09]^^`ț_F+s a2DZ`Z+> 7"Flic-..2#"Gz)wD}ts Bl@䏉8[U.gff> QgHҮST /$_IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-enriched.png000066400000000000000000000027431237252063700274760ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-html.png000066400000000000000000000031311237252063700266510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkh\e:sf2IӤmbozAQA]ĭ(ayaaYve?A ^H\ɌML&g̜{|9=$xxρw{="PET~RS$/z!U:6$BIֽǯ#O di,n<P|Kχ[V["Xg๳!GvxSQB` 8-pRl*Wy\k䳂]RxW)'7)Mʖ`bq"^c{"ʖ9$5LSpzm}*}~wqqVx؄ڼMt N0(^rhHPq\0XF4r\-{ # w.oxF!)蚆ihdPA_ gꊅ-TmO'nWL9!1ضB@kD.kCKq jԠ+\DNDQ>U:RͶZPg s5Ci9& JD c|ri֗143ߘ ^ǵpZʔ &JCdi9^[=Ϣ\}&ե5i*&-7C ÀO) @E03LYp O@罯gtS5JJW)j:cslc8g[cn  oOaejr nk.O>pbͣVD[ph֨^s(| FնazVVf!(>L}۷Šs H>0O:KdiwQi8UU;2>Až'" ǰE|&[`a%`ZϓfFLmPoyv?KV+@Ғ/~~ OTxrC-fm1!EܮR5'N%_ @OfI^-x`e?,Ѫ'Oqҭy)0xjAP+A$qAgfvv6^k333KLHF0R@rR_ ^ť˧O~ܶ -`wzt+ԩS]o&i-G0p+q%iӂ>9qGSSS_?~i`$y4ax`S=B`-Fb|75IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-mathml.png000066400000000000000000000015751237252063700272010ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-plain.png000066400000000000000000000021621237252063700270130ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񨨨S&tRNS  &(),/2:<<=@G,,IDATxmkA{&V(=TPXm*XՃ/k3bԋ`h!b$3lReyہuN/Su]yD yڎʫЉ$pA,࢝ cAk9v3zgs^2%? Znr^7D¿qɈy"Ϲ ֏CI5O~s#z+dcu S/gh.$p~ Pt{1QxKqSn=Ds~܌0'#7ح陁FWOD,@;H8..n v u5導G~`N(>TJ`۪_s*atp$5iA~#` o*n?t#`g6tQKQuz<JJ}Ջ$cw (Yj(G|&' =4^&_ ,gHuQ>!l" PIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-rdf.png000066400000000000000000000030571237252063700264670ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE /j2Zl2x79x;Pg@Y?=/ABWgBoDETfIQN,]NO:}SVV*cW1S[=\ X\m~]V^4n_FCbObd>EgvEkWl('myo5o|p=ht4|zZ/:gSNߛrߝޟࡷޡ ᢹ⣺⤹ߤॻᦻ়⧼᧼㨽㨾᫿㭡sr#V1 'tRNS $'(+/189::;<>?F67IDATxmKOQ\N\h j .&$]w.L.L(D(Phvfzj[Bg8sw( %b8'8 k*`0@_e@Y@S켥5t*Xy;SJbhZ95?:ȹRoz?-e}_*  X2SiP`̠`t]j "n!>HJʫa[D_0gNƕC#3.L ̓ad L3:qzH `F7"3Ii5P#~KT.4͞r );nIA )DHńO3o+^˸ɓ( 7,PDlYEIzWt I'zVz &ZH)p!e;Y P.CR89@SE\UIJ3m[ɘ0* V" 8M5qHИaR5rہȪOͨ X TwJQiۖͧǥ%T>o,UpX~t=w)hU|$kpHpgW|xngl"&j4 }ѫ t<#G҉( IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-rtf.png000066400000000000000000000027431237252063700265100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-sgml.png000066400000000000000000000120511237252063700266500ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-troff.png000066400000000000000000000022161237252063700270300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org< IDATxڵWMkF=Hm^^RPmV!t -$RJVǦPڟMdh.J_ea*  ιgxd( Q,Ϙ5HLD;~N,#96?IM&pǶY)ҵVi1("X?GQiQʜjR}p%0,CRh0djQXxq` PPm5ڠ<` 4 1  " z@]h"d_t^I$`dB%+x>Vx' K*dUSڊ 8B>Hha hǞ(`)"X"Pل.Q@ Cw -7B` lL¹eD zbLhs ,yxԌ@i1H d*7z ;'BSibR.!Qbh4nN8C\vn瀐d6QpKzP>?)azfc{{xa ],s>( |" NȒWx>c4o6xxxȫxH))JHW&3~NGd+B=yY{u||| ]ل3a$,2L!ߜ.$5; dk& A2 ! }QJ)熀*oLp_{xA{qY҄?uhyqIw+ּ9Z>e?3+Yzzz_ *Q\^^KT7v{#xIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-vcalendar.png000066400000000000000000000026461237252063700276560ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-vnd.wap.wml.png000066400000000000000000000015751237252063700300720ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-adasrc.png000066400000000000000000000027231237252063700274150ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE L M QUVVVWW]#_%`'`'c)d,e,e,f.f-g/g/h0i1i1j2m6q?F0PIDATxmOHQƿs=c=J^@yOt]~ b=$,(%2xB^.;ѲezF5(j&f.rҵڎ>)`Aqq"s8'0{>۱lQ!J#_6ӧnT;VyL | Kg^:% `;@W_/.rMwÍ P X\zv0&- DМ#]Ճ)&Mt dce$3*г &Q:Z~!x_Q`9O2KT m#+!,CMK-<QIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-authors.png000066400000000000000000000120511237252063700276400ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-bibtex.png000066400000000000000000000026611237252063700274360ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  !!!'''(((***222555888<<<@@@AAADDDOOORRRUUUVVVXXX]]]````aaaaadeeeeegggkkkmmmnnnrrrssstttuuuwwwzzzz{{}}}Ɋ" (tRNS $'(+/189::;<>?FVY\mIDATxmMHaIF$Bx nBCv .a$!u$%tcUD(xCBu Us?ٙ9< #4 nO}S `"f quV;IAP@^!!# l[( !JSVv4Cy)JN:3舦V; ;V tn! J\Z*ۻ~d7&z%3V\1#`s? ݹewy>Z_p*WcË357 ,K=|tgj ݛDVF@?{1 ;HɆp.2zkGu <Ж;ILpul'O'玉w~j 9cG  g\U$O 0 `w{ W BJNer}߶z@]?F0PaIDATje}o&$mBCzXmт EWх!RB\xށ ހ"BAEFDbML&3<͸!ȩu*Χ[ʈBH"|NntZ'g!H"5яN/KNd)ffRZy1JDğ B( TDN{=o||] .Ys&_+*Th ߉,GIFJqs*rPAD,xU% "+)B͞k fflnn\TY/ܙZﳧޚ>5 2#KZ{}O1: /եU]3Z Bs[O~_D[`HBs)!0n$T?'[֭7 rRn]\.÷F`eguݽaw@n phdp5g1 CF6|g*(7:h^B47"z}} *Q@3.Pi;bn"@>@P hw IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-c++src.png000066400000000000000000000026541237252063700272430ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<dPLTE L M PQRSVYY[\!\!^"_#a&a'c)d+h1j6k6l7n8q=rAr>yJyI{L}MY^\]bagr~ބ݇މ̓ޙ֢㞽襾չ'tRNS $'(+/189::;<>?F̑[IDATxeMHa~Z~Aѽ`uSd ][t $>ܾˏtYwٙijw;=bYzW^s YSD $AΉ9M}} @0 YiZ: OM Ct%$IArD/ğTѵ[u?B@G1!7"G2 ^ "Ngz4WYAZ/S;VВMW ߭7 NR gW6ԩ(twikz$T0Zzo\3Q&yuBT`wt$wCxr1$ȁ/iyAD4Ϥ:%1$%N?nŦH),H>6/783l HXxUm* 1+5՚h>_Z-Қ=Y.0mmRe RtTJ;(?ssllv>Jk囿*@8'݇b+}q4Xh\_ʩ֬VЈ$gL?.rE7-&ZIni~L`YiV  ;Z1mO(x{ƛ IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-changelog.png000066400000000000000000000120511237252063700301020ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-chdr.png000066400000000000000000000023561237252063700271020ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE jqqtu xx}m㎹|~W~'t倳VDJua('tRNS $'(+/189::;<>?F0PGIDATKke<;3\jB5m " EWq ;GQ*tSԅRAHh\疙<'59WB4L0[QRI8h=gOtm.BQVgdQ3KUdRZz!PB;yѺBP!%3dyz-BTК|Y2O[wSDHp.+nID@V$T(33p Y_<\znA@33]w: sznɣ: Xڀ-^u< Qvo1 76F6^1BK|i m B7+wofFBO~)&xztuJP![k~d~ԗTv} ɿӣppN\' ?XD;Ψ20m~i ʃX[ʠΕavNމfzwtHfӳ>PiƳP1i7Bv`Թƃ9@-F$o ZMIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-cmake.png000066400000000000000000000120511237252063700272330ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-copying.png000066400000000000000000000120511237252063700276230ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-csharp.png000066400000000000000000000030241237252063700274330ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k2l4m5o8n7p9p8q:q;r?F0PIDATxmMHTQ8~%TV (((,!$6.[FTJ@#ڕY %.*+$S#s>}Λ{7KތY~JZK+f+!#iDd"f(SfB}9dv *R@ DSMg@0D`@!%AKMqÖQXau 2ya %TlhZBcA>&#PȊx5,mMC }S[}<|qIʠ2҄ jsKf}d#SJ ҁ8".=Ӻ~f̨0m~HW΂^kA(~'8bf[W-7v}j5=ѦeKݓ-ecAyrY=L G}Ϣ4b&meM=֓7LGp%ԣ#z=nZvLy2n?\7!$BZ1+oxj >_~\ܢ-׷\90 !psaᎠE-g.ʻs1d-19P'i1j$,c'#4!K Av s-IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-csrc.png000066400000000000000000000027231237252063700271120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE ""#%./1227>?ABCEFJKNOPSSU^chkmx|𷷷k'tRNS $'(+/189::;<>?F0P~IDATxmKHTq4 -РUIM2hZXe!Zئ"h,+aA>J'4Ǚ;;z< w_@LJv#@[%+@ Y bFpPUV،󥫕 $D? GNYEwKWZjm3*zmWhM tۘg )0}e59Koq%p VGZ @i M}bmʒY\wljEcyp@s+l''v5$E3`ǐ`I,8GA9 k@<ۗ@͟Tb1Z>i'>#S I gRldn7НAlTpo<3߽8=PPdbוk T !ۮ`~?3u ƒ^C)d`n% ~j2MU1@7_f|}<6{hQ-{ XFaej>{(:z5&znV wP`I+=-/̊R>*RAFpֺjJ~!+&9>/ KWT>5_QڤbhIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-dtd.png000066400000000000000000000015751237252063700267370ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-generic.png000066400000000000000000000120511237252063700275670ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-hex.png000066400000000000000000000026621237252063700267460ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<FPLTEpppkkkvwwwwwz2.tRNS  $'*./1389:>?IMrIDATxuKHTa;Gq2-˨{ڢjAJB7JL6ZV2(+iB SJ8s\d{x?hĿ͗9À8#!Bo=@,K@4P G0 5]jR%2Dc2 4rD4sȗm=B6[0 PO_K+?i4qu{}&I R+7SϣWl-qUe 3 tBx\()BIGjwYĿ)f/O(][^=]c{ _wFI{H唻 K e~W4z"7sB._(˽GΘU(@ bWHi x/Be֜ U6?X'*;y!?HmS{Vt]ZВ5]< \xoQqMoY>-d_܏Ji"5]!7?M cЅΝ^~j<{z@ۿ0}4{ *J:)13YSi^6uFD-yW50C 8NZKh4q( ޟH#u1 Io3n88፲=_RLWIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-install.png000066400000000000000000000120511237252063700276210ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-java.png000066400000000000000000000033071237252063700271000ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<DIDATxڵWKOW0+ A"*YFJvMD".hWhi7IH+,W*V0]f\f|^-/dYV-6\.&'h4888!g^x`&< >Bڵt:nKKK/,h\DHq h#FGGQ0==jt] q(!Dz166W?A3cytAcXJpfzx?d)ׯ_Fj''Q.P=>FU&S%z I^/D$9,èI,˺8QG1LjDm6X1ɘssst@REF@%Rxszz p!%@-7nP+ 4H0jr@@튡Vi8.091cA~v b$4&xQ*fLn ryVObh jO! '@XFU*/ _(J=xΧwv $R ,TlK ggg h3vI_~{ m X %Y$~RE?=N'#JIjTs2JlK@#Ԕh|J[ 5W0"PJil.?*ʷ;̢Z.I9P-UZL"$b"S7j8m6`TL o;hZ*Xѩ7"ey淥rA A'6"z0wu iEBtk⒖:Nj8<Хi6zN\H=;o^"E$#ygV{b1bmm ׯ_u=EE@F牙 d O98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-ldif.png000066400000000000000000000017661237252063700271040ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sIDATxڵWMkQ=4_%RbJ؅.B.EmEJ诐R".QZK6LީFF饇7o&}3M&1u!U,&)MYJŖ#&J"*rW&'' ~Ća DIMMM]E@HBd-@?񠏞`Br=P@@xjw0m5_w庀 XFmdAAEuN-Qnj 9x\Nj_:yڽf;0K29w;4LSljײn4ޝK։x ٔ|V#! FS׹M.$"ׁmrвluNŇNrA h9x}.<Lk/py:W81Z.QxlbtAe&-ܸr. C!t=j!O'&Ay;~k;cm(d=D`[EPZ.lB%*9[񰤋N[0r!m;H@=`[!G_¡%|0(Bv8+"BK_V*}&F˲nvTā݋!a&n6h4"jZ 0Nzi"H #˱#|J"@~Bs0;;aaͅ^o+Q "w)dars~~gDUT~{9P#09]^^`ț_F+s a2DZ`Z+> 7"Flic-..2#"Gz)wD}ts Bl@䏉8[U.gff> QgHҮST /$_IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-log.png000066400000000000000000000120511237252063700267340ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-makefile.png000066400000000000000000000024531237252063700277350ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE j['tRNS $'(+/189::;<>?F llIDATxm=OAvn' /+ cޘX'`Z; BLL,+Bz޺;337 LvO2dh'}1*m61DƠ-zN"0 "e\[# !Œ'  626h++r&1TD@5ߧ9c l0 LOoz1VNE ʕjǽmUv `_ |(a:wE2(0y9o9D1;M? 6[Z _-~ @gDĆ]{"N,hF/FP ֲߤӻ0Y{ *<G` XctzhVD`ݳ1Zk75첌?~D1dR2`GDrX@x`odH`0,1F:h_IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-nfo.png000066400000000000000000000120511237252063700267350ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-objchdr.png000066400000000000000000000023561237252063700275750ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE jqqtu xx}m㎹|~W~'t倳VDJua('tRNS $'(+/189::;<>?F0PGIDATKke<;3\jB5m " EWq ;GQ*tSԅRAHh\疙<'59WB4L0[QRI8h=gOtm.BQVgdQ3KUdRZz!PB;yѺBP!%3dyz-BTК|Y2O[wSDHp.+nID@V$T(33p Y_<\znA@33]w: sznɣ: Xڀ-^u< Qvo1 76F6^1BK|i m B7+wofFBO~)&xztuJP![k~d~ԗTv} ɿӣppN\' ?XD;Ψ20m~i ʃX[ʠΕavNމfzwtHfӳ>PiƳP1i7Bv`Թƃ9@-F$o ZMIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-objcsrc.png000066400000000000000000000027231237252063700276050ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE ""#%./1227>?ABCEFJKNOPSSU^chkmx|𷷷k'tRNS $'(+/189::;<>?F0P~IDATxmKHTq4 -РUIM2hZXe!Zئ"h,+aA>J'4Ǚ;;z< w_@LJv#@[%+@ Y bFpPUV،󥫕 $D? GNYEwKWZjm3*zmWhM tۘg )0}e59Koq%p VGZ @i M}bmʒY\wljEcyp@s+l''v5$E3`ǐ`I,8GA9 k@<ۗ@͟Tb1Z>i'>#S I gRldn7НAlTpo<3߽8=PPdbוk T !ۮ`~?3u ƒ^C)d`n% ~j2MU1@7_f|}<6{hQ-{ XFaej>{(:z5&znV wP`I+=-/̊R>*RAFpֺjJ~!+&9>/ KWT>5_QڤbhIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-pascal.png000066400000000000000000000031741237252063700274240ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[O\U]̅aJiSZS XS륱iҾ*j7h&&5i4hME(DJ "rœ˸wd xۓ}f9{o}}Ea%A0X.'p *[UX Qֱv@F0 5Qu4rBHTQN#jlly9$!@&-ZY&#gbrM64 ڻ2+A4?fQLu]D"hll5jl>VOЃrcGGx%Xe'EW&P* ĔlQeTe$- >SnJQ<8B"3 x/ 66$DT2jz?"-8kXK\5si{|tdD+|> lg7 j^,Q@pJ^vuu$]][#)\/-ra=X&Umμ# eF)܋X^^FOOfgfH zP[[ KNܼy{E]]d࠼VUU%׫M&bJRHBBU]]M<{!^#}x]EjF+d*:8ri"yCŝyQ#h sa syu477jzƜ J۔ˏ? h;Nfܸ+bߑv-755 sdJFȀ5Q{Cc;0CR^ *TB{`]|!`;6{>C37)U }:98MLzE]3wg]´ $-`R)WVVXT4` |094jrڟ~ 'Yv#QX#s ]Y` K:DC[,"^4҇Ȧ#Ӹ2,/x6Tܵ\qmG0 Bj8S@ 2z1&'C%IgϾ`\=TJ^UXA"m+Bzݻwow9 V'}qbbp_m# 59Yg>lQK%@ ot_lKDJ(@TIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-patch.png000066400000000000000000000032101237252063700272470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIo[eeŪ"@ .b uifjuڍIkgp<;nS|nAι{? / GG'!n >l'y69ȵcO+*4MV. a0+}jVS/P'ask AԴ26ry,O$ GfD"=FL/RX]]EvcbQ-Io8HqWZYGP@$0" #5><.Sam}]D!"~rXuˢ*!l:P-g%R Cׅ s~SjAg$!9L$H./cumMBUYi Ȉ+҂;0GFшF|}EV7X!$gi1 h?_c߅CeѮ4n4) D1vgUYN_h"nm.t BiQ#Hnht崗`NSH07q l 0jązl\x1/ `? eT&!){.FjqB0F`NܹYmnݲlJ<0<ȡ?2POdG5Gn# eHFr.r2~"^mO賗ؽhQB~ Ϟ=,S9r'м8={*y:N?Y%5=BV劼<cgQp}Gh}y.de`8jL:Wl6k mgT.r v W }ID9zO<="7Q 9Q  )O'~FI9 ]DVeNNT ɫN299 ;!a`f%p"`UYr"x2k핫 ?~1G Q ;q^Pp듽^Ņ UCW ߾䴜<+\NUNgdp8h3 նDSv{Yr%E ܐ%o6 ֚08 bX%_rc*VO>kI|9` LD8[7 3qr,,*"PP윭jb-/3>3&{MډłĪ(Egw> G$eȎfTDd:xBRaHzV YM&Rne ʛ E|_}3.1], lu%|Q~! M(R8Jd)&wxtSf|޾Af,"mʕTP4~+ȷ3@\B _ JA4N7Q2Z\o`\YqהƈԗwG4͈,Xm҇hjiA#K*),ttxA;hiAd+spz+̎ ]W7m^0Fey fju(h߼gptˇj%[8#1E)35}*1H[ERJ 0e "H(8/Yފ9%N|n8>t?_}sixK$I6t: Jc& C4 a:YE˘_KׯѸzfiJK4>y۶)8MU%K-!D$=O,LJvP;6 k}߳ 큻J]/]x+J9tvs'rkQ0[VEv"E |_?կIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-python.png000066400000000000000000000031141237252063700274740ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoUw}R-EP!, 4v磔$Ɲ17ƍpGԅ.X_ljB"Eyә-$|3Ιs5!D i cAxxP@^g=;p? UUFOXs uu44MEWW7ЂZ[[ 0ppp >S<3hO!BQq}͈|M47 w~Rc˹9X&9T:mds3I WU\x 1p v]3ܸ?YJ@i"0p >8$a_oxcǼ͘Z/2MT, |(xW?k 7݉ #:tH$V~ gca2q U,6$6=wv\}Ҕy ~ۏn#lP؟kzc J [ LPZ /JHMDBRzPqT*ULNN^#M"ro4yLyΈMӀ!;KRp<+UJq3٬#GRP$jh؄ChTdDKH mhi@8g{(B#|ml߀Yhjb&aE!0\$A+(N=Eۀﲺ9BL&eB@,+  #Yk . J~7" aЍU+2 *ZF.Yq% yoE*b} Unԗn#pa9.l46^lVJ[6v7ZBZ}#{LbR\32c:3(RMa4'V-ܪƑ=F9mEk(&"t.Q0Q۰x k:g `>7AR; ÐӲTx@?Zѕ8;A:8ޞceD³B-ik{ 35#o"a\F_4422rBQXKT*H>_>`īV|p:;;FS]Ĥ=FIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-readme.png000066400000000000000000000120511237252063700274100ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-script.png000066400000000000000000000022451237252063700274630ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<"IDATxڵWKoU=~6qLM I4$>찢 ʊ)E}@ *`XPEm6y `(uc'3ԟtgF~c_sƑn ED (41m)BEB8S=?j%`>鳴 E,CjxC¦0ZZ}$q\^^""lЍx{rCCax&a F0==Ŭ\$~58;Gqrrd2151-%q∎ߺc*enĐTnAd2T҄߀ڋ Ju7i4H[ wϞaB2fdf- q7u:҉KKK!ř}<1H)fY(X[~҇7+dnߞf"̘fm0QVQ.Ci~wfAB$ 9mB[~NCof:jPZ-4M[b jP+Q߾k};3,YV׸EuX4Y{T7px,,Ϊgdue?|oŻI}Gz;md-B+x[ g}ßǏr2ve_(|/!>r y t=MX~^A߈\yHd`g;6, כK1n=˃T*ї/_ `_h C]fLPLgiNzR)C}#4fy֛U{~r~888_" $PS0??//T)}@Tr.C{Awt &FFF(N#ǫ+2%/_#]@lnnr9|5 !wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-tcl.png000066400000000000000000000026131237252063700267400ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<LPLTE ᄒIJKOOPb3d6g;g:j=nDk?sJtK݆cރ_ކboz|}䠅壈壉框²ó鰙ŵ겜ƶ뽫쾬°ȹʻ̿ƶ˻\gt'tRNS $'(+/189::;<>?F0P~IDATKe?}.X:]V!.Ej2hӦMhoAjA(AZ it1͜q<̜3yQ!hەHҬ~d6"T2`D ~L\^ќy*GӾԼQBAXdMdFR !Uln3??pӝ !?/;ٔ(P!a‘W[|3s92yh* ԚM "ZU  p 8:ӟܻԗP]9̮Ϳ|>I $4k燻G)($\i<ԦRmP$DDƭB % ?M9l+M)T_Oo|;k D9Eس{4jBBA҆;Nl ?^_mIX _"A ]c͛4wd7 q@(XYY2ZH3(ʧ'HPvڶcn4n FnwqSK׺ w>awW׻@Ҷ5./Er'=@bYEA[rzKJ {d] F@1IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-tex.png000066400000000000000000000026611237252063700267610ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  !!!'''(((***222555888<<<@@@AAADDDOOORRRUUUVVVXXX]]]````aaaaadeeeeegggkkkmmmnnnrrrssstttuuuwwwzzzz{{}}}Ɋ" (tRNS $'(+/189::;<>?FVY\mIDATxmMHaIF$Bx nBCv .a$!u$%tcUD(xCBu Us?ٙ9< #4 nO}S `"f quV;IAP@^!!# l[( !JSVv4Cy)JN:3舦V; ;V tn! J\Z*ۻ~d7&z%3V\1#`s? ݹewy>Z_p*WcË357 ,K=|tgj ݛDVF@?{1 ;HɆp.2zkGu <Ж;ILpul'O'玉w~j 9cG  g\U$O 0 `w{ W BJNer}߶z@]˺R)&O|y{ -Apg[;`L]ap`Lݸuߔ[n˰#:_9"G__MlV!1 SKZF>-m4: d=x|/u8!}PjεX`-EЗ*I!,AՎ[BQı@9~_DPOpSqTU㡏= _KP~<%d}ǼwOuwkf Q$ K{\Ɗxq/=X 9iO>GLLL.ޝI [syO>`ƫMXH+ւ!_eG$؏$}#"?Nٍޙ֢N@L^ZDD_n}^2~8%IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-x-vcard.png000066400000000000000000000027151237252063700272600ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<JIDATxڵWKoU=3?NjP %E( TlBRȊس= V,X@B ڠ@B^<_>{):3s|s_DB%` TH 9uaD1OW4 pu_~v| @4 -@*i"Mw2sV@etr؎"iko`G԰N2 #HyRC!m_k"B٦:*[MhQ. `V PB B!H\1<$q]𻺏sp0y2dtNhS!ܸ7kBV^ QʽJ? PWx155y {&2V_˕)t]u]RpHH>߷x0v*g&Qۘ4)޹^3}8CiU6w7e&M|.4ڞH_^ݗz] 1hi5^![lv1p{󊔷O`eJOؽC BɡV@<*a6f\.FVbj7k=a0^p2Jo# \!=,>TfT*>|;L4 5 , `L슔4RItNDAv*nܾ0yZMO|5i|K2;@WeL& յӥޚȥOKˇ/f8 ^eI( @A74loL.JL@.yONNpk27'uIMCYivJ;w>Gm rB9!dqT*DannWY[[{L 6܉NLLHB-ͅǜǘ}BakkhqqԶg(cwV"!Ha O.bDBGP!h+tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-xmcd.png000066400000000000000000000025511237252063700266450ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWmL[U~huP>:YʜY2513K?c(1 ?l3dS1&lDa )0nBim{q{OI-9.K R"e`zz: 0Nڂ>CCCg#0oh [.w nu9;ʷ<8OWO-hGp lLz̮Z@X,/$p/<bː&)dT!8xyEZTWW0HG6ki >ćHI,=. al~M"A88Nǃd2}M =rg:DKۉzc\WXLB$l.O2U"@݌4 ȥ%oL N׋L&#W92%? !`Ɉ}}}2u(Uuf $yHŞőȏNuAydnWNpcJIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/text-xml.png000066400000000000000000000030211237252063700265030ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񮮯ֵߜᒳ᥾☷z[_aeeih녯mnpu|쌴v|}터{4(tRNS $'(+/189::;<>?FvLIDATxmKTqu:8c|vQ-\*VQm6EP@[XEh(e䌚C33\'s|@(|tռUdN$ IрPm3@Z\({R˻_(MlZBrJ !4JH` o L 1pV]d?hId@$_$U3]pSqB^!/W%W[ F cgTU@TbfInYzYnjgGzY:ǹ0cZ<`@TG|؂g&sW; #ԫK`N%$lr$CpzTwWLu/mhpOsmg@}&&4,] 98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/uri-mms.png000066400000000000000000000031471237252063700263230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/uri-mmst.png000066400000000000000000000031471237252063700265070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/uri-mmsu.png000066400000000000000000000031471237252063700265100ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/uri-pnm.png000066400000000000000000000031471237252063700263210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/uri-rtspt.png000066400000000000000000000031471237252063700267030ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/uri-rtspu.png000066400000000000000000000031471237252063700267040ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-mp4.png000066400000000000000000000027751237252063700265440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-mpeg.png000066400000000000000000000027751237252063700267740ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-quicktime.png000066400000000000000000000027751237252063700300370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-flic.png000066400000000000000000000027751237252063700272260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-generic.png000066400000000000000000000027751237252063700277250ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-matroska.png000066400000000000000000000027751237252063700301320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-mng.png000066400000000000000000000030321237252063700270550ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-ms-asf.png000066400000000000000000000027751237252063700274770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-ms-wmv.png000066400000000000000000000027751237252063700275370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-msvideo.png000066400000000000000000000027751237252063700277570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-ogm+ogg.png000066400000000000000000000027751237252063700276430ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/video-x-theora+ogg.png000066400000000000000000000027751237252063700303430ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/x-kde-nsplugin-generated.png000066400000000000000000000034701237252063700315320ustar00rootroot00000000000000PNG  IHDR szz pHYs7\7\ǤbKGDIDATxWmTU~νwfvctm2H%~"Q?~ _[l0q!hˈXGX!Xd~`ۺ+̝羽m4:3{9>{Μk6E ܹs޸qD"AGࡖNW{ <.ZR7$8"5ك`y?Ջ`/K sd3:f/v e܀qbkL) Ru*=%?eEyZe-m*$eLH|5i01fe*0CK@L qTXuRZ(of@͸pG9+3X!0*6sat[ЌAKL> Ф3@e1<^yqwJ Ay"`C &˅ȤTR3 )¢24%_` g2AEmD.`Z&E3`ؼ9-ќNWD[0{,Y dSˎHFK"Yd4@@F TfB(ڛaU qI]( Zri[^9 Vnocs85h3OBhx7ghkJ x, Rvm<*I _^=Ջ zrlD\^]K,aH?J ) F#cС0J%FR>/LP񪉕HjxfX86G>}_(:t%Uxief#Rc'WE@ %߅|ۇ e&<^)2_JrNJx-ˊ_JHr>UumBwix&D{ҥ+D$ئ9MIHLkXnO?y̱U%V4M1s.:2e[c~}]vQ*jxY ,|t_TmAxVŶm.WuKoO=rYyE?$yw>UC/}RȐP|<=JP* BR~mֳf͚@c;!m:JkY6li͛7bŊk'Ot^]֭ѣG%@l(Sjmjs|_> ]'N|u7:uJyZ ܿjvMׅajBM}~/JCA я?ǎlٲ~7|``?~x\.k[V]CQ^pG:thΝ;?o ]^~X~=QoF̈́e˖V'wp#˙=gϞ\ԘNdنF6ʻ(,28є̡޽ 1y"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/x-media-podcast.png000066400000000000000000000025311237252063700277050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڽKPup e}1B#@BB«"(i]@^.mSzrFy! vyb"6uVǕc3rW(! G7@uM=̆gOs!AVH PS[-b07I{m<>G.tGJ|0 0okpNX`,'S&QO{=[𦓼\ֹӔ0}j]wk\U[Qϲsbf]y$vY1|UXkP@ P墳.qe ]xOk |  HRxo ‹u6uT(uFk|7DΙ @;|"?5@I6:dv|{.N.Rx} uV3g=A8 [|~og<0R "-t||fGX%bSq|:F3@W^Y,u_zO\| -`!oC4wxwϝ;yT_|YxF/Nbw>Do`ipsǸ1|Q>^4Yv^ tvr;spKlN[x(`2g-p"胉f27(s90gXF{ ;?pMe :a\c#f c[~lz-{ ,z{oh 4;K`:u^o]ݏu΅i@e Y܂ &1@yy]\. >Yc߇@='7AGGaSˠqFB ȺV "Y" v`1 XOO,I VʟZԆR+J<4" ɫ)iBh5blD2^rеXxA 5 [P?#=΅+0Pru'*cq tKzL}|L Z^T{2%( %bO F`H$}3]R5F$!Æ}K|MJEY3 , k*9U #')Jlhe:^dThtNӋ([5xHY>AJGf=j(WA@B6q 4n'k SoTTJ`)N /֦Ϸ/[Z r]{vXUTSx,0A<0ωm/!P`"^ij݋:Do{&+_+Wn b!|0^7 p&F%d:=C5|ɯ2͖ҥKo3ہi~awIJ9ab?#clߌJ)2\`i?_~h$ҔciY!F2,&]ĬC2g.R "zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/x-office-calendar.png000066400000000000000000000026461237252063700302040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&|"@hbDH(l \teڹϹm̙N O ]={{o[L5!ɞl#d!br忾)1, W@]y ԏ3n2ɟxO twmTύHiܲLM6G/-Dt$KMZ4F|*G8Ŧk$#% j#fer%,JF'Zf;1 b1tm4S}O@C NK h7)p! X8:n7pAEA'i_߷rCA;,?2Ut:]VQPknWZ(eL\ZE>"bͣj-)ȥ,]z Hea 3j ), AX@@C哵 ^Ⱦ.yz@*K Z |љuty_ՂՖ -D EI/]>ݟrCR90-Ĵ՗ܹ eBz>@\Mψ${kmxWDll#I#A,{?NͤC3tz&I|ti$B-fO?, 3RaflxqfHpY8">SN-*ј^W?t0'z;}mMcuܩVVFGKZ'|=NUX|;$J5&/Ɓwf͓MW;6a@f=pZ]*훏e걽kN:rU>vcIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/x-office-document.png000066400000000000000000000014011237252063700302350ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<~IDATxڵWn@%R k?6$'J 6k1XtrSV띣 }"ޟ4XN"KSr`8яK#D!ȗľ:`B>{MauyIENDB`Collabtive-2.0/templates/standard/theme/spring/images/files/x-office-spreadsheet.png000066400000000000000000000023321237252063700307320ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8[NCedEpYhnji@.Cegg/kohhyEچ/&~$4~itOjz*ިrΒuR[@*vk*T(sX:?/)u9Oe ptkwIiJM|6O&4ÝJq/( *)?^3LmI]R(".XSmT*֛MsRs\R֜TtrpnuHt?#O3@A_ Bzc7۽I)jn'S#ڮpe^}(ݏcO ˿?6wItGf6eIENDB`Collabtive-2.0/templates/standard/theme/spring/images/input-bg-a.jpg000066400000000000000000000010231237252063700255560ustar00rootroot00000000000000JFIFddDucky<&Adobed        yaq L ????!MA?!?! ?:??)Collabtive-2.0/templates/standard/theme/spring/images/input-bg-a.png000066400000000000000000000002361237252063700255670ustar00rootroot00000000000000PNG  IHDRʚ%tEXtSoftwareAdobe ImageReadyqe<@IDATxL @ XZ\h6줵JXϹ3gfˋ(8ـk٩8v"?:UU}.>\q{?|) —^Zy<*===?D"!zx-,LO7wwwVa -?B|6t4)#f 4:8VUUܜԩ| `Z'෶BeX=~}Ι 1H]`MDŽ5e/˫ @tii)H$yϞ.I,v>@m2'*1{BI_]]><<K`iWǵ'xz"섀&sTqs@8v@333oGFF8W3"[W*]JJVlEӽ<*bͶS=@)n}vv6W*VXx9+9ug/@hv 0*\qoŚٝ*ǹp{F Yg"v0 W>7if9QqhVtWwO)毯W.|ŹZf\ Q1ͱ= _`"捝FgM4ڭRX?>*/ϊ/Dv5@$;!,*;@iQ?PlY  qKqLgk&\@~ qx2ifÁFuP` ᄐ |1]#~iΙ4 'CK:#'''3ft_EE&LB,! h*x!j/bsQӽrv -77ɭht !X_\\@I^OJ ,D. I"vcjT}p EDjvI4D\I;l nTW1_4Qhd! n"yC?>>Yupsaa;Ut@K K\}<{>>,//ot{k d5cVg|+N>TObЄ546r,x5~l D½EաhO^r6==i$ .DU<`屩̧IENDB`Collabtive-2.0/templates/standard/theme/spring/images/login-keeplogged.png000066400000000000000000000011161237252063700270360ustar00rootroot00000000000000PNG  IHDRЊtEXtSoftwareAdobe ImageReadyqe<IDATxYMK@6UAA/b'=Wx " ~xb mI&,tξ&& c(JwJB Q 7b!,xMEX~dMwbX i Kf<ݢv`)gȲpf*q ^I OI9'|DFN%A&яXNH~j0 Cֶ~RcڶA0, ?C4?Ftٜ8eb(͔I rÏiV>ׯďX %O8>쌸,G?@IA)J 8JcscVe(k3`HHɠ#`͆_FE[S e\jC`psG3"*{2 ,N?"`,.ugEГHƸSpR[GK;k9 ƅ|feGY[s (lQkıFAُ<iq5D}@fU8z&y?zA<a|{u}?.t!10|c .gP렦"mb< F(epZ0p_ؓG߀Ry7P3͟ 4|бyo5KxbJ{n {MSAG>ooOV٦;e.g!sBmݍ -ܧN y`~< &䩡r5}Z?3<LIqjYoV8Vo mӜ641BSNgg̑F\E.sӬS|@)=iӆ6͇]P cJi3Un[?ܖ>3 RODylrSL/&W@>|XRMk/*m[eZgzX{g~)sҕX]+%\⺹"LKQhζ2,NF)ѐW?&{Z5=Nbx#1:yܴpzƚS5 |E>>ߔYkisYhcqs,iVl!J3+7C?r U&hA!+BEv1Hm{ |)Dl"1#-gyOs_dd 6ṯX^js!]#ݮJ_7& (&B;|dmj9N2֨mvיLW3ʦ(tl`<ײLhOy MBͨS1'7EƑ`R|S9ՆSy5 !h'j>E669*B}umBZOL)CQxT7"_8RQ&IQ[7UL8lad1{Jֵ\Bd.{->m߷:#>LhbdzF+}XWk1ܿMm< |w#kVED2fQW`NBDdqNE֝m)xmP͍u+qaBUG?B/3<ǻۤƯSYEe;@I+ҋW=bʭi/ȡ1,(ӘDO{kT_N;Hbto{@Q|^1Ճ—A%j~cCK4{nQ)8Ҭ<a>7ju+Skoߵg(yЗB8__]tz}Ձ`Dy*B2VZރR :#*I{lwv幏+B̋Ҟ :.O8CKcgmmK؈%\xO,h5G^]/~mXDbF#V7$9)wϞsw\1ϛ-N.5 qGԺ>('"::bR6@̄&`4"bץ;MX%\h8){?ŋ't <H.]`Ql޾T*׮,ܸ8\"fnAs( }G' 7PB!ly9&2idY$Ir9Tp4zhh=wMS ';;$zL@A8ABR9kgo@25;zimL5Ӿ]аSUɩ)(˘dK*Tn.h9R ヹqD[O`u`GD[@fhpDj쥖6 01Q^IENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-admin-b.png000066400000000000000000000026401237252063700260560ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<BIDATxXKLGv~6`p D!A_JD{ȡRKHMK(jm.9BҨj$D!IH%m)T `cX{׀vMHoZofVPUIʮŔiH uGDiDKh(4{.(H:g)K )0Dmρ: w*i4YL}gtT.FL9U+LyB1y hYy9%R,LV6c$"EӌFhTj׍02-u[CZڹv>CHn@ev޲v-P2am@:#Wڐx=!*[z'cf[*>I ?Dv`J!XBL̺=Jt[>t8û3׋}ߛD9)l||3zuRyz~mQT,?^F4t5fGmu-74@Vd,|!.]T,$8twvx<~4h֭b !'akBiڨsץ#,>߶evVUA01=EQPJD)I&z8ұ 37 9wFWBs* `DA3'b߿cW䳣G;ᰕ聼Bf2%irUc9F4C,F,gډ4{! *UILsOz*xi *%]ybB(jW&)NjD80E"[rGTLn֩S,YA,s[+Hoi`2dLfl"P SJC$X%JX E2NRT-Hv үQ%eF$(lPR [R`wL^kCF>\3Zk0wrV;HVǁ罏q~?" F~ 'OD-/bAH;Z/njs{hڍ\+~]^KwP91 h2L6>uޯ0*fɌCD"k^hFfOb}wbBqZ ̨G&]{ǎ:x_(ȿhmn7_|y<)ᘴ45r7 |ibVsgm91 F{@ --G أOʰs3}@.}~8,fs?'0IENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-admin-c.png000066400000000000000000000031741237252063700260620ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<IDATxX]lVIAPV(4 MC4D>bLB{`HѾwW!M-iRЦӤayR ]$IC'N5n4mw9A0JvxQË ܃̈́x&mU껥+ffފIWZBG^BsB3J'EDP{*Kz֚l+p*cAY_\O I4pZoX9@R Rv+hh9Hp0ϊZ+f*F=X,ęf IV*:,|.$LO/8X9@I |9q Gzζiw(/I咆) dˊ-#Np]F{+r u;3 ȁLp%Rߚo=HJn 1NJjm$c$-+ds g VE(9''u+RƸE:QYۋv.(`pEpV.֌NtnWCG>pHGUŋ. 0gnB]ό״wxbg{glE x%|盛w~;)^04:~/rf MV:uOHp`?}toJ,v.I ,vjj- C/#}y}@1{&C喙Ґl|)4x`n坂 (F!M0W lyj$N:"Ka/Y>66֠ہ kiF: @PXJfr F/i ݺ8, ܛ ^Y/oc9=qOeP0 iBp7n4]p799}ҹ#\3) :F3lwC]?}V$DLFyڵ3wWym24 JG^'r<5Nx"a<p477/\`1#㸮ˁrŇoBS$k31I1 HӀ\AWA 0kooJ<+/ߣjP[[ |>e2|P.L`WW׈n!?o2XF'nݢ "osU3ɷ|9K1T9,T2"$ՠ|Xsr*\u+!k_X{V鋙U jfcte0Ⱦ+H*P.~`zk3O,g~ݮ>-3ƽj?0'\t;~C慈̴{SthF,#y(.ه^vāKu Ӏ&z+*ߣq|Qz*]%סP y?؃ΰ\8Ք BgG糿|pt{[s*ZTϡZ[[/J< ˳WVP.%Y֊([?lsV8_< 9๹DeIENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-admin-d.png000066400000000000000000000033251237252063700260610ustar00rootroot00000000000000PNG  IHDR @{usRGBbKGD pHYs  tIME /UIDAThXml[g~{mǎ:N&qta]!l&:N*HhHlR5>Mt_4b EH+e:?cdkŤѬS*4mǍݴ}?r#UYcl_sD^sC:cJt9N:V:|gZi&W $"3 A1 BD7F"ŘFA46oef5\.FP'T{ Fۊ-V@<[YE(tfцrU;p)ڛEn2Bt[H-s"28"#ܼ7"*7 mIbm`HDDj4>6wȈ\.3WH XDMU7dc^Lz6[qIc: c5v: kDs ,^Z:o\)nTguvi–/r#"OKU[lLb+M0Ot97&'O'biքB%qoKmwU ]@JS7Oxg-DO=m}t FL }Lm۶2ݞE ¶q\8 X)⥞m kD"ADaT`:Jf]g|vç*Mp{]4N!4 c>G>GTaKYٲqt B m*!XU:=r'wޭץzALwiC 2\9No>X#gE mA)% =EJ` 0 ^U uqP>t ͷ!|{m7QH"M!Ce/DG?shÞ'|EK峐J"tt6I?'OM0*(B&hj\M[/篨릊Jwjy^o_}=k׫jQDRiΗx/4brt+|魉~lݫ$qyT/}㉃G>633_ouK~x\~]Z xS=? K_o_v]xǙٹ-y;v~C67&־rЋ 딒]A ,UXhÆ\6""èl9B̙:WO{ zl|6.b@*J!m;KdhJ)MTTTz?vϣuuC+ @J ^JI03 }}$#,M\6 A)fRJA*IBӢx][pHZ}#x % ᰆٹ9.\)0hb x0XJ?T.ue`~ٟdT`VPD05uF6ˮm[)s9EJ(xҲdR]Ǐ~4qV]7-˾K*sB_'0V.K ,J)%HW$ ='veHE.FD|X(FA\7$u] nwp͚ȈNV2TM$^{@C <hb8٩_fIENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-bg.jpg000066400000000000000000000006411237252063700251320ustar00rootroot00000000000000JFIFddDucky<Adobed       WP ? *"X PPQ,,U@E((,A XEXCollabtive-2.0/templates/standard/theme/spring/images/main-desk.png000066400000000000000000000016141237252063700254750ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<.IDATxjAOULpbB1,&`0\E D | .&A>m)QD"!2)ϩ1LjPU]uBk]I23xdGQBB6ed!AvL~f v9@: jd5ÎdnLٕ@l$>RwF Ҭ$_SIfe -51k)sh۔(d4PC!_g=jglDyjfS?aeҲɬlQܟ'AѼ MA.h+ l@JndԉhPcBc0MUͳՅ40D:ӏ#LyUv z&#n\!DJI 6Žhi2 +#,U1GIe 2> ED< ^u R>(LOTmG v Li rN K5Lk@T*!pG*^PP\mKiz-v=FSxv(fw wN:Զ@Y )̒+f9 TU$ e_ʛ1bvӦӺ;K!VOCǕ許=;;K(HY8.f2d2hS([v&nmm N~ޟt]廵Zm_%Q { `m~ttwIK \UZ]h4쯿@ೞ#ʪҚC(!өs'O EQ^"1 X]RFodX,2đkq(ρ?" ƹYMX95b#j'n$rll,Ht4P|OD` KR6s>lmbbbs}}&|Hq=n76UU]Cp"&@EH$Zϧ[>x'mtuu٢'y ۥA()ռ<8~F !GXܛ*Jn%\ <8~%\D!2!D"E>x#G'R)?NOo m\c 7~rr E`"}a6lo.r5Ԁ"KxEE Ⱦ!oSb<>>ƒL3s~z}?>>^w܎wvv`WCn5XxS ՍØ'|3hb~ffW[*v5"X=Ө~]4;X$9\I|lʷj*߸s+pGG2!v'| dяb jЪp S###6s (k/H fO)IENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-prof-female.png000066400000000000000000000027001237252063700267410ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<bIDATx{lU̾n%KʂƖ *@ $Z!BƠb4+?j(H[@BMFSWAY;ywi)l;tcI~9{ιs/H$$GHQ 2c"At.9ݮCq̂d-l& 1\H|hyFHVю2mRCۘFAm0rU(aXExE/"-V^m)N Y)v*{̬aIחS5SQr\HO#J&0*! EvGlQc"S-8:9:֛X:L:VQ =fK\y% "w'/,4 _KV&4S493\nEPe H/#%s`oaɪayH\é;@ˮ]98(n=r5%//Az#}j1BrǹhZ!|w-`&+ -;`8l{ <ylEA|9z;HNPjx"Et; Mh RZRVLfp8]-}hFN@EH HqDɁỲpWSy.-tZ'|x s& gh!H 3-_L]8n16uG G^"wa?7i{i[?Qu/u:,-ʳg)`8:x}sgO(|~nyb,v9X๰ȡ ꎵzF+J}.979 h 8/͙R6wv.W{=8x#IK rANeok΂斖q2c?jm[Kѡ[SD W 5P/$ זMCy< HK_؈~6]LË.0%-8\HΥw^Ұ=9AGH^t 7x:%s\{/TSWzp//NgBy?w+[IENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-prof-male.png000066400000000000000000000023771237252063700264400ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<IDATxX[lUwҙ-[CMbR#a#R /1PMJKA iVbm6l-nw2sf<;X {NL_v9r$v {9-aژHiH.%y K1%@& b{B6@`=@~"Qbl!- ^ ! 1Ak,s4Ia UZh9y*ϒK112/FW\xКa~CT4 P-iȏ(%RAp(4HY*Rj4!lfXm OqeC۞@1>ФfcW~B0hK49:d}o54ebj:$p}Hj͚bJoLSPF&  ׹y}K-x}mjtQOQ]GbNXl "DG$ CLSmDIVk!&zsQHc$HB(DSǐqTrx9!>:2+"g/ \ AHF0̀LU8 [يJ_BK0 =]ۭ^Ukc5VK?:.2˲{} I'`wNcΝ?j(h;fÃ'O>@(| m -C3={6S?vNLf%;ly@M>>>G wsFl2.ِwk$d'Ï?Q-?;PFFש v}rjr_T hjl|d4ĢehwOOǛnL{c5Ȇb6AnZӹord}}%kȟz9H9JNHIENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-settings.png000066400000000000000000000016301237252063700264050ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<:IDATxMOAm@E5ME1i{܋Gc@PWI4lbR,%-@DFX]v ]-qН&u'Luqqqc#v &g8'q[(Mnl>:8"@礪v@\RCMRC vZ 0]y"CE`ܕ3N#Fp}:<pgE D [ TQO_>*~*xߛM#@Ku[fD;f;f]ོ8h9q/'(FT'nƄ= vnCkl^{ 6}[:$I,|8niozc<~4F}5["@BU6[E9B t:oZiMRm$ X鹭|glVVSDS eaTGU"">^jKP.;3(JȾDGy&ZUUAN:^/||86%>C8cx<( #d2nuu5g=|vv8677TV@PP(>P g- r${2(|ooMI; h6gpuV닋67 B6yשj;;ӌC"3KQ̓;;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/main-submen.png000066400000000000000000000002611237252063700260350ustar00rootroot00000000000000PNG  IHDR ڛg`tEXtSoftwareAdobe ImageReadyqe<SIDATxb<n H<8ğ82A9@Ƣ[g`BD7πP>"/`@ ڨ6HIENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-files.png000066400000000000000000000004011237252063700266160ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbOc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@#xiIENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-miles.png000066400000000000000000000004011237252063700266250ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxblc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;If9@?bә W@ AlfJ6ɧ@Ļэ dc]#IENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-msgs.png000066400000000000000000000004011237252063700264650ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbLMc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@I#ήf<IENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-neutral.png000066400000000000000000000004011237252063700271660ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbͳc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@$_8IENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-projects.png000066400000000000000000000004011237252063700273450ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb/,c``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;I9@?bә W@ AlfJ6ɧ@Ļэ dc]Em#|ZIENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-tasks.png000066400000000000000000000004011237252063700266410ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb4*c``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@R#hxIENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-timetrack.png000066400000000000000000000004011237252063700274770ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbwc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@#9IENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side-user.png000066400000000000000000000004011237252063700264720ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb ύc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@##Q;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/next-side.png000066400000000000000000000003331237252063700255220ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<}IDATxb<31:f b@0IxO/6IdSI tbk IP1(K 4$ >ĿI2 M.X]ןΒ'EIENDB`Collabtive-2.0/templates/standard/theme/spring/images/no-avatar-female.jpg000066400000000000000000000060021237252063700267340ustar00rootroot00000000000000JFIFddDucky<&Adobed j        0` @!P" !1Aq"0Qa2BRr3`# S4!10AQq a@` q! S#[S[esBJS#׫T6ئv'b@2>U;7F]q#o~~S^A ]^AZHQUP_# ~d^S2!`~i( w_t5_50Tp*RAG[ %?4?4?L6~ZlJzk9#-Z򄜍ePN,4lMg|)Ȉ-(j :)$_fZ;K2+ݡ:MiXm'I }V43hv)͔BZOvkp[`hp)v" ]C =d<"EGt1fݏ; G1"CJ3w9L*scte+p X#k--AAAF<;I2@1uuZ壬^R*8w11TV/o'%{Ԫk5ޥr,Gq 6lx$Y9b8;t\;yxԸt,{GS-c]N$4gkOs+ P?2l+nhuS?_B";ܹyF;72:V={-˗._\a?!Rt\t5~yǨ*%:x砣W,CùrYr?!NRt~Q>Cgn1^+JҠ KKБo,E w ݖi͎o > d]>~./kM#Oɸ^@mk [e@$% ?WpJ*T\3@*TRJ @Ԩ"h%܁\]y-gEL1M$HBt7jr!PPYxIuX˾T;o̎\ODHH*ڏUUW(U@űTfp2su3KE/AA4HRxb:JܷE _%hi2&>i$c! /S{z̤"ňvfuo,0Zڥ nm}$!I ~y Svd9۰e2r{_& h 3PK!u'GY^HjGj~|Xs ò <^c!RC;|n͊;D g"CKnc9<=UXU&*19<} VLcA";eJW(yYU?~'6.:Bx5 }<@3>噛 X;ӬX:`Xc /.,X˗.\r^.\rffffff}?Mj)o2"EˌA a,i$\e%PAa:/]; G9$)?g1h.2u 8քұj:|MW꼢},DPڑI@ZLҪƔ겤D2r Vz3+<2\޳iŒ#/Dmj̅XtewlF7==VU&6 sB}BuۣȠtyk7>KT⤥x+PҔ+I&ixdžTa]Su/?!DO _b&G{ ;h}4=XAʓ]㓴GR"C:.\Gr/󎛜Rѥlqo|<!i ũuxvꓘ9>IbYEn~n/߿UBj\Œ\*c Ad˗/\?! 5aSGg|!쐗:3}+ ] ^3.\z\r%?!{ 5H)- `q ZE2a̪^;auqu|cGS/ Ilg %, ?@_` g`?[]M fH lodO1ӎ&ik!]ɼm{ [d}@$$ ?ֵ*V4RJ+Gh J*$H @)W.ΑǐbbUnw$tx3TO.•rAcԉ7~vǀ@9BKFAL U:&bQлx+| 0 a, BKςK` xP@AYA#:A2+·VF1QbR=e`MKrB }$!`į(64Bb,cԧ!q+_::;ce:"sgcNnAJFn m}%%׿V ww'#S##CB]0ۧtW֊U*fB5*; ;n%[[&GKMl.1! qdY䠽cEAKyD&oxP;;6Ӎ]pyI`VR] :ȱu4 @0bGA_\Xc.\r˗.\ r˗33333?+lµT> 0xߤA{ 4d> e*R^Dse`DD\M=45N"eO?/n#6<{Ƿ2 Dz[euePv!Dcg *Thrʕ*kEyU7TzNҧj:/Collabtive-2.0/templates/standard/theme/spring/images/onlinelist-hover.png000066400000000000000000000001561237252063700271260ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb@ %|IENDB`Collabtive-2.0/templates/standard/theme/spring/images/paging_last.png000066400000000000000000000002661237252063700261170ustar00rootroot00000000000000PNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTELKKyZtRNS A$IDATxb`bbb`b &ÙL &*Y ^ P :IENDB`Collabtive-2.0/templates/standard/theme/spring/images/paging_next.png000066400000000000000000000002661237252063700261320ustar00rootroot00000000000000PNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTELKKyZtRNS A$IDATxb`db`b@hqHj" `pIENDB`Collabtive-2.0/templates/standard/theme/spring/images/root-arrow.png000066400000000000000000000015771237252063700257500ustar00rootroot00000000000000PNG  IHDR+fltEXtSoftwareAdobe ImageReadyqe<!IDATxXMkQ&$$MSZԝ ;qZĺWJ]UDETDDE)ꢥh4z^|5R7fpfy}&'bc#eppwjy6%0ȁk~o겦MWGXH `0,T8YV_P;%TB$D'y*FyCCK!o\BpISkF @ C'S<0P"&FGxCwъ_h3] ReÃE1/zwd@ERMks7l:RZB!0t]3dπq#ΒB؝5%ť/=e$բSf $() XoiL^#cN^ (wvjmGV*բ_y'fPn皽oӾqJJQc`RGG_/ Bnie 8O\P&^l;]Fǫ<,#W=mR<"fD[xJ%^*sYmŊ-DnSt-e )ZՌ4`$imٶ8p.lK/'NbjԐm m)8-.lKY-Ao٪],C %aA"A? m murHnmƖ,nw DaYJlńmDz%k4-Yؖ,lKeE~44pkM&eW2Ԇ"`jN6IENDB`Collabtive-2.0/templates/standard/theme/spring/images/scroll_left_miles.png000066400000000000000000000004061237252063700273240ustar00rootroot00000000000000PNG  IHDR,9&tEXtSoftwareAdobe ImageReadyqe<IDATxblsc8؍21 j 6 F6$6,f=@?a@< a@ &,VMa?.ĀJJEI6wl@܋-ۻ| fBS=w$=\5ڑUKVBKx..~dSk{IENDB`Collabtive-2.0/templates/standard/theme/spring/images/scroll_right_miles.png000066400000000000000000000004021237252063700275030ustar00rootroot00000000000000PNG  IHDR,9&tEXtSoftwareAdobe ImageReadyqe<IDATxblsc``?q+c> b)0b &r' w%!]5JtȀ 0*9*9%Yb Mg2_bW\JC3~\v-gL&x7sX$l,\5kQT##LIENDB`Collabtive-2.0/templates/standard/theme/spring/images/search-butn-side.png000066400000000000000000000023741237252063700267660ustar00rootroot00000000000000PNG  IHDR".M˹tEXtSoftwareAdobe ImageReadyqe<IDATx]U3/L\Lm b?HExWR,4{'HUtY,(Ue!+MB^%̌9O;&$ҽ9o908MN$ԛ{9CpmC f_IÎSWg\,gV8@`f9L(gF(@`9^YIENDB`Collabtive-2.0/templates/standard/theme/spring/images/statusbar_complete.jpg000066400000000000000000000010331237252063700275140ustar00rootroot00000000000000JFIFddDucky<&Adobed         $1!1 8`i?????T??!?!O?!0 ?/G???Collabtive-2.0/templates/standard/theme/spring/images/statusbar_complete_b.jpg000066400000000000000000000005211237252063700300160ustar00rootroot00000000000000JFIFddDucky<Adobed        ] S&!" ?099}l޸&ɃCollabtive-2.0/templates/standard/theme/spring/images/statusbar_incomplete.jpg000066400000000000000000000010171237252063700300450ustar00rootroot00000000000000JFIFddDucky<&Adobed          z"a  __???????!'?!??! ?F??Collabtive-2.0/templates/standard/theme/spring/images/statusbar_incomplete_b.jpg000066400000000000000000000005061237252063700303500ustar00rootroot00000000000000JFIFddDucky<Adobed        XR$! ?xJ[)Collabtive-2.0/templates/standard/theme/spring/images/symbols/000077500000000000000000000000001237252063700246055ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/spring/images/symbols/activity.png000066400000000000000000000025561237252063700271570ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxsUdz?ݤI时VJ*RhZ$L[|_/ʣ'htJ8cb;eH2Hhj+_l~'q>w{=`$/ { `9R/ `0kL3IŹV_3 5ʽR-*tSz{7(̱5[-0nZɧӜ(KQP+JQT (mEOs\!5V.[x=Z,h4f.;TBx$ŲlEAj5{<'BCFЗUF޵p$)hɕG@wouuO5mnh2ix> 4$-qL(!w[71Nϟg`9GS8qэ͍ĝt|S.f }}} C`$Ym!\4񰧧jlhS$iMO)X,|\&\糙L| rR",[W6 L/_Ȼ*N-lYZyC`,dy*5REJ0E#0* s&A8V\hR')0x\Tj`PAM[ z  K$;ṙ0&̖W(vE vc1(!ٚvmmMuz#XդNvp{K陙HN"z7bX9MBo|~Xxbiwv úľ˵ι©ոÿp ! , "^1YIL[j[&u︞ŠmFNcT5imv_&e[= )z-~}ffyiwrunpv­IJ͢ȷƹӴџ߻{^!3A!EVd ! , ='j XWLYxzޯ bXH#6LS ϫtEqSpj=pBeM۳x૿iuyrwz~~kpdqʵ̷μɽĦƨO^AzA *Xb`0d^>b>! , =t" Wj7YI;ݽ69O4B n"iz%eX%bwfolotuxSy|zcfAYpeijlnI7 µ׹H]Ywo~E$(513tGĚx%7_{WS E^t{Tzvgn}rDjxaƿ·־֣׎;_9xb 惸O._3miB'M*~/iD o^IK~ ,! , =ɤ|7 $ '33URL+#(t+);HMJk9po~^Wْ9]-vAyNzQVpm%q)}rvk\~Dh%̼ӺлѾ8`s۷P! (1ٟtw_fqiyk{~dfEpz|&Ŷʺ̼ΨҴmM[|%a|#8`a?*Ȑ]D%cNw&ݕpJ!i! , =ɤ|7(j%amɦ3wF,cHC( Kb^%5Mw-f7.\LM᷹{_u'WmQ~rv@jyYZg?²ĴƸʬ׼սߺ][!z :h7 a w BƏ5^8! , =ɤ|7ٚuqpc 79[^Lp%LFͫ/Bۯ;NtX]lg^G<gqZxVzd|S}btôȾb޾ ilṆ*pb+<! , =ɤ|7YIk˹@N#6ZvdtE'yVJ49W5]oY ^j,gϻ>~Xxbiwv úľ˵ι©ոÿp ;Collabtive-2.0/templates/standard/theme/spring/images/symbols/basecamp.png000066400000000000000000000030031237252063700270620ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxXK$WUvk/Y\G@( #(2@"%$7=)B%#xPA\pq[^guu$ ~^+ar]Qޛjaz6wXfd_X6w/be< DDknn-..|_:|.K9G---'x%`28-774!!{]_-.$$D @隦 Jw@ammmePXwyyb2UUaʛZ[[ o @!-)ixx8# z,a?999Cߛ7tec6C=iooůPt; i憒o7B[02+HvvvhNNKHQDDI! eQQQljjqSmllp`J7sĸ(V  [\\d,::183g,3330Uj\\\iyyy.X}E+++ *sMfgg[__@,,>>P}I K}^UUɌ&鸓 *++`\^^櫍+a]\\ v||WrVIrrrymmm@IϤ~gU1=hg !2K^^g!'!!0'v3нcF"en?0~fO4!#r%&$G8#oG_ sn+49)11I[2+| kMcЬUZ Hz҂ D`U?h§pZ "{`gB ɔg} e ̷}}}PKRRvJJAʀX0zvQ(b/--mvGb)צB]ʾɯ%pܯ1$pj4MA $ǧ kkkMMMH T@/ f}BJe DDPSS (ӥ@[NIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/blank.gif000066400000000000000000000000531237252063700263610ustar00rootroot00000000000000GIF89a!,D;Collabtive-2.0/templates/standard/theme/spring/images/symbols/closelabel.gif000066400000000000000000000012111237252063700273740ustar00rootroot00000000000000GIF89azzzYYY҃䌌PPPTTTVVVRRRXXXQQQSSSUUU{{{```WWWOOOLLLfff___KKKޡlllxxxyyydddZZZﳳ㇇iiiNNNsssMMMggg|||ccc߹pppeeevvvmmmnnnooo,/2X]$(Y';8*'G?,T!'M&HO*DS0 4+8FB( WN1I"\0V#>[+EfiņPZиjH *806ܐAARTAP8Z0ń%0Ƙ$h"XD 'P2ȀPT Z$ = ꔫWJ;Collabtive-2.0/templates/standard/theme/spring/images/symbols/customers.png000066400000000000000000000031321237252063700273360ustar00rootroot00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME6.)!IDATX]l\Wsνw׻ήc'QDI!HiqJU  J҇R B^RWZ7uWJh&|ٻw93y觙93]܄X3l6Ud IbN8?wn.=ݻWDx@[DB! ybpr ܾ}Wu'$IJ0乩y~+NZWuƘCm~,XkATfAXkFP *w`rr硯*8F@~C8fkdժUnZ9$ẒwJMv5vi;" " bQ""޲=03O{DyªH]8&fglyeݏ-pfe(( ! !Pڕk魞@D@BVgMe_; uM6Q6# d3(NEL }tV_%Ӝl&$P&ٌl-[;z K/ )aQl1޾47{> _-xW[Cq]S K9ԈS{|G}Yn¾={..2ͮ[Bۻ*َ|?ћ7> e$~ꕺZr$Żf~[ނo|pexx#s;$n-T֢\{PWv N>=_G{d}gt3ZOWk5<3r&7.Z+S*2>ܯO/,,Ȳ##X`~4f ^Ҋ,Xc7J {{|S}(1c203@)(yV˸K$N7 k- B-[Mg M3Fҵe4@lj3zkh[{" z/5:G \"dBPIB3VyFZ 0D(J""`=8sk 7@ ]]łWxHiEf ꍀ_!k a*^FXdy**AdYf4}!˲yv?9"z]N*k PÁ߃gvHN`+bz[kf{Z;e锰˲dJU+:Zۭyrɵaj H3y9֡y y+Œ}/Yk6IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/empty.gif000066400000000000000000000000611237252063700264270ustar00rootroot00000000000000GIF89a!,\;Collabtive-2.0/templates/standard/theme/spring/images/symbols/files.png000066400000000000000000000022001237252063700264070ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<"IDATxXk1Ɍ~ڃ -D*( AOxB$zVP63M N!f"cDű 54`r2#;sc8yFV I CDſYo옻0`M( \2g)@*\5TkOi)P EM3N̸b{ *S_&ݻ;sl9sDzTUnq#bqVq--a?] ++\aC8^:03*'WVw!s j_T?x*Fª|҂9~LLOXV8vdCO>|R)t e!L#v<)騹 jjPo,S؆ T[n%-‚$%6 .?_(@ M077'Aʒv#t;f\j./} hfP/l0 e\H>wWf%A&RBPusɌJR/PHhP.Κy:gE(D@DGQa(lT_8)W&JJr7Q8\!޼N;A fK;5m5Ojj!v[Iz7̴f0[:jݽg3cc&SE٥ѡq(L,ۀK}+wOg2uIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/folder-root.png000066400000000000000000000021111237252063700275420ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxXIo1~L2ҽtAe ~!! Ul*4M[d~NO!/=;dDWEvF<1۶12JPoEhEXQ[AFIk|jgS;Haj[\L)J~5FY|Dli)|X먑"XHEy\--xTꓧ&[WȞ.fL3Vg3~r\?hM]bz(X& e1M 3q(6,,aޖ? {{dRr#lB: ih,|asB"aA%}/Qf"lMݻa<`YA|/u\VA$ϝb9 p tvA|eI“ojؓgp!ر#Y gOR DŽg܂3܆Qu4|\U2qi*RJ^-(BA?G"DRS6U\)NNj J(B⽫+˟@Gj%CO(i'!1$rZZ Ҏ!GP:TJ^"H%V2 &:o,.qA܍@#4jPkoqv=IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/folder-sub.png000066400000000000000000000006261237252063700273610ustar00rootroot00000000000000PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<8IDATxb?@&pFFF@J=2z\\933s?6񇏟2|򍁓Ov/_1>~p=>^nG:|VżIaC3 b@Ѯ٨WTImIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/indicator_arrows.gif000066400000000000000000000034711237252063700306520ustar00rootroot00000000000000GIF89a_\'Gm7$+!! ,w Ie9*, (*(B5[1 ZIah!GexzJ0e6@V|U4Dm%$͛p \Gx }@+| =+ 1- Ea5l)+!! ,y )䨞'AKڍ,E\(l&;5 5D03a0--ÃpH4V % i p[R"| #  6iZwcw*!! ,y )䨞,K*0 a;׋аY8b`4n ¨Bbbx,( Ƚ  % >  2*i* /:+$v*!! ,u )䨞l[$ Jq[q 3`Q[5:IX!0rAD8 CvHPfiiQAP@pC %D PQ46  iciNj0w )#!! ,y ). q ,G Jr(J8 C*B,&< h W~-`, ,>; 8RN<, <1T] c' qk$ @)#!;Collabtive-2.0/templates/standard/theme/spring/images/symbols/join.gif000066400000000000000000000001051237252063700262270ustar00rootroot00000000000000GIF89a!,(,Gj4bIA;Collabtive-2.0/templates/standard/theme/spring/images/symbols/joinbottom.gif000066400000000000000000000001021237252063700274510ustar00rootroot00000000000000GIF89a!,(,GjH扦F;Collabtive-2.0/templates/standard/theme/spring/images/symbols/line.gif000066400000000000000000000001021237252063700262140ustar00rootroot00000000000000GIF89a!,(,G}W(Ndh;Collabtive-2.0/templates/standard/theme/spring/images/symbols/loader-cal.gif000066400000000000000000000034711237252063700273040ustar00rootroot00000000000000GIF89aNHWRb]©䪆zuﱑ˵! NETSCAPE2.0!Created with ajaxload.info! ,w  !DBAH¬aD@ ^AXP@"UQ# B\; 1 o:2$v@ $|,3 _# d53" s5 e!! ,v i@e9DAA/`ph$Ca%@ pHxFuSx# .݄YfL_" p 3BW ]|L \6{|z87[7!! ,x  e9DE"2r,qPj`8@8bH, *0- mFW9LPE3+ (B"  f{*BW_/ @_$~Kr7Ar7!! ,v 4e9!H"* Q/@-4ép4R+-pȧ`P(6᠝U/  *,)(+/]"lO/*Ak K]A~666!! ,l ie9"* -80H=N; TEqe UoK2_WZ݌V1jgWe@tuH//w`?f~#6#!! ,~ ,e9"* ; pR%#0` 'c(J@@/1i4`VBV u}"caNi/ ] ))-Lel  mi} me[+!! ,y Ie9"M6*¨"7E͖@G((L&pqj@Z %@wZ) pl( ԭqu*R&c `))( s_J>_\'Gm7$+!! ,w Ie9*, (*(B5[1 ZIah!GexzJ0e6@V|U4Dm%$͛p \Gx }@+| =+ 1- Ea5l)+!! ,y )䨞'AKڍ,E\(l&;5 5D03a0--ÃpH4V % i p[R"| #  6iZwcw*!! ,y )䨞,K*0 a;׋аY8b`4n ¨Bbbx,( Ƚ  % >  2*i* /:+$v*!! ,u )䨞l[$ Jq[q 3`Q[5:IX!0rAD8 CvHPfiiQAP@pC %D PQ46  iciNj0w )#!! ,y ). q ,G Jr(J8 C*B,&< h W~-`, ,>; 8RN<, <1T] c' qk$ @)#!;Collabtive-2.0/templates/standard/theme/spring/images/symbols/loading.gif000066400000000000000000000023771237252063700267220ustar00rootroot00000000000000GIF89a&&&似̪ظppphhhFFFHHH222PPP666VVV! ! NETSCAPE2.0,@pHL<á ĨtW`4S退-k\J%<f4c`𸜛 GyXg{wQoX  hDd aeTyvkyBVe vC pyC yFpQpGpPCpHpͫpIp pJe֝Xϧe p X%ia6Ž'_SjtEYB!  B !BvGur GA! !,XpH,(q9XP2TDK%fPGC P~@D@XĆ۩S~ S  S!u~! A;Collabtive-2.0/templates/standard/theme/spring/images/symbols/miles.png000066400000000000000000000032141237252063700264240ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<.IDATxڤXolSU?ڮؠus`aP B_ DB ~"L4bhI B8`0Ǻu]o֕ۜ9wN9W"sKaўohd#?^!R[ut'i[ ۇa;8N=I9{څydTtY!f^U}Sa`SCCq\N>ñ]w&@=+/UTWɬ]b_ˆ1ڷW`c4j}xgǶP!x,SdݾuvzDR$DJE0LHD0Xj_ʊVH?bd~JẺi` K&8Pwh1JƤ8Lœlr84SǿDî1 ~?R48v- Htt^ ަȅԔgc*(/gW˝[ аr'Ri`2[xk{& xkjPԄ&"b+6669>T2 rɹz dg3`5dotEV"0a1:4z(^MZ 34cr6` ˫iՅeH d9>*}6/7[rιqboxkJ V+4<5 3HFXHLM2?}Ͻ^&7eΜt@ٕ7l;w` 9oZ'{c/_da}6ĢQw]E3B; ?Q0RzBNe>ִ' e3n&˴R$14~?Hpl<5.E6##*A$DH;H&8ٌvW&kׯY[W?/Klny=rsWd<zvb8IMĈճJ $˹7GƫqZ }E 0N^wo\'x붴p(рeIbgvť#$apuiI$練wWѧ[sJ6`*ܘlF"CVHblִOEBlTӖD)PFy##Jgc F,9јfl.]]{q9\p jk+) s%IFZP'HP_=1иV_'_ ¼ԤE_ LdC ѶFgjjs1Ħ%8YKeazI<ŀgshR#>ëk$`O GZۈI^]W  ( q|f BμST%*Ύgȳw1Vj2$YB+sd$@`&D =KUO.b|$cF)գ,%Yu&Ȱt*dδ@!?ڔڢtbERS:̓JV`P:k6Qeu: *3f|#m+E!\.?MBݻw mt``ff=A*55 A.G>FT(ZI?L` gAFMbzO^9+سw?6Ds.jg#3H&&SIttt L"E;"Q(FFF|صkD m"*rmjI&I!њ6г)I@EDVJ 7v |?SGx ˔*W (hʔPk4ȷށ.^Dn\@:8}χɛ7B>Gy]98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/plus.gif000066400000000000000000000001311237252063700262520ustar00rootroot00000000000000GIF89a!,*/Z"'hny&gSuM:+;Collabtive-2.0/templates/standard/theme/spring/images/symbols/plusbottom.gif000066400000000000000000000001301237252063700274760ustar00rootroot00000000000000GIF89a!,)/Z"'hny&gSuM~_;Collabtive-2.0/templates/standard/theme/spring/images/symbols/prev.gif000066400000000000000000000005631237252063700262540ustar00rootroot00000000000000GIF89a? bbbmmmǺyyy廻WWW333!,? `&dihprmx|pH,ibpdӦ@i@0CS +&vOR =Dak# ~Xb%| BLbs# i&`LQ}eg|X""Nhr#\C&d"&x \j$j&~ȄrXtu`YJ"+*$H0 TPaÄ#JHS;Collabtive-2.0/templates/standard/theme/spring/images/symbols/projects.png000066400000000000000000000026171237252063700271520ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<1IDATxWMoE~fv$N\'$*R  *T =rF Hpp)D@PUHJ>4M4;gzgg?…_zvgsc ?k˹ Y SBy R <1"XJlu jm(L[  {{{L~  踌7~eX6%:T*|/7;?|K\oSCXaCD|G5Ɔ%lVԬ=ӓO%ɤΖ\4S m6-+cp>=yZ+ s[!d)0fbNOL:y̲9~Hh`L?dsL^^< 1??qLs ~'yUh[6-W Hxu $Clnn~0ͽYVclEDŚH#^91N*dqsaOMN"4vb!Q>6Yn]Y× Nc⋨jL; QF40U`Ƹ\{u2pxx(Ad2q>f403yӀ拏9, q6(J3r~i5OSfXG anתUk/\x"ba畉3"ZX41zj){{իs[<ۉjwX+сOKdrclomT( =24O~}Y|偏RXo՜ufFU;sh騀DO~+k+IR>~WȊQ==g\O~xzz5U"Y7k*J7##}^$la.=L]^>_T.6vccӓP;VcۉRU \y!-P"cCoNON&#T*)g|$z `ag31kx-s0[nGxJ5EWI_Işi^ ۺugʪXBP9lH(f8Yp}le[t&`j3Jʼ5NUF1 <4Un1b&O6yw-PͰDq<ğ|lZ;s=\z1atQJg!X+qc]]k}("r 8JW# HS[)%v#t@ dXs 4nj9qT4!'cM0;IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/search.png000066400000000000000000000025551237252063700265670ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx_L[UZI\ EHfHH@`6=%7.|@gmIA#5Bs^ϽMl=?$ˇ?CD^k|G?2s2|?0 @"rOYPTaIjŨŭP(~왻Yj(Ww$m򄍍 PZZJ~ \=SFPIQ{矺Az  > T3CF[[[Exe3t> mooQ@c' h  V0~cLn7k+.U魷yMUMS%GyEE9,W0vf7ȁFou2<=M=BӴ|A-X s=+_! ʂ(X҂!pqEQ `>8hssI(Bopx[vFT^ٓp@ nll,z>ޕJvaN*SI~V,y}QU'pxJS45h 6t;_f;VG4 Օw= RʼnW$2RBzt>vYOUh斛 S~,$ 4=g{<ޑٺ:C`zzc^2 S*;us{WV&''_XX0ԃ0Ef::;?dYN$芍z C!h z`P eD{ #^~@"AO8 @2ud0@ah*c Dok\ LοEzp0 093tpIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/system-settings.png000066400000000000000000000035661237252063700305070ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘p WKT$K1Eog4a 5=E QRQA38EDB ITR0)I]rroEtf{`Y+ ޡx7yxYq W@M0JBlt}j%k6?-5so\\@e/!*zRAS({hkzRo (dslCC ;j7nݹdF&|˺rvvC\]ۻN0Qb2rؓ6wnDevXс()z:0 MTorO2`༥[(fPoFchawRS&$$`1| &v jTP 00pJ'd@Z֢~d-fQ)*'&B+:mYݿs"ۥ)Cʩ;Ŕ\ISŸAZ]Yu.%xdt\GtP0J0` 'w<3<1 FuG_MԔOf%$^gw,gO-;˺~V Os߰477Attomm]ǏX,Ks 0LOUa x0%k!H1#[nR*Up}%(**ј!̏ mY:n@@U8k|nx\SƏKy榾 88'OaaƑ>ƍt)/Ct7Ð Zyi4]Eөܼ ].' zwUuu5ߙ}0##rKiʂ;t S𽊿D0\˿R`=بbd$eee(&YP+SOĠU,Wn5t:`̘1D^tXN0m.1iyݾ}ݻӛ6mJ>^˹Tۿr^NUmZα]Kg{ewE N5L 33Ssp9+w\Mu)jgFz@$܄*FZ^a#VYPR7Nj[ERL [S{͚q Nc=+.dDXC :ɍy77FI κ%Ό&[7J,`pkD{m6ͬ5۞??D;ʳo'?!ޠxt;/JP-A:I] U4NunJ""Mqn@o5bS uY"8^O]72Ar HmĐ$K#HCDM6W Nn' 9<ar {Fm(:Æ\?^.,S;Iu֏+!Ig,Z }{"rȊpim )]XMvz;lW(FeLP(H)¥9Ml؊U]axm̸ F~h+/ A@ /"ԁԢ&WjuJ7p#7uq$zs*HH Pc▣Rd3.mcA?N.:]P ^k]5BvO*7ݭUPyfnaXo<_ya"T z>H1>901{+ o7Z," R"RVUPtAͦS*fdhƆ6}-yRK}{7)l&>^OwdhJY&)*3ہMϰ|3R.R~Oў%dR!=f6Fwl}?]Ow\4o<47[l/&"b" |_Oh7.-9& CB8bޏ8ff"F)gJ{Vt>Fۊ!\Q͎jv_/'IH b!_*/.5ts7Ju0kx>Sf2d s!;u::sO~6^MåwxUA@`? bnB{^<Jb S!1LY :B77Z d+~/)֑TaZaE EqL3_<5ٙ} I;081a(U,^Z.|[;>DVځ4N[Xf]0J8┒Աŕzj 9qaO6S C{$is^mc$i¦Iqi5qFkdZ0  "&B/V DI*Dْ雓9WFT4"C=Y`z3usiBY[@B;m&]x&"gky9bnd}s9Nr)gi3z$")I@$꤂@ R(@PLDJLp"I@p'VHaXR_ s}'UF1JT] _A(NIcC. a.I ΁Bʲy`02ixibKu%ٚumu2NR399ՎSwv}jZj 8D( NI}:HVBzj9* S)sG,F8$umd'𨂜<ϣmS\XYY^[kmNWU4xyH!qx 'PavĜB<844+`u^Z8aN@. %焜_F+H2fZISq{ij=k-)Q#Wc1F|abs}ρ ũq#$&ML[d%ABU!d03 \p"s<1rY{a()HSgR+e8ƉwkAjW/EDu﵀3^DʜAI vCGy2g>VZ7Z d6p*&TDe 1%л/]W de6Juõgm J*lczhfDk'-[ꑪ VͤbtݛI[]{gQu[7se'-ϵrSxwŭqkƭ.yä\l Y1`@@ZTbMu!v288|\v]VrΥQWW]+E-fDthtt|3Af.qYkpT8l]rW`jz?ht:HDs9XkamʾZfW|wE?]dê8׏_YXZ ,tWgw-V+pQ",4Dn.'8*Q\.VkVZbeejzj ^û!ô&L0ayٺ4>w\liA&G 'RØ^<\5]NxN 2`c=įO~?Pp%5ݰ/~.4ȝIXh=G r^qb e=q`G(>Oڽ_vE\Uug0~30W_}5?X?uI @9Jݷ|ā] n]s/?Ea\pѲ3MNNҫNVo([:!q fw3I\ i'Tw>[JGnʪ?HX,Nr05Ƙ>HObHS?<ٮmCk4IʛԱP($x@l {Ÿ}t"gcUXpi :::jg3w/ )ff.aFrP ͸BvdAIҹX5 SU/" jvTc2n!"Z\\Sx2`\Fed^!pzzZJB݈]"[k(ܹss={l~! > 70_©SjI9'7{#t!c4 Z\\N'<>| nqE$|| 삹?*SSSZTX,nuۦΡnZbaa^~v45jh4PULL{箇w~}sCnHWQO^:i]za<17rKwNKKK8iG/`f 0Dŋ/BD>K_‘+q+Gavn6kl'B$ ^~zLJ?v \n6}݇Zz/7&'&0::Rq`=-d C}kkk.oIH,C֚*nO\]w-gK%TB7`0XZ^tN\lvu韡j9 {x6&IҍZ+>AW^E2@ss]1 FsyyNdA:X{-靥4/fw'3avvV?*lB7볾*t:m$"r980VkIdDtuŋЉb4ν O#\]Zr41eJwƺJ>0y8ws3`f8k9 38vlE\) @T@ 8qYfF?z Je I(= nQpE9sI\00FK ؏?pO?AG@뮻u7o T\.@Xľ=8vgw dvQn# CZ-Z-" C$I4M\fyh |?yJ% b``R R B\n={F=t/6&lf'Z;vۑwΓ统ۋIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-desk.png000066400000000000000000000070521237252063700270110ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe< IDATx[KodGۏ3!RD~bM#~@$xX;:DH#ÞĎcV;Uu}$J}ޮ;;ꖥsN|y  /@N [?؛~W>(43 cնZ]mG|/UM(;iwXQ/J[:TXg n+,ߍfuug7o ]yՕo|?Pi @N3ι|O c V T{l=y.g:WpwwlCПL,v' Ks@SƃcPƟ5`#`r)#KɁ%0!PTq`Df]Ο?y۩0 ^fy} PXg Ö,ʜ| d4tT@:e8 Qk*NX {a/ q$,TSVQGa|MW퀯8˨8*Ƙ,Kr ++3isGm;=,ٳgG{Sd,;?eBT^Onnn굵EϤ7WT:͟m6T3E\Ă)z۷ƍtnnnTSy_SY( Lf,6fS! 1(x֐+- QUB?FKT^Eg7CQ:$+b,Λ'E]glT^ڟG7I%7ft/Apa'zH\e~yl0Ub䤯 Tܪۯ/Bg BR8,1v O话d2!5~J@^x-8njD73V낙RRLRlP]u|L0"Z=͊'`^9i3 Bꈹbݤ/Jm"=n{IPsY8YWݝ$&YٛuggGs n]Ѱˢl/*HOھ D#IPW*7FL Gc~W߽;wijϮj̕NꓥL!Da?<4{{{b&x ϊ%`j51;;$m#`(`~kkKλ.rY@Ph u9j׌X9Ue.)ٜ-=quȀNSNUA9$uave>&ƹߝS}+C @nln}og⯨V˹+j[ArcAn%xn"&~~֓ĮڿxX8$AI|2T֭\a#s.OwΪ%F `J!ݣJ̷r/e@ d-YbeA0SE_\N1@x ٌC^qeLrs$7\ZF7|z:x YQFcsIQK1M&S_>AyDA ځ@mpnղ X`n3MOXl,x[70pĢ(O*pǃHkwfo -MLm:.*j 0AI, muJYĦ(؈c+hρ$'aqli&b<qC^s-!w@hoh Z$gk{|2SD }4߸fYl}l_nc!THFEד%CDP%B,?N` t7OM&j'pL!!s^֨5M= r) @0s11w@jU\vGWV8:?NEFTNu Dݴ_ z86F )eKAicxS=;2U#zs}Ey,x4?ܵhA#q]SF)!@OxL$2/_RƏ#\|4;ɓ@s EhEI.ܲi)j\c^d;o)>+.| O,Ztq(=O&% 4#*#q@P$& 9>#C8ds.hZ|an6HVta E6)й$9Kz{ d*-lZ}ؾ]oE @X%?gَg\HOȏzH"xd%EA1%ykQi=} sgR~ wo?=(V!ZǁDMdl^Ԉ&gsd ՋO(嚪}btVkJteù6{?xZPA2Q(L3IJ FMsH{tG~k{Yx76VaRr$ Ќc= #*|L'8s92<3cg- i`.dȚ ]mgd3WϤe GtQ)+l'{]ueC]QdA,sڤZʹ8ǢGw:_Ə2j'BƆ鸛lPc#qi۳;_u׳-ЭC~}Yl; c,QS4_IcVO7Vh} Os'@OgYL<ܼ ]' [ڿ#oͽx-K0*PE z׀0ʢpKi1Ye !sǏ"zU͜}y }yhe$O@VDdltnr Ki+H%6iAdY`@ȩl6 H6% ¶P`{=MceJ 7AcFve[Y q>=𚝁% a/@4EU F7l9N `< .TV~gwՕ"]j-c2 djy<~ȯpC1!鄘Kl퐖 ܐ1/FvG;j"vCe}%K5TIPE@O敕,X 2䆆*%d-36hF1$Iv|"WՎqA UeIі%&R?*x]umM~z*e % Q"C!Gnn.Fahp q$.{z P[?05>x5fCh B\ 0p'X2̕]Lkg.&BN. J°˳®]HᆆsrY[nR0pF͂`ւQMW Se ] ;X*ز.ɕ$כͻ b1MSDEHt wMڽ{wNaQ mPmVj04s !3±acm)w]e!>E䖾YwM-|jvC7nd@o&Xntttֳ#Y_aQgƛz-%-Andd4ğ4Ot Wf=vZ01Р`QQyQ^WQ!mիWC[[\N> }}}i@jkF۳-HG]qHt\۳Q@qN6ˍc+A C|eq15kְvЗ/_* ]qLπ^{; wn8t}4Ȏĭ@w{[ WnڼTQa9Z`Ds9Lu&j xS#pךq HDمOY(WKAN&?)Py!L)qYYQ{h # ChO|?C S."& 6 vF 13'4g:ocd ᕽR}eğ?@wiXkldʵ $ ܌AZuѣ)q*7~ɗ;u>[ P:5"Ơf "֒p|ƾƑ3&pwxŘ%γ|j75[CQz؉A?Ȩ? 79 @Μ*|&99duVLvqmx 7v`iaNͼ2VX>xu<@؝5la-ʏOR q8&ɓ= (+ᮯ. `U}TA8m :dCyQ14zXV_999MC;r#LA׫ Dt~Pڱ:&>!7VY +g:}]u5FM1kB82W1t`b-b؟]b1gEK u 3W XevI`>e>l5U {8'D1v.5H 03 YSzpd]+i{s_ }WPu*l4{>.ʶNhwy\} [(Bi(DSrQY~Kx],z DSC@S@I $xPi~@?6 Q*ݺQ0=m ;o]" d6)m_qȒ6Y*?3$@dJOh/䌲K1 J0n`󎃾RWcl%nk+wlr(8na9œ DbI{7 WF3f3cr%߰sֺTiUј',Ibr FV>#-ftEΊUyI,MI60:nLC3АK(3Bw ~694=s{d~XS`ΖZUywދ][/6(ԄK&0ZYaeƓB4 }vy\<6|5/j0"=mh 0|SNm)}%tc^b"ڝP0;czur2 ф?ECMϣ 3 Kw:.$(o J?n pz3t( U!PPU;uwd,ώ,@T }wwKH8H-Hw+j54)N޵<8f&F!2.S@ichBBI8xR]qb:>PtDPU oQ2گwxbv_EIvN k,8HZd$mHhd"q,Ah7;²KIb՞m5QT(:(`w3b2 "%ek ;FUkKg@EIFr LNjjFvN77 tmxlCE7l>y$0Ľs?~UwL'PNb/wDi孮=X#F`n6#23LAwioF HO=_mwUw0CWv^v#8 T>s[j{4nS6Kej@rչY<%׺{? h{7[G'[$7&-%ԫ?yh{Tܿ. J 3h~YUujF'VŅĘM=cc0e~U3{}~C}uBL(3CfL>~aQ& /ډs}%Ȑ^W7ȦQt$)$.x.lyGcH uFWr}'g#ܦH@tkj&9#5m30/=JifCEmRWCd1%\+TsTg߿=&n  U-C&8 1 tUK?b$A"+fL͸!/2J[)zδvC~cD"#Qr^0"1JR)"tPB۰#(ʼn?,-Qb` }r޶n_:.}XďK_mFĜYj+@$ԆƧT^ . mUO^;+鰡Y eDd(XɄ^BϘ+ )( WGSؗo^[{s5coPdUP4ʨA:OcFk@%.$X+&J'#OM%ljJq榁8 /q0u@V$=g]_㣆HStI r+ le' Qt$1J{ VXR1&%Q`F"ai$"5SwbbFM+Kd` /K'tkfD)I gQ1903": UQU E%`88d1;d*/c٦Qb3ȲEʞ3!9"^=r^0[<_Rd^/cM683sǏXr钞&p*|O`s B^Egi9Xy19l1"--͘&8@]?˔)e ]jGEs\ue 0[Zxebţ52Rk#: |W}k^[w<mxr1Ikyؽe;kXZj>3A &8M&ͽZ%H9F_uxw׻vG*+06kFX.k!lзup>w`K[>Jz/]/ / 7,J ?L{G>w.mXe~=ggo*#(+]fw4~]g/ .jn*FcqvE|wqx/$ V9N_|ʪW'ކ_k8R 4|S=dm6B=zp7*~'~mjˍs$t~oPͲɏZAD~h|\$;Z:}Xٽx@]n7E(XFviǴoܴJJ=7P>ɋ9^!R /hx}#eP6^s{&p艧~Ux8PwtP-mۣuYJ>߿\ BrdD;ڧ&;yb' g!13W\~@NV[y_iYL&Y FRTDuU0hʈTTXM )x*ԅʝk,slcYa/ xElDۋ ׬f(I`I]tfzRgJ"555EW_-ٲߙ$`d "|̅m2IV@6~`)b<+1켵Ξ=ksr"`N)PT$$[N(g.߻ZvDC)3@`R4@udGޯ5.:JKN˰lh4}Qرc蠠QF~ckb|4n,PАpuTO* nI]B:\ H}[ZuA 0IYI& 0³>+Kȧjj,։kQKt  X0_O_fGF%:%U Š -}Lx+"^%ƾ>DaffիWQȑ#[2qu)RWb#7N~x$.<$?>5e%:i .`XWok+NN`bbn޼is3JJJdL) [?s>/vӏ=g|&e3:z[*Oj7n@[[$FΉ'×\kbqxt^<~S3e>墑(f;DA7TV—>SS_7aoGl޼"V#, "w!L0|vEs`u5ѓO:&@.lZU%OzʕUь-?y)}8s`jfa6jfs@P{V:^ g׬VUXms3~Db&wzn~~` 6r<+B=x:ʫ_r_>`qeli61dF&` 2{awܝstWէO>gE35]OwU}Ror #zc]05H`:9g?g:c(| +?raٶ׽dT疝g:~$7kx:*P b\~]6U*$3Au'5|>zr=A,xXt@>=Ȏ¤.^Yf(Cf[f d?c"ʣ`OX!r]U'$6Z;l@YűkE][\2:@'l _tXcX"φu 93 g˳% ( èObXYW^9"#jkǗV8NVS:$-.;l.|g>B\'9| ^'clZM!9[K/m,y9 R%n ku' 6')*[΋w421qG I+cp}nO ӛ[g'(D1odd~Zʧ-59Oby.8fE@n* *Tȱ٩ 㡉P4y'8E2(b9%xd8@i @S^]aR4ԧ,CB-kIt5gf1>qłmq1H E|ìXbvR(sdl6 C|皆HQ #E#rbgvZFȠYm1hfc:jiDI.LY#aFԅtߺlX0jҲ bF;]lKw.nNNAPgr\~MrO&q%M@ HIMEIȡ̛$ng#}֕D1 2e+P&. q0:7Ad%VoU  {zbE־Og'z; ; h[Ӥ> 㒁S.#0ZNB<0`mh!"W#I 0o/.c??{٥(`Rm@ӬQ]k7 lLg0lw\)$UdѶ:ƅK$قi2@oߦf5ZP'eԽ~Xְ?m2|dhsES&Ó$`IA 6$_W7nŗaj'Ų7Y4̤5XI8dAU&2kg#1b,˄s~a0B?0d 1ԛݫ"",>q?FyZT&ِkRPQi1ҵ.+|T^ym쪫? >EAʄgAgڨVVԳɯ8S>8AmfE]2;/aw_ʓ q_P<N=N8[lةH;9kf:g Jhw Ͷƻ^=d89\Դ-90V-Dh/lN>ʂ\/ˀAo*w^2p~,2 6;37~AzjWXƘ-OCrm`0D[] + Π$s  '~QFu;{ϧO&1ma_ő}3ʢ./Wd,PX&o:~͊ tR fuIl]ʵ~=O{QON:Bh xYMɻu۶mf$WuI *SYbW$oA-=)[P2\} {>sGvSHuXzb6졲 X=$6g7/~B){N(KYt3-y`#1[[&庆qБm3$[0a|>MgR^r!~ mkIa@NavнEsY/Jf! Zuh"A'[H1)99N^'08cBL6/|J^wf aXMWe_ qԩwOY WAAEYEnˈ?ޡA"ttydj[oT7MSB_^._y?#Te$=WwGV1g`m'L仏!?oP, 1)6,S 2^s=uNR$N`K"TgBog\" erwYuy;wap8rZIh1EѬaBP7 1(C&{Yme8H mgo}TU`UVVV8}֓vX dXd|>JVt ,௸駩c3PG[Zl`%Ê+a?Mc /|hBJ,SSS,.d吒aA"eI[z_XD7u:p zֵ%=cK&נɱu\d1>z!5QPR@#7T8HU\/} P}1/ٷUIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-miles.png000066400000000000000000000111701237252063700271700ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\ylyؓ. > '/,:4V ;895v*rZmKo<^R+6G[9UsϾq9hZ*$̊QSd_PX|+"0B7Tomgj PRY= 낶//G[`[_`z/9v*kIuHxT#S015s!S " ar# pGsv | ΟHGՑek&% 2$Q]Rano;wu@e;w?[&d"YG2U)dTC]u*4Xnh|g[WBa8\쳔U;=׵$V-e %c` UebI$m)0:zW`R#@ڝn(mNd/@7 v_ b޾JȹdDH%n2nj5van}':~9FQH#T5TzM%AZl׊{?$ e[F*pn 00:M>g{_;f _A;}UUQ&V+mj2ZWU!%$iKt/\+a8_;v ĶA `R{=Pq4G!}t2G̔!B.ՐXt<VJH]ހadP}ѴH&! ]<=C6GŔ$RCI)O8RTQDbBJYg'>FfaCxQ1)mл~O2g#H_A>+{S6LɤhI G9.sa`cS6.mu9gJGϞڷ\t IQU3xLII$$r9K3m̑ l#bJK$ۈ."Tb*L'%SeU ,Jyث}pk?0gi]vBCUAIHW&D[QH])I"\,.80<2$eвS-@7PuJdv{C*.t<TQ4@Iq Ia ގF3;Mi֐نDJC;C`6S̆)&ѬQA"W#aX$zK9]*"s6rdltK#d '0W.Ì lJ>G!{&Ӻ)I*l\RvI\΋Vs ܘ]g.Tv$*YI8MD MBZ% !% Z \VT2(J fdH=^1iX,$|!P=bQcPªcW2D"H+EGcc@L;KcE͂`ٽ׾΃frJBUQqPUsdմI&vm0cJgUmJie8vm))Za5{KUsŚۓ[2/B]h;'ZӬn(I[vMw˕\X&de`Mٵ,PtwA(+ Sx>酇OAT?F_򈙛F`Qt]YxRBaCI5C_26}9*+3J{`Zgŏw>WQi$ >ʫgv~/x{ƣYSrDpiNKL@yy=͒1xPS 4g:GHuEz_z;ZxgM@;ޯD:ٳg!Y\\Rډ8S=6 A 0;pAWmskPX\ #ס'an2 ;,ɶ nNJ@J[:x>(ls0-hi?)ntv]<9ohjZ1<zd}w4X_cd<y0뚙ROɉLe[bha.h3!P~VggWV~l~u ±#Ʒ4I H:@[8RיqO Ox^CuUovXpG`]龙Mj <@zk)iEm远>J 6>"pFqB0 _gm6loQHad0?6|/<dۤizkw!V N}&˝O< 3 CN8𕯂tC͇ wkW.{ v|>`PxJMtے`xDJ. u۶|ov, v]&ؾyn C ?غMH}X],q.I37Zr3s(}ܱCƼ7?7w>'b>S 5C4/P~pꍣ0Ixb! Z+O9>?g/}yɻDG糫'͠%*L]{:C}K+gwdϩP{u5d4g0󓗡htNfzw91*%>oӮ-nymg.Zv[擫]!IC )R |eQiTo~^IW/I9x T .كqq%h{t?Jo?Kx\ OO:ikͤIB:+ ^EG@U kg|0 3b%u`'`eh%L@Syz,v^H]u$IFRsak)ibZ+Z͘~lȮ uan>i$1GL޼.#75ö rv YL,>Ǘ0TJZ,dF0uk b$I@AW%[%r`٘ժ}Zi47Kz?#LhA~˧ 09̆8IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-msgs.png000066400000000000000000000101221237252063700270240ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\klfvvsc;qEx*6$*Rh6IQ+?*_ZAD! $Ďޝ~ۙfc';k JW3{=qqe"E A.\9;=޻{vqDccf#^֒2 เPm urnEʯxW:WH$rf48[3)CiLTգ1%,@r03KQi? |ɕh955HT-QY9g(5s95*SQA4[7&09M GwN ,Ɔn ]6uѲ%>j帝nq =gi5tקRυIc6 =ec= LÿnoZ+:oXJ=A޼ E$kh*8NZ:ɵ& E%x lGꉖ떖Kߐ*J @&8_<Ƈhl`5WW&cf+NJ?!/;2:x}vnٴCC up_V ˎQlk2++`{JG`>yPK4k2!bhmE7}ƘZGf3U<,;wS&N*Ǚ1ff2B.c{OJb^vV,i,hNO3C-V ۩z ˱,S)"OxI|-~pMٰZG')"ӚJx&6|%fb%@vb < (7hPrs`HPSTkggHygf-UW @sqN1S{w0c<˶ HvJD(@r**=0@(Nfe4$ ^MTdJkW,1Il9Ч8c3 b+7*Ϫvi]IȵoU*hx,H%E^x$`hhtp:5$8O ᕯb ho_1|Eb0Zx| lۺYlj)%84s{pN2@Ss~ xvAZ6Iiq@bg/X[6 A&ɤ}J=9m1in[M›b̎04dt'j 1M[%nڦFp@3 *Lr83ٞ1Gv ̨xVY-l6MPHGR(Egڳ 0i.>!N,+9i]m7Xv &ql,0epha.u["NM $~h&Va9in @Q9Lo<abb.d2xz*`I\8Oddb5gKl$X<*10 3qoŰɉc),n߱Mn oNNq/2maDao eE;NG@F"a/`)eK3Eܰ4!yH) l=E@[±}옼XjddHeNL:i%Sz[QbC Dt v*e"E d齻GNELXѣQvF6Fk|~k7|1)#ҊϹ̆'K}=TĀOS]]=_J<$ZGh[k Dk׮] U i ʕ 7^`8{,(@UU(SS\X 5|E!OLÏVU-ϥ !nEve%LTVVFKy#̞G=]r-]|C|/R,3qҜnڵ{MNN&=pz;fkoFeK P;::+ًzfڒT#ORoo  2=.#+4:|,F3亜3\ X.=uuu,=\͖3M6%mHv[S]Ko.utQ08! Sܳ{Jq;+Kz 񃙲7C"wks @icM2-PawO6:Wt{/yy0+38EkUե*XJtَ SIIwvv94 #e;m`یm`"A@Br>&KKK Z/r$$v|MMۗ8Y6uu͛o5ȴYFtIՂB<Nk1vbYPCv/[ O @fRvv:Dgϝ?O~V_-JEuKsrղ͵!l~,BG\SYEz(Tݽ}.2<<,7Y+ionndF W&|,D#JJ(C#OizzZu,?~ Fi`TZf Zǎ ,^r={㔗祁^ +WɪOXC40mKhMb%Hא|%$PWw'g9518_I9܅rc:]Nh;If>\SŹ: =$<-_ﰿ UGϞ[pQPWr}C^Ko$IQm4dP N,2AGFOJ۬T\/_z0s rg'$k>>ArO!b3nP$!`1{!qOZ$ X] `3| /W\"4XcJbrOސ<Жn8h. lS6XX\rЁe`r4`1*9uA}Օ, QPTҘ<+ &''! mOIo:֝:e(.aưlRc.=ɑE((nl3 :d$1* Մ(rUZurRPL9LЖl=+J),,/-"2 3c%?>끷EdF]HT6Yv\RW25kעm0K:S߭' 6e|N 4TּeL6IYw/fR$&>k"TWr K := MC5w:Ob&@b+Ke5T٪pD/2fNqړ'Fu@e2EG9_[r%1&IW7\SQ3spWi3tt$H Vb&&N E_])AGFMdN,O Co+ ـD=hO0F,2iGC{'[ϊrPHMH]9.rj~HUK RbǣY/,*k~(%B(fq' NAVwJC ?P%%5"V/l}<(H iU>@hω{ 2Q3}NG& hrA0@tf3kЦOK4a50 ?E[Sg/AY_B婶GzM8K,VYr91I5qמ@n0ӠleR'N֟?&Q ǹWh5̀Q]R/ H,V*:0 ,)HRe g(T +o5[{h<7:6ǎi*/%&a/rja{|* {ش. w0s4\76 =}}s"KexW3 3T oe 0I۲4dРS>t~{7 %q#?GBg$oyW9 8 4Q;eT%s?1kTXw%>L,/Νб^a5ʐR|UVa\miFKhL8ܩ*$ oD;fSJ;rv\>2Nl%j em:.-0MJ 4RĀ.]DSIT0\>ǢʄEL0RQ۶=(І6OT[>7 J Ä4V 'Ϝ;;:޾0l1^H&/a Ecr(8ZOO7d(wQ"tvu'˶3 {peH$j~"gQlWh5?826t54F$S26Ro!S|)w>}>ieKYw,Wm5X=X]cE:t Q g䪓UWV]+ZbKfQ;i"~@V򕪖VEP33 Sx:YєL'&sUY\eMEIeMjj%UYOe#;հȡwp޸M%T` ;ئ|llӆ捰XPv1b 2fyY:дCFov]WζQW(Rah0؆/5 )rPOuzsZjdQl e峲OP˜ IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-settings.png000066400000000000000000000064601237252063700277250ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe< IDATxilǟyw׷1C ID*jDhVUJmoij!FCP%6j8& I8X|zPۻ^$c\;#J_MZ\\\\\\\C>˿,~.-˹9UA5xJ&gP)wʃn< ‘}v/~ԇ*2 (}[?ԺsUg`30F7{sC%L'd}z}|mKgމ VTd'ܬP8U9 wp|1!i:&x6` WkɤZdFd=q\SP"]x༦Twa"8aX+m\YKg.׺(7}WI>`uiu=`FcȉaUdē/C X]YF+6:fvgLPS}{]ծs H-P0U{Y UHaM :yzϊ& qZPddQF) "P $YE]T OޒfRc<-M J]{`֯.|&'(ZbArM %SV@6A\O¬B(ʀaE8 U=PD,0V:( $inUZ`B$gJrpa seXe'*,BJo4CaifbLߋ7%5H=/!1*2 z>ʀ-xj@a0n-hPZy<:L XM6[GQdON<@_=/4tl-0=(Sk¦jP Ik|ʠ$,fWy@TkkGplha)mK2fdR Ƞ0QNmSSV̦ɁFkQ4DLC*qH \L0qq-Aժ!sn!Մ[;6A)*iI\L?ތOFĤtXL.f|O" P2Gۀ_ނnĜ2F,I;z;%(*{BT&pfbc%:=Ӫ$cM_ȅ~3p?n222ڒ~ٓ/zlLUfw%<xVd4ZHTE4`N4{ٱs7SDo:$o 淯xd˖<^)dw 0>91q$ANI+۷3.^/ÇwOk! tf@E_@Gѱc>5S:92Y\++K\. Ú^r%y桺qs8,ܥ!YVw: {zzl,R" CTт̑HY&USH7 m!; W ׭[7TUU*"l6hӝn^6nFtU(O`2@^qiӦIF&I`oo`,bNOOS\<|00l(]bBArgz/ h?bQ](^jPH+pl555ڱ{ 2$re¥$l@Lp#)A2 W% C߶֥$&d6.m-K0%H^A=Jc,iڵ~zmF) y͔o 'Nf Z.3}}}H(yKtIڲex4TkόAAZp8GbG{졊 m!2v0qrrRk$[STo^#-$ (-C.CG K/#c>IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-system-settings.png000066400000000000000000000132621237252063700312450ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<TIDATx[ pՙ~}̭gt[d$\NL YԮͱ@ڬ8Bva%$. pc[aIHfFH3{[<%"i~};ɲ / Է>}q~/I r ȝU{wq(0*^y  hp> o_򁶫~W|[l*35>WZ7~7QqJ ]Vw+ؾ/+eԕ$}x_}ٛ_n6#L =g_K4*s󡭸Z&\`4{4=gC=ξۼc=ګ*ۓϽ~6./@#nl GbQj=UH;m9C__U_Qh==bdMD/8AsQ0 v +>fԅ3=o1oeMRդ Ac\4foc6K]e FR R3v`68hOv@Ɏg )f1OE89ؙIaCyd*S©)XS .>t4SaG#B(M.3Q{+1d E>DL %R\<[<U,EHH•: ̏?F 4Ga9)&˫JT/.+FB8=0Il=NIDQbE"!T9J4+ZFLeh*NKfNc;:6q5c RF^X3 -AD}yjmls?//MRLg88E/iMwdjмZ+i$a _=0Z&ճ7 AK0EhPٜ֜ I5&P\:QB?4%w$ --]HG!6.S@$h嗣XҘ&13a?IhW!@ [L#m){} ϊI^j&Aa~!w0K賟׀N iz˹!_":8.Lu/!J^Ae:X]cuHӺ }$\VE⟾?v pYC㳖")>C4$$g76iƀLpH3]`$=VUe,{ uАOR]Fsl~ (ɦ~քB+zT֐#3G; Cr`%4U4 4ҍ$G΂d|~!XQe XL)?jB^,yԀw%-ӑ#c T4(iYVf]ͶT`ٰb"xL m@aA0G AI@f`&UKYY%R>szdisJ{-wpA$R, %I)OdW 9 ԵGߠ PVC btwrZYTMɤt3 N"S]ѩyIһ@@;i5!Olwy5YbH[Vz%4W5y~a˔ <*ZeYNkDX* /ŕ _.בuD{n8 9ݳfzK}"KP2`i+-Nb,sR@\bS|G>dF$O}O*PZ,%U:pKݥW>j/W6!~jsORZn_ :M˪`:ʿ'ЀQ贕SGQx`N,fZ&ҏp뿺iͺ63N(jquU;s뗷Tvȯ~e*u&9'#C}ǢHd2xq 7ɻrZv&cڸq*[_ގWKk0Mk>~䓟DEkEuV!QV0sQh-HDy ]vyC?|_cSMcadxm-1-M{lOlڱ n~v~]]DEqeڴi]?j0hylN|&a픕juجsJpӟsUt0{Ȱt"}=NZSA6]xZ4ǣyRĤ9G'I#tt`>4 V^}Cqa!e̺:OϿtv\sڲe۶m.-]9 77.Ysu K3l|"2i$ [i5ʖg8(rav'j!}7o޼n͚5?yU[LvӦoZy/zj57S/+;Ҭf:Dq7޽ZjkjL"EAAc$U >WzV[$ )UqyVܴb͹DK[KO>: O8ԆmK%8Z ]{Vybh[o{|LfF x<׹J*V-9γS}R-R5Ygۂ8tvvbQZ\nPt:w=Jht{YwW';cέNIf!Z8um[mmŖkUı۷M Ȟ[%X++-% )W^===M 3!v&XOwW;T( gâQ@D}ιvNX,tw"~OY[?VL/`0А ~_qG[e]t`v]#am l޽boƁ4-M냎 aT\uȵs_`I.91yFFǐ <T}`>Ki F˱Wu(!Ϧ\K$\<S`630P8cQk#r`PF\ǫDd koogGQd6 Zoذa $3QJ ׫gK(7l'Ҧ3ݕd6ƪA> 9KpٲeO#5J?nDr ''A(2zQBG4@~H\6RFM2y<ƬtZN>"m0ʴ.OTvŐH`r ;w#MMMY4Ea 7L(*`ת8( SN1*Y S Z# H*@.˖ ]dlhhHMFu$ p*Nqn ҬadlvOf@7r ϓ^7s"l,ɘq0)|'hP |APN ;J\AHdޏkL;Ŷ D->O8RϝlVTTrرQ ScJaVHeHӤ'$ ajJ B tJY;1h(D'١b547ȪRȿ⍠hXQ㊪4's -CD 4H 0 'ͬj$-֎Ȩe&@yΩ_cE݀ʛQP@SŒ|]NpJ b!9=>%$rcwtGb'lBI%2UR`(aqv¥Ů89@6@z&ͣ&fZL#yv?b(QLgx($ Ƨk0 &&ŬtN$ZF,&hEHZ2&ZZ)x#.)~we$0UqYrdʼNfaRdT4KNa/a iyL2s\<`^( 3,R:G>&ƱI=c~^G\ قa]jeHrQf+3ٳG>y }i1V6B ؙDYԴI;yZQsoz UVz6!#L^o=slYz+-r3u6 "NNFʕ+%Ʋ) VaY,2˞\nCsƻn7$?%Ns?ZZZ؎; 7ܠ'I 㱛Yx\7-j|OmfZ91yH9xI-iСC 8ꪫvH+~Rk 2"Ֆ2ZI:KuAjq0ʀB6E4OGɁQr2KRӨS4>HI]<h x/ 0BPA]IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-task.png000066400000000000000000000122741237252063700270270ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<^IDATx\ t\ym/h,nج&RL9(9,M!,%p4pڦҔ 6^wKFϛ^{㑬6=3}ܲ,ا g ?~)_?>͍Sޤcn4 'PL) 4W[r/yZS(^_5w>X.~>tw~#a*E|g/|#(1 23#\Q]`ْԡ-]jӥMJSEGИOSVnnSHUE5گeɚ@_n&*>~d.Ma*{~%:6tIGe׸֜9eE% ;-Zyn=U&C25 ڛNs YlVm͑Y.CN*g57zuu/h^hޯǹo'JB$̕8eǭ3u!42́0)?xd0|w~hmVdfKcM:xk]F ~uwG.>nBۻv;h$Tx@$A4yζ%5Ar6gOo~\!T"ЕW^*4wĝWa3˴WRҡ:2p^'3Za|O9/8< {v KgK.UJGkWw$]R]KQ5Kh.zsY˦ywׇd'Е7Lcݗ򘷶hm5gͨ5gϬ3a ʄ +60O%BBzi$ rpD:Ζ}ݾ=C!Z晜NR$$xh#Y\%z#A|"HKVmʙ#).M ݕ(9JAHnb O:9dO0$A+pd1<Zi ڃuP=KP' ii8dY &H?*ۥZ| *iqhK|f 4yj-1#*3O' 8 ZW,, P2-L bqB]78D:vu~#}c+Y ܂07]JaN!Aed5>)% f%gnB4 (/ Y4-,}uE}SU|h*o'@sȤMQDŽtN(iEhE')Qdu>Ahd(3QjY%ʨ*@D$3"\◃ PvR;޲0iR1x,oj&',H ZxSmHDŽO?aݚhifRU4W$@R6#3ҤB&MCi"ˍGIo4 ԣ,IE8(e#Ax>2F)g_bWIJA3x@&FUQ= 0Cnw+"|l M ܀4ԟޑcL^qiәp|G|V\#RQB")4I~ 3jpQr&,νI&*XqRh#J(-?wHȷځbdEe] [tQA"^c%P=خ«-C}M#+",{($G$WCo'F6ABL=i,Mb@@46@Oab[* G]: ɴ({?ZȪD%~>0 MXKƞՀ$$r4Y i 10A4vQ,)T` a Dvb@QSor2[(.+'z&"w!wNt.4@1Yn^K͡+r:7ɔ$r`(j  #(@L؍ /}.`&FS t xz)h,`)9KpL,, U0An [edv86 X=t6U ƥPD@$ :v\MrC{@b^QOLk~$dx2$'aGР0UҺlU4Kfݶ_mdNTo ڋ`X1MJV''צA,9!O$wJD)̈XQR9JKw&$7 p$ʅE3{ 48aJ$3r2V21X#j0,4 쳙z0&1'D[4'xWᓺk",8ZH) Pܲc+ ]'1d*&[DYmɖ"ZeVe56K9 ES.jPY-OO@̈́P6~7+o?1EG%|&{}~C5s=mĺJIl z/_뾋gM(^NdLtU:zgӴo< W6?WmV Xf߰iG]ހve7\ұH]ifF۾tuR%{IêhƵya=lo٫l]ڳmS+NG&N^{]yN- ,]l.r^xϦ4 Tmqu닱^Ixݚœ <^>ͦ~_k}ML2;gwr"ۯBRS`&X貳/]E>[~٤6!2R&`4S.f_{W@o6=}!= ݏy߻m]M3g?k^}O`" D|p~3N\wuN nYv|wa C͍ͭ^o,) .C]we+$_;CBUt^gm?S~g߶-JzQ;af{/-\K c Mk.<5!DϫQ-԰3Բ `)T6zW=uMz)JR9:vO{ O28h-oʨ2δi( 䭬}${cI-l+ +N-U kOl* R}M,z=Ob .U,lt,d ȳ>&T*%8 $M DȰUF p`8;n[ָLKe&Lj=yȦNHM0rTX8."aRY=8 T g_(.23XqYabcrN/2ض(~)]iVUoynXOCĪWI~"Wb|z(Pöd25I"b`m'1yRoQ!RcB x e #2k;RWTU+٩-*g0;bjȷ폎OZ5W@drx{+ MR-lZ(U>C`j)7,a 9 ,t9+,IRGd4_lVW!)S-Y@̃Y1p{P?N6|.+;e~ab!AJfY8`˳lp%%s F% Au ln5n6w_Ϲf {odܙnv_ι;sϽYy 7@N;~wj[Itb/̺~&Zrү(p!`Ld`ikʦ(z <@;tB]Slz ̔m~m;R[2b a2afLłBӥ\ӁsbLz>_{LfhhM!h8>vT2~Uarklkol1Kå/΁ev9_ws PZ䗙 #I ÂVE`9c=/9`&)ЉO`~#׭ 8 0<9Llw&ClXdTCJ-q ׌䮹#C@u#aJ!ܾ. A*)̖5aS˂s;RuLdȩNJڎEpG~^FMWXC2b̔, W{`u3/ή>E _FtEA)eB(-Of΂LTm .5֜ڊB.8273Y,+|$Q)My\4\9 o]'}q )Xu(Yլy|vMTUqK$2lX(hhhLkC#qW@>80Ρ2ZuJ8C [ǙeX3\ϨHY! >{i`D"|#HvC2{ >h=04e,hhhIToɬ$o7 Cp iޘNQ>SAI3&S90AFid\׾^y}ߏZ •!l9_|lDV+p Y*{$hJrgJ)v((9]v>텄<݇V@B1@Մih;*]X&2Xb0znM[n0 ϖ3c×u~?#M'Hblɽ۞\rST͵0Ae8tlaC?jh4 LbJ/ -O3M1L"crL88©Jv*H|]9$ne=F}͚},榹P74e9p v?Rm= 2.O4 ܩ^|vwɉZB6HO׳{X 1qr}耤:a b%Թ6)*6^zf,S%Jm{@N}N*Y 2 \Vc+?[TKg(t;LZ3id&_ayкmzq7ښJ8Zny8+OZPlI-]8 ߂#ܺy5TF#ug_t|uar'wlduuuYO$ g o~{?ܾ~╯{Auiu!fCWGԙwUU b"sA(Č=+#Lg6۾=446CpA> 3<ᄏ"f[ڐ< s?mOLۚbL,^160Ƈ|nؔ(} PxvpM4kƙshi(Rb n';zðY,ale$Ig/)ݳ8D(*,@֘t̚0*7)Fw}7S3V;6Xh2|Zܻ09=jKmmT@:z}:{ L-)G%gLJ ǡbT㙟܅j*b|qI@}ϧMPqEpatX|U5b7?6]Y`M䌾!VX+ʺ&@3rQQșM>~u#li $G/k.. 2xXY()C,,;"Π?{h#:dv=|OgE|0 4 hZ%JQ}Đ 1ʅ%5rLdL%Ce7V'Lɔ>wzF&ɾ&RàI`ιrdJ=|l2Tdu55*BG^q~0$˒DM!P.~B;NU⾅Dzyo☑"?NIÚ-GJ4S|k.̞8Q!"68]T  &%l9$Ne5j)Af2Oҟʟ\Xjhj?'v]*%r_6HZi4)9:H"$U7Jn:(zF(žChȫ [ˤҹ$r]l!4$=.b4ؽRA~>&M3̛6lê/}xň 1/0dĵqqa];)ћ:,{~wj5~I mUT8XۈO!5> m"JnϷ`lV&#gp8G)wOW^82RTVWyj*kqg^uk{f +]p1J(ʟG5S2@n'ǥF(JTW>4,rChSd|[x^Ca0q9NIvUvH:q@w0Hj\9>ҡ`a[WTcէ;p0HXBY4::}`LXq$Z6UGU&.KVeI7]n7Z:(0UTMn="{揿DPxWQ0?p#98VPPXVJ!v"*' )9Tf@u$DŽfgr9Lt-T)cq4/7|5R7[{;r&;;O ,A&ڙM u$? I1i 4U$:*1L"b+&&!>(;krN\8vjR:spS,a$’4/fW&D%{(qǛᶙŶ3t)#hwPɕ +5(DÄE;|r!0p^^XE I谲 {o}T#vUfYv]".)I&΢L wb<ݷKoo65IUURrȥsPeHGX`AڻTm4:WHB[ +}N J3pL&rcقoeI uNZl6l#ŒN*D:@?1w EP~0״զolNO4J@rNH+sӢ{Z-;畼j*(8V5+kORʹPU;'1RJg ’]#%`}HI*w ;\q jXh|y[h,K/+r;,7z˱qĠJAteE`Ao& K7 B Ε4Saⶊ 9F d7dE+2XQwV\^dtZ+Q+ Lʅv'sչZ釲qB:!ƀٲN~Ԥjm-9 >n^j&̑;7t4htU8xp@JVG !ta[춬NR r0Un{5Tru'l.*mm$t.۴N6z"ы8t2IC.]?%Qǜ6r+|; b7띲?9s0bPSmtiquC۪eۻ*u H"c#2T"9.%U\HCZSSw / T9v}߳.kntA/+KvbA{7@$mWo~s= lվ   D|M Y`Kjpƥ;\Ň}UhR[t~U+&.W9y =bw+{Q/&cPKM3YYwX=?T{˧ZѩsF<[\e/yw]Dz'{t34//ۗ,+4 T=kb MEV\z,**@}aWr80"c죊r`Äzix<=0-2h9â=X-l“u*:_|#6%Uoٟ}k Կ²z{nXp;}3 %` =g›ncaꨌ A1J$YT$n-^ 59nx7ؔjH5@O++7]Uٺݿ篤,s̫ko5k,˜8- (9s 5tvFҕitzYS̚/7fǡdDw7_XU1W+H@/ypج6<5@me9!@j4Z 90~KFִq#R^K¼Fwԕsl<%w.Z(`/6Wow,FEQʋ XY9(^+vT!gnOg0#qÏO^בv:EpD ~EEs%؆ +E}zWM6'Qt8*!650a`4yNjy堢 )c ":ePv ښ0"k2nZ06dL샎czͼAlE. d=y1+\ @wü@K>_f&£8z9|< ՊT&-ESfaKƯ?;K߯gUX2b@5zMFs =)Qn喧XEgk Jc|#vRC#&M%ACjELѧF!PO5Bq1ʅ1) (8~Ly-fmJ긨+QOX6~::Zx ^&ٗeq,xtT[OwtP=8݈R+L9>DF7CM9$eNĢsz{/S^>+lEqǟM=mX焰]g̔ F7Tq,rZ N+ǯiY1uhKk+>2ݡrH?O*hn-+[V!s,eˌ0 w_f#~~ h C<8sFg!v(.;>ǟAPte5O[r/^k8hH_ /De' T n:rRaDWSU/ŹR5-FO͜?IMCV$̹ MbF\jBa1"' 25ŧs=Yݮ!  WhV1$񨪤& Xy dMıc.A,1Kʼn_JK˧"DDĤIazBbζf&H݈C`Yx(6 Hbѵ6ԹyՁڪrx~[7HJJ MM-2)}?~I0sﯤNF|J5Űl]y}o2e%h)iԈԤgRl_Ii'}NRɒaftSq]Iss!QzX"#z*D=x?uNVCȋ@sto5ekJiTZ@1LZ>wG{1!MS%ފ]vxɽz'ښnvvUUzz:A"6 ?n_QDMkյ~WȢq(͂2MPߗcZ+-[k^ASjٹYm0ȒZr!HJsC/J$),r,5*aS١3$N߯ے|f)~ysZ[ZJ 5US+ j(Q DKdr и.߳S|#%!7wTSQ,ù'Mop~ٶɷEV Iu%dIaJCG[ /woSه8yּ˻JGT"wjpte WGVr O 88Xpwwt:K4`'V2n^MT}_m@xL|ypyy'GDiISBSm5܈ae$HY۩wz;zjҜ*,>Y>o{mDك:SL<(+p)r6wIg9L& HWUWcĘų^CXX&ރZ/ס(?c`E/p=\_=$SK`:<}H*F_w *C^;w6hTZG Aw/>o,n=|up,y[ńEw#<*ZP ;tR4͵غf%-"GdXN, P_[&?ZO=|4%hliC֬)ܔ^3ǿ݃}hLG}x<@6Q5UYEXLQcD80r^-kL͔Of!Y;@)1BnE=i]e9j-<HtP`q5] m[eySYQTgbs}Y_^)4.f_a5*8~Wd_lYWΩɓ`W e+1Z k9됳2{?u-}o ^0U> l:IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-userlist.png000066400000000000000000000101421237252063700277270ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\y^3.͹.5 *6FU4䟔ZJD+U0&@D "ž}3}ggvfvg2֣gz^ޱ29_< σ<rAȳ+'E&IY}WM| Bml:OYfx_'ףGU].S68"n:/t\c<8t%΍$&]O[}ڊRq*aL&cs̨&wMTJ*BZX7>< ۞ ̮'p}/eIuifM F^ӾKҍ$B%> (B#P(.[#uR:jHCB=l;qC:#n:yT9:MPTZ z7ёS?,SnNawy3הȺQ?˜S9c(%5 ,Ɉp )dèBτxY4#O=j/z[ZT4W6A&^Zzų$lCz(W~p6IąϩBc>J PP**ȓe l/x}-*IL YD°+ }aa2ʁ|\!.y=3)cQ*MDc"Vt=YEp d䁘M̨}c<,\2WqFhpUU&`̟\GZIbJP33!N9*nP}jvj<'*`VF5c?(XB5w;kX{A#H(rƘdX2Āo`qr$VV1dŰ`_ep$/y#OE,u~\lN:6.=UK&y7>Ҹd#X]% ,%"s[I$"poW@u>p6_fȡvl>2o&\R\Sq`"@36R]W'SBx,T֭k7CaińS;RWcA1d@ 3P[S z,|Gv .$mۅB:-@攠sHVWC6G 1x@̑!82j)ɔ`R5A;flf */@SX$cbpg[]i rUqP(^$’zKl˶3F#ݭD&1IsO('ҹ#Xrc)rrka? xa<:/Pϛ9ёϮz,wȇf󜪞k6ȶL7\נaDbߥ]i'a@+%"բ6ĞeV/^lh #VQ.kj -&݂ 930MZҤ S] kiQu+sУȱ0qa{`(E@/imف,IMe'B]A!qO+O !f=!U2zL&E!4+%TVfgoDMA! P{جd1ɳdx!"'t*9vA(Ccr -#P5*ӱL&!q5p]l14mK)/zZS0 30(O3L2ɬPo]2k9h6Yd5G 9_aXٰ6%cT6nY֫uY%rf:V\^~vݓTCk!O!`y[ `7 ΛHan4b?$atڿvv ׉{(JzpF'˥o:UviiR@Lu^Z- ŦMNTLꦖ&/&ǿ:n&`'[O[Uܿ>urz!)2:qSUUG1[ Adk'us+`uj^Ȃi]ҊNde† @vvwcGiҟj=wj*(U!@&ǨQל@!IUSY-E+/JyoA|a\&uFQD֎? }Qrd6wri/\_/Q8NQEr)I^jj`*>$Ic^׽y a9>'=WPP{-Ь@8QD'}w1eTQs6*?=g)tKNIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-userprofil-female.png000066400000000000000000000111741237252063700315040ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\ lyߛcO)\DQ$KEbYaǮبuIE(6c@)NF ,NR)4)Rk{3C-)J]2j_3;_Obi¯vw@y7VM?3Ksy_α+/AP-ח=p+0sPȹUr>0!~k[8g+=};lPJ])&SU>4t CK/}{g%WQl[wid~24$QHĦx R M춰y꽪B|GÛ>su9Ny@aVb5ljO?Ek: k^J" PU5qC'<7 Oڭ׃OY 62U5`]("CQ~엁iU$>&%I)AfD(zUPt@܋U6ٴÓѮeTcH'oJz Ǧ` Udb0LIOO^{|0x|Az|Ö[fBaˬ $!xvW0}k/P@8Zd^d=5K( LKüwpJ]g4Ȋ,CgOsĠHP!AlH^YZ`U"kLWmr`c˶жףqW=cCd8q__dt=N R %dt?= yA8(PRǂ~ICD 71da˼iKm O_.SyLl/2% pRV,9 PyT\XS~G !}SeU|[kMtj .4CxZ|C`_&)/I p'-:1Zٌ;8#[gy3nəh")52t"[ݙh3PuC:0f&_0#BFM+2W׎Gq {2{,=zvz|6w'Tgzg8yY ouuvmX>LȤAΉl +&)ߴX4ENr -j;GgfH&b.|!&TYVf6Cl̥h 7-I?mRr`PLg|&pXYP= 5& d)2epm;fbǨeJ+mp>dڵqlEYi^pax75Z$ [3DJԹuxֽwMn3Xp@9-w9A\4g;Q~=ȦiUM a_ʤYiu8ƜY9 Yͤ9GklV=n sZӀ@jIҜc{--: 7vc. 7e2B8\9xRYcU&۷{\[0;k s:}\A,y: Kں_-+Ǔ;gr֩gN R{3[ukF+Q^LcN}d$p [R`?>&H&WuՖH7S5Nܥad¦mjc5ȧq/Y %&{ UݶVY(csGas6HѴ% iiEVI^-PQɑٗmYWK-;I'}ScY;g!-.+ UR9'vu6 F[]ea~y d#d_f3fv\j܇{>(Qz}hU&ZvKܶQWZ-Z y7D_@o@o%<zԝT-81Ƨ iE$(x͚T(2r otL QE(W}^>ućC>HbP.*\.0:0$*_Rx<2j,e3bE%"UY󉺴6=$S(5}M_@dTA?]]p|^E8myi'"4@>`y.AQVZUw'Z㟋\EQU"@bp7@U!w\, L,[YeA?GSL:x8 3h4JВQr;dHƓN9%U5~zI c\m{Śkco L Z" :e˵ukz/ C ++-{**tt6W/OBK*9KzZFdzz]v*qHJ  \ZzwOu댒#:sӼBȒ62C+0FYB^Y+i>&|M<5 d@r]Z^hH?PI;!_ՆT+N+<^~zW~6;kyyy&$K&yQ/1NS9#SSSΙ7>1ݣxvz˧paߐ0R 5ƧmזKblR ˃ǻ{dx]d:p:掎ق׊tFee9<֋Rpޜ/+.㊆z9 [6ɶ6S!>xpϽиu+ ed x(#inoQ>1N #%k ꪫ1za3+ $;{'qG%\Dl58SHH-3$Nr>`Gαa3ٽsiÈxϗ\@-;l;"ӾgW=2߿- ?#)IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tab-userprofil-male.png000066400000000000000000000077651237252063700312040ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATxil}Ξ]H\HuR۲#Wv@I@jFIhuP a#Q#"[LZ$ݙvvERy7\q_Yma\3%yN19EOWBu]sdPM6[LaV ]sPȮ"Y$tAyuN((QB",O϶lOz(J\d<g;&V}Ć@ yVkoZG!L41T0&f oh0\]8t߾K &:#ECUAdV,Ȩd<EvnTpC.\Ϛf=qҏ] j.Ar:$EC9l0cOԎQy&/Ļtu Eӡ*z`c)q^Qjs8:+ˢRhX7ݦMޔ:Tu-}-=bՒ$XAC8ϗ3!ΥMm{.BXg.w?o<"GD*[H+>2*`oo!{-m62Z wsb.1^OfkDma4e:^ʣUg;"uM[Al6H5ki&@ s; =WHG.olf%Xm]mpoFiYLPn[eZ1EX݂$ls;s{$O'bm|Yв]/*aH&eIՕ$j.sBMM@ueEnotH5 ;DXaZm!j}eVzFk1ivӓG8Mxӕksl8@8=_EĞ(w%@Vr:\eꘔ17_Lbr Eud"PA/)H *pb_m:6YPkeuqL ^dtՊKR( uTQ,uU yGLcZTy"9,oloo!7ay͒Б8_uuB+@׀tfpkG<1$k,תrvIn2U E{:&וMֶkO3?Tk#$mAlu<#}$ kj`[fuCV(XE> GCit! [IҔ hFKouHH\}@X;l~tNO[Ē]&-xF7{ھ|wjpOWFT>w}OPV6j p?*ߡ`gǺ:C/Z*m zׅĜM+ M(|+ *vp8'G7ӐH a@4/,s=Xjη*n5}ǓƏ~@Bt`E8˟Q̀)P4/;C{ pYm!?Dڅʚz\EH̍b54#ґc/F{LG"911k;9U$@ET]S/OC!ӳ}`2NyCJ6cug?f̮1|~ldӸ^ȉPbiEBQKA{^Mлr˳׍Jo5,vS.5L1:VյMb<}; #KL?!4 X"4TQx=Nn.2(#E 2qlPȚ loEhpEuTZrR G-I:6yPW-hWrŖ̅Uq5k'ϝGmX#l~aAzo I\ RUCz H%UKg+h[kW'߂'5܈Ffg˵1w-wށKeyEU{WF`y-GU(PS=q ][ YV(ԅ,24%P#5!Ld+okyN= DdCSO!B%;z{O?é)X<ɚz }5C;v@G GYO=!uH]8!z>HX|g\:&:rvbhD:B[nȵH||[(/zסk;)ϭU 0iM憥IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tags.png000066400000000000000000000027411237252063700262550ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxڼ[H\Gǿj/޵ [#UMJ}MADlUh^|(y'AX)-AxkŪD&sx4&g\7o)c\z`SczQyU0K@0o+2H2J2xή<{liiiejjꮸ @P'n}}\\\>s^cb+xYJKK׊D̔gdd R>?o3AN͛^iiiߚLP:Ƙrpp@E(++[c3E ;;&`3쪱Mqqq8_Q-@O xzzBPPݏ=uVFkkkт8ll6~9n~$醯/> 4 bZ}$Cdd$ihh `ޢYampp{zxV1: =#7/(5!cDDZ@˂< pFAff&s:.84.v@@`` ;RRRNat@@t bAȬbaH xbbx0θs@NXp7+vA bx9$ttt۷osɞ-LgG^e^OppO<5EEE|x1ΛyJpq' hGFFVNt"C0ިN+uXXXS,՗%''cJE d/gB5 T. y'Epi^U )jۘB-Tt. AA]]UW3CKBmm-pD9¦vѰ,7Q^q-+//ghX&fXXii)C/~ C~!0uGECPP1F F=@Tj:djrVWWܪ GGyPEg0.OԻ0To:F '@< -3'`7D8"P.q%;zE7GX_f ݻ|Yt:8ϼ*3YĨu_\mRKv~LtB%=F_TȁK轀Z(E\DDgAtwcg6iti0I#dH~"7DH_󎢧0<"j !C`*{4c[C~@1z.IE|KkrzMBƓ:v (յ#Fw35{1mon80 g8lE~' $Ԅ3"1)wwS/$Eϭ/.o,CT&(@\'sDeER@E@xf=> gfOwFǶ6MӴf /5 /IU@Qf@wb ?)xZi\Qjk6{DޟmOֺ^-i8NhcoڬL wWSJޕ~)YkAwYX[H(;HPڥ n$$pZ/Qו,Y q׾ЖZ3`QzJN&U9$IxA|CIL6d{{)kӟF]UrT3Ўbu͔K+]x]Ex[xNb!rIT=htփG@!T TJ ThNbŹlQ+=-0 ˾z`XS0R (+ ,%x=:7 *@ΐ"u*IOP9YFtJu6|ޞ_  !7WL 2F_IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tasklist-done.png000066400000000000000000000023721237252063700301000ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘]h\E̝lm>M7MkEPJ?,`RJcTDACA'%>X*VS-mEЦ56dΌ3nfo}:93g/0ݪ{8AQ@x5pa0ƃQ&.&1iwak` 8>满umoI>sgO? f@A0:ef7l{ CqP_7oH`v  %6_Ks?q %9H@*iֶ ޞ9of`j6" ǺLѕ!)Z`h.BXW' ӽ>rfS/XL]? mzqu a`)fYsc0͙H$mTQ@$`{j1`xFm+*;j)IՕ1SV1=eeROSe I#FǮ2qL3'!@{ajf!r0ƫP@A̅yuc?•PhKF4JäbF3kĸ0wx@Y=Wq&R&2۫ ;2[}qf&0Lէfo{ۓprȽPkK3+L* F:9z"|5~ oa7> ܚJ ;=MeuRF̱Gv¿ֶtZ 7aǟ/6<ۑ1xKp~ P&^j,fb9mA-Q$s +- /mE9tnV'8H\~n-Hu$!%3(TFn}!859[O~;2Hf[$rKkXcUޕL{Gc:bpqrbۙLGSu-<Í1ab%UϿ5 BzaWRI}@W?b{/Ja/0-}k .{ķm4:V,lŵu׋8U1y V ?Հ ]9TQz@D$J utCV yfG4 " l(DIT1;  0S+V^IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/tasklist.png000066400000000000000000000023471237252063700271570ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘k\En66MZ&6ѬZ VBh-AZ"YD_ED|DZ+*R@jM&Xڴv,ޙq77}pp={f)%_ABH]ѷj`Hg% Y \m{  5 vLF|?cQwWЅ*0${m?;x%TUF㐁m=3SsWoFPy* kr5듋>S]xP-`!As;אָRZ:džd  7&(0@Lew eP.ҟ ׽-Uf>H&sO0$D&G0VH$M/^it:R@"b! *ar9m5eG#eQ܉zcpS3:Bp) Qf>'glHTD2ٿtGZˋKVuz6TT vx)8==T yn,cR $ $ R!…ؐu80-2Qlnj6ʃgݡ&/n"TftgUe.^jRX}6B+ʤ: ӿąYTwjok2_0lɹKW`zvv3*nU|8У74 TV,g#{Mjq R* BN €w ފ*R#e 9k_L+;ڣsO2ae3'Lj  F=/uLfȨ B*Jcz}E`dF}s5 +:g:/Sz3@u ׮'6BkUxR˫Ciӥ3_k15)KiWQXI? ʒoM|/ށ-1]߱Vk `alMYѵw&iqԨ @u*Vv+DXE1Ò8U1r ,5zQG 8\U GR )Y']D#IENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/timetracker.png000066400000000000000000000043051237252063700276270ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<gIDATxX{PSW$W@+X[]+;řnngmήmwǶ>jk3]XQVv|2<0 $$@&Эyf~sroN;0xZ"f 6A`,xλCaxd!ĵ②N[s}IXhcP/> 5yF'. D^ueR6f}^͛yӢs߱w)GY/:z wCIrn ŋUO52ơAFc8t6dתNo"-k[^yk y'+9N"1zBwPbڲ5&6B U#7Ѧ+ΕUG.P#&!D3<8p,+9~w~+qnGNBxa~D$>6wJdZ &y71n3Cx]fQm['hoCq"B"+C2aL,$xŐ@%ƍ{R3sLT|eyN_+=v( >($ - ΋;wC탈|/=Er01FHh'ci\>O_ /^gGLYtQRB0LX ZM(X"2; %D+D3Y,F*54]mCth!u&MPu Sl ]-cOj/w cc1[ Cɓ)([ y*|oP?m_BhTsHADT4:v п~w ~]>xIoc_& ahrb{PB`CI CH'1$#"ѷJ͊C:;|%⢩1]jh^!ث2 l2فVGC< 4b4!G;"+8:Z\_m\Qq_Оӈ2e_ӟ&]jOZ'ca늋8ˆs\:Pa6Ѩ;^LK]Ŏ Sc:vj!'N~SzlMV~!@Q]Wwz汫=JC[Mõ*K*mMā-3Z-HNO]+_ۭU54ڛtc55T#$x-Ņ/>rqv`"mjB8 IJ;|AD/!ї(^ 2"dMψSq6n$FאTZ_EB@U(BHnz͝0E㮮Ow&X>"93 )ex4chR(rVn,:Fw:~p9$$ :) *o@MJ V#J>mBBV>̣F9SRL.2."vw~ChbdXdJh5K>D__?qaGbӽNV\QhDGſ`BWe J( i ]8wGN]!5S=ֆPn oV'*"dgXNP%Rخ<Ǩ~VGh;b凍95Փxs~ԄHujW{mf<.P`r}e^[ y3s 񃜻;gk*Ń;2\Ij9ff03|!E:O8huPbIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/user-icon-female.png000066400000000000000000000027011237252063700304460ustar00rootroot00000000000000PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<cIDATxWklURB (P( [aJb`$1FmL ш@b ЄC!1V( t1> a)ᵯyy '{v^;8?}#''^ ( Ľ-w+mcN,PpHIu֦ؼ쥠miL]2 Y(Q k ܓ1@ư`,@$h*!^@ceeFS)i` =Cg/Re|dE ݋U>{$ u錅tMXyvּ?>ݴg @&J5=4K*M$ $ȗ›[G%'m* 3XA,#1 -8,,eAmFAV!EXbh԰441B҃CMgf>1cnQQ۰T%|6]ouNY` IS1C>@e j=Hbby9Brq ^GRڨ9!24&2Z(&EȢ#Eg"8o˴ADy^ \d>b⹋t/̘[B8L& W.L-9|gS&T6&R>* "Ot2pPPH I;O?'I(vZ^ZQ8"#._$F9UKN Y͎>Ȩtu_}>%6}ڸPO 0yi"N6&VHX0![wJ4WCfl2{q^D~ݹCՎh[t_O;_[)ٶߕ~Lg v]qO7Q,J iŢL}s4vmZݾK} IG"2\΢gr;xf21kG^*[zmJFD}$was{~e74@9d |IlUU5ܹi#. خ'd.GP-,;,aNop)l8`; ŕo>՝ @oHnN=L%ǪЉ`PUU@QAo{%OK!ұ"m&dO4piimIQAV44kк^G{@zz!=D´h% W{ 45O 8Q].,CRG׌1=8P?lT(ATP06ƞ]=g`O2Fa!?**o`EI_c2ib0@H<;&0v 6P2l Y@:No GwNP:&:7Y= qj jÊs\U Y4Ѻa4p"8jct UnOj`Kﻂ`MP+v\DKPr9so[z[kGm%3c ^#ka-(u<: ܷiÒk:sLn{+_UedϿB05A 4* j?%S0HsG9Ow­OKJ}]*T|JIDF` J!4T~DBDCPPhx.iSvcfgΌN/2.[nLvYu]8(w[\hS{<{a,o#NfBx{?am;+=£ dB׮{Tg!VԶIJz("" _G!"H1RT -!ݡ& $lS(l^y}5"K62H/X@B[ao77[E-WY}BQLʲ&޹t'>{Olh&rokRc^a Tby=eO>bC <*|7+OKaCcs/K8o\``&8ȃc$#rF(̄;0?pR}|Vn$s96$G9 9ȥFVbT1T^<im_Iz`@PP4؈ |ޞ@Lʾ?=z@UD/]520s#q&{XxK$Sc{{ #sciSl:DOVְ,?!GTO_j:^Q 'Vm3ey "\ɔ6n=9-1A <rD%--ͳV_S"eh&"?x+Rj-"Û`5 ݽ#\}}W#QKt#эTf`ޢ Dc۲J9^-I'nb1 I\DKC5KH$**JXT /XQ42FzOXF&F `(hz*5d)s & t j5IL"k' 09(^m:ЯӗPdDT?C,F,3S #14w '#E`P@|=Sm1#xߞ9Sp7Ŷ5)x>hIENDB`Collabtive-2.0/templates/standard/theme/spring/images/symbols/user-marker-male.png000066400000000000000000000023771237252063700304750ustar00rootroot00000000000000PNG  IHDRr ߔtEXtSoftwareAdobe ImageReadyqe<IDATxڬVkhU>wfvg1; YjS["4i,T`J_ Ђ H1"+DPhQ[iZkMyfw=㹓$n6ޙs7;u^(sw Y:F`۶Ӵώe].8 RqABcq%RyokbFZ!U胮&m5BnP޹y;tHd "j0 BAcoAh-0ܸ^(U s/rM 醟~q3#L#2O8*'PA!|`[ JԬMhO%뮎wښk qh ;60Jugx`xw[҉7rlo72#+v]ʜqsmb9xoؚ|s̃}+Cqm\K(1Ual2N}'Nky9ȃV!G{JOL`S^RB 1|vJ3 3`= гixOqĨЭԇty2g 7>>9h8p,h.;?81ctԊ3 z3{r) ZC/ }S:l=3NޛSĨl^U_"V d]u]SGDF Q0:|(`h|,TXI{oIYᳶa_8~QAsD$`Ԉ/`bFTw2PH/"+"#_(`$Lȑ&Fd@)IG}}:Ya/x{mU@T1%"{G GV!7V_E [QĢ3*zŭ2a{v'p)}h xq'v04++(3m^uiw `FN<3 +7"WY<%xviHhC$Ȅ<8 A2|5R̃0g6eV|Jd0ܜ]<nc+UqZ2͜ mT N~?q\*[=xdk$Μg1nL#q/#ЦAݍ'GJURһ89O>#s08<'NųKW.΁xzdأsf@\zTIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-projects-bg-b.png000066400000000000000000000001561237252063700275330ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb|U@w 9 IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-projects-bg-c.png000066400000000000000000000001551237252063700275330ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb/,0V?IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-projects-head.png000066400000000000000000000001541237252063700276230ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb/,0% IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-projects-sechead.png000066400000000000000000000001551237252063700303170ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb/,q0fGIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-projects-secthead.png000066400000000000000000000001551237252063700305030ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb+ 0{scIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-projects-thead.png000066400000000000000000000002661237252063700300130ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<XIDATxD 0T&#GAA8x- 1//MJL [[٧t=`fJ}yU(6^TIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-tasks-bg-a.png000066400000000000000000000001561237252063700270260ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb:{n@妙IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-tasks-bg-b.png000066400000000000000000000001561237252063700270270ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbzU@k tPoIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-tasks-bg-c.png000066400000000000000000000001551237252063700270270ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb0*0!:eIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-tasks-head.png000066400000000000000000000001541237252063700271170ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb0*0+!,IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-tasks-sechead.png000066400000000000000000000001551237252063700276130ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb6*s0&JGIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-tasks-thead.png000066400000000000000000000002651237252063700273060ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<WIDATxT 0 B0t!q A 60O/.M-Gn Y@am{ϺLg޴Sjs W?y TQIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-user-bg-a.png000066400000000000000000000001561237252063700266570ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb8~x:@Ϥ=IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-user-bg-b.png000066400000000000000000000001561237252063700266600ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbxE@dIENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-user-bg-c.png000066400000000000000000000001561237252063700266610ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbxLE <IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-user-head.png000066400000000000000000000001541237252063700267500ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb ύ0E!S*IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-user-sechead.png000066400000000000000000000001551237252063700274440ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbLf `lͨ IENDB`Collabtive-2.0/templates/standard/theme/spring/images/tables-user-thead.png000066400000000000000000000002621237252063700271340ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<TIDATxt 0S$#e(~Ng0ϼ D9Fsi}`šQJr_y^x hIENDB`Collabtive-2.0/templates/standard/theme/spring/images/win-down-side.png000066400000000000000000000003741237252063700263130ustar00rootroot00000000000000PNG  IHDR MetEXtSoftwareAdobe ImageReadyqe<IDATx1 PD#OH] vepYeI$,b* s|^mFL@iB%qaÁn?H&RHC, M/`dva&b!b' ֛23,Z6i3`_")kXc6m4CH~ndcw]8ɴpji:tgiaB^b@O^M \ \ 6=za-S!6y{%DzyM5 䱄WEzT.+y<)* [ EA-Hp,V n;tvpmV`Ko$+Z IEpoq'pՎK%Q|xCa3gk `YV(u]ϩ)Jgn+X}KSeZ6{_k|/[Bl5~x:f5j樬BÕnyV.jVȈ'2 gx?I}n{WSqԊŽSKH8\y|g_l~[$(njLbΝ+jܒ]6bL;>%f*VZYLS_ r2;eb#MÍyŽ+DPQ31pfckfI/7V~(JKA6?\tb! JKAuzEvIF pűru#1W BÆ8saɵLH@AVi\A1BCϬvv$ǀcCp83&pJ]Iɉd=9A@)k/&z,)&ۣms;f@!筩0qUC:eY%d\em)94瑮*q#X{xD38 Zvq5p2 *;ۃAn7Tx2`]ΠGV_I7oiM7:/;jˋfXL@ą'o*G'n%Bp2oA[r׀(BE 1zs3,NZNJrl.\Y!f "%g oo-1@8.f'wp,Den(\'u3Ƙ`E _8HD}5}kV&ZLYZF!gz{8̓Fn@jʎvu+\Q;&a:gZU ֦HW>4$cP穮v 'IENDB`Collabtive-2.0/templates/standard/theme/spring/images/win-up-side.png000066400000000000000000000003501237252063700257620ustar00rootroot00000000000000PNG  IHDR MetEXtSoftwareAdobe ImageReadyqe<IDATx1 06EʔVb*^*f#x'C&` gxyBb hv;H=]Z! 'i4mk!? 5(~0k=fyAxGjwi4p`"(#IENDB`Collabtive-2.0/templates/standard/theme/spring/images/win-up.png000066400000000000000000000010201237252063700250330ustar00rootroot00000000000000PNG  IHDRp0K8tEXtSoftwareAdobe ImageReadyqe<IDATx옽JA7WHHa!D0O` b3؞`" 猌.{[a۽%do{u]+}.щ@V Ö`k}CT. {7Cuo =;5m\87d6XY/7e=;b y[D \F#^R^!tmRyJh rE(j-{ f =;87dêD aSȖJ`JN7wś>m1dgɨyʏ=c`:0Sש24PgCY09',T*vq }{ȁm@l#ȉmBAlL:8L]f:BjB٭, X7O~~w!IENDB`Collabtive-2.0/templates/standard/theme/standard/000077500000000000000000000000001237252063700221465ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/css/000077500000000000000000000000001237252063700227365ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/css/calendar.css000066400000000000000000000076211237252063700252270ustar00rootroot00000000000000/* CALENDAR */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Calendar JS/DOM v3.0 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (C) 2005-07 by Michael Loesler, http://derletztekick.de + + + + + + This program is free software; you can redistribute it and/or modify + + it under the terms of the GNU General Public License as published by + + the Free Software Foundation; either version 2 of the License, or + + (at your option) any later version. + + + */ html, body { font-family:Arial, helvetica, sans-serif; } /* Fuer IE in IE-FIX */ div#calendar { } div#calendar table thead th{ font-weight: bold; font-size: 12px; text-align: center; background-color: #cedbec; padding: 2px; border-bottom: 1px #8b9dba solid; } div#calendar table thead th.weekday{ font-weight: normal; font-size: 11px; text-align: center; background-color: #e7edf4; border: solid #e7edf4 1px; border:none; } div#calendar table tbody td{ font-weight: normal; font-size: 11px; padding: 2px 5px 2px 5px; color: #0E224B; text-align: right; border: solid #e7edf4 1px; border-width: 0 0 1px 1px; background: white; } div#calendar table tbody td.weekend{ color: rgb(198,36,36); } div#calendar table tbody td.today{ background: #c4d5e3; } div#calendar table{ /*border-collapse: collapse;*/ padding:0; border-spacing: 0; border-width: 0 0 1px 1px; } div.calendar table th{ font-weight: bold; font-size: 12px; text-align: center; background-color: .cedbec; padding: 2px; border-bottom: 1px .8b9dba solid; } div.calendar table th.weekday{ font-weight: normal; font-size: 11px; text-align: center; background-color: .e7edf4; border: solid .e7edf4 1px; border:none; } div.calendar table td{ font-weight: normal; font-size: 11px; padding: 2px 5px 2px 5px; color: .0E224B; text-align: right; border: solid .e7edf4 1px; border-width: 0 0 1px 1px; background: white; } div.calendar table td.weekend{ color: rgb(198,36,36); } div.calendar table td.today{ background: .c4d5e3; } div.calendar table{ /*border-collapse: collapse;*/ padding:0; border-spacing: 0; border-width: 0 0 1px 1px; } /* DATEPICKER */ div.datepicker { position: absolute; text-align: center; border: 1px #8b9dba solid; font-family: arial; } div.datepicker-header { font-size: 11px; font-weight: bold; background: #cedbec; border-bottom:1px solid #8b9dba; padding: 2px; } div.datepicker-footer { font-size: 10px; background: #cedbec; border-top:1px solid #8b9dba; cursor: pointer; text-align: center; padding: 2px; } div.datepicker-calendar { font-size: 10px; background:#e7edf4; padding: 2px; text-align: center; } div.datepicker-calendar table { font-size: 10px; border: 0px; margin: 0px; padding: 0px; text-align: center; background:#e7edf4; } div.datepicker-calendar table tr { border: 1px white solid; margin: 0px; padding: 0px; } div.datepicker-calendar table td { font-size: 11px; border: solid #e7edf4 1px; border-width: 0 0 1px 1px; padding: 2px 4px 2px 4px; margin: 0px; text-align: center; background:white; } div.datepicker-calendar table td:hover, div.datepicker-calendar table td.outbound:hover, div.datepicker-calendar table td.today:hover { background: #e9eff4; cursor: pointer; } div.datepicker-calendar table td.wday { border: solid #e7edf4 1px; border-width: 0 0 1px 1px; background: #e7edf4; cursor: text; } div.datepicker-calendar table td.outbound { opacity:.4; filter:alpha(opacity=40); -moz-opacity:.4; } div.datepicker-calendar table td.today { background: #c4d5e3; } Collabtive-2.0/templates/standard/theme/standard/css/dtree.css000066400000000000000000000005171237252063700245560ustar00rootroot00000000000000 .dtree { white-space: nowrap; } .dtree img { border: 0px; vertical-align: middle; } .dtree a.node, .dtree a.nodeSel { white-space: nowrap; padding: 1px 2px 1px 2px; } .dtree a.node:hover, .dtree a.nodeSel:hover { text-decoration: underline; } .dtree a.nodeSel { background-color: #c0d2ec; } .dtree .clip { overflow: hidden; }Collabtive-2.0/templates/standard/theme/standard/css/export.css000066400000000000000000000130301237252063700247660ustar00rootroot00000000000000.export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: ; font-size: 12px; background: ; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: ; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: ; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: ; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: ; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: ; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: ; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: ; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: ; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: ; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; }Collabtive-2.0/templates/standard/theme/standard/css/lytebox.css000066400000000000000000000051771237252063700251500ustar00rootroot00000000000000#lbOverlay { position: fixed; top: 0; left: 0; z-index: 99998; width: 100%; height: 500px; } #lbOverlay.grey { background-color: #000000; } #lbMain { position: absolute; left: 0; width: 100%; z-index: 99999; text-align: center; line-height: 0; } #lbMain a img { border: none; } #lbOuterContainer { position: relative; background-color: #fff; width: 200px; height: 200px; margin: 0 auto; } #lbOuterContainer.grey { border: 3px solid #FFFFFF; } #lbDetailsContainer { font: 10px Verdana, Helvetica, sans-serif; background-color: #fff; width: 100%; line-height: 1.4em; overflow: auto; margin: 0 auto; } #lbDetailsContainer.grey { border: 3px solid #FFFFFF; border-top: none; } #lbImageContainer, #lbIframeContainer { padding: 10px; } #lbLoading { position: absolute; top: 45%; left: 0%; height: 32px; width: 100%; text-align: center; line-height: 0; background: url(../images/symbols/loading.gif) center no-repeat; } #lbHoverNav { position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 1025; } #lbImageContainer>#lbHoverNav { left: 0; } #lbHoverNav a { outline: none; } #lbPrev { width: 49%; height: 100%; background: transparent url(../images/symbols/blank.gif) no-repeat; display: block; left: 0; float: left; } #lbPrev.grey:hover, #lbPrev.grey:visited:hover { background: url(../images/symbols/prev.gif) left 15% no-repeat; } #lbNext { width: 49%; height: 100%; background: transparent url(../images/symbols/blank.gif) no-repeat; display: block; right: 0; float: right; } #lbNext.grey:hover, #lbNext.grey:visited:hover { background: url(../images/symbols/next.gif) right 15% no-repeat; } #lbPrev2, #lbNext2 { text-decoration: none; font-weight: bold; } #lbPrev2.grey, #lbNext2.grey, #lbSpacer.grey { color: #333333; } #lbPrev2_Off, #lbNext2_Off { font-weight: bold; } #lbPrev2_Off.grey, #lbNext2_Off.grey { color: #CCCCCC; } #lbDetailsData { padding: 0 10px; } #lbDetailsData.grey { color: #333333; } #lbDetails { width: 60%; float: left; text-align: left; } #lbCaption { display: block; font-weight: bold; } #lbNumberDisplay { float: left; display: block; padding-bottom: 1.0em; } #lbNavDisplay { float: left; display: block; padding-bottom: 1.0em; } #lbClose {display:block; width: 17px; height: 22px; float: right; margin-bottom: 1px; position:relative; top:-4px;} #lbClose.grey { background: url(../images/symbols/closelabel.gif) no-repeat; } #lbPlay { width: 64px; height: 28px; float: right; margin-bottom: 1px; } #lbPlay.grey { background: url(../images/symbols/play.png) no-repeat; } #lbPause { width: 64px; height: 28px; float: right; margin-bottom: 1px; } #lbPause.grey { background: url(../images/symbols/pause_grey.png) no-repeat; }Collabtive-2.0/templates/standard/theme/standard/css/style_form.css000066400000000000000000000135631237252063700256430ustar00rootroot00000000000000form.main { display:block; margin:0; font-family: Arial, helvetica, sans-serif; font-size:9pt; line-height:normal; padding:0; } form.main .row { clear:both; } form.main .row-butn-top { /* Button top on forms */ clear:both; height: 38px; } form.main .row-butn-bottom { /* Button bottom on forms */ clear:both; padding: 12px 0 0 0; } form fieldset { display:block; border:none; padding:0; margin:0; } form.main label { width:140px; height:25px; float:left; padding-top:4px; font-weight: bold; } form.main label:hover { cursor: pointer ; } form.main input { float: left; margin-bottom: 6px; width: 307px; height: 17px; padding: 3px 3px 0px 3px; border: 1px solid; font-family: Arial, helvetica, sans-serif; font-size: 9pt; } /* in Userprofile */ .userwrapper form.main label { height: auto; padding: 0; } .userwrapper form.main input, .userwrapper form.main select { margin: 0; } /* ## LOGIN - Form ################################ */ .login form { width: 200px; margin: 0 auto 0 auto; color: #0a182f; font-weight: bold; text-align: left; } .login form .row { height: 38px; } .login form label { float: left; display: block; width: 34px; height: 23px; margin-right: 1px; background-position: 0 0; background-prepeat: no-repeat; } .login .username { background: url(../images/login-user.png); } .login .pass { background: url(../images/login-pass.png); } .login .keep, login .keep-active { background: url(../images/login-keeplogged.png); } .login .keep-active { background: url(../images/login-keeplogged.png) no-repeat -68px 0; } .login label:hover { background-position: -34px 0; cursor: pointer; } .login label.keep-active:hover { background-position: -102px 0; } .login form input, .login form label.keep span, .login form label.keep-active span { float: left; width:153px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; } .login form label.keep span, .login form label.keep-active span { margin: 0 0 0 35px; background: url(../images/login-logged-butn.png) repeat-x 0 0; } .login form label.keep:hover span, .login form label.keep-active:hover span { background-position: 0 -23px; } #stay { visibility: hidden; } .loginbutn { border: none; margin: 0 84px 0 84px; width: 32px; height: 32px; background: url(../images/login-butn.png) repeat-x 0 0; outline: none; } .loginbutn:hover { background: url(../images/login-butn.png); background-position: -32px 0; cursor: pointer; } /* ## SEARCH - Form (Sidebar)) ############################### */ #search { position: relative; margin: 0; } #search .row .text, #choices ul { float: left; width:137px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 1px; } #search button { width: 34px; height: 23px; background: url(../images/search-butn-side.png) no-repeat 0 0; float: left; margin: 0; -webkit-border-radius: 0px; border-radius: 0px; } #search button:hover { background-position: 0 -23px; } #choices ul { /* Autocompleter */ width: 184px; height: auto; max-height: 300px; overflow-y: auto; overflow-x: hidden; background: url(../images/color-a.png) repeat 0 0; float:left; padding: 0 0 1px 0; } #choices li { width: 180px; height: 31px; line-height: 31px; background: url(../images/autocomplete-bg-a.png) repeat-x 0 0; margin-top: 1px; padding: 2px; float:left; } #choices li:hover { cursor:pointer; background-position: 0 -36px; } #choices li img { float:left; margin:2px 0 2px 0; } #indicator1 { position: absolute; top:0; left: 150px; width: 34px; height: 23px; background: #3c556f; } #indicator1 img { margin: 3px 9px 0 9px; } /* ## BUTTON ############################### */ button, button.inner, button.inner-active { border: none; font-family: Arial, helvetica, sans-serif; float: left; height: 22px; line-height: 22px; color: #fff; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 5px 0 0; padding-top: 0px; padding-bottom: 1px; /*padding: 2px 0 3px 0;*/ white-space: nowrap; background: #384e67; } button:hover { cursor: pointer; background: #001e40; } button[disabled] { opacity:.6; filter:alpha(opacity=60); } button[disabled]:hover { background: #384e67; } form.main select { width: 315px; height: 22px; border: 1px solid; float: left; margin-bottom: 6px; padding: 2px 0 0 0; font-family: Arial, helvetica, sans-serif; font-size: 9pt; } #acc-tracker form.main select#ttask{ height: 150px; } form.main option { background:#fff; } /* ## FILES ############################### */ .fileinput { position: relative; float: left; width: 315px; } .fileinput table { width: 315px; } .block .fileinput table td, .blockwrapper .fileinput table td { padding: 0; border: none; height: 24px; } .block .fileinput table td.choose, .blockwrapper .fileinput table td.choose { width: 10%; padding: 0 0 0 13px; } .faux { position: absolute; top: 0px; left: 0px; z-index: 1; } .fileinput button { margin: 0px 0 0 0; float: right; } form.main input.file { position: relative; filter: alpha(opacity: 0); opacity: 0; z-index: 2; height: 25px; } form.main input.text-file { width: 100%; margin: 0; } form.main textarea { width: 307px; height:90px; font-size:9pt; padding:2px 3px 2px 3px; background:#fff; border:1px solid; font-family:Arial, helvetica, sans-serif; margin-bottom:6px; } form.main .checkbox{ width:auto; float:left; margin: 1px 25px 0 0; border:none; } form.main .radio{ float:left; width: auto; border:none; position: relative; top: 6px; margin: 0; } form.main .input_error { border-color: #be4c43; color: #be4c43; } /* ## Editor ## start */ form.main .row .editor { float: left; margin-bottom:6px; border: 1px solid #000; } /* ## Editor ## end */ Collabtive-2.0/templates/standard/theme/standard/css/style_iefix.css000066400000000000000000000007561237252063700260040ustar00rootroot00000000000000#sitebody { min-height:100%; } * html #sitebody { height:100%; } #contentwrapper { width: 980px; margin: 0 auto 26px auto; /* same as footer-height (for IE 7) */ } /*# Form Button # */ .butn button { height:24px; line-height:21px; padding:0 8px 0px 3px; overflow:visible; width:auto; } /*# UL LI Tables # */ .content_left ul li{ float:left; } /*# Calender # */ div#calendar table{ border-collapse: collapse; } /* Datepicker */ .datepick .picker { width: 187px; top: -239px; }Collabtive-2.0/templates/standard/theme/standard/css/style_main.css000066400000000000000000001525211237252063700256220ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Fröhner ## URL: http://www.visional-arts.de */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#082343; background:#28648b; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: #001e40 ; color: #fff; } ::-moz-selection { background: #001e40; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color:red; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; background: url(../images/color-a.png) repeat 0 0; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background-image: url(../images/login-alert.png); font-weight: bold; color: #fac3b7; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: #fff; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: #6ab0c5; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: url(../images/color-a.png) repeat 0 0; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: #6ab0c5; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: url(../images/color-a.png) repeat 0 0; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images/main-admin-c.png) no-repeat 0 0; } #mainmenue .submen li.customer-settings a { background: url(../images/main-admin-d.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: #c5d2e1; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: #fff; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #6d7f93; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #6d7f93; } .content-right-in a:hover { color: #9daab7; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images/color-a.png) repeat 0 0; padding: 11px; color: #6d7f93; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #6d7f93; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #6d7f93; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ .export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: #001e40; font-size: 12px; background: #fff; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: #fff; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: #3f7174; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: #365a76; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: #65635e; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: #576d5a; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: #8f5f45; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: #824e48; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: #6f6d6e; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: #484f64; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; } /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: #fff; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: url(../images/color-c-green.png) repeat 0 0; } .cal td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: #fff; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: #fff; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: #eaf6e3; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: #fff; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: #009359; background: url(../images/color-c-green.png) repeat 0 0; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images/next-side-user.png); } .user .datepick td.back a { background-image: url(../images/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images/next-side-files.png); } .files .datepick td.back a { background-image: url(../images/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { border-bottom: 1px solid #3c5570; float: left; position: relative; } #onlinelist li { width: 184px; clear: both; border-top: 1px solid #3c5570; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #6d7f93; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #9daab7; /*background: url(../images/onlinelist-hover.png) repeat 0 0; */ } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: #fff; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted #fff; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: #fff; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 585px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 585px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in ul, .descript ul { list-style-type: disc; padding-left: 40px; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid #fff; border-bottom: 1px solid #fff; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: #c5d2e1; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images/symbols/tab-projects.png); } ul.tabs li.customers a { background-image: url(../images/symbols/tab-customers.png); } ul.tabs li.tasks a { background-image: url(../images/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: #001e40; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: #203d56; color: #365a76; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: #62332e; color: #824e48; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: #001e40; } #modal_overlay.useroverlay { background: #bbcbbb; } #modal_overlay.tasksoverlay { background: #869cad; } #modal_overlay.milesoverlay { background: #b49591; } #modal_container .inmodal { background: #fff; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid #fff; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: #fff; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 0; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 -1px; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 0; } .statusbar_b .complete { height: 8px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 -1px; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid #fff; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid #fff; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid #fff; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid #fff; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid #fff; padding: 12px 9px 18px 9px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 230px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 176px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: url(../images/tables-projects-head.png); } .projects thead { background: url(../images/tables-projects-thead.png); } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: url(../images/tables-projects-sechead.png); } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: url(../images/tables-projects-bg-a.png); } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: url(../images/tables-projects-bg-b.png); } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: #3f7174; color: #3f7174; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: #3f7174; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: #8caaac; border-color: #8caaac; } .projects .datepick td.wrong { color: #8caaac; } .projects h1 span a { border-color: #3f7174; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: #8caaac; color: #3f7174; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: #275154; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: url(../images/tables-tasks-head.png); } .tasks thead { background: url(../images/tables-tasks-thead.png); } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: url(../images/tables-tasks-sechead.png); } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: url(../images/tables-tasks-bg-a.png); } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: url(../images/tables-tasks-bg-b.png); } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: #365a76; color: #365a76; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: #365a76; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: #869cad; } .task h1 span a { border-color: #365a76; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: #869cad; color: #365a76; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: #203d56; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: url(../images/tables-msgs-head.png); } .msgs thead { background: url(../images/tables-msgs-thead.png); } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: url(../images/tables-msgs-sechead.png); } .msgs .color-a, .msgs .statuswrapper li { background: url(../images/tables-msgs-bg-a.png); } .msgs .color-b { background: url(../images/tables-msgs-bg-b.png); } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: url(../images/tables-msgs-bg-c.png); } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: #65635e; color: #65635e; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: #a3a19e; } .msgs h1 span a { border-color: #65635e; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: #a3a19e; color: #65635e; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: #464440; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: url(../images/tables-user-head.png); } .user thead, .user .contenttitle { background: url(../images/tables-user-thead.png); } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: url(../images/tables-user-sechead.png); } .user .color-a, .user .staterow { background: url(../images/tables-user-bg-a.png); } .user .color-b, .user .content_in_wrapper { background: url(../images/tables-user-bg-b.png); } .user .color-a ul.files table, .user .color-b ul.files table { background: url(../images/tables-user-bg-c.png); } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: #576d5a; color: #576d5a; } .user h1 span, .user h1 span a, .user .inmenue a span { color: #bbcbbb; } .user h1 span a { border-color: #576d5a; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: #bbcbbb; color: #576d5a; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: #3d573f; } /* USER PROFILE */ .user .export-main { background-image: url(../images/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: url(../images/tables-user-bg-a.png); border-right: 1px solid #fff; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: url(../images/tables-neutral-head.png); } .neutral thead, .neutral .contenttitle { background: url(../images/tables-neutral-thead.png); } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: url(../images/tables-neutral-sechead.png); } .neutral .color-a, .neutral .staterow { background: url(../images/tables-neutral-bg-a.png); } .neutral .color-b, .neutral .content_in_wrapper { background: url(../images/tables-neutral-bg-b.png); } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: url(../images/tables-neutral-bg-c.png); } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: #6f6d6e; color: #6f6d6e; } .neutral h1 span, .neutral h1 span a { color: #a9a7a8; } .neutral h1 span a { border-color: #6f6d6e; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: #a9a7a8; color: #6f6d6e; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: #4f4e4e; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: url(../images/tables-timetracking-head.png); } .timetrack thead { background: url(../images/tables-timetracking-thead.png); } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: url(../images/tables-timetracking-sechead.png); } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: url(../images/tables-timetracking-bg-a.png); } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: url(../images/tables-timetracking-bg-b.png); } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: url(../images/tables-timetracking-bg-c.png); } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: #8f5f45; color: #8f5f45; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: #8f5f45; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: #bc9f8f; } .timetrack h1 span a { border-color: #8f5f45; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: #bc9f8f; color: #8f5f45; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: #6f412c; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: url(../images/tables-miles-head.png); } .miles thead, .miles .calhead th { background: url(../images/tables-miles-thead.png); } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: url(../images/tables-miles-sechead.png); } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: url(../images/tables-miles-bg-a.png); } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: url(../images/tables-miles-bg-b.png); } .miles .color-a ul.files table, .miles .color-b ul.files table { background: url(../images/tables-miles-bg-c.png); } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: #824e48; color: #824e48; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: #824e48; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: #b49591; } .miles h1 span a, .miles .content-spacer-b { border-color: #824e48; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: #b49591; color: #824e48; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: #62332e; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: url(../images/tables-files-head.png); } .files thead, .files .contenttitle { background: url(../images/tables-files-thead.png); } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: url(../images/tables-files-sechead.png); cursor:move; } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: url(../images/tables-files-bg-a.png); } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: url(../images/tables-files-bg-b.png); } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: #484f64; color: #484f64; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: #484f64; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: #9195a2; } .files h1 span a { border-color: #484f64; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: #9195a2; color: #484f64; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: #2e3345; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images/butn-reply.png); } a.butn_reply_active { display: block; width: 100%; height: 27px; background: url(../images/butn-reply.png) no-repeat 4px -20px; } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 4px; } a.tool_edit_active { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 -22px; } a.tool_del { background-image: url(../images/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: #be4c43; } .marker-today, .marker-today a { color: #009359; } .green, .green a { color: #009359; border-color: #009359; background-color:#e0f1db; } .red, .red a { color: #be4c43; border-color: #be4c43; background-color:#e7dcda; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images/infowin_green.png) repeat; } .info_in_yellow { background: url(../images/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #6ab0c5; } .footer a { color: #6ab0c5; } /* ## Footer ## end ## */Collabtive-2.0/templates/standard/theme/standard/css/style_main.php000066400000000000000000001677431237252063700256350ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Froehner ## URL: http://www.visional-arts.de */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#082343; background:#28648b; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: ; color: #fff; } ::-moz-selection { background: ; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color:red; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; background: url(../images/color-a.png) repeat 0 0; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background-image: url(../images/login-alert.png); font-weight: bold; color: ; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: ; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: ; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: url(../images/color-a.png) repeat 0 0; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: ; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: url(../images/color-a.png) repeat 0 0; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images/main-admin-c.png) no-repeat 0 0; } #mainmenue .submen li.customer-settings a { background: url(../images/main-admin-d.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: ; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: ; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #6d7f93; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #6d7f93; } .content-right-in a:hover { color: #9daab7; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images/color-a.png) repeat 0 0; padding: 11px; color: #6d7f93; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #6d7f93; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #6d7f93; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ .export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: ; font-size: 12px; background: ; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: ; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: ; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: ; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: ; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: ; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: ; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: ; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: ; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: ; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; } /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: ; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: url(../images/color-c-green.png) repeat 0 0; } .cal td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: ; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: ; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: ; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: ; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: ; background: url(../images/color-c-green.png) repeat 0 0; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: ; background: url(../images/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images/next-side-user.png); } .user .datepick td.back a { background-image: url(../images/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images/next-side-files.png); } .files .datepick td.back a { background-image: url(../images/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { border-bottom: 1px solid #3c5570; float: left; position: relative; } #onlinelist li { width: 184px; clear: both; border-top: 1px solid #3c5570; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #6d7f93; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #9daab7; /*background: url(../images/onlinelist-hover.png) repeat 0 0; */ } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: ; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted ; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: ; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 585px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 585px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in ul, .descript ul { list-style-type: disc; padding-left: 40px; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid ; border-bottom: 1px solid ; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: ; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images/symbols/tab-projects.png); } ul.tabs li.customers a { background-image: url(../images/symbols/tab-customers.png); } ul.tabs li.tasks a { background-image: url(../images/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: ; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: ; color: ; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: ; color: ; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: ; } #modal_overlay.useroverlay { background: ; } #modal_overlay.tasksoverlay { background: ; } #modal_overlay.milesoverlay { background: ; } #modal_container .inmodal { background: ; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid ; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: ; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 0; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 -1px; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 0; } .statusbar_b .complete { height: 8px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 -1px; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid ; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid ; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid ; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid ; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid ; padding: 12px 9px 18px 9px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 230px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 176px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: ; } .projects thead { background: ; } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: ; } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: ; } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: ; } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: ; color: ; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: ; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: ; border-color: ; } .projects .datepick td.wrong { color: ; } .projects h1 span a { border-color: ; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: ; color: ; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: ; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: ; } .tasks thead { background: ; } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: ; } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: ; } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: ; } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: ; color: ; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: ; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: ; } .task h1 span a { border-color: ; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: ; color: ; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: ; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: ; } .msgs thead { background: ; } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: ; } .msgs .color-a, .msgs .statuswrapper li { background: ; } .msgs .color-b { background: ; } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: ; } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: ; color: ; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: ; } .msgs h1 span a { border-color: ; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: ; color: ; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: ; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: ; } .user thead, .user .contenttitle { background: ; } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: ; } .user .color-a, .user .staterow { background: ; } .user .color-b, .user .content_in_wrapper { background: ; } .user .color-a ul.files table, .user .color-b ul.files table { background: ; } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: ; color: ; } .user h1 span, .user h1 span a, .user .inmenue a span { color: ; } .user h1 span a { border-color: ; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: ; color: ; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: ; } /* USER PROFILE */ .user .export-main { background-image: url(../images/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: ; border-right: 1px solid ; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: ; } .neutral thead, .neutral .contenttitle { background: ; } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: ; } .neutral .color-a, .neutral .staterow { background: ; } .neutral .color-b, .neutral .content_in_wrapper { background: ; } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: ; } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: ; color: ; } .neutral h1 span, .neutral h1 span a { color: ; } .neutral h1 span a { border-color: ; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: ; color: ; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: ; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: ; } .timetrack thead { background: ; } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: ; } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: ; } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: ; } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: ; } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: ; color: ; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: ; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: ; } .timetrack h1 span a { border-color: ; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: ; color: ; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: ; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: ; } .miles thead, .miles .calhead th { background: ; } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: ; } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: ; } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: ; } .miles .color-a ul.files table, .miles .color-b ul.files table { background: ; } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: ; color: ; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: ; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: ; } .miles h1 span a, .miles .content-spacer-b { border-color: ; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: ; color: ; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: ; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: ; } .files thead, .files .contenttitle { background: ; } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: ; cursor:move; } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: ; } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: ; } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: ; color: ; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: ; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: ; } .files h1 span a { border-color: ; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: ; color: ; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: ; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images/butn-reply.png); } a.butn_reply_active { display: block; width: 100%; height: 27px; background: url(../images/butn-reply.png) no-repeat 4px -20px; } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 4px; } a.tool_edit_active { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 -22px; } a.tool_del { background-image: url(../images/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: ; } .marker-today, .marker-today a { color: ; } .green, .green a { color: ; border-color: ; background-color:; } .red, .red a { color: ; border-color: ; background-color:; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images/infowin_green.png) repeat; } .info_in_yellow { background: url(../images/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #6ab0c5; } .footer a { color: #6ab0c5; } /* ## Footer ## end ## */ Collabtive-2.0/templates/standard/theme/standard/images/000077500000000000000000000000001237252063700234135ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/acc-open-b.png000066400000000000000000000005721237252063700260310ustar00rootroot00000000000000PNG  IHDR R$tEXtSoftwareAdobe ImageReadyqe<IDATx1 0cp\z+(]]"NP@;8{ktqI6A!^%$N))>19s #Mc8Vhf djצƨjVC&&Ƀ7̑Oڒ-Cwq~7w:yvS, W.!XfqzGg2[gNꓧXk.sڐ%_GL5RE5REh!ZC^`\&=%(L5RE5RECr|IENDB`Collabtive-2.0/templates/standard/theme/standard/images/acc-open.png000066400000000000000000000004611237252063700256070ustar00rootroot00000000000000PNG  IHDR R$tEXtSoftwareAdobe ImageReadyqe<IDATxb\fd`.(8ċA,i@jEn!!!a<,*H1} #HւvQ0 `b3sVTT 2'k9[+@s Un!BU f)mJDF[̈́f :@vA-DRȕ"F*$1sѬ!?s0|fٜTIENDB`Collabtive-2.0/templates/standard/theme/standard/images/add-files.png000066400000000000000000000026211237252063700257520ustar00rootroot00000000000000PNG  IHDRP3qYtEXtSoftwareAdobe ImageReadyqe<3IDATx]lTOl7%YZ)_6/ZCPih!xDEoE0J4 e^Z^@T뀎)Hd]˚&n?νv$|_sϹEOΰϠӅQ uAhBfPGهm]5Y 7oo l0b(ˎBZ#,;g:]k32&F@3&JpCrl%vZ뢙oW ݐwiK8Y+ٍ%ujSxS9QBZ@Z)v1ЄHlRL)3 =bnw1+ѕ҅%ct4+҅@NLi z|^ g+&D};{x<@4HG?:-I;c;`xx~?<~tc̻xw;acQ\/^e3k7~9vY7 FLH|[1%KRxV,' OnwtسPJϖB F}#JʹxKQ'/UK2}[HQ;laVEo|bXu'B],˴7Rm㓂 chԱy(c4nj)b嗯\չeEjl @`wyՕ|Qܞr!:jQȹJ|:ˣ*jVp箕voN;nQ6g!\U>jIYM{h\Hnl $-@EgEp8ƴ՝pnuc?u ": ƒ :>oc>=|e:XQ K7kH:ݴ(Suw-Z`$>uϑ`.eX``NZS cȗ(MAߞ>wO]}4za|#1ԃkQW7#u|I.KKIxϿT' >xX雚1 !T3xS֪Fwp8Jl?\0ږW[  8I4I[-d0-JŬ Id6rSV OYګ/8s[ nB/IO-ZlL(t.8rMs+CR)jUEhSt `0uAU}gQ~h`9H&e,oBULhy*c^ PLk:?K客IENDB`Collabtive-2.0/templates/standard/theme/standard/images/adds.png000066400000000000000000000004541237252063700250370ustar00rootroot00000000000000PNG  IHDR3u3tEXtSoftwareAdobe ImageReadyqe<IDATxb?]vbi y ĻYDP(CB` 01PPe0aDHaxs4iPOT2ȰM@B@7 df4Bra5\7$ۃ2 Qf s` Hн`DbXÌáIJf=/(4? z24יIENDB`Collabtive-2.0/templates/standard/theme/standard/images/autocomplete-bg-a.png000066400000000000000000000001661237252063700274310ustar00rootroot00000000000000PNG  IHDRH7B-tEXtSoftwareAdobe ImageReadyqe<IDATxb1 -b ?_bIENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-files.png000066400000000000000000000004111237252063700270370ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbOa؀؂ 17 j ր F6$i,fS@ b'@o`_@|f #t>M `?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 HH ȢIENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-miles.png000066400000000000000000000004111237252063700270460ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbl`؀؂ 17 j ր F6$i,fS@ b'@o`_@|fGut>M `?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 ĕIENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-msgs.png000066400000000000000000000004021237252063700267060ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbLMc؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-neutral.png000066400000000000000000000004021237252063700274070ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbc؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 ߴʓ\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-projects.png000066400000000000000000000004051237252063700275710ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb/,a؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNš8?bK@<T] Wvd蒕@Oqye7k\\)Ȧ` )5zzIENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-tasks.png000066400000000000000000000004021237252063700270620ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb4*c؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 _stIENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-timetrack.png000066400000000000000000000004111237252063700277200ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbwe؀؂ 17 j ր F6$i,fS@ b'@o`_@|fet>M `?.ĀJNG^lIz>K3Ļ@IAȪ%+ n ⹸SMpS ~IENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side-user.png000066400000000000000000000004021237252063700267130ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb ύb؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 8IENDB`Collabtive-2.0/templates/standard/theme/standard/images/back-side.png000066400000000000000000000003141237252063700257410ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<nIDATxb? 2X$XY%X&F6$) %YLP'A; (23vTr%ـ$(517$X5k Wn6 : Iе0~dh1FIENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-bg-side.png000066400000000000000000000001661237252063700264040ustar00rootroot00000000000000PNG  IHDR.sjtEXtSoftwareAdobe ImageReadyqe<IDATxb1Е!IENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-check.png000066400000000000000000000006611237252063700261470ustar00rootroot00000000000000PNG  IHDR(tEXtSoftwareAdobe ImageReadyqe<SIDATxbYf  9xBA^@j? ^Man@| 6" rjD ď` e @,$@M1 ~Pb1jTA`r#)hB].$6  *r Nx% Y@0P[@IP rI8+"Y5z8Mh7_i@ [0'QPVI⟸ X7Wm /0z({+A ^/;>d 3P 6jبa3arh>Z=#2ԩ O0@IENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-del.png000066400000000000000000000010131237252063700256260ustar00rootroot00000000000000PNG  IHDR(νtEXtSoftwareAdobe ImageReadyqe<IDATx+Da3n%YPv(QH)ʎvK(rll( e5)e+Sr)6V%y}lNsu l˲J![jWT9*,C?\4MX ?^(wC1=q <ɐ C$=24:M:)ÃMsba 4G6xq!|$(u .=yIt( B^;g=kwe2 v u5傭ZR!u x?1ZjO:"4K9P/3h4F-/uU<%XP֬t{gO<Ep9e*!ר&^@qGNzOrHNrJ$k!K}…$s.nYqִW`4ꈃhIENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-edit.png000066400000000000000000000012241237252063700260130ustar00rootroot00000000000000PNG  IHDR(νtEXtSoftwareAdobe ImageReadyqe<6IDATxϋa̸jEŃAQ?@ʈy@)Ùخ1-QО˛d(bWF[Нrٲ,J_FGr i.{IENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-notok.png000066400000000000000000000007051237252063700262230ustar00rootroot00000000000000PNG  IHDR ,sRGBbKGD pHYs  tIME;~EIDAT8ҿKa{0hpph 7E J EgMD  ¥Q\DA%.w!*45t[ ߻ܵ9y9Z-\zm0=c?vc_pcs\+ ;Xs 8wc)ޏPͱ$"p7*>b %ȖBO ln N zx|J5qn*!JXk}K!a=1MwE`XFM;M+]:Ni`$ѬLW+FlGm}?2EbY:IENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-ok.png000066400000000000000000000006421237252063700255020ustar00rootroot00000000000000PNG  IHDRmJsRGBbKGD pHYs  tIME XE!"IDAT8ӿ+Qu/I ,, An&ժ`-hڕ@B_˹:}~o7|yޝW.IaMAٖ3h$Zq!E .m?CF-uBFB`G Jdg茴 ,\y銴nDtR 2~iXJQ)T]bT8 ؍)F=xXЛ1)"[5:wy׻kXMiט[٨ fPΚVd K=#I53IENDB`Collabtive-2.0/templates/standard/theme/standard/images/butn-reply.png000066400000000000000000000005251237252063700262240ustar00rootroot00000000000000PNG  IHDR(tEXtSoftwareAdobe ImageReadyqe<IDATx @ElZ%hx` &IgO2E'1f7yN]<45N%@5yJ^ b4@;AJDӈ tg/`)*yNp+8@d_ٸOLh؉נ ,amU,d'W%5p 520DZc=iJ&T":oF=l7KLDTKIENDB`Collabtive-2.0/templates/standard/theme/standard/images/chat.png000066400000000000000000000005461237252063700250450ustar00rootroot00000000000000PNG  IHDRJetEXtSoftwareAdobe ImageReadyqe<IDATx엿 0"v1b|#QG; EBХr\i>r_XJDF-Pa[UUqT|G*J@OuVR_d*!7EJf\|##dձ2w *j:氱V@BcP`(Ft sA`l3"wU0fW'6!h]=}%GD@{hJ7I'2zw SG,s `l37b\ /wH3wIENDB`Collabtive-2.0/templates/standard/theme/standard/images/closemodalwin.png000066400000000000000000000013331237252063700267610ustar00rootroot00000000000000PNG  IHDR8;9tEXtSoftwareAdobe ImageReadyqe<}IDATxOQƧ3m qQ`#M#ܹ_bBH\ $l *PX[-7̴YItfns9\=y%wt mE)hK@-"Txi 5Q;=. t݆.C%3h hn;yD ^.8M.t/a5WaȴmhOֳ*b,t"k4L$hEix~* }7y&f00gYcf? 7újf r(ZIshˆK -'Є@U[g>Qudf_Kir Mif+%V mf`,etn71a폟Vva:`T":WO覺_z#hČyjlZ8{EV]H*д,[7ѮCcЌW>lقpyHfτʰ)9z8}>굜6Gt^,A/b`ʣ,?ן5nK(Ú֓  [1uDm#JʴÅ$ؐ LvQ`'4n呛`m-{n͚1Abt#KDM~UQBr#i$m˶Ti **l*4/ŨMԪj)@cu7lYoYkٙ{g׎5t4;=s~<=k_,ʅ4Crؽ$ h63#dl?'$*dDH1^-d0nLn+ҽ= ,`fN-%B )#Эm9AlNfZn '89B r06 ݺFW $J.gdƃ#2hdLPdyA!iO('RQo`-Mgf.."Yd#&$_$ vrOŦ{ HJZ!KV_t!\#:J|! 4-=cyHu=Ʀ~X垥tsDh BY/Tz=C5$@ZD+ M?tH!y%]# he#$UgF,N0e@ARk,cjnFpE%!aՆ+5tX*3(cI|P6Ssc&wE*y1!Af0#㎀umJ*v6M,!PKVb}2^i<Ҿ$E~y\2!]HR-Ҋ8gĖs\kT{wSc$ib _N>%(YR?7&MO54#c6^}$4XS$ Y2Xd,sHvP7XcmE5;Of0C]#D*O/lq,g;B -{YIK"|rsDj$HFR2Ib5&wXe.[XaŹ%VV8Cl&]lJH0۰e(Lcy;JYUHYWcBw (\t-du1:Yݧ*A_ZGRqornR3Ȟ%B }&o/ g-ADZЊڤg' AV;6rCٰ|W=̹;鿣Xrϛ]+.nVgD^IB,v露b ?|]q/,N1W''D2bx=mTnjIqZcWG]9ف ~c~^#bź,x f/Y[">] -iYg%%RInH-U [i2|[Aw~7oVm@Bg[v͑Ecw 'xV|ʟK$H"]!"^[EACRa;R4xp0 m,G}ZĎܸ-*R |b ImɌz"1e茻16 ^nHXmu߾ha-+#e~gsO@M:1i>8^8WPa{RXq+U!"!C禆Hm8V7i3%>"Or4Ě&O<|McׯYw _Vybߟ3b7?>d̉W!Ɖ.|rB##@,UBVm$qs5i5Sy^x$$omnu:K}j|yTlӦHִMd`zVHTc%f5۵L-XՖ$i+?Dj^ "ZrBkN& V=wY#a"'P z2ɢy+Q”Tk9&No6>+)qOH_/22D&ܨ'XfnwZXώB߭ Ģbrdbc~ 'Nɀ\ XSB3 1@lYk?Lchw:pn^euAk3 _a}mDRibz2C"O>[;u(pDX"CFf9.qNbWdz/D9O IENDB`Collabtive-2.0/templates/standard/theme/standard/images/export-msgs.png000066400000000000000000000051621237252063700264150ustar00rootroot00000000000000PNG  IHDRv3B2tEXtSoftwareAdobe ImageReadyqe< IDATx\}p\*&B*`` 2f# 2SZ upZ'w38u%І1g$JifETb#$޳7ݼyyHl<= `õm=qNJu-Qq)T2c1x?c>~¸1m;s#l3@˸Oz#5+[_``Ο ڶh~nN@XGǽfsfSߜf,e|Bǘfn v4Ʌ0>Mn[=&ݱEiKOl?vГ㎖3b8wIjD]H~C On(98ad="7и^A ?(뎠!Ezq5t1Vz'=(IăD yn +Ft3n☛$A$< 1dnǴ>78FFOm+c;Ulj3@t"O-uST0CXQ tPcb,r_smrуUL)m"*7DUU.,UX DYt1%w \<5j $?&X'-?i9fȸ,6,i-*1\O!8lʈu9LR- mqo|cnL.6Ec'B ?H*uFodJl'sh봨\FXF>XXuw7 Zm3m I+Ȓ "nNb9G!A|5}d5[A(B])p=$*@UЃDL↸iGct~w7s)M3QqMkD )6X4*N=+R\ 7"}1JKrńB%:5n?7*8kMU '*OiKPH%xA!U\K$Pdk[>y\wq:utXԎ^ctơBlmzm!]mv~3pĥw.xq8ǵFmR*<>߂y#/lya 6 Nxc/?;ߝyPǍ2,Tqy _q{@7;߮x[ޚ_hld`LIc"'\!G.tmgiy|@;W]1vqo .,)n#|~`tƕ}&Q$9!|3Y\qzH@W\qjt.Oi\BUS|0t@1֬XVErry_WW]#GKA4@zD.O)3^3kÐ Z #FyN6b3+g@=pضzX^ F8$;?~K !Y((ůjTi|~ZƧX<֡@cg͑p0t̩٥vNlڕ.k CfXx3#C7@X+Ý4蕧Q/= -5쌹=$f\EBN%MQJ@Jc{HwzD[q}kHN9~iUƣݩz_aTRAfSlj*R'B58؄^-# }%}fN(y9h]]'DU,R=QZzYW}Q-pJOBK>D+TY R+fNPDJThIXu^4wż K Nt%~] Khl^KOgCj۩Uo' ܵSdlֺ#r!IENDB`Collabtive-2.0/templates/standard/theme/standard/images/export-tasks-headline.png000066400000000000000000000042231237252063700303350ustar00rootroot00000000000000PNG  IHDR_3ztEXtSoftwareAdobe ImageReadyqe<5IDATx[klU/RG[M& KH $ !QIiB`Diń$J4*-(e@.tk-)Ҳ]ﶇqv:dNevf;s9]O$QTR$Р /F۹EA$Z;1 @XO _ =hF[O7I>pNqs{@@@sNGU[O "!gvjr:r2ZLpkVĮ"maǪ"79C<dލDL-D%*p8!awR`YPy ϵC~FN!#0FF9 `/F^(PbdGc%Կ$YAm&].wA%MGpӡ3 z4d˘C/DXBy7a3B (hd3|Ixј@QM$rCh䂩pԍ^M :NZGB4i1=C,;]VFA0OC;y(%CƼ!v}EL@Ofm}:0&Fi -idXH¬F>M=̫g 2@v2<ڇ |r|ئ}Wr(9pf;./'5>xdγLz}BNs5ԭ'ݬtP+xJdKKK+..s?2֟Yϯ?0`+:>^ ~=Hį%Z;~]JbpjϧV ™yZWkO )po6)CoNXYbvx"NN7*_ VЊ`rWDm\12A~yvJ`l퐏󡉶tQB-C-_((.^/im/L`ͱQ N>Fb @u6uI/ i|"֧mR`@5FU+P"'&/ՌNڕT *CC;jA?m*zy%ٿbcѓgXHK] )?"4̇3a*."4@Ľ}8Y…ЩW-8M):/XTH?cZ2(#),?3QP0SXKZl80+L:Fue9ʪ׶IX\Er0 WJ35"k;RJoqU>eʤ Pqߡ;oZWm$000^­opg Ju]oYxv.~U0}s nY#/-Yܻg^:!ϱ"` ܇:#x$ΪTW*{0*:5bOF"JNةs~:;pF}Qx$Jsmh A>UIS2'SB"b@f@͌70alc=fṳz~iQ(n+z a>=O91~y `sr]DDITq%/3>In}6ݱhOO<F?"qC+2dN$N.!?&F'QJ%{,NFX?Y|M4Wbn)Z1^AiNR$^FI畨@!bD/.+IO"`@ǁ<KQ]cb|'1w3Ν0J4u v08[<ͣ:C q3]U%"[ݲH CQ!gS~ZOZ?z`2\' P(B[,۬xv2W1ݹ@'^X-֝K(T 0&ya G^<6/l OFcz7uXNj2,֌&=kim߯y~ -';k7K|_}e|tgN#C (2>θX0>xݢ0iJ \~4nM0x23~xgA[V1l!I:) Kh;dU16#YpG:| w=u_èx̅w>[>>qBv ~?J0(_ [i6H=C=q&~oTw.]Qu \4$?r%=~WuZn?m:+Z5,]5HkVY:Q.d=ol:K12TQ,uKJf%k0,)5B< % IBN-2>5cnj_cꍑ3Xl\7MCMI?/`g˫&D.mn]juz/ar[f?[RHDun\4:>q<-v+ ~{a,eOOן;W+B c8IКV=b-pQb2ZtSq AW4^=󪡸\EYoi'q;Z;j+ypB/:;ԉ 9m=I[,7j0fc5۵Fb VܱI =\׬ 0g‚ŷüR1BD:r8`{hcvEBtz-k) C3#akWkcDbS4ug > \JAcvSl]r ]czm8DX@ PŽ gxQ:Wՠi|ɧU B\:Tt†8kȊc툚hoPy".mJIB i!8m qD  kwױ9- DcځS N$= G@id Bzm4O{_{خu VrvIENDB`Collabtive-2.0/templates/standard/theme/standard/images/export-vcard.png000066400000000000000000000026311237252063700265410ustar00rootroot00000000000000PNG  IHDRZ25tEXtSoftwareAdobe ImageReadyqe<;IDATxZhU&6M:6$Sl/*E@!fUpbg9D&fP2e)FܤJ]lmRkm,^ۙܽ{7~サsmkm.k/FPHtãm!kH0"}I ٦$g:5*o7NQg0' bJР't8^eGd=y9:D^eE hB[țhmeIG4r;D}B/I ;Qie! E9:dZBO.2R/M5Aq g'IE9J=F69x "{TR;0Frp'oB!R]<U1+O ~E1d{]1S=$'Gh=n)."UJSD$_Rp>IXwQ 1Un~=1 B%A,g0' Lۨ.(3[n7Pxt5XG;b\vAM}qī#7G"~_sOPKUJ<(%޹ݟuJe{ hޝx$Eh[kMX9<3IP ` Nw;F/unW+k8+!aGS=@gƘH[D%rQ6Xj% Hn?GGN\/B4J̰h.V,rNV.k6~%]b78QϞl^p#_0>/o}.Lu^agk>,*q>0WGF,O t ~t(~4h`.ƽm]scC-}iti <L`Rn6}ďCW+(lf?9ix9ADBi0 ~S28]ݏq*.J~ȹ2E@7d90ʫ\s,'~.~-9zo!n,Wcizq)uα>܏(ΰcmecƿqc"7c9;:V#d}_xpa75DP_\wGIENDB`Collabtive-2.0/templates/standard/theme/standard/images/favicon.ico000066400000000000000000000015761237252063700255450ustar00rootroot00000000000000h(   S-Q-Q-Q-Q-R-Q-Z7$vW5[7$Q-Q-Q-R-S-R-T.S.S.S.eC*lAS.xX6zxX6S.S.S.T.T.T.U/ T/ U/ U/ MzM˵iz˵imBU/ T/ T/ V/ V/ V0!V0!_:&V0 nC|||||NV0 V0!V0 W0!W0!X1!X1!}Űp΃ى{zM|[:zMa;'X1!X1!X1!Y1!Y1!Z2"Y2"gFޗޗнc=)kH1sPkH1Y2"Y2"Z2"Y2"[2"[2"[3#[3#nI4mI3jLל_D[3#[3#[3#\3#\3#]4$tėĖ]4$˹­]4$˹s]4$]4$]4$^4$^4$^5%fǟө^5%ıͽqL8Ƞyz߳h^5%_5%`6%`6%iA/ƅdNrM9ֲֲoW˧|XC`6%a6&a7&a7&|ͰjC1a7&}YEa7&jC1Ͱ¥a7&b7'b7'b7'зͶkC2uN=fSkC2c7(c7'd8(c8'c8'c8'sac8'c8'c8'd8(d8(f8)d9(d8(d9'°禌{¯¯iWd9(d8(e8)e8)e9)f9)f9)e9(e9(nE4iYe9(iYiYe9(e9(f9)f9)f9)f:)f9)f9)f9)f9)e9(e9(e9(e9(e9(e9(f9)f9)f9)f9)f:)f:)Collabtive-2.0/templates/standard/theme/standard/images/files/000077500000000000000000000000001237252063700245155ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/files/application-illustrator.png000066400000000000000000000124001237252063700321050ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X]IDATx͙ tƟ!DcI R%f%T[Dj+JRS'5OfRTy*THdLy}'9wַ-ϻ_Diwpy篫u<QT T)lwҨQM^WqbR|/)1ˎՎ5pc8;-J![]F}tmvVFQ_ [ ~"~hA+uAhM]}u(N7s _#2w/`}=ɞ^go?Y$'U:P%7;@.|wgCk8T@Ȩkph! -~`Xbm0LvM5YXGVxcoF՞ܟO%<YiԉZڃ`lEsԚZׁ"R )D %Ժ}F?TG+\B]]7h$0(Q ನ-ZyQ1fǧ`Urna~zE/\L]ox= R r%vcjvm?4P=' ɝaH`_ PɟĸAk`)J S+E:M:F"UrY;BNAG!%N 57C'kzq1 >l8l檙o׸\qIP)qq24&;AL$Elyh `@ +A:t1uU9*9C2OL j'ES-}BDhOCʊ.ѧn`#vԖf:-'yڈKb:( O)(4}[[ZZH#h=ćԋz> 62mzÇ@z`aؿpKgIȇ)Cr9u [5l()O y xn@;k  XOT[g1 tSo}%h)ZfHJP_ *](C1Z!k<^ dW^J%TDKOOO;R (jRuF q<__졎s3SkzFSWʞOSua>zROxWNvbx^N;Xp"k oi"W&L.Li;-pijg\˸Ǹ ݫ.O$ <yl  J6`OutpaVs˜;@ u`' Ԗ(< JV@"ϕJ@p}FT X!VD 4ʀFW7o1tO>> Hgu:_Rf \)Ю?AT7L7 pq3Yrsod3pđi5qP 0DB !Ia1UG ' p6flA-vnj:(J;vѹn/At r,* - jڥKpU\8ŸYAZx>gn%vG Xre[S`4o`Eho(Ef@g8XlM2lO 䍘1֡B G,8kc>r7H2?P=*xeqj+;^v)}.rgGWTWj0{z*n)SjM^1X̀%⡫!TjQkUGzzUA2S:ͭo4a#@ G>h4HoQ&r;1F`3x=XC}6`ޒ}2Z9 8N:z_]._V2ZzHe v]եC%/G}f, KpYgkr2p'q @SMBBFϋ 7#Z `9"c!`Xmo(+2[/"Z :AW)ڍ HB]0P}n]2L2{ bUpϢ8j@ogPMC! *|xp`TS= ׇ_Ώ\Q? rWCt m m+D@+*}{{@{W~qe3Ic 2 3t_!L)~ѹ@)~ c i: Pn>+B/Շ}Bw_g ^w}oWͿ;ǫ:ϚgmvnmN c+kr.EԒ%[ѳ8 `/@7'gc.O .8U &@L\=༪bySPғpLvD;fjP&Nj MW7UWm?#m5"d࠹qL켪rokP(ځ Dr#?l v;e 1A@kU:0uFwcwc1@^ԝ~ğ"OD2Q"':Hk<(ϜTw`]RAڻ]t@D"^8n5b Lj yZO'TI;!wBGߐ (wm/xAU<o пedU=׼5զM=RV[ÁmpImv`jz[fUHKGpJp퀯h( e'yPc,fh/Q;̟*x{G-ZzOi+e#PEqpV4~Mu?4z{!)=6n@Ʒvb[m @2tqnvha:P>{YwǺpy2LJ_15G1ubI3\_Fa0 "(_`ۃ$ q@k`[e{&zʟWW#`n#ы5`;e!bK{kDY%hFR?8iI$@yh@Xɇ? ZxLA ]7@Xް|=h5W(|/24qwaHZ9q%rrSԹsa'p)@l.W@@gta@U;A,0L]9P[zm zzB.{!2'O3g0`d^d7+y?Xj[T؜:+wJ x$ylHFSϼ&zMƟz~Q(#0xG`od^ֻ̌[X¯KBm] q=m鶥q|RDw~"ZNBZO5!37´3/։zg̓wxkǗV+F,3g_Zi[*l̟R˜_0|MWMWLinYŖ3 14pߣR~_nuwE:>2 ty.OU(_0,YfzA^%BhtpDp [KEۼ)@~yFv*L4U''TSscklkhI$Sږ3|fϨ| z<:'2 lɿ@k Wftz5o 7p8lET]rKG 6~>uPyx+79 V #+N@w1NhPYko+O.ߕ]wrT;3vFL],9ˮp# P ;-zN[C-nņ_t Uj_e'</c@FC"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-javascript.png000066400000000000000000000030661237252063700316770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[oEv^{}K'1 %!REj+Th/Tx ~gxPQJU(S'i(;{㜣VSc"$'L(0 0C=`P$x$xtp$KsS 0v6Zv, 9 i;y`ZM3Oǂv0W X.D\A0MaA$9 +1@!h jA?VQ(PC@k76r]lb``@s4oRd2qmLNNbvvt}h4022¾BzŢ|KDB,IdRݝ@7a)e$B CҶyj@Sqi+lxaeeJcc@\?"q@0 X,,Bj2_ű%DsI),dB; "Hp%piŚUsxċ1Ir-pdlQ8& Su&,|1$KjmW) 3mbů#*OWϠCc?rikLYTWD]7VaBO 80B~!l@JS¹x V9C%R>D^ nVJ\.N~yds,: k) N(q# V K $/J)XWjH د!ۗa,Hr'lŒ &a"(ymc$J%i:&,3)-\.##W`ceD7%!d? :{mD ֩WWWi Rz(Go H `fs 7D̔TTBЀxqDH`[|hυ{wc{#">=@WoaHؠcr_|!P/)w0{LL2Z:x=a[/DZ699NWC} q=[uOo3D2mxqqKRlY)J'*sv409`}<۷X ЗUP:%0e X\rkkkX@*e]wofzzCKFܕ-wCuܘD[ܨqixZ.s[tfkSdqF .Àg"$Ȉ俪w,rF0zv?_H.]zr;t CBb|(w ϟ?xCw8tgΞ=.HjԒ(k$]%4x$ώ{QG U5IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-msword.png000066400000000000000000000030431237252063700310370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIo[U8C3IJ EZBbZXPʤl邲A@l/@ @tQqrR'q'8ߑoڴye8ѽ>~~ιׯRc.1`R& ]P4y=s'a#6\%t1:Um̭+\ߪ&@Ey/ u'Õ_w-n @1˭0VEEw O4|/ 1_+t{νroʀe59h[l_&x|AiL's^b gKcH"9d4c6&SJ/Js (@ ALA8 w@6\jgcuأ%xr_}W- L d; w7φp._&G VސtV6l»n7?nXdjd|qx::(k;s9+cw#@|Ws ;D==zT r8B갽 ^nX]]E Б= 8ǦpX8#S,a~~t%133׫/..M pC3mYHc9ɐxDBDZ0緶Z*")%ly6evW3, mhjjBkk+~7;;gIBctsssw҄qِ56ҙ U͗L&޽{$Y U1sV(8&W 477k#~q>GVVV $g:T guօ&6˜`)QYL'iCC{$iN1$xֹS(z{{ eg)97攗@< |1I92s:Ccb%C08hUgeW/H]ƬK@)}S{jY :鬯q捫f%@hr6|IS@pR:S8هOL`o%#QFIB_Z z/Ԃ??b%t+H} oZOc,'9^Jl{*y u؉@3TM/fcO8`BNAtr N lφgz;-^>%ko9Ug$x3NUh|27?߇L6|S?O~Uvcd' V5o=G.9WO h$212r;yQ^H ޿%Xh\7H$[<֣xFk;|F|QsN_L6yɆ9whaQIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-octet-stream.png000066400000000000000000000114451237252063700321400ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZݶS۷؈77·s't]s@N@%or}r7<ĝ$~_fFM3G.iRx XMN*J́mJ~& Ey}s`:ٽ?…Ȝ8\< õJ͛Q~M߽͛ ]g,>#m{^f:*u+41κrK"J+\먔JjBe^skh ^^ sP?|Hk@M pb^]GF WĦ#C" ƈ0RD4{ PQj,LOܺk(qGeQd'&sq\ \}*,`0TJsD }H$pgyBb7xqAɦ*!*$QIb@Ezp8\E(vt؂1 HD1 .t:zfҜt ˜;|{P쵐mخ͟5(ϝE|V" ձmZ-@HQ[NRFV3eYp #2'A@`_x)eSLLHߘiB|rrcb8ꄥůD0@2[MqsVeU"0yHBmC5&$cyD a;kwP'3UGukp"bQkZg}}}4 ӃBrlPzO f6^)D U}bkk[:(0&9wwr "`z\./U"B[yQ\ZZ ⵐSٌgɞAu.Jֿ:OߗQ @IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-pgp-keys.png000066400000000000000000000036351237252063700312720ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-pgp-signature.png000066400000000000000000000067061237252063700323220ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X #IDATxݘy8"KII2-ZUP2nȒ)cI*Z$4-;c .TsC̔QJz59\}|}?&lV9t3;qomn!_|]ML>c н=*v/knB.@ux-*GUejxxOc62YƏM$ԘzmYR/T k23/8bb@MU~siBvLP>tށޗݖIqwkzzz irEwN7 tcqEJB{^H`P_)aOZw\ԊY;x@G ё  Ɔ:1ۜ5@]^N^^((B2 ) Cج=thHteI]uuu^**jYM3j8IFRKRGؙ,tzxNݒe'-Hց wBv>y;AP_EHTK;fZZ7Mi"ΣZGjjũEjjj> 栭]@fbF opcc5+;$'$CC5=Mׯ]?COCe*N$+:\ڠ5=pߟ=(i.Grl|q@Hh3V@_ٕ@YahÄSORA>֡HJ~6V=/>(>;6U6@H`a_M0Gmb{tQՇZ:A\7N sp\Hm@ N8Ǝa0Ƿb)FvY8JTl3%^ w§! D?pƻ*{ rVJ cwEq0P?c<*f"1nXԒ ƧQAePzB$Bf.?9h7԰ԕ ~pzw3x6>k3Z 0aee]0qX[a.4و_p^6騺^WT~i>s:S7Jj!IQQ<[&ox.ːKn,P2WR+j1afRclnbPs@UF$vaY#?NSSV4Rsi,ż%H?HG"CCq۬S9HI lDp %DRoh+돟Sq;0pCCm4!OA 4szz٧%2»‹Dm:vr<ѝK,laܦѳ1[cMx|-TGd^^ʟ?KHyxw7:9BZW:Vb%9*N`|@p4afu8 Pf~]B[o`'bxGxGxz˿NBÒ yJmB;D~myh:j~yrRG*h8 1 ƚOZ(qpECujuj_5NlPӿػ!wWL`6^h@md9ckVdE) W8w;gb ]|y̽_3BW6_I(6LjcҳH21Q\qϹsҾ;|wX[ZnrihH\x4ѱkg !ZRg.;qDS*bt:r->!6y PĀ8a$Oxayy3W]= `|bkWW]]CHƍu7R{іZ4zI/xN9/[{1&Ęk[[Z^z+Ljd\x xL|>+6oLL!2 .y^چ L$LW@؆ՙ 2r%y>_|>fMmzQ0-`8E)OI __ *D _Zrmm}%WӧݧԜnBT?11 J+"4jD!P~_A6WwcZ:j082vfb6z]pw.Z.e.e g+.{]ss6Ϝvo}730!EsUO֦C}SƦZj$>-tvAO{p>fXX*cKӏ|s@4&f gYϒ] 0Z rҌ" +xvEBB`$/$ZGD?a]FM=(4G<:1>,a z#Ac1L1g22evSuJEi҆WO2j5Rn+r~,iMCtL..35"#XV3ZƆ jE#jژ_HR MqFLާ8[^̶W^a~ncW{yRuj}MGtذة*Sݨ'x&2ՂKH/D'H=s[mI zO4VڒHJG3'\#LeP^(±xzrjG1K=z\j%C,=|ɰ0i)]b?-X#"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-pkcs7-mime.png000066400000000000000000000036351237252063700315070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-pkcs7-signature.png000066400000000000000000000067061237252063700325630ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X #IDATxݘy8"KII2-ZUP2nȒ)cI*Z$4-;c .TsC̔QJz59\}|}?&lV9t3;qomn!_|]ML>c н=*v/knB.@ux-*GUejxxOc62YƏM$ԘzmYR/T k23/8bb@MU~siBvLP>tށޗݖIqwkzzz irEwN7 tcqEJB{^H`P_)aOZw\ԊY;x@G ё  Ɔ:1ۜ5@]^N^^((B2 ) Cج=thHteI]uuu^**jYM3j8IFRKRGؙ,tzxNݒe'-Hց wBv>y;AP_EHTK;fZZ7Mi"ΣZGjjũEjjj> 栭]@fbF opcc5+;$'$CC5=Mׯ]?COCe*N$+:\ڠ5=pߟ=(i.Grl|q@Hh3V@_ٕ@YahÄSORA>֡HJ~6V=/>(>;6U6@H`a_M0Gmb{tQՇZ:A\7N sp\Hm@ N8Ǝa0Ƿb)FvY8JTl3%^ w§! D?pƻ*{ rVJ cwEq0P?c<*f"1nXԒ ƧQAePzB$Bf.?9h7԰ԕ ~pzw3x6>k3Z 0aee]0qX[a.4و_p^6騺^WT~i>s:S7Jj!IQQ<[&ox.ːKn,P2WR+j1afRclnbPs@UF$vaY#?NSSV4Rsi,ż%H?HG"CCq۬S9HI lDp %DRoh+돟Sq;0pCCm4!OA 4szz٧%2»‹Dm:vr<ѝK,laܦѳ1[cMx|-TGd^^ʟ?KHyxw7:9BZW:Vb%9*N`|@p4afu8 Pf~]B[o`'bxGxGxz˿NBÒ yJmB;D~myh:j~yrRG*h8 1 ƚOZ(qpECujuj_5NlPӿػ!wWL`6^h@md9ckVdE) W8w;gb ]|y̽_3BW6_I(6LjcҳH21Q\qϹsҾ;|wX[ZnrihH\x4ѱkg !ZRg.;qDS*bt:r->!6y PĀ8a$Oxayy3W]= `|bkWW]]CHƍu7R{іZ4zI/xN9/[{1&Ęk[[Z^z+Ljd\x xL|>+6oLL!2 .y^چ L$LW@؆ՙ 2r%y>_|>fMmzQ0-`8E)OI __ *D _Zrmm}%WӧݧԜnBT?11 J+"4jD!P~_A6WwcZ:j082vfb6z]pw.Z.e.e g+.{]ss6Ϝvo}730!EsUO֦C}SƦZj$>-tvAO{p>fXX*cKӏ|s@4&f gYϒ] 0Z rҌ" +xvEBB`$/$ZGD?a]FM=(4G<:1>,a z#Ac1L1g22evSuJEi҆WO2j5Rn+r~,iMCtL..35"#XV3ZƆ jE#jژ_HR MqFLާ8[^̶W^a~ncW{yRuj}MGtذة*Sݨ'x&2ՂKH/D'H=s[mI zO4VڒHJG3'\#LeP^(±xzrjG1K=z\j%C,=|ɰ0i)]b?-X#"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-postscript.png000066400000000000000000000024201237252063700317340ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE b_`bacddeebdedeeefffgrv}}~__!!__""~~++,,--KKOO99@@ᨨ㨨蝝'tRNS $'(+/189::;<>?F67IDATxmjAsn̘I ѨWJ@to !D+.(Q!FD4AHH2{I%v~uOW7mPJ@چ8V1|XC <@s'b +)`!4Ɗo7$ !DM0Ԁ҂5BPxBϯD@͟Ի~Wdh,P #@Xvb٧ctRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-rss+xml.png000066400000000000000000000021601237252063700311260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxOh\U&$E4ik@].DӅX(7J[ BKEucD*6شD:q6:I23)"q| 8Ѕ83{=s{s$,6RS01WRJٚ[jl}3Q07釬Q^S1ܼ}*/ZO~W>}XXZ@qV=>هo=4<"A%p>Itc`@KObphMY< 0InkTބ   1y0BMF@XD6z0 0Q9@Q ":hQ[#E@Y/ h\%C D˚B]%uҙTOn2aa(1} l[-[u 7 YM`C5Yת^%@1 C,5bV.EnB~|mC56 Ȥ  [{l} z_Ν0:9Xug @Q8* ÍK:"%̕8~ = ,DlN"Uԥh,<{ACR$wtgͷRʀ&=m5AHg&{7i" ͝n9E=yjSx'z`hD;]'AϞ 2AH@-<8f@ _U/}AXz5 $kkQ^ԺmpUTbXhX>sZ7WVU&vQQh}@ۗgvZY"5#Z.=jsB*#0#^k}8<8DӖE Xɷc_Xn|t2Vl7j]čy.2'GD & -'pBvRL;n/ە^IIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-rtf.png000066400000000000000000000027431237252063700303250ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.ms-access.png000066400000000000000000000025611237252063700321740ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IPLTE xxx}}}ֳ'tRNS $'(+/189::;<>?F0PgIDATxmNSAtW(  BD !!F+}/ h/54* У3vW&̗u1bq*p :Ub" &bF(7,0 ZК@xgHT:D!U=W!#@):%;ş RYoo.u :0VF)}pRW$z%&2ue%nˈ|#;ǭ!BYha8' Qʀ:ql_ 2aEtgMLZn_"Z'w [{2 eWRqvDD}Bn<"T[oA7$&XB7y^Si=e-;NA37x?'=kx|¾ fV*=umJBՀKyy$P)|hƇ0lu)n} @0yC=h[FHۣ&˪qaf#IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.ms-excel.png000066400000000000000000000026031237252063700320300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKOdUy3Ûf4YeD3+WY111.0I\ ݻQL!m*Ts{o|S{: XZ j!2 5g'NJ&4qpM}7浆j!S.H\t5u }W" O߹X \mܸz6LMu)Oj>!vqKco7yJ~{K>ԥ[fZ(ћ 8S\qsS-3qaogMzV{PA@C5AL)mJ.Y``paY.X%4_Sx.+bdP/Hqhx@쐱i $sj[k3گM y`UbD0lR U[*M^ŗP Up{eƐ5uNctDW@5޹a ù0/TmTSfBdjмZ4Mm%áR*B?4,^$yEai~xx\ǽJ!/Tf b.&jBGGeGRyr}2Djq vkCHGR;Ԯ.\@CǀSRF1&ȼ?tww$@/%HAz߹̝ f[[ \v_j8\=~ +܉FՅR,kR TbT@4wfM p,@ew6O3cǐ3gTmD $&k7fgAeг7o|ڠLX\/o^ TvuX'[KKE8r&mvtTr-SU@O"Bc͌qR aQ: ..~xᰘ˹UVR+liQ@PmۤQؒUE]V:w{l T.ccdddRٗRgYfoC@-ᮭaa!6988!c8D"hg299UZH]&HlपAݑ$>[[[E~ @kƳ Plg,-, H gVEm_]0nX.#?J*@Ev)P9' ."܆4Q u?: cccf'sgs ,E?#x>޵f8`nӪ}ûe8IENDB`application-vnd.oasis.opendocument.chart.png000066400000000000000000000031251237252063700351510ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵKlTUyvfBiI)C[jR B `7(F6;,YXX F1!$KK-VJi>0;370Co<9}s8LI2f\=v ּyV-D"tM!=q(?,7Ϛ(TxZ P0h+rY.e{ӭ"su $E)/ x^8 oѾ9+NE!=q5؁z"yj@ 0d KuWYP  $s UOpud'xjs[%0qv_V7TŨC* 6/cq. Uf.~ HmR)"M1i_mmJgLp<$O N $/AQF@ɗrYLA42O~R!fzqWj-WpH1f"!R1Oun@;ւdS`$qYs%9MJo7`&zޗf"͸߉㡡ٯw8vд UվH= b@/uThG5TzcPIe @ /_=g۾ޫ$Pvyt sa;LrdEͧe.].c+**p\  vuu} d2/$p=ZZZlU*~rcU:0lUUΝAlޜ I8;|'0,iBE ODgIXL&R(ݵkGx* BvdDy"ów8uqlVB O^{V;w~(od)P­ܾ}]1N 2? 烨q͡|70"H.kX& 64@B{YIENDB`application-vnd.oasis.opendocument.database.png000066400000000000000000000025611237252063700356170ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IPLTE xxx}}}ֳ'tRNS $'(+/189::;<>?F0PgIDATxmNSAtW(  BD !!F+}/ h/54* У3vW&̗u1bq*p :Ub" &bF(7,0 ZК@xgHT:D!U=W!#@):%;ş RYoo.u :0VF)}pRW$z%&2ue%nˈ|#;ǭ!BYha8' Qʀ:ql_ 2aEtgMLZn_"Z'w [{2 eWRqvDD}Bn<"T[oA7$&XB7y^Si=e-;NA37x?'=kx|¾ fV*=umJBՀKyy$P)|hƇ0lu)n} @0yC=h[FHۣ&˪qaf#IENDB`application-vnd.oasis.opendocument.formula.png000066400000000000000000000031371237252063700355200ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe ĩ"q@ܠ pJzhPT*q8A R%mR֎ݸqx=-I}ge "=|xA.={fL3ng)^8/q} hB7 :*z%LYlb4lDnQVMmsc0VU b"22 ,f˂T"WA!WQ$rȥ: e&Q %`xK =d%TTb#OGj5 GJÎPnN`- 0I9bRVƠRYg˵A6; xn?.cO:q⮇‹>|4+O:985'I^k{5VZ*v;ORPJis)1Fz1՝8| SQsDT(@ݮU,?Šhyyyٚw,HnYkR8 bq-Y-jM-q>Zzk%N湗s.:W9M J+++TUk!Yk;O?uF&?PXv̍vߚo3?\w]mh\lp%RېT7sH Bِ^,r\DyQor2K @o>qDi *Tx*0N=z8:b4Y<VdpL!6F'>kB8749##*жe04^:YԼ^uyJ{P(HsH0>>")vo뀜{~wn]0I`/ >=ou}N5>.L#k(ȹZ^el!+W>5 ]a1 .H;\fŋx,zq'fp9sS5K=1 rC/ `ƺ4fXLQ#4 FR) w12h xlT2P5Ct(a1tMٙ u"!W UV&puL2KKCUSM&2u`w_oASiUpCz3ELtO~լ4!in)q6 õb^V5,}%̳,2LȺhimE,]`#nh`큡uԕ4"F/!t T*s(HX^^N2͖9W8zm8;i acc;/Xa}𲽘xdoXú'֘'0%%zF;3<8y@ uا/ HbkfhLLL<4s.<UE 5EY?0,fyFlLfyL *&$7`7}CIENDB`application-vnd.oasis.opendocument.image.png000066400000000000000000000024521237252063700351340ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<:PLTE 9-;( E/ I/I;#N2NG9PF2R3^<`>b@ bN/kDke[mf\oMofXrKtNuL wb@xL xo`xskyqfzrf|xozp{nwxyZ y_ c RæƞɟѺ'tRNS $'(+/189::;<>?F0P/IDATxm=kQsGb!uBtEh\ vZXK/kbgcK$DB%ffv ;L8 )Ef'2%)7HECnз)/"-PE0Kp\È YHų'` 9a=.nӼ+N]"d#0mih3{39PVJ&nBPCR/VS7%@WY~pT&b,a[bte&ԯ^-?$y,cwi^j'A F5s ۋ/\@1"yu/з "[AI5[= +-:(lֺ &H_A*8A)W Rm@@dsr`{] [HW!RBv)#026IENDB`application-vnd.oasis.opendocument.presentation-template.png000066400000000000000000000024131237252063700403730ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKoU=NGDDj〒böHHH"!ʢ ~Bac]~D TyTj7c^ 3M=pOwFs=}߽c#hS.@ D*4K?=ƾy}6ΐb$?Q|먐T9jQXl~ei}lp45%7 0L&Cς_GLj8d0yx\x\FWe^D@6"'ພ8*v8YS8Ry)H&@3  |WAQIB]ceeQضu!'4Y<,, \w@RyiB5CnG;LEh4[xOJp!*2|q"=o_H3Rt:L@qbQ<60!\ȍxO=BĵQV155L&Hq:{Z{ H#$,:;w(kmފHul0EaܾjctI&N76`̣;.=G~wBr^sV|`U(,`Z LO))~l--пK*q:;!lCY[{al>{w$7tdu[tWP|-dmkɻ@`v~(maW >`^ Zo_\dl]ITb D}X̉ p2NGG0 !=!7 W |&ʁt)8=_gLږ$ `}Ejwl۬9UՁV4i/^\MIVd`$8oq\G}^JG0qVsM*""dW"7HS.~Y^~ı6+r!<3yݰ'5/<یۊ0AD!A~㼓;aƠ+.@" ͢\.o~N?;yB7$*333?xDZe*H Q" E؟Sqc1ڌ-KT@X%F=‡vh耨W/۶uXW;b} #_Ko4 #fJE!,' u}zz5LMM3 ]l[J%,@сcu\\2Q#d[.1ZKȽ\\?!y" ۸(NXDEܡ2E~ͷ8:H̍ m z:;e|zB*C ȯ}GQd`rܠIАt<|?xa:3{{'#?*oN( &$+ӝ̛!p ʙN.3 ܻ9, <'ֆ$m{;KK0t`O7o(KnfĻw}e;\Вe4ZnƑ~VATH;tNŠѻwi΋PBn%{UG`:F99 ܁ :''09pd޹x@?-Zn+R" Z_K9b*%Xӧ#SS!`&K]Ua&\AnkG$ ǰo@4Qʙ3RkO8PINjf~~kr"QfLE"Y%$9s`gg-/sk$N'̌7b ̳8_vwwPٳžMτdMbETP~aaK:'  H$I/H)493@x7C+ޟ8Dͨ1M9U zWG _I E4Dϩg ha-bd "\N7[IENDB`application-vnd.oasis.opendocument.spreadsheet-template.png000066400000000000000000000023031237252063700401650ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE _װdݸef໡fgɽhh¨kпŒÌ‹Ǝ9(tRNS $'(+/189::;<>?FIDATxmKnAa{ǀ8A=^#p .#@ [XۉQ~ݣZjA⮨ E|U%lx'B@,\!4Q l/cyO?Bϼ੐0>K{_Բp?څSpHDXXy H@’Zk2#Sb">DZteEkIĥ:رg; IcCtشg鎝TDT1A(z3=2C 3ۀ]ݟ̡ ȴa974[puoY.fC7ꪜTy%eJ>rn 2#0)0yckq`UFQ%>)>8\l .oh٠??&֐Ơj|??3:`nPdᨈ_oy9 Ynh 9=T-uڑFq"Qe% )bIENDB`application-vnd.oasis.opendocument.spreadsheet.png000066400000000000000000000023321237252063700363560ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8?F0PIDATxe]O`sv[>At:xa2N4^_O !F@%mL9nv>5]:?M'$3pT: @= FDIWxbs*@7w:IBDN>E$0 ڠұw^dE80q^tjs%"_f [3 DM ͌$r\\wmk5yrow ?%l~@R8Ez៤li8A ]P%vX/2ޑA<4֬mxy9s5dYv:vEpK$u*a)oj* xis@a#dmUNcX%uQ*iPv8֞LAL;Fx8ZP\K40THՖQ˲pr1}FSBךTknSLI8`vf] 0u-$e.-mK{3e 06cfxasx ֒PQVy^U3ZJ{0JBWzɀm'@@qibĔ(󪭙U6--$ۀ˅]AoIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.rn-realmedia.png000066400000000000000000000027751237252063700326650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.stardivision.calc.png000066400000000000000000000025121237252063700337310ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE pppuuu꟟שּׂΰް龾`='tRNS $'(+/189::;<>?F0PjIDATxmMOPs 0Â(`ٻw`Ԙs1DIgD 23 N{ ]pŚ#{V'oӫF' mPR hJwpO$@ VLUguBb`LE;@Xjzл6EY$ lNxl,Fw¢얷T. &ϙg + * 0T{*dėI4rLpC@"Y`T!PFlX 9BqĪ# b`J(Gb2a6 L q؄Xs MmȅߒfD4kC]-9~q+2`aF:߻Zk6l7n@$XT]k{N=58 #:}iۣl"fBCN]֖_5d#}h" Z/d\O/j@ BZ}~Oډ? ij;~(pZ!$+p+oIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.stardivision.draw.png000066400000000000000000000030321237252063700337620ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.sun.xml.calc.png000066400000000000000000000025261237252063700326240ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<+PLTE ݰз龾ꌴ뗹똻z슲쐶쑷쒷쒸쓸킮햺z'tRNS $'(+/189::;<>?F0PjIDATxm=oPsnԉJ[:t mNJ UEX@ #(02 !DB+Mm'vQb,?yϹĄN$#@s(R7[Y A潠lu2hDA?q YEc\FbIS BU0aennhg̈>@WrCߠO`V@M$07ʌ 4W gK2%D 3Jthe}@TfFGL4\SSaM1]#Vf3(1q7RD%YV uG9e()*8p(J[0lU6tRye)T"'JȆ6 VQ'eX :_UQʷ7Q3p7]I_syAj/l5p]|Y[ vj֚oYFm#bCޯyՏ'[ E}2|susdC҆zލ  N] ~hBqQ4Bt%i{~-BDL>X]cwBIENDB`application-vnd.sun.xml.calc.template.png000066400000000000000000000025121237252063700343520ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<CPLTE _ݰзd깠effg齣h龤h¨kпŒÌ‹Ǝꌴ뗹똻z슲쐶쑷쒷쒸쓸킮햺'tRNS $'(+/189::;<>?F0PFIDATxmInAWf%7H >`8`'qd,X 9`{p*wuEI_@pVI!E8r pJ e`dxqh601抴A\H'8Y@U*;.1vhHbe58fm XnS {ѯ7[S#rV';lC#V0P+SV~}`o}Qr?꜄SV'b2=*^*7W-^z@Ek>eKMbWꡏ"Pu&mF&hP\Rjd Pp&wդ1t!|9ky4fgPvD\teF=3+% :_ ?\'sWfb<[fPn6$d ~&!r`ZOdwi@J X2T=Mz~%ȁE4oD^(NQ0!K"?ޅ IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-vnd.sun.xml.draw.png000066400000000000000000000030321237252063700326500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`application-vnd.sun.xml.draw.template.png000066400000000000000000000030321237252063700344030ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-7z-compressed.png000066400000000000000000000034521237252063700324770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-ace.png000066400000000000000000000034521237252063700305250ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-applix-spreadsheet.png000066400000000000000000000107501237252063700335760ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-arc.png000066400000000000000000000034521237252063700305420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-archive.png000066400000000000000000000023611237252063700314140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-arj.png000066400000000000000000000034521237252063700305510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-awk.png000066400000000000000000000031611237252063700305540ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񯯰^_`abcd d e hghjklmnqr r!t#y,y*z,z-{.|1~45~3Ά@ΈDЊFЊGыGґSԕYՙ^כaםdןiעo؟hآmإs١lڥqڧuڬڭۭܩxܬ}ܰݭᵊḐ῞㻔㻕áĢȪɪɬɪ˯ͲԾӻӼѸӻԼս{'tRNS $'(+/189::;<>?F0PIDATxm_qbhrFȕ3rE!h+aDÄ\˙3h[M[|oc|7 |]k^}|Y AM`;$kox!lp Jah4fΓ0D<9pEԭSf(z {,ȧ*U*Vm@ZOHnPwTk =ai4Qr9EQZehͺ:l'>×; 'VH3 drn'`lAX=;  w %"/ȝ .eɬ 0PY'A/K*AWIo8y`[uĸ/i+wVCgΒAC><#ތR \t}:6boеC>R>t?!rWC5VI16c 6Ϡ<TC}pwEIwG1|A~Q87+C.E 8਷J'\bi4;$ӧ:d3@o@7 pbBk,fL*V(tqVJo ޖbgL ND'Dulb"i1KQY~yV\W%wnm>@zvqXԲC_ڵhB| ݨG ss4IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-bittorrent.png000066400000000000000000000026051237252063700321700ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWMoE}=3@A@p ā#B"倄DrO8!$H"x"ǎb{?磻y3&=UlwWU]{)4 Z#"&74ĕ(#_ZEhZL||xt[exs"i^(Nf5vKK/I$'A`!^p4tb%1q.@ #I]Th- Vs2a09[y_hn+!ow#d [ fG8D(Vi2nVB<kI(X Ҝ'М",!'ڣKhӰ!š$uD"lh8np (2$DF A v^]Ql(:l4ZpFI$(vPDFD%*^sLx-K ў}*@@JJCTb$UKZK @?A3e8vC["paUpGFU@_'1Rz{>- jSRs0t oE:b;?)hDT5}B^a4z3x|wK7DGn]4b /X?Ե~%WF kBUZkE :?H yq'< _DS'/qd!N|'PR Uȝ5Aso+å’$Wx>fSW 205Rp~9b:½{wCgLHJ)+[,XHK 8Ghts}IG>u(. hBJ֡OoCԑl1Tcz8x !m"CMpLuʳ!x S>Dac?Te)b>coo6[ܳބF <œ}l6'9s 5LNɄ __`:`gxw/wq<0*g?׮](dyrOc86 >;~$SnOߋI4vW{5ᆳ'g5|1_,~ gsPj<H7"zWaͧp8|7_(ԨЋ>mv`pm#8ytFS(XcR%8ɿ4y[""2 1$evƬNDn})IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-bzdvi.png000066400000000000000000000121351237252063700311110ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙itTU}N )I') "* n" 2 8WAP0 dJM}wj껮wٶdz'*I  #–aWsgG{a>m"B >|#a [v!7®SMa;l@ pCSK}˗{Wm-5"0}4%}mm [A{J<+^s誮8'A/AAt`CA ]@kt+ ^ AI? L̒' /)|E>ϻL͡ /L`'&qbҩ[}v3?îvj՚U?;ŠV@H?oDM ƍ2{u[\6=rc hOhP Dme7fbzԚo<&?zeyiK]톊tϓM 07nM c~ȟ8];vWG'~8q")Y..5卸fk:?8=c+VLFΏ*ƒw`M~[OztH.IޜrTo B ml(ZL(jYd$(\T0V50bA(\ܫ8 s7vqN. Anz{+y/y2 .®0cU*[红?\j$R$Q ]=*VC٢'߃&{QT?>~; o_ҿW.6k~Ww.ecK-Aw魡ڻԄ_=j}I!]vի/[SaW[]w"j׌O@?^? D6X'3Y@3y1 ǵ^ZIb "QD(( X/)K\=~ж*oX(d?{PRCm?z ojcK]}# @E8 t{ $mu8+62020)(;*ڠ3 &o\1q(u.2g5+κN(ܖ}ʀn/W./=% 5^7(K(н2.Xm%)ARs[@ɈƂ"g`3zz9f@CCcPK0Oíc >SQQ-QI"pGo2a@W\esb4Iq~G~m"Rus3'HAz#Fu]fcȫv: 'bV(@G5qkpr#T*C|xC`4"_d'{L-YoMkwyEf: p*E|!#P,Psv*ɿ?4 G6ʺ_v|nw|xg7M6E_Dq)ү3>^Z_}*= >1ǨλΘ֙+gAyAPϳ*oәū@1?s@,%&(\h utуj=8/΀;3󎀾)seg< ->`3JG~QC.x'hNl)=Yqt?7!uocp௾ ӄi dC)1N< 3' 2Lsū 5ʻq;΃IzycF]*U㾈Sǽ|1jF̷{!i|/D7/f;㑱.uo̷hTWʋ]1꺨3y>GЬxU5Ғ4L%)sxZjHM leDE58ǜl쎙qEDt߈O!G٨~.w4؃Poz "s\[%OS"%ln ż~3*sXt0L/+aֿ T@;@$W|! ҄9`MQh֚> Q&U1`jVk:!zњbrU .ljAQ\ Q,  o /A@HuAظN1d*bx'b1_eLd߂H7Ժ>^$S@Ѝ;3b+KebGC7X[Zv<zx05o)5 W)3.ٖs@vn9QݭdEmهζ?[b{9\nW\   [@DQpM`Q9 XijfR41ԂQAp;6̾En5[78$%&EɍmBLjjY`Yḙ8z.ۧP_)&jH.N;7_BpPh&fj* u3"^UknCs!0.n{o`!ȖLUץw׃mrzqvƔi5+׬ZrO_dӢFY UYzHR 7aFF{ $R4ٛ P+LmXժG^Wb  Wˑ_d:N?AFFy0Sͼ7Ks>?SɆ*)Q@%J_ңgI/\r˭o+HF%l2JFe)k"k1h^& XLJW uHB'u |#|}alqvMEWqyͬa2A#ތ{s&ۇ]>cwumoxnù ;[n9h%/VJ40nt|VKk5LJl+ZA%wW|e%B3F[]eޑrW[I>jJy3 6EEyERugNͿh+J/]KPJۼf%۱ {/s_?w\mmε΅΅c1٘ ח\~ c~kĤMEޚRsgʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-bzip.png000066400000000000000000000030111237252063700307300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-cd-image.png000066400000000000000000000027531237252063700314460ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<hIDATxڵoG3{-N@KDQ_ZJ}C)-O:łn`lRVe 6޹kRE:@@e-.fe>x6Cy?'U)1F#r#ɩ O6OTPZM8~}2! "TbAv"%-U_9+> scWs 0S)Z۞E7 7>Ziwyh!bݝHzadMP(9yek§)UC6%)^=ajF7J0!ɑZ@ \@<@sm NǍ+@2Uڻf$F8Ή^B_E1?awlLH]Qr=6Y"jrvLl.YujQ_q1 +[䮝+g.L&pyR%GuDhl."x&Zs ڃr5S܅qn>HuӘd@LӮ"2&OX+bS>yNꉅ35i<ͤ~C`־'sQ=@ɦl;20NwQr&v H@Sȯc @.!M:zg?@ qFzd#&18(g6qd:y)zŗ,gj6ښ{SnlluE! MGϬ;Rč!ulq]$ fZWVVݻCz  E8.p"ժΝ; ~:'H1R[n} ,ɾ > { ?es_T>a~9∁k!O(P6FY^HܜeDRIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-cda.png000066400000000000000000000032301237252063700305160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵ[l\G3s;*4Q_Z '4&ZWxEЧB} U7 ϷNn8''Na)lmHiLdD}B¶ B[\~w::?2):^rz:CBĶ1n@y'p}@`z̋s }~ B4Ci_4Qfƭ{YƊ4ҲiyK2,mT2C pf6M2"#G̪إ3MPhGn̥l1(oi D<VJg?EPA[ j鴳}H[F (q/8qSOdN$V6N j ֛HA]';+銫4QF8;eR $BYm~We')!!SG/:k4ArZOvB""jY<%dzf(4LW+tXDajfXr5[8|Oro(+$UJ :lg _W)̞n|oû୛k!~0 d> Q:Z&ֺO'\+-{p1:$3?%9 ]Ao8fZNZի/'lƧon?^}\K7=㌃Hq#'C9++.]-`Gk0{dP=hڏ[lNr~zA}>;/<ϳ~9)Y^^.E`Ո܄}\ǥ,oq==b _=&O?%7kkk+W| e=R1O5=h=R$[[[lll$uuܹs,,,RZZZ{T>=s:A~^__/...>_V5m0YvFŋnviJ!Af{`7))e_6L R Z8 > 7C 5!s>tfP?)IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-compress.png000066400000000000000000000030111237252063700316170ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-compressed-tar.png000066400000000000000000000030341237252063700327210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[Eܝ}eѨ#!QI@b|D$$11Dd僘>B|#D ,,ٙ~W4‡=s9uު"[z*z>m4yQMFiVަMḰ/?ygOdW{[<Z& lF.̖skh>t(T0O < ڿkT!$к "t-锎RB6X&W+v Xy׽?M8 80K. ebp虨:-$<[Yts,6>!cD"T@OOo mXfG6 & px!%XUx_ZX Srƽ =:שl9obA(uH5Ds"<?EApL-h*@pԉ11U~H8.8.#.Z6#i;$w>\hMEhU B%3 ĵ5 @B. Ռc9gYo,}iK%ɛ:Bp\ (F}៑' !9Bp^L ".sLZ5K!T輣w: YxczXԞ_ E!x̓"C3DZ2пs#|9xo$A6c]Fǧ``ƒ`G-\<){ӟ,@XŮVxǂUqueUsWP[@QOiLނ,qDpq,@f)YhK3ܲbb^L! =;gPW'NԈ>.)|Haʮm&`xd6- Zs4EH47qQLx Ҍ$@Ҩ Ŀw pHq 3,_A8 NrONY޲ADߤ0)r35hrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-cue.png000066400000000000000000000120301237252063700305410ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XuIDATx͙ pTev H$KXDPA gDP #숢8"ʨ3A$lCCʹE5zU*u[i~gP_g{^oѪ *6X#{CTw<ڼ SM-WLɪK>`E?\~r#(~s;{<#X= a WwIC* |UխZrR %BMl tn鏳뿴"*F_ttqw|"~~C S%.N[g@ Z+fԯ9 cTHIuZ ƌѩ8%-Dznm1e84Mif._nٹ6 lZ} "|[=PpWp:m1}rA艈F_x+rc9ȟd6NMwҷ]{99 h` RAgirhcYy [eVwd+jݬw`JVz@HJVg/}\^h1gImLUgMx{{KͳJV!iV yU=gΜxjʀxWTXY( dP`s#Cls<FtĶ={n;5`tA"XΕ`t!bbmv6 *ƞo>DWӺ[u*s(kk5K7kw~z;*--)qh x^mh1N: [4!I lژcAt-(?J8}z&{;@֫㮎O~E!zW} PmBTߖͲ(O\*ȷRڈCBu>w`6$xǖ畟};"ႴO׃Oֿ+?X ̱".:<ѕ' ǶODHQkxf*VOCa%a?ĵ8!ͥ&*pʍL@ptI^0^1^S}8@qENJ05t~FǚYB03/엊?뾙SjBvn̊(9Y}{Tۧ잛u騿EAt dclK//9ǂ_{AkeK mG2*h@ 2,T]]mfk1 ys|u*f-99+Tw<@i-:Z:8jsw%NuOr8_X (@d.XF!ws-F2]A>6BP%oI88&.N*zl DEԻ1Lkڧy28={3T1fx!|)4eWY֫&g:JMH?~KlV2*5`vqLG#WܶG7_4iȰbP@D@Le_K4Pڈ*1g$x&m/ 5Yq=:j{e{gMdO^+p{7%ow+A֛aa`ZrM)x`e䄄]:ւgL*ϋ}`:L[͵? ^=_r;Hx9^>Ole|yn/?]^ EDohMh=Mpz\-_ kFa pda`~0Zsm3g{sIjgAŢT.59/l-1\YYӬ q==_>#͆‚j]L< ~IZ}n745mxf.u~{-aDeu}!e p*0yŬ]])>tXmtOUJZC/&Nx~GtX| Ì`)fל9Ws;+^TOP}o@Eٛ q$(FpA`ooҺ?p: !sKπYa_":GZK.Zqx|ܢz|ioyTsTW0%KIbzssR1[* meu6o mZ߇ӕOͷjCKmXU\/P>*p*lncZhCgn;???!nIgWB Dhj.,\zWц}>d]i_+-1[B~/LtAVLO#qHm+vqۡOo~v_HzIQ⼹[frus# !G.SKs`+d̗V}޹Uׅ;P sXPtlϱP}6wԕP1e;j!m?ju-N!uY)ϛ8kڮKS3cf}%Az|zR cgLqC8SjQ~B)W#=٦=4;1@>7?B/CFQulsMj6m*mFP!Y<*Tê]C -yϛ`dY'vOq>zG5 3/m_bYe}/}I\e%*+p+xCZZAH(XbJ*Ii+L Jjx40L~_}} C+W_Q# XDwY_#52[ԡuQK5>uϴ=lwIrKN;hѪ >!q!RvlJ4hpqqIÒ.}>>r_uKͱށYmc٨gc ܣpfV) <;,7*p(pȲgLkye{l٨fr-ZZJeT~| [ E r׮6ZǦ L;CSua ]#7A{ǷJY^j8Y T  F Z2DFpqm{jC檭S^ڷזOzmI݃vN6PoNnWP[_-6û܆ҝ=o6L nنq l< 7=#c"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-deb.png000066400000000000000000000030371237252063700305260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxWklTE>sna*B IDD1c"QGL#?R_jhLD?bL 5 "H HKҖ>g33ٲ ~{v͙sδDsftuuFP/Sh`F69mڴ݌8omk(1iG c9- , J)X)(5q\qέ;?yt6gy]=D29aB.{PLJ”,*\}P_Xp9(0k98" _E(׈߉i‚7_y]/\LPiiJh&5Pku^Wv.X-5z$NA ν,]Č<CHEo`#M22Ve847N5ww]pvj;fy̝ P9m q a[t2U5=+z=a55zq>͏O{;`FC =} 7F!oI7UQҹEs=>{X1xa,^%<~Tfm^!W@hAXy>|wwq68r';\Θ/ ذvI=|xcajXAD,R8|{pix ϵ8etѫ+wup>=NȪ́y^eEx^ kW-(WAbE[r>2Wq`~>@1.[L݂L_作p|FF&k$WFd]ڲ#δDD!#@:n٣W*?86ƭ(`MD䠀e?Cy0=W FkwP,i.:a$]r:D)EI"H%7g.˘ptR=X;i $ &9:Egdt_!TM=B pkCH+˪cBp-b m_Kt RIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-designer.png000066400000000000000000000025361237252063700315770ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sPLTE nnnpppz{z¾ƿ8'tRNS $'(+/189::;<>?F>B*IDATxmнkSa7M֠[A R$RPI.VpRJ'ŵ9ChBSHȹMnj.Ϗ+6D$tY 1C%yr[ahiy\( a2`b=<"\ڀ,uAW";^(1)ޏ&f_z o!WZ- CtA[w gUBq <ߝY,yuUD|8T0 H0qf=zx{27¡À7Sm]wqpD\" T H ٕ[ tTmQۦ??V m[1\>eV/gg\vG$8ۺYYrfr4w+DuNl~?({;M`sofl64mX][Zl >h b[A}Ui nS 6]7dWM;33on.N x?;}s*vS{fZ;yyiq(3aD%{qC e;{LX-|S-Nsr0Cw%M|o`Xϕ\ ϑGKO}8|ANk@<;:?48{nidXz(O!6`|![me\HD0!cLxRsV,,#^'N,R-""6!l hwmq1PD@"ffİmu|*/dDǢ>7YUnfBW01PE7Eb|{!aBǏժUWk9ukVr9tm(J^I:: Ux5Nᤷa+܆Ll 5 z8n<9v. &,TloˆU^$s# t̖-R,2y#ԃ/gDl|pXUMm:,wgOWQSPA +;U|~N,]HȰ A:``%xE^-qX4!Q6GYM<6 $n>iag"≈"r =w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-executable-script.png000066400000000000000000000033011237252063700334110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<>IDATxڽWMLTW3 QbbL+"6 iu4M4j-E 6WMݔEaacEC#A-tCd`p&3`Zwa紴4JxYH_ؘ0yΝ;~)g$=k=tP\mkkkɓ'[,wܹ^yzp{{sssM؊)..;x`3VCCC+#Go߾x>/--)6BmrNNN2CZyfIcccWDtUyykCd?\؊^/<}UzI8Vi5JU'''=!gr@y&/Cpƍ?X VۭS-[0S=qDeW/$XXXM )pOy^ml6YWW) 5˚^u)}5ڵAt-0=H8++ ٟ ]6XVVMi ˉ ccc WGGG/,tDd<-HCzEfF0̙3fpeq@jar*k*~8y䧫_r䣔``(3è%Z{n.)dH%«݋?}- $@ t8&HEk8,6>>@KWa>@>uS ؠ8Đx#R/ι2,Yj/nȍ2 Z = Q oݺ5d><|"Q1{t}DoR  neb^AgiۚJllRTUXH8B[Pư`Jʜd b ϸ2U\ɳ~jt9::z.8!771"IA̍4Hj&&G Vuuux{)ƫ4-ajÒ;w|800jZ| m@x5&5(yUfDj>s Q}B-~-o~)=?X60Dmh[WV;pl!uJH6dR"x#NYnQQe &R pXQ$^+nPKKKF:[XIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-executable.png000066400000000000000000000022551237252063700321160ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<,IDATxڝU]hU>sofl64mX][Zl >h b[A}Ui nS 6]7dWM;33on.N x?;}s*vS{fZ;yyiq(3aD%{qC e;{LX-|S-Nsr0Cw%M|o`Xϕ\ ϑGKO}8|ANk@<;:?48{nidXz(O!6`|![me\HD0!cLxRsV,,#^'N,R-""6!l hwmq1PD@"ffİmu|*/dDǢ>7YUnfBW01PE7Eb|{!aBǏժUWk9ukVr9tm(J^I:: Ux5Nᤷa+܆Ll 5 z8n<9v. &,TloˆU^$s# t̖-R,2y#ԃ/gDl|pXUMm:,wgOWQSPA +;U|~N,]HȰ A:``%xE^-qX4!Q6GYM<6 $n>iag"≈"r ?F67IDATxmлkQs;3kV!A$ةu,bgoc#&" ;%3iԨ yϽfnyH)8{.uPhi+&t܉;CQBzf rh) @.@H Kh'dqP?@BIi[WbdqZJdG%`YK̚<X 8?{lr}kasE1%;u嫨fCYkZ h櫽U?_"m$ Ltk8~'SrxZHȦ(O?ΫCSnU|u/4(kk'l4Dnl'+E*1cח%e Ӹkg~\鍡hGa:Nz[r;vHNm;.|!m/6AR$v /]jo/,q7%(h{Gà A9$ k'3eHІʻ I(E dA0F96`IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-font-bdf.png000066400000000000000000000023261237252063700314730ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-font-otf.png000066400000000000000000000023541237252063700315310ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE AAAEEELLLPPPYYYZZZ```aaabbbcccdddeeejjjmmmnnnqqquuuwwwxxxyyyzzz{{{~~~S'tRNS $'(+/189::;<>?F67IDATU2(*"rP+J;1,L| /Xjg@023 gޮՐ }ШS1qO5UR%H`vav:j)I^Ii:~mRuxѫ<]*A=~"qtt-dw 2<7lt@gC.m|vAvǿA%ߝ^%_\h~vUjJp*5p}R)z_@/~|e+4*0UAInOUt@ժĞ  TU% C@ hTIx4ه1 DΒw1hU뭕}n}CE݅ywrzp3ζ}[ L?spӀ{MGO>|v Hb?}ZAۭ/zt |4@sb hM#4|thM`\m4vuvy=EIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-font-pcf.png000066400000000000000000000023261237252063700315100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-font-snf.png000066400000000000000000000023261237252063700315260ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-font-ttf.png000066400000000000000000000023541237252063700315360ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE AAAEEELLLPPPYYYZZZ```aaabbbcccdddeeejjjmmmnnnqqquuuwwwxxxyyyzzz{{{~~~S'tRNS $'(+/189::;<>?F67IDATU2(*"rP+J;1,L| /Xjg@023 gޮՐ }ШS1qO5UR%H`vav:j)I^Ii:~mRuxѫ<]*A=~"qtt-dw 2<7lt@gC.m|vAvǿA%ߝ^%_\h~vUjJp*5p}R)z_@/~|e+4*0UAInOUt@ժĞ  TU% C@ hTIx4ه1 DΒw1hU뭕}n}CE݅ywrzp3ζ}[ L?spӀ{MGO>|v Hb?}ZAۭ/zt |4@sb hM#4|thM`\m4vuvy=EIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-font-type1.png000066400000000000000000000024241237252063700320010ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE 999;;;<<?F67IDATxmлkQs;3kV!A$ةu,bgoc#&" ;%3iԨ yϽfnyH)8{.uPhi+&t܉;CQBzf rh) @.@H Kh'dqP?@BIi[WbdqZJdG%`YK̚<X 8?{lr}kasE1%;u嫨fCYkZ h櫽U?_"m$ Ltk8~'SrxZHȦ(O?ΫCSnU|u/4(kk'l4Dnl'+E*1cח%e Ӹkg~\鍡hGa:Nz[r;vHNm;.|!m/6AR$v /]jo/,q7%(h{Gà A9$ k'3eHІʻ I(E dA0F96`IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-gnumeric.png000066400000000000000000000107501237252063700316050ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSm"B >|#a [v!7®SMa;l@ pCSK}˗{Wm-5"0}4%}mm [A{J<+^s誮8'A/AAt`CA ]@kt+ ^ AI? L̒' /)|E>ϻL͡ /L`'&qbҩ[}v3?îvj՚U?;ŠV@H?oDM ƍ2{u[\6=rc hOhP Dme7fbzԚo<&?zeyiK]톊tϓM 07nM c~ȟ8];vWG'~8q")Y..5卸fk:?8=c+VLFΏ*ƒw`M~[OztH.IޜrTo B ml(ZL(jYd$(\T0V50bA(\ܫ8 s7vqN. Anz{+y/y2 .®0cU*[红?\j$R$Q ]=*VC٢'߃&{QT?>~; o_ҿW.6k~Ww.ecK-Aw魡ڻԄ_=j}I!]vի/[SaW[]w"j׌O@?^? D6X'3Y@3y1 ǵ^ZIb "QD(( X/)K\=~ж*oX(d?{PRCm?z ojcK]}# @E8 t{ $mu8+62020)(;*ڠ3 &o\1q(u.2g5+κN(ܖ}ʀn/W./=% 5^7(K(н2.Xm%)ARs[@ɈƂ"g`3zz9f@CCcPK0Oíc >SQQ-QI"pGo2a@W\esb4Iq~G~m"Rus3'HAz#Fu]fcȫv: 'bV(@G5qkpr#T*C|xC`4"_d'{L-YoMkwyEf: p*E|!#P,Psv*ɿ?4 G6ʺ_v|nw|xg7M6E_Dq)ү3>^Z_}*= >1ǨλΘ֙+gAyAPϳ*oәū@1?s@,%&(\h utуj=8/΀;3󎀾)seg< ->`3JG~QC.x'hNl)=Yqt?7!uocp௾ ӄi dC)1N< 3' 2Lsū 5ʻq;΃IzycF]*U㾈Sǽ|1jF̷{!i|/D7/f;㑱.uo̷hTWʋ]1꺨3y>GЬxU5Ғ4L%)sxZjHM leDE58ǜl쎙qEDt߈O!G٨~.w4؃Poz "s\[%OS"%ln ż~3*sXt0L/+aֿ T@;@$W|! ҄9`MQh֚> Q&U1`jVk:!zњbrU .ljAQ\ Q,  o /A@HuAظN1d*bx'b1_eLd߂H7Ժ>^$S@Ѝ;3b+KebGC7X[Zv<zx05o)5 W)3.ٖs@vn9QݭdEmهζ?[b{9\nW\   [@DQpM`Q9 XijfR41ԂQAp;6̾En5[78$%&EɍmBLjjY`Yḙ8z.ۧP_)&jH.N;7_BpPh&fj* u3"^UknCs!0.n{o`!ȖLUץw׃mrzqvƔi5+׬ZrO_dӢFY UYzHR 7aFF{ $R4ٛ P+LmXժG^Wb  Wˑ_d:N?AFFy0Sͼ7Ks>?SɆ*)Q@%J_ңgI/\r˭o+HF%l2JFe)k"k1h^& XLJW uHB'u |#|}alqvMEWqyͬa2A#ތ{s&ۇ]>cwumoxnù ;[n9h%/VJ40nt|VKk5LJl+ZA%wW|e%B3F[]eޑrW[I>jJy3 6EEyERugNͿh+J/]KPJۼf%۱ {/s_?w\mmε΅΅c1٘ ח\~ c~kĤMEޚRsg b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-gzpostscript.png000066400000000000000000000033701237252063700325470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<uIDATxڵWOTwsy<(", *Ʀ!тƤj[æ&hMiMh+kւ*4 <<ܞs¥35I~\}j(%`3,tX,8=i" Qu  zv_ɽy?'Kx{vR),..+`ʝv>`YPH TlZT!|YYP,VN|1 HZn#$~@9CTxu"\u&09`^.E(&bQBN`۩a\,Q4*p;8=x`~oofhn"4 xT!X?\8?ٜ[ QIC7^Jr8`em)Q! !x$H?F)[p8xlBR 'Nx}Ob͋H(JPÙ(aF~3u@f0f% Ek׋&@/dHj6ǢKaJJ IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-java-applet.png000066400000000000000000000033231237252063700321760ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PIDATxڵWKoUlόv켓6N!TD!*m)EFb #B)R%TRRWK&MbKJm8ɽ{|3q#)cS\pn??ɳ[d\>?m3u4¡9wugi0LsPpӣj `<;Yݼf'♻é' Po?61$W* 8RŹZz%~xVOA ?E ||$T148 GW36GoE8LzJEz-xB+]xmP©P,05sUlHv/fxs0Z@G}!tG:Tŀ; rL qIXgd %|-GdтV^qӇN@o7PV9 Okp膁M%$H~AYf~dtjAb[L&ܛpy0t$ê´HЇhЏ5`%و*>g 4hS>IcmW#R oDv@N#/WX`n"::kkãP\.qz/Z繱P%|IXE.7ds͛-=>r CQĻI$pK#>}7`uEtP"Q:g_E2+bkk Í kDda_eh8sB }O IʹLضͤ $hK+R[ЫXj6N ʚ Ԃ,-Qiy.keTt a!6p dittb@Jw, ViF Z}6 A,-GH01^\4QÅ|ۇ`0(~@&$ $̶-D@ƙcd2L˺9a*oٖU 1Ax.~JmcttPaYLU4#w3:1HBv7rq x+ 䀊x?`!C h/f`N"}( wW\̦5|ddD;%*q큍H2Kc4FI-^Úkoog.Hh{wn&ٰvuuP(p21(X__;UWYYR Ä~|ll1D@"b(:N2SSSi)insEpD˜h"Rw/+b8&''yD,5"< K}2;+%ֶY…4.Ц~pU ʭ&q s5H&'\tf Ԓ_6E7iC. 2IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-java-archive.png000066400000000000000000000030521237252063700323310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lUϜn[XhKi D( &(#I BFBjAQ o@/J/`YBms;gϙÌt0!s:FplЗ/<$s]\Ims_v\5ܗ˾*`hVRƹxS٩oذuΈ20Vb 0,7+r.5ԾJDx) 8IO #D - T cVWhe q;Ule/˞"1 Sb0ElSHC0؂mMȅD )' M3^Q~ aڕ$' b1I0¬V aƴI;:2 :QK[AJSi8uG? q |X!YC>S`{Z)OmKsܙS`\ڹ/s#w¶vF7_a6S`Ϩ;*|YDH a+Ric\\8k"<:H&>{$V<-zߗ\˲iUꀉru+*AbZ@%l0.}"$x^-F!e|IcytqvQԒ$ْ$$SE3I8 Kkt6͂ z)rXok@L@!n`AsH&wT@=F,iӧx 2*\I0B876w1>} T<*I uM@1kmOpev/LBfɊxO.SKs> 5u*$P>YPk3 2[5 D"!u$ĸTI1 >rjUe> AǦwƫ4b&}*l6rL/p8K>D@Uc#-Uq5+ KruՍME$8*|ZB.{ 4MV2ȥw.c|bd5rI(sUi0\e5LgAMu^Xf#ѳb%8 h\8vKّOOOKNi+`DXeaxxXd, F`-}0Q!&ϐкrֻ%%pCy'&{(IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-javascript.png000066400000000000000000000032671237252063700321470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<4IDATxڵW]L[ev?EÕWKL1;F/4ƟhLvX Å~dȘ2M6m&tP R -=Ү(ɓssysx@o6#! 5Cl j6 C0D0B(FxtD$H4 N-#O`Xi\k x3 ܇jλЪTBގ6( }}thS)7^YDBAlx+ & Fny]r% :"R099 rkM|/... C~6wa8B1猤Oi"2x$]Hr$FlaL $"I:7\9sǎ~0~9(E{QH@ϟ\EybOPNJy@OBW&%(}ywǣ᫱DJMא}ԍ̿sr9GSmM"Ѕ ?%ǃᤃ%kZQ׳@Vx\NA wY(T!wxp q~_ao m"ĕo.ݟ *$&% ́f]hiE(yAܺu!9ꉭ+a8=K"0< -8OJ~}}}0;1r"px?]PW0پszg'#b1FWWW}Ze 4_{2(fff#Z r|/Ih۷,'l$+@c9o7,Yuy_k|?~M@Y>3b',} &a2//\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-kgetlist.png000066400000000000000000000025741237252063700316270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIlUfǞfEJ %,ŤJ b\8 RTD/ZU 4%FRocیgi< vͼlٲ,@@dTv3H;1A `5)}[ν:cW$IPGA(9M/d.CįmUraw+d<N/(<׮+ <:%> QUr{[@(g7Љk/__Rb&Xΰ]#{wH`2f֐9JKZ Mtu0-tu4(Wb: ԙgmm~^ cuE z6i}x{9[ȒHX$sK'FDmN/𾦠D;M'"_mHN Z>L@&q!s|B dH;)ȻP_z^dsHA R0M,tSU!d@W'9$֗fR}} :]~P0a&P2=,Ip?on|ˤ{ Wx3NP!l"2x0L)OnXy>I.H؟eLTvF18>>^,Tv "(HKCq}~{06Õ.xV]Sx8SO߅tNXpR$d O>fFz9ЄKg?Fxn`qq@nqa]׹7"~vv藸8z[r Ԍi2r=sڇzӼ MMT.s0C42"l&''~'ٓǞ@ב܁^œx(_i Ս顡W$Ioѓg$> v<c|xh|DSSS<`ȵzR=ϯ} o `Bdsss###/&b}-Jrf'"`||`@,T534wspEC{@QND*cjhSιXE" `Bdqx^N'ۧOE}T²$2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-krita.png000066400000000000000000000027061237252063700311100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  y |!"&')2$;(R96S:7T;7W><[DAdMKkhlWTvca u|-- BךΜԣЩɬзɿ%Ӣ֨)ܵߢ྾!!⽽纺齽ﶶz'tRNS $'(+/189::;<>?F0PSIDATxmMhAߛ|y Q"DHRR)ED$GE QjE$-?^4_Mv7fH; aRR8nV]j [Xc! dc7E@*h 0 &:PMnB8Rq410 D$202t@Iu=u lr@D hBLqB@ZgH NvN-ud(`HًfxKj3t?kg#Kɡjt6^Niɟ G%zuXpLD~qr,a1? F[_U;9J|P؟:VΩݾRm0r~GZsM;6(JH>݃}7h0MQt̏XW,MMY3O|cIW[79) ߨv}vfZP?i~V+WLȕF-0`5ׇЬ{(_ڇgqSDIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-kvtml.png000066400000000000000000000016651237252063700311360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<2IDATXoG?onQG"%%Q*T$P$: Frr:8r9 D|ֳRvlNF|3߷O3A,`5 ϭB"x lH^ۈH؉CEUmvV1\p!"#)д'"jH@Sxz?ZLh'Yiu',pqNLw%G 8MbInvl5 b5T*@$^ Gp&jÈ7KpM0f//_P 0lJ_ONV\9Q] =}W7<|뷋_٩&0ySjx06 LĔP f|iڇ?@ _G=2xPy5U>d_ 68Z4Tl8(R J9LtO:Թ"T9t`FcL)#GCJ5v(1qY666X[[ZZpq&Z0XkJتCH6gΞVvff*df+t&=Bu/"w$I1VzRV_a=ha׌ғ0 /v DV\*Lj{}εoRIZT<!+0b-9(z& 7[]TIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-lha.png000066400000000000000000000034521237252063700305410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-lzma-compressed-tar.png000066400000000000000000000023611237252063700336640ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-lzop.png000066400000000000000000000030111237252063700307500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-m4.png000066400000000000000000000024531237252063700303150ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE j['tRNS $'(+/189::;<>?F llIDATxm=OAvn' /+ cޘX'`Z; BLL,+Bz޺;337 LvO2dh'}1*m61DƠ-zN"0 "e\[# !Œ'  626h++r&1TD@5ߧ9c l0 LOoz1VNE ʕjǽmUv `_ |(a:wE2(0y9o9D1;M? 6[Z _-~ @gDĆ]{"N,hF/FP ֲߤӻ0Y{ *<G` XctzhVD`ݳ1Zk75첌?~D1dR2`GDrX@x`odH`0,1F:h_IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-marble.png000066400000000000000000000034731237252063700312420ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs^tIME 2ʫxIDATxڵW[o\W23g34--/)?(!">O'*** j(MI|̹ͷl+Pfoַ屇s;73E[֣uk8~u0(JxY|΍>37sҨF^!-?@F$\<:*4(K ܺ23|=đZ"1?p.s#YdtV`Ц9ǔR ::yvjb{kZyg_#sF>ɬhR7(E# 0,+"CxhXUi3ІMJ Utgei1Sy,3\&66g}U0| bJѕƩ?NXeL};E+$VѾm:M;b8rt03H7`?>k1:;'qYqG&N- ԏrCe3«@w?->|(AoiZaoo>y*JKᜎiƅOcܺ{oEZ_ifSa\)ϝ/րp9`%h',S%Vsb}c, (~}xwHzj3jtk/-XTي2ۡ0 |v8v`iO='Ծڀ+SkH#i2 ȲK@g2 a?Q(5,׳¸Y~7ԇã F@^J+ihnc*3xf+ [Na jIZkW}kw+pJ@! Y-vA"KlDb#1t93+WcpA$I0Ќ|hcpkx?AIWjǃw  Y2ҮvtRBbիB\ku:Iq؟a L^qY⥫u -E]Z`sˠ,`&9=tݐj1j`&D G4BVʬ@ ӧ$NKP y9d ˀ+:|X 7xb`^ qasW" :-i -NdR)RF{}V1ƏZEYdskrǎLkE٪B(o,W#팩}Uޯ4( iK0rXxjtL'S,*<}"y m7 `Z͐g*/ .JԬATC(A':@,QzVqU)A~`f  i B8׮'3%EQ" Y2~F7߼K)rb v3tbr4dRG'N@b?鏿[ogӴv/?켾;K +ĊIGIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-mimearchive.png000066400000000000000000000025771237252063700322750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[OcU(--V.R:*L)d$18Nݿ$dˋјh(a LePti-\keX;!}ioΠp-6jF?Qz%eAuMMM}5222 QSS^=Vwvv}J߀u:/kIItuuuU|rp+W$̫%=\*VM Z5) 2{ k(W$J'eΤNailthxa28mb#"B ߎ@{hS|烞+ܡJG5$1vFd*`aMFf7?b7Gww^|Wrpv/oXNn$pr9= L8 Վ&\cv,.a*cjV`N~D9vy`2Cvqzz*-F@ss s` |Mq(q-m#k?*J|*q4=2V&ĊHf]EjǴ]'''dچWF# l!DpZ:E6Ϫ&*(|N~l4d"x(kK1Ykl\<צ@):QR;)%&<`<&UBff^d2<*8ߖ9UD{: 6^dBň{K%y "U?|w? JDMp ]EXTפvUd2u_p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-ms-dos-executable.png000066400000000000000000000034771237252063700333250ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڽW[LW] rQ40[Q.j,MLmSkڠ1B,1Р!M+}H<Tj@E~_a]}ZVVࠠ Yȉ'9r*AѣGvҒW^d|R:::zoݺu~|| SAyyyi`g~3g^ ^gn߾0 xřB:ccct:\JJJ4١={) Ru΍7ZEnA@|Gd6677O .8BƱ$--BZT/զԡ!m.22RygG`0 իWAӃ58>-˗/' x?33#r޽d,aaa?ԔhZC!!! m>44Ty5559bp\9Ñn/^ 0{@ɽ_Zvm$(%da !jdՑ/hRR {4|rwqq u1=a:ŋA{ccc@ 3,K*Uԓ= `Hi)Z~oKKKOˆeXe bTpx)m z`$AytAn Ufxݺk~qe W@z8*:Δw|Ϋ1?ϑr'tHwxt;Ζ$;+[,f{J7Jzzթ 6LMfW]& '1YԴV'y ---K zAay+7(nd _<ˈ{z,P5q9Ώ~,A4a@Җː![U^:Lឌ܆YF 7w:?jS<[r`//v'8mȒ:'L&Y^R8$ yGpVbav^Sm䂐f|&cGwE"$GyJHkBI"333_&z$uME'.̓42@Fl{\l߸pJ*`%30*&oM(p% Qc 6.K&nܺv¸pE\*+BhPKj1-t3};=m[nHgνϽ4 8xYט2q}gWų[[ɭVmF99sM?n>P[ bW`WvW9-n|<Q8'Nh@ѯ#^#Z" SEN m{n T<+r 5fZ\Z8lͤellly@X*c ;A[- 600q9cc4^ <^ 73gзo3Ȉ)[048J%2^pLY]>@&ZT[ %ӵ5%ðer#3Wz8/H U(;o#?='0-UN7%𢧧GeX,Z hoG>KMma:uo!r8|>E0.Hf (EV+ Q`6j4hzco.1'O}eqvBh5/0niqu K?"5%hD&T:* ɴ.H9ù>8Zb{R`Z۶@2Rp)_yggS /bҰdݲxaԥz\0qeaEXlEd2DAբ4Cxc%F ʾ'>( ttt3NЖs%n o/!u0H 300Nt&x,UOpvT*EZX^ghTx__2;nHT*;4^`TEfZC{Ŀگ!B}NMM5!!~<񺺺 Q"```j!d7m$"(WL?>8r(A.luѶ nώ@;1芁۷n1C} 2@Vxo獙L&J6eYE >y1Gܐञer>Yc8}>뤣Jlyf/ GA?x}ҮZkzz)qx3].7Ok*8.^s1Y`ֺxl/+++i,{ٳg0'k{20;;ˬXםL4d<' >388NG5C[N`:5]&( *KEO.B4_4ऐbM 'jitk5oH$ur<2("P!dU f,[_޿t+V$ Moq<-;VL FlC#96>Z4+$\A$o$]s $T9Y,ɇ&7eL$ cH "N$ fuǩt!.̓Y8tFT~R>F]*Ӹm:tGGaqIsss p2(eq?Вe 1zLK T(a. yWl!e\毞>-,4[[_]PyRǛ#܏~8pf;6K#%;P~mXs"WjDc8K5u|ɑ ]zHOktQUI9:.ģ$5 /' xk1&./ ǒJzGhaG]c f$JQ!qPht_Ld`(*dN[涺}Nf _͑$")^"DK{IMyrR(rИ߶o=vuLivSFWjW$)q-0w MFrUXwN:i6 T*nPTJ\AvAnjA,ɲP WtDT#hO}GX':\Ok{hw*yոs"C-t(2_q3:Aw  զ -xۈ5kft6.h%89mv=QYM)O) ĐrU{5qIp-rth}޹~2Ȇ5b6V1BσYޜ>Y$a<:YϥOrW`44oqt򍬐v\K䂝 nR45Nt6dj%xir\#YFT%4J}J+c)VZ0{\cx1 09 lf+@Ym9-; X}Dn ?p܅XY`{|oĂ2r[C= p;鸣]os0Cj0!U8}u  jnԎ OH/ $9/@ƳFc-qkRa>;?5ŽV9>r;s\Pj"mE;9A^5 o[v +{4p$K.ek<ۭBL)=\BS e%+ch %`k\^_^-YU?51!YI3OY@ŝVuސ2i`|&씍.C/n dNiyL=z<,`!/hƀ̓we p;o- =aSovgCZfʋ겺RmT wd5o|$S+S@>Jm`-锁X`4Ӂ xt~ odsTjn0/Bnx>*N(7hYNxL 0X @ P2PmA3OYHWH{ _YI߫8k5i]`IvN[ԢAeXSDsbUicMB})`+2 p3O2RN6TӠz"OZH5#wcQՠC!BZ 2OWɛ _-1'i$?{-z1 lT0/lw*|^^_*Cb7WWW-epux40bE%$~M [aW¡5/Ν/n:֟ }B8>ѐ0ʔsASMKUb?5>hVsüd^7 xy3JJ$=]#fvR2 ( MA2\ݨOm`)> *r2k8T n8G-^<ɷ Ǭ5E% ra!GYE} FL>O0_=-WǸFHOȃǯ\ )CFO}V g$QRS~}F8 xP)Vj0v)AEoB6{{YĭR!uQ ;vG[ֲ#w8woAU'W\=;yylpdpTp;;u!/Khc/_a38cqf+2;7;C[؁]ѡ3;B}<*/yG5<f;3Y9191`W3J/]R977a*[fmk̼s~/}f"g̊+dsa{}M>lAJ S]NrOCgrArH$U M ID⌍o1f@ ɜ_>}P63 JrEA.:s;QE*,h]ƢoR^ZrCƽ5nָ6`^eSwݲX 6*^A/Y`ͷ w׃wa86^ Tҙ=ܱ uE"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-object.png000066400000000000000000000114451237252063700312440ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZ b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-pem-key.png000066400000000000000000000036351237252063700313470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-perl.png000066400000000000000000000032221237252063700307320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoTUs93s˔NoR,J "(`c|??D /UӖr)- mgڹ3=ǽLw2t$JV>gﳾo}{}񸮋62+M0ǭ\6ܧcu`I\:~@Y^Yn[0£_fU|>a<@lƲkbTde^/f(UjDc1zi>߶̿i@< 3֞Jm7 Cg9=N4&2Pl<@LdZJmm]]rL"'T#H$O4=(0XKuFa> )v3E\˥,H\WKvͦ9we*`S\dj4Mȭh۶M~~٫(8+ ѻk6bQ@@ZZ|10`PL7%8n7I& تZr1"&49 cC*~{o t>DAhFT\PAZöʨLv f(Fa)`;!LuN0 ;LGjHi̝eY 9VsYS]dg<`;u g$++Qf#A)k5*wyU6y ^AeX` yYY.9,#3 'K$UidQDU /Q(Ufwos7D#AJ1>~#'lP]|+J ")@)R@P6k2Sw)V-NN߲^ff(iAfbJX`r'hBξƶ-^, Co@^?6Uaf:Kn.G.p&ƯI7W; +%uE@ p-A>9mmz@ |\ڡ?DDjH[2wdj[W@I^J!3J(dQ:%OLɖ\pѻ^a-~9~TWS!*`cXt!Xgߖ_ <(R͏#q Ɉ =t:#}k\LWX\` <4*6dn^a`װGKHuݹs0 [CRZ^ (eqҖ~]BNΎ sـݩӧO dULk;tvW? $䒱|?E%ógd2O4d$gBYzʈr" 昞Ν?0+ &-n2-hDEŋ(ո-e[\\ ]yϞ={FM7ښcccm\ m-5ƶifx;@yEܝfTmq ^XfO* *z>i?`[th8a7IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-php.png000066400000000000000000000034251237252063700305640ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWilTUf{3әδ{-K R@ق R, hܐDYpCM, iefZ>Ng:73K Ϩ9ᄍ~Y9L&Et$G,QU C }HTu7Tbe^2R)L& ^EYdW 6/z=Ӗf"hD2D~^B0V+~X<C͆4yf# !77yo,A)ݤe7"''' ,tg`T Me P$X$=HYG^{צNʮN@ǪF)D"q X4.Ͱ Ph ʱ0(v(FtubAd2Dco` )őWhBsCxG#"q#J(-wBov)U6━j?Z\cn6(2*<Oc=s8M}Qt2 a%eD45a+}鬒@h8ǐ/GVFOOz=3&Osg@e/]ƸD ߠiDEy%^ LN[~/a%l۵ rBlߺW;/nƎW/Ag+=m z{fmIx5J0z:0YGl_9n鳿@{^:-F}ttqՌu oM?`Gcښ}r PBo0|!{ByDHRϢfCwO;[QHDŸY0 ˹9G4"{A^)RW{\T^$Lp@Ņ gOJ`9t5ݴuKv"%vcv~!7&Vż+,AqX I[6K!BLm'hi=J,^@lpkd,mБ[ JFz0MS)~TW E:Q"@`؋X)6}ohYS lH0Is ߜ:jB)$R}m;v = DbmhllW_A]ԆUّc bXJ?zQ;^*@xn*F=8u bg?ؐxze9U0`T=l\+W.M"0r|r[]hX&(Ƹ-YՅ^3Z[mmm^J?f͈AʤT~R swwQE \iӲ.Y94 ۰ah]\)r<0{JQfn~c(L"Pp802;}Y;-˗?*ͣ4_H$&NS '(krN:HHvSv"]DN~OBUHd >6_ϹF썇IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-plasma.png000066400000000000000000000117141237252063700312520ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X)IDATx͙ pTU}f& $B"8e4N#ACM)( Ű( 8Ą%aIط N~j*/53T}U}~?A-<ܯ~0kVhSeKj2detHh2B 1L/J# #!Q| 3J 2CDޤ@DN򆈼D@@DEˠ"!"݇j<"$Q1KbyMަ|~Ee^W 9㧿S=\r磝t/M٧yA-M4, X=hbWXޕNҝNoFH[f\pc*] IR/IvOY//~6" l}sup7+|qiu"NeRgKXZ +`W X$= ztL3D{ GW7 yROu@EzD|S9lǢ%w (`N N%o~yum Up+fs},켫ߡs $߷ %.lB+1>gZ۰_;&_dB;#u{ckK!fb:`1̶k=+$A؞u^O]]/#hG]]_Y+;Ŵ7ŠQb:喝"fSv"uiFo\yͶD[> xl8.{/~Rƭ ,jHoeb3!iֆE  jDA!˔̺]nRjڄI֒[8hnfDԐR rKPZ~^Q={F"SfՌv? ~5;"q">>=.O<}2Μ2q}d=FybחB$?v \p=HwcՌj$"`8V^9b:ډTF,r]Z(c} ~jL iw\rI`4[tq?6):8?a[%eUhv] f C -zM\k<^zrCw^,7Uqӭ)q?&EA֙SDdXڅ|A;vru"]mkpg_+0}ƚLU/^_NxmH~J~wJS2+~=B\KAWIט/t¡Ֆ_GMY-w1Qڢt >/#)fKMq?UԂ}M F?;>~fk4rHiLX=« ||Lo"b/l3*w|( ?ڪOA>܋4oq_u'Oep@@mxԓ ǵ6vu*zPrX.a] {p8?K i3FٕFΦ׵F .U6#}nihߠWŦ>9^/a)θ|M ]5`j]Bցo+"ggt0fܿb)'2H1чӧ`gP.W+d,k'l0K@!F!4f"RE q9wvD93OEG[3MGG/JM^۸ZAGMcԟe#~ o?uȞv{dgD{!S"DF|(˨v+S~R-"Uv iZ(Jr }%>w_C)SP-EMϻWh䏻sawn pm_(⾁na)`ޗ"V`&s_(DJFbuCyi< !oy oDYz"»`j ILz$8NmקXM9[c䝸ȬK,N]C1|&Z8J vaH~ &e\ѮCGR5͝6֪Տh-vi4~~~TY[צ.`yr6D M sO31eBi/@za*`(!uC{?;-n>s vSkGE `2ֵK<|/z-tDg;fT$Ǻ?uw2]>'JrѦM\߆f{kk,PM:9:^ٝ x򆈵xT! ȸ^}"m9W(J RnyHQ^U^p=LAqloQ]~} 4jh'|S \MYytZK/_ͫʳ5z4'*':'6jQsS)1&\+4?<-slK#y֩8Νhg4ϖ} B' qers5V)SrEι|6v*To{()K~Oq'Ź=|lҵQ%s5L,6; ߙblbbGlDttss$P.B`R tu:TN^ILUCaZq^+[4Zs7.r~'mK.<_w+EC XiBLP%;oDFQǨ]>w8MGB`4vH6즞Q[;]>>CQ@ _"Knn__F{zڥfv}6Kz(PqE3Wd.Ͼx,8Xcl3SZioPWg 588pv; y"PH&VwFH*BUM{U_U-MHXfZfX89|.3ygQgpvµ{'t{zBO Dt4Ǿ~&[/7p%_9ǔpW+y!!T}K{Q5^B}!\±JN5e[xo3Rdraqۛ<6O8yd0Oyw!2$][n~+:`1׍q#Z x6C>&b`!;GBxqyZQ#N_z{[6s~bn@npnG76lh}/m?N<ƴBџk/g rM'55:e֛a}"5k׌Ѭ"  ]Qw *Mh"*DBvX!i"f" %sBlL;/W۶vv^ZaզUL˝@og! lS_Yܘ%DR o^!yWd 3? C') ~M$"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-python-bytecode.png000066400000000000000000000114451237252063700331130ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZ@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-rpm.png000066400000000000000000000030671237252063700305750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lUΜn[b)ZlU|@DH$%45B">hbPmPPnQFMBJt\ϙ vh*2! p(p!(#×(]3UMٖW}t$l,q,v"4 Plvz'>qE;u<ՕdA6ڦ][Y2x|6_u[b(roYcCFuzdL8v>^ LA#)ʉ SOWghP@rH2lہx!R1qP(,]U|oZfru17{1s kѼ\D<k$VﻅR5MG\T ?" +Kȍi |Qgbr 6&q3 3y苦?fSHP fD  㚚,@SLmcf)/=ut0{o򦅙Y ã&{°cIS0=[/ |u,5% 7Ef k/=%ƱdM(IVXY >pXu*l:$M]GP@ `L̠r"E| =a]Š Y"eDM[ Tt,[4C#6X2O*Q,ۊΝGuH.C7I$"pfl vP_lіe6ᅕKBt?NdY|(t啋Ey2K.C:Mv\ih_ӆIi3g7t]/#eb\܈D33Al`?zu]6:2*m)8 *'+h6<ʦ"S h<~iwׄƼk% H%GDE1I LnCL.&JB\mt_wNxYbq "(N[.l`YT>R\LxȽ ,& PN1z0 $X O(:G"%#vWpVCfqC AbA98dL&!קyA|x 0j-Gx D>EytIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-ruby.png000066400000000000000000000032621237252063700307550ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org</IDATxڵKlW~ǞW'f E@ JtB*HD.j) $*!eE!PgA$13wΗL<3̱swZsh 4tMK؅s< מѠH <~r= Î"! }{qrv? #(ƒ H ǒOtElggfU: "zȏ靍;I H!ccc?`tt*ri=WBJz}H%tK.Y^^&,]eownZ8F nhj4 0c Fq<@\?33c=@$FCZb_d]dq|6*u ^|/ #XrTɷOZm-jwi`۪p_Nvb"ՆynJj06en]\$\\8حq?q'Ȅ5y#O( ɡ6w{@v4yƍ?ˆ$qʄXJ\&吮 zכd <63FyyVPg9Y*xؐ%&C m~!Gs8 :BaS ʽ |"{us<6) 8G'~) # Ƿ-4^2DF4lw``+6DkdV굗)}uf&7K&V$9B#IpjLg_tJDbNm }x! YI$$v"q@DHBW,JNX'u6|bF*y%Ye0ȳVBDJAmD06IccQ {ShxH5FzgbX%4u#]{n̙erD{>29Z,P|ѳ%K4;adsk@t:ߧy.ĵ8v_0X/Rhm3ޯVVa>Qn߾yҥ瀲z[LV jffT.lpid7uW e`} mR.陞.۝!"0X,tZ+jaaaʕ+_nVPkRf~hm5677nF^1w^zls8gΜM=Zv8mlmmز_|ZPgi8^z=msfgg 27N4Ly昕0NJi !!p|W@Lg+=Cчlb_*@d>csPpIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-sharedlib.png000066400000000000000000000114451237252063700317330ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZZO4R& ɢڐ a{Ff3J{{~~CN!S? ҀSBi??C)@9L%*?N@YVasX !E9#1K"5bvc (xUJRP{Bq"@WǏ199\EdrFn}d{‚fvR|jj Lpxx8L1uy\#c|k/~ p}4&zZ6Ȁ+WK899JB$ w9 Q86ӹc`qm[rW *h4p̾7oc>˨=qnPf#Q> h<(sدSgRW˗~9\'D㽽=0~@;ݝ5?.Bxe_C? ^w]_ؑ@dg]@ +OO6 FqgW@mǯ ߗwS{aTĄ|lszȃA ~B7j? P0wapZa||VJemnn-4x#.ȍr[r~{/k fff/T8(}BZ .-*Iۿ]`&¢QȧEWҮXdYسlPB𽈯h:T$)GInC/J;VP1٩T*/D| Ni aGXnK.&L?<3 IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-shockwave-flash.png000066400000000000000000000027751237252063700330710ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-siag.png000066400000000000000000000107501237252063700307170ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-tarz.png000066400000000000000000000034521237252063700307550ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-tgif.png000066400000000000000000000025171237252063700307270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoEǿÎc;8v'o F E IR!P)\ʿ7np+AP )@HB4Mm8u굳kv6YkD꓾z3~޼7?6eY7Idrj&1MI}B.NJ< lH:Tp ؾwou;"HӶܑ($ n@7j#Y pý l4ؖHFyjaT+y=3 /˼q^<~}Ýw]Lm 5TUa304k ;{EA $!53muy b |`p4V̾w-?$)8nؾU$AK!Sŝ_^6Vk(K{k-!Rm- T:c1ʈri_(ݰmyH JVt]g W J$S!8{،cF_ZwrS]5Ryj?lArK `Dk%t=}NL؋ %2@X G˸t'pn;HБQ![D7ÕBzh;s%x>& fnZT=^p/L5'-|_.׫w'C8J_ZuRn `BMY&ƭk%}|ϟM#oMp wmؑ2 7ߑgc(~b2=xL-7~/Uq\]E؁{8 &3`;~ݖzhl4svXXX:+LloUU H B|E",MMM ǾeF+oy ^{?`XiXhj\4 l? CI-89ՎSڝg6s,7QTX L:ER"qo3ܞX ڢ Niߜycgg o~ f,g9\&C%`Ҿ499*oCGYH ٻn-//_%iK>pS\?3H$C>Y%xeIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-trash.png000066400000000000000000000032641237252063700311170ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<1IDATxڭWklTEnmKKxqQSi 4(1@SLԘQ!#"򐠩6AK)hv˾ ۭp._gf2wΜs^0 ( #ɚqN1'3!ެ{ 16f-,~ml. w}4K 0 AVZ$8%$4JsI.CoG hsG,!ITLI؏,XT%x"吞+9^3R`6%`{y9Q阇4!F`S<^D60]3_AEb\noX>4 X WwU#~o$$9XbkZ\x~NT3Nt%TaQV ^t KIE&cisWh~|ux~S&a7P?bFb#I# 1Jad26 a-C-n1.`")Bf)ȕb`_ kyN1ҝB0Bj-8/RNBR Ŧw7w̚]p/!dya+Q{Zf2b8ObuMCeNXF LJՠ>Y':ӹJ EvGȷR40B]?V5(s?~F9KȱH2g4Z@wϕTg !w%}uB$"z ǺjqxC_/{A4S RkI; ΅{t[[8i6 hKtLQYbF{kD)_bŒ@(/B{OƊHFKbx?'/_S4Cwc`xlB<~/.8J<"X ETD:Eb0bCE린)("n6^^i6NI2PCF:uS'cp؃ˮoWPV<"k$J]$\qtBA\r5Wo[vH" M M7=W"omQw<-UXl yדk9fܯYm Gط*ݾ<xf_GOnx<=sm3L)t-~ IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-troff-man.png000066400000000000000000000022161237252063700316630ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org< IDATxڵWMkF=Hm^^RPmV!t -$RJVǦPڟMdh.J_ea*  ιgxd( Q,Ϙ5HLD;~N,#96?IM&pǶY)ҵVi1("X?GQiQʜjR}p%0,CRh0djQXxq` PPm5ڠ<` 4 1  " z@]h"d_t^I$`dB%+x>Vx' K*dUSڊ 8B>Hha hǞ(`)"X"Pل.Q@ Cw -7B` lL¹eD zbLhs ,yxԌ@i1H d*7z ;'BSibR.!Qbh4nN8C\vn瀐d6QpKzP>?)azfc{{xa ],s>( |" NȒWx>c4o6xxxȫxH))JHW&3~NGd+B=yY{u||| ]ل3a$,2L!ߜ.$5; dk& A2 ! }QJ)熀*oLp_{xA{qY҄?uhyqIw+ּ9Z>e?3+Yzzz_ *Q\^^KT7v{#xIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-tzo.png000066400000000000000000000034521237252063700306110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-wmf.png000066400000000000000000000020511237252063700305600ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-zerosize.png000066400000000000000000000013641237252063700316470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<qIDATxڵAo1zCО{(!Nmo (BFTv3V&kE"dɌ1e@z+g4ߤ?݃Z>EYal?<o$a #(EYaNJ9wk--=DI cE4־ Dv{j{ouR[Pʲ>1#AYZ\.nj0Nǽ^? w,O}aX``>c4T+07)ЪnFfikLS#b8~? >6>3 sOh 8q۽㩝׍\)?"};ΧL&/`_R#x{ysKxLkfIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-x-zoo.png000066400000000000000000000034521237252063700306040ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-xhtml+xml.png000066400000000000000000000026651237252063700314650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<2IDATxڵoe9lwm#RP%FJ4"^(M^y\z?`4zxgT6RGj[3;ϯN44Ml{;;]]A _j׀Z1B*H/#+J^%B .FGC4+@7Pñl% SUC(+<Q~=&(bD̥V$sN Y$q~1Cͷ@P`pb{E M:Yc'%Q "G!%_z,3ZuIk%lWxIt];'~D|zǛ%wl3y*/mh斘)V5%E//Y=h: ʷsܓ'UIᦆ,K+L_x۟8 'џտ&f)v~,V.ZU.B7ks'|j]%N@h]F,M N[‘/*P@R.0ٹ#JW8G+_A/I MRoE[0xL&er1rBa _BhR))"/j_zO7T0-d*cEee~v&/@8L73ynu ye٢eu)Kᬦ0\ݣ,yGɼւ"PYҝm}A͍9~.VRRpbL >CSen]r|l*Wn8nG+P{ juf[xSs;f Tg=\G` iqg>g_* ꃪ#'s@C(i7,yLoFZS-7+ʱZWyL<B<2kV>2@lBiYy79™へ G6ǥ4s!||!jk2xf uV}4DBR4m'B Ds8@,[e"B ٚK3Ty277,\.NS/@<5{wʃMbjj62OH`lԂD0@B r1M3{WBƆ!%> [qi|gg{KKK M۶Wq~M|9OFrN: +_@A%  iX 8}E`B$.0aƫlf'O 4'GJIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-xml.png000066400000000000000000000021661237252063700303310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵVMlD}{IDZ*B@" !Ís{ʱ-QAphZHYIXdƛ5ifǣ}kG))TQ6nz?oט+AQ g}nNJ Yp]RE3mm@Ïa'bBhsŝG^>fGcM#}l&#nžnINT${4` H3My%`q)eP|qg%wvs-b-L̼l]a{30 rі4 8^g݄܆8vH]"<e[ \Ft{@3 PBx}hl; J=@Jxy0" Ϟ@(_xSOJ`_"0<9C%NC\opЁ)8;֍w.} !_; xg!8҅3`hQ**YxGhC8x_G`g[6::i-$v2^rWxqZXXKoC(f3ljXJVY.O?(b܎׺iIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-xsd.png000066400000000000000000000033731237252063700303300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<xIDATxڵ[lgw9ilYuk-kGĶT-J׍ .Av*'1 i&RGiLӒl9:cI68vbr2+[i{?!RB hW>eׁ8B@Vi 0%ǶADe{Q%4@*pN$> .U *PuMqXo`. Qk-Hj\ZV|u E7.x{LNtnᏑLn\)^넦 `rmUǙLsd7h0igo>$5v}a'jDWq睭>ϗ\>ywخON#>yB0uORR35Ube񱱱3g|yaaX\)^ WRʕ Dʶ>}eBx=(J{zzN+;_@iH)ke^qLӔǎ0,Up@ p?  8z<`mU9_$ kIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-xslt+xml.png000066400000000000000000000033731237252063700313200ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<xIDATxڵ[lgw9ilYuk-kGĶT-J׍ .Av*'1 i&RGiLӒl9:cI68vbr2+[i{?!RB hW>eׁ8B@Vi 0%ǶADe{Q%4@*pN$> .U *PuMqXo`. Qk-Hj\ZV|u E7.x{LNtnᏑLn\)^넦 `rmUǙLsd7h0igo>$5v}a'jDWq睭>ϗ\>ywخON#>yB0uORR35Ube񱱱3g|yaaX\)^ WRʕ Dʶ>}eBx=(J{zzN+;_@iH)ke^qLӔǎ0,Up@ p?  8z<`mU9_$ kIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/application-zip.png000066400000000000000000000034521237252063700303320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-aac.png000066400000000000000000000027151237252063700270530ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-ac3.png000066400000000000000000000024711237252063700267740ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE  rx"')-:#@?F678IDATxeAk@즻jk(-z&?xxś?SPҳ/wVA(JvtwIf٤N7Bx_2! cH]d=%)@^YN@5R Q@ V'(e= sDq&v8} Q@!PK@?<B=H@@#( *y0v׀n1yboUt(RrnOAYnP]_u8& `]$Gq=9Y|mȈ3֬|3Hsۄ˂fY ZV,wW&2I/<nq2h7s$qu7ı 6u9ݷ/ QZsUӸTVNwcMD Ơgf]u{}; |4c~Ba PD9&/ʦ'nIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-basic.png000066400000000000000000000027151237252063700274100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-midi.png000066400000000000000000000023761237252063700272540ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<{IDATxڵWMoU=36hD I$]d(B ! EeEfb nPDQJ"S$ 3v7s޽۶!PYv )Hrc!?&o+/Y@Y(I=+EG 8ї~BhO.&)| wvMe[dkPpқN5]sv~_uK߿g^DL;0 |< rY+H$9_ ",򽆗nìp{( N_3z`}Y/UջR&x:^p8 > `Iʦn# #,Qř~>6,`nn+++F*X,5LNN"NcbbΉ8]~}}|NPh2>ݸ"y4׊<2E@V*'zMm̓D#i^i߿ #@2p81k2̌L&8HU 9b(777Q՜:#ν.}A*eeHprr#iox /m3f% 3CP(w޸'Imii}1wWWtwI03$)B|RGAn ."f& 5sLz@lF~j܄<\,6Dc'gggz7_CRXs*"9$OAIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-mp4.png000066400000000000000000000027151237252063700270270ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-mpeg.png000066400000000000000000000027151237252063700272570ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-prs.sid.png000066400000000000000000000023761237252063700277140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<{IDATxڵWMoU=36hD I$]d(B ! EeEfb nPDQJ"S$ 3v7s޽۶!PYv )Hrc!?&o+/Y@Y(I=+EG 8ї~BhO.&)| wvMe[dkPpқN5]sv~_uK߿g^DL;0 |< rY+H$9_ ",򽆗nìp{( N_3z`}Y/UջR&x:^p8 > `Iʦn# #,Qř~>6,`nn+++F*X,5LNN"NcbbΉ8]~}}|NPh2>ݸ"y4׊<2E@V*'zMm̓D#i^i߿ #@2p81k2̌L&8HU 9b(777Q՜:#ν.}A*eeHprr#iox /m3f% 3CP(w޸'Imii}1wWWtwI03$)B|RGAn ."f& 5sLz@lF~j܄<\,6Dc'gggz7_CRXs*"9$OAIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-vnd.rn-realaudio.png000066400000000000000000000027151237252063700314770ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-vnd.rn-realvideo.png000066400000000000000000000027751237252063700315120ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-adpcm.png000066400000000000000000000125701237252063700276600ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-aiff.png000066400000000000000000000125701237252063700275010ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-flac+ogg.png000066400000000000000000000027151237252063700302510ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-flac.png000066400000000000000000000027641237252063700275050ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k [ {    !"$&'%() )*!-"."."/#3166848!9">;?@3EEIDLELEP>P&RRSLTHUNVAWIW'Z0^N_U`Wg\nnoaoUqksTwcwfxdxb{W}ikjƊwɐ˒ϦϾչా׻{v'tRNS $'(+/189::;<>?F67`IDATxeMkQsLL,IR!VeqB.ܸp%#HK.nqѪP+*R*Kivd3;;p/s /K`%HrwbY`DPC_ݐ;=B&LR+ҹbs@) !L0c\( RR\QݑrhJd`rtZv%J3}iY7tɗ }P0 D@hazAz7ՠqRq`ps}cgϺ"{q3chV֊bZ}8ZCor aL)* RO1 'ڙL@de̒ wb Ѕ^ GZk= jw5dz=_!1v2&Sfk,zk4ޘg \#]KX)7WqTü1_33?Gf~x%JP6;Q$=7L-SxFBnC* e@FS{uI~)}8~z9^JNGW\]m1SFWz\RX x$%H< laX^xFi:0N/Xb(IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-generic.png000066400000000000000000000027151237252063700302100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-matroska.png000066400000000000000000000027151237252063700304150ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-mod.png000066400000000000000000000027151237252063700273530ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-monkey.png000066400000000000000000000027641237252063700301020ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k [ {    !"$&'%() )*!-"."."/#3166848!9">;?@3EEIDLELEP>P&RRSLTHUNVAWIW'Z0^N_U`Wg\nnoaoUqksTwcwfxdxb{W}ikjƊwɐ˒ϦϾչా׻{v'tRNS $'(+/189::;<>?F67`IDATxeMkQsLL,IR!VeqB.ܸp%#HK.nqѪP+*R*Kivd3;;p/s /K`%HrwbY`DPC_ݐ;=B&LR+ҹbs@) !L0c\( RR\QݑrhJd`rtZv%J3}iY7tɗ }P0 D@hazAz7ՠqRq`ps}cgϺ"{q3chV֊bZ}8ZCor aL)* RO1 'ڙL@de̒ wb Ѕ^ GZk= jw5dz=_!1v2&Sfk,zk4ޘg \#]KX)7WqTü1_33?Gf~x%JP6;Q$=7L-SxFBnC* e@FS{uI~)}8~z9^JNGW\]m1SFWz\RX x$%H< laX^xFi:0N/Xb(IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-mp2.png000066400000000000000000000027151237252063700272720ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-mpegurl.png000066400000000000000000000027151237252063700302470ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-ms-asx.png000066400000000000000000000027151237252063700300040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-ms-wma.png000066400000000000000000000027151237252063700277750ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-musepack.png000066400000000000000000000027151237252063700304040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-pn-realaudio-plugin.png000066400000000000000000000027151237252063700324500ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-scpls.png000066400000000000000000000027151237252063700277200ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-speex+ogg.png000066400000000000000000000027721237252063700304730ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE   !# $!!%%%&##&&&'''(((***+++---/,,///111444665666888999<::<<<@@@AAAGEEGGGHHHJGGLLKMMMOOOSQQTRRTTTVTTVVVWWWXYWYWWZZZ[\Z]]\]]]]^\__^``^baabbbecceeeggghigiiikkkmmmooopqpqppsrrssstutvwwwwwxxwyyyzzyz{y{{{"'tRNS $'(+/189::;<>?F67WIDATxeMhA{3IK,m F EHA֋7ҫ^{= jA/E{hA"P$iiuwٝq߬ɦ,7${h!nBWؗ$AD&Syǡ(R 9: "!W zz݁Y`rz_$2.H} hn%=Fd`" W+9?x vyV !ܣ\}8'/]: xpi,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/audio-x-wav.png000066400000000000000000000125701237252063700273710ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/encrypted.png000066400000000000000000000036351237252063700272270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-bmp.png000066400000000000000000000030321237252063700270570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-cgm.png000066400000000000000000000030321237252063700270470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-fax-g3.png000066400000000000000000000030321237252063700273660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-gif.png000066400000000000000000000030321237252063700270460ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-jp2.png000066400000000000000000000030321237252063700267740ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-jpeg.png000066400000000000000000000030321237252063700272260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-png.png000066400000000000000000000030321237252063700270650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-svg+xml-compressed.png000066400000000000000000000033651237252063700320470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<rIDATxڵ[le3ve)[l)\M(>@Л&M4/&F}%>hb|0'1x kmD (x[vCtw;;lu%(8K?fiz @چp;K*yp@‚D"{ Y2jn1y @T dP305 0 1gbFX&@6V(I^*?]6_y,6z)U)? UwP砃Cj_FqjbK}x pp2?w):NM7I9uP˷pt ^Ug# Rncp n2/&UGT 1xS(j*y< .1d{jˎjjY0"_eY3&bpb[+03 +-@Ym1Ԕ2dB@ITw@7a4%<ĺ7[l`:wNĭf)E!h&)ęlEw{Xhd: a /U̶Lґ`A2WdYo}UU!6HC X_~MAtҾ\|*r!U01{/ޅG[X]AX_WG, j>=WT@.L&(xvv<N Gޫi*P)A<pQA0 ;ذvA ؽњa&f5S$Pdm-} a$Krq&'Τ:S2ӥiXJAa{ /) l*F&,)<MՐJWJw)X(0;?g|cc~ d29-RvZ R:$`*/$A$XtɳFa.Q$n< "gPqLЪ#@_c{ SMQQkY) 0>?qmrAT Qp08xGĥKhZ^gGO%j,-926)lH܄Eub+-j#>S(z΍j_-͈S>a۾fԤvڭ^$.Z*Af݃ŕKW\15^Cwũ)۷o/!ư·8јfnOeU 32";p~:z-~ хJH4l{Dv'1@o% ,ge}4[D'*|VbEk K¸>4Q`>:6:IoA x*t6tҘ̢d vlڎ@؎logftvu`t%X?$Rg&OO*0i\_œߤ'A},IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-svg+xml.png000066400000000000000000000024251237252063700277010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkUMd7IS$MIV*Q0DDՊՋ" *^^"XA EV`mmvn23;,'CFox93}K)E(+`&TpoL @Z`q$VhW' eLlCÃY`- W8n%E1 nUuD`ik 1V1%qZ&\t-ׄm*1%-(ݨ02k5l{mYe 7 ?prq!ㇳxkx+A>Y䇙[tibc 6 pQ_>8=G>( FGQeNg|ze9}ُm7{!Am|tZ.~>6R6҉mK:r] /@+V=%T0xtK'Y&'mKs%[k)*_ !Q8oPR1HO&fO^wo=MFE7Wʮ~6#_h?'m$[^.?Wꏚ' \;-$6{ n-;haS2f.ҝ !r[jY}0]-4ܨ='m׻7Pq=ikbpT5sIP R*t `Ξ4F/Knšry^Z@tx+KRຮ8b0$, lct)?,c1q hZpȵࣨag,υ OskHb0kQsi%‚>>R[[Q /wHeŕn1eIC.1<Lp'K-ڻݯtѻY8 e˫ߡT;zKBA/AKK KGy.r&/4:H.ӵ=[,/a kݫ OPJ0@%cAF ^*L S)s@l`3RH "sO p<mSOIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-tiff.png000066400000000000000000000030321237252063700272310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-applix-graphics.png000066400000000000000000000030321237252063700316410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-dcraw.png000066400000000000000000000030321237252063700276460ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-dds.png000066400000000000000000000030321237252063700273200ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-eps.png000066400000000000000000000024251237252063700273420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkUMd7IS$MIV*Q0DDՊՋ" *^^"XA EV`mmvn23;,'CFox93}K)E(+`&TpoL @Z`q$VhW' eLlCÃY`- W8n%E1 nUuD`ik 1V1%qZ&\t-ׄm*1%-(ݨ02k5l{mYe 7 ?prq!ㇳxkx+A>Y䇙[tibc 6 pQ_>8=G>( FGQeNg|ze9}ُm7{!Am|tZ.~>6R6҉mK:r] /@+V=%T0xtK'Y&'mKs%[k)*_ !Q8oPR1HO&fO^wo=MFE7Wʮ~6#_h?'m$[^.?Wꏚ' \;-$6{ n-;haS2f.ҝ !r[jY}0]-4ܨ='m׻7Pq=ikbpT5sIP R*t `Ξ4F/Knšry^Z@tx+KRຮ8b0$, lct)?,c1q hZpȵࣨag,υ OskHb0kQsi%‚>>R[[Q /wHeŕn1eIC.1<Lp'K-ڻݯtѻY8 e˫ߡT;zKBA/AKK KGy.r&/4:H.ӵ=[,/a kݫ OPJ0@%cAF ^*L S)s@l`3RH "sO p<mSOIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-exr.png000066400000000000000000000030321237252063700273440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-fits.png000066400000000000000000000030321237252063700275130ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-generic.png000066400000000000000000000030321237252063700301620ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-hdr.png000066400000000000000000000030321237252063700273230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-ico.png000066400000000000000000000030321237252063700273200ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-jng.png000066400000000000000000000030321237252063700273240ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-msod.png000066400000000000000000000030321237252063700275100ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-pcx.png000066400000000000000000000030321237252063700273400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-photo-cd.png000066400000000000000000000030321237252063700302630ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-png.png000066400000000000000000000030321237252063700273320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-portable-bitmap.png000066400000000000000000000030321237252063700316300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-portable-graymap.png000066400000000000000000000030321237252063700320140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-portable-pixmap.png000066400000000000000000000030321237252063700316520ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-psd.png000066400000000000000000000030321237252063700273340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-rgb.png000066400000000000000000000030321237252063700273200ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-tga.png000066400000000000000000000030321237252063700273210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-vnd.trolltech.qpicture.png000066400000000000000000000020511237252063700331670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-xbitmap.png000066400000000000000000000030321237252063700302120ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-xcf.png000066400000000000000000000030321237252063700273260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-xfig.png000066400000000000000000000020511237252063700275030ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/image-x-xpixmap.png000066400000000000000000000030321237252063700302340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/inode-directory.png000066400000000000000000000012471237252063700303270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<$IDATX;OTQڏsy@E+576Xmlvv,lV6Z[NbAabHhh@` s>BDp(tU'ُÈEJ.; ^JPt*}~yQ>^^&O%5 Տj͉3zekf<3=!ߗ^VU .XQ|ڏ G1L*6 ̿|xcOSMޯ[2m>te2Ud1fT5e2V5;yޅPdJV[2L;`":*Kn#6!FLU14P%mL|B&%RLN4M. LJd)f"O6´/ #<}scOt(g.@I 2"Ǯin̴tpiڠ+n),;@Y?=/ABWgBoDETfIQN,]NO:}SVV*cW1S[=\ X\m~]V^4n_FCbObd>EgvEkWl('myo5o|p=ht4|zZ/:gSNߛrߝޟࡷޡ ᢹ⣺⤹ߤॻᦻ়⧼᧼㨽㨾᫿㭡sr#V1 'tRNS $'(+/189::;<>?F67IDATxmKOQ\N\h j .&$]w.L.L(D(Phvfzj[Bg8sw( %b8'8 k*`0@_e@Y@S켥5t*Xy;SJbhZ95?:ȹRoz?-e}_*  X2SiP`̠`t]j "n!>HJʫa[D_0gNƕC#3.L ̓ad L3:qzH `F7"3Ii5P#~KT.4͞r );nIA )DHńO3o+^˸ɓ( 7,PDlYEIzWt I'zVz &ZH)p!e;Y P.CR89@SE\UIJ3m[ɘ0* V" 8M5qHИaR5rہȪOͨ X TwJQiۖͧǥ%T>o,UpX~t=w)hU|$kpHpgW|xngl"&j4 }ѫ t<#G҉( IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/message-rfc822.png000066400000000000000000000025771237252063700276660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[OcU(--V.R:*L)d$18Nݿ$dˋјh(a LePti-\keX;!}ioΠp-6jF?Qz%eAuMMM}5222 QSS^=Vwvv}J߀u:/kIItuuuU|rp+W$̫%=\*VM Z5) 2{ k(W$J'eΤNailthxa28mb#"B ߎ@{hS|烞+ܡJG5$1vFd*`aMFf7?b7Gww^|Wrpv/oXNn$pr9= L8 Վ&\cv,.a*cjV`N~D9vy`2Cvqzz*-F@ss s` |Mq(q-m#k?*J|*q4=2V&ĊHf]EjǴ]'''dچWF# l!DpZ:E6Ϫ&*(|N~l4d"x(kK1Ykl\<צ@):QR;)%&<`<&UBff^d2<*8ߖ9UD{: 6^dBň{K%y "U?|w? JDMp ]EXTפvUd2u_p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO 98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/odf.png000066400000000000000000000125121237252063700257740ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxڵytTնvU%bhToVDDPzA #H'G H!#8$jޮ /Q5֯kxF}Md[2He]Ĕ]BYtgX{{gֶ-ݤecZY8v U ȷ,";+C!ߋjl_}дSǜx}wgs7M?4ü̠2-LĜg)cڪ)vZaOՓv]GLyo[xLaFkr~U_t{/$}ͼMo.';N7{\ʾ=}i^]\ŕ}z$837ͨ%LLuPBBXaGc)i7ƦMv L L Z3~!,^)(̑R)pޢF[ߝ:YյH $z/|bn[X}'t__8k-)j7'Yf%7ּ@y [2H*e$iTq][vI+,3-ᰪ!%^f[کt$isU ={,_RL,i!ij곏@لV_\^#@:$\,H9V?T{عwjl.U_P{/W('BKSj?mׁƠCIE^ N(xN&4SUC1gBN>[46ol_p@m?ufDA^Β%|j3p|#GrB;O]cYқ*^Jl[`wsܽbQˎp6Zdz?"#:n' :i&t\?$ff56Xl%sYeRLolRhF-M:IL jP\7d e9@֨n]PQn@H!,GK1f9Є@K z6-ܟ6Z*49gYi`=yoO.e/CϽ|b`J ({ w:;z4L#;WA%`R]ؼBs9|.:@mVk%R3# L'T^-/m6|Zֱ/f*9rU 11W(p:rk(uhu;GϾǔӏ4߈aN)gN_}禍Vո'r{M|詽V.'C:H,xt%@a(+e'З $["GUXryV<R5()$jQ]I3w!~g8d}P7FHZ3\ԗ嬈{1jWQU2畬Z &1fA{H[ڃ) 9/& TUP- TK22D ꉁ= lb+;@zțRmҌvmTO;먴ыDer}\oKYd`p6)9|6@\po1IfYsR[fef[h wĹ^RYXp.L[2Bf:DKǛ> Qr%Ts7\AKY J ,;gV rP&?o3x9Y9}[a,y\W3=SDxgQ[DzX =f?K!×e; o?# zgCTBl+pMMwb$$e(lg7@^x8o@doU$, Ua!,[Ar5 p/ȿ_k(YL³?$(OFNwgLo  >zY NM{dEK;t'SG 4u]HK=`:s\M|DopyG K)2X#ջVRR(K<@QJл _+Y hz\0=C }OGf MR) zN+ <l!TJZ&j8 գB?f$D,tCz)%A `p룦8D;bm{w{艡z9r)N7?s8#\q]@I)`KhHKi.M.edNG41q۟;V{ǺŝgE3/@U 3 y-CHyth (CX Hwg3@<w \p4fDhd='KSr>]G%t =*Q3]ww \PA@_ ^P9mR9\ =AVaa q]'?"FPDJV&\H0bN?gLUS´]Fq~ AL;s>H)O@ZK7\rc[ C1!I#>^I._FC+ O[e.}qA/4r;M]>P/'4Tgl*yxz#0G= E]^yu0It҄@,ECP^w{@&ӚzgB`STrBvAx_gUTQWλD9w`m)$TYϹPtnfmjn wyNˇN;Y2eҀtepC4 =]Yz[ lJhmڸh~f8#o*HM6NtS=zЌ:p8{`;؝\gv:gρǝ{<}4rMȻk33ޝ”)w&y'~>Z1RBFA`ڄC@-GH.M l.5XcTV"| XjH\gЇ >evܢMg|:^n}n]5֏hO3f]B{xz[<|~QEQӇM)YꏩS?.f3Rf.x[i|։`':zZIȯ Twt* IKpoSzR zX$P|R6 UOrK=u [/+dZjOMΙ ]{ujf뚯}ܬ;.}~F׊)NNHLx) ?{ $S VPY>dLPU-hIG9rYv8Aih~r@e& _:Rg.#\W :^/>S1= ;AYmEvLvX]_U7æˋ0n-N6iwM%PC7Mt#?kЮ*sp`!_3ۄZ@&H P l&7l zf9j.˚Nd}=xv{wnPW^_e}%[n1شauD @\QX YRnfhּD ƛ[fBd5a>1C0r?8T )CY2. A.c\w)Ko?gWfEk2ꋳo& K4zʿuz:Ajy/׳&ҥg {{xzց2OH2;e-! & &H+\R:E/e9sz.eWz{s^#玟oY1k\3xۿK*\عY|ˇv393ί;e|f4͟! k!{r_t WrzwZ3g)3g_0v b.T*#6n`ܠO }g<52k ǝnA8h5"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/package-x-generic.png000066400000000000000000000023611237252063700304770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-calendar.png000066400000000000000000000026461237252063700277660ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-csv.png000066400000000000000000000023561237252063700270060ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |||}}}~~~Gʢ'tRNS $'(+/189::;<>?F0P,IDATxmӿo@%iJ*J%@RRta,L쌝X!D0tEC$Q"J؎Ϲ#g;Dd?> !6RH4CCr9>1B$% }x @4 C\@]n$DR$r(Z9UEX#>s0u dC-k{Ij_ A.,ymހ)W q&?/Pp d˅05zGC-~> (4GNn}ăI pVlJUlvw4JwOTB{|* k^]gg1 #]n^J.ƩrB9}@yʥ-, wG^t̏[2| J* Tb:b /FkhTLˍV1kJYu,Gb{) 繳ze[0RBM5D% ݌,`hg09p5) 70E ~IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-directory.png000066400000000000000000000017661237252063700302230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sIDATxڵWMkQ=4_%RbJ؅.B.EmEJ诐R".QZK6LީFF饇7o&}3M&1u!U,&)MYJŖ#&J"*rW&'' ~Ća DIMMM]E@HBd-@?񠏞`Br=P@@xjw0m5_w庀 XFmdAAEuN-Qnj 9x\Nj_:yڽf;0K29w;4LSljײn4ޝK։x ٔ|V#! FS׹M.$"ׁmrвluNŇNrA h9x}.<Lk/py:W81Z.QxlbtAe&-ܸr. C!t=j!O'&Ay;~k;cm(d=D`[EPZ.lB%*9[񰤋N[0r!m;H@=`[!G_¡%|0(Bv8+"BK_V*}&F˲nvTā݋!a&n6h4"jZ 0Nzi"H #˱#|J"@~Bs0;;aaͅ^o+Q "w)dars~~gDUT~{9P#09]^^`ț_F+s a2DZ`Z+> 7"Flic-..2#"Gz)wD}ts Bl@䏉8[U.gff> QgHҮST /$_IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-enriched.png000066400000000000000000000027431237252063700277740ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-html.png000066400000000000000000000031311237252063700271470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkh\e:sf2IӤmbozAQA]ĭ(ayaaYve?A ^H\ɌML&g̜{|9=$xxρw{="PET~RS$/z!U:6$BIֽǯ#O di,n<P|Kχ[V["Xg๳!GvxSQB` 8-pRl*Wy\k䳂]RxW)'7)Mʖ`bq"^c{"ʖ9$5LSpzm}*}~wqqVx؄ڼMt N0(^rhHPq\0XF4r\-{ # w.oxF!)蚆ihdPA_ gꊅ-TmO'nWL9!1ضB@kD.kCKq jԠ+\DNDQ>U:RͶZPg s5Ci9& JD c|ri֗143ߘ ^ǵpZʔ &JCdi9^[=Ϣ\}&ե5i*&-7C ÀO) @E03LYp O@罯gtS5JJW)j:cslc8g[cn  oOaejr nk.O>pbͣVD[ph֨^s(| FնazVVf!(>L}۷Šs H>0O:KdiwQi8UU;2>Až'" ǰE|&[`a%`ZϓfFLmPoyv?KV+@Ғ/~~ OTxrC-fm1!EܮR5'N%_ @OfI^-x`e?,Ѫ'Oqҭy)0xjAP+A$qAgfvv6^k333KLHF0R@rR_ ^ť˧O~ܶ -`wzt+ԩS]o&i-G0p+q%iӂ>9qGSSS_?~i`$y4ax`S=B`-Fb|75IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-mathml.png000066400000000000000000000015751237252063700274770ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-plain.png000066400000000000000000000021621237252063700273110ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񨨨S&tRNS  &(),/2:<<=@G,,IDATxmkA{&V(=TPXm*XՃ/k3bԋ`h!b$3lReyہuN/Su]yD yڎʫЉ$pA,࢝ cAk9v3zgs^2%? Znr^7D¿qɈy"Ϲ ֏CI5O~s#z+dcu S/gh.$p~ Pt{1QxKqSn=Ds~܌0'#7ح陁FWOD,@;H8..n v u5導G~`N(>TJ`۪_s*atp$5iA~#` o*n?t#`g6tQKQuz<JJ}Ջ$cw (Yj(G|&' =4^&_ ,gHuQ>!l" PIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-rdf.png000066400000000000000000000030571237252063700267650ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE /j2Zl2x79x;Pg@Y?=/ABWgBoDETfIQN,]NO:}SVV*cW1S[=\ X\m~]V^4n_FCbObd>EgvEkWl('myo5o|p=ht4|zZ/:gSNߛrߝޟࡷޡ ᢹ⣺⤹ߤॻᦻ়⧼᧼㨽㨾᫿㭡sr#V1 'tRNS $'(+/189::;<>?F67IDATxmKOQ\N\h j .&$]w.L.L(D(Phvfzj[Bg8sw( %b8'8 k*`0@_e@Y@S켥5t*Xy;SJbhZ95?:ȹRoz?-e}_*  X2SiP`̠`t]j "n!>HJʫa[D_0gNƕC#3.L ̓ad L3:qzH `F7"3Ii5P#~KT.4͞r );nIA )DHńO3o+^˸ɓ( 7,PDlYEIzWt I'zVz &ZH)p!e;Y P.CR89@SE\UIJ3m[ɘ0* V" 8M5qHИaR5rہȪOͨ X TwJQiۖͧǥ%T>o,UpX~t=w)hU|$kpHpgW|xngl"&j4 }ѫ t<#G҉( IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-rtf.png000066400000000000000000000027431237252063700270060ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-sgml.png000066400000000000000000000120511237252063700271460ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-troff.png000066400000000000000000000022161237252063700273260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org< IDATxڵWMkF=Hm^^RPmV!t -$RJVǦPڟMdh.J_ea*  ιgxd( Q,Ϙ5HLD;~N,#96?IM&pǶY)ҵVi1("X?GQiQʜjR}p%0,CRh0djQXxq` PPm5ڠ<` 4 1  " z@]h"d_t^I$`dB%+x>Vx' K*dUSڊ 8B>Hha hǞ(`)"X"Pل.Q@ Cw -7B` lL¹eD zbLhs ,yxԌ@i1H d*7z ;'BSibR.!Qbh4nN8C\vn瀐d6QpKzP>?)azfc{{xa ],s>( |" NȒWx>c4o6xxxȫxH))JHW&3~NGd+B=yY{u||| ]ل3a$,2L!ߜ.$5; dk& A2 ! }QJ)熀*oLp_{xA{qY҄?uhyqIw+ּ9Z>e?3+Yzzz_ *Q\^^KT7v{#xIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-vcalendar.png000066400000000000000000000026461237252063700301540ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-vnd.wap.wml.png000066400000000000000000000015751237252063700303700ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-adasrc.png000066400000000000000000000027231237252063700277130ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE L M QUVVVWW]#_%`'`'c)d,e,e,f.f-g/g/h0i1i1j2m6q?F0PIDATxmOHQƿs=c=J^@yOt]~ b=$,(%2xB^.;ѲezF5(j&f.rҵڎ>)`Aqq"s8'0{>۱lQ!J#_6ӧnT;VyL | Kg^:% `;@W_/.rMwÍ P X\zv0&- DМ#]Ճ)&Mt dce$3*г &Q:Z~!x_Q`9O2KT m#+!,CMK-<QIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-authors.png000066400000000000000000000120511237252063700301360ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-bibtex.png000066400000000000000000000026611237252063700277340ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  !!!'''(((***222555888<<<@@@AAADDDOOORRRUUUVVVXXX]]]````aaaaadeeeeegggkkkmmmnnnrrrssstttuuuwwwzzzz{{}}}Ɋ" (tRNS $'(+/189::;<>?FVY\mIDATxmMHaIF$Bx nBCv .a$!u$%tcUD(xCBu Us?ٙ9< #4 nO}S `"f quV;IAP@^!!# l[( !JSVv4Cy)JN:3舦V; ;V tn! J\Z*ۻ~d7&z%3V\1#`s? ݹewy>Z_p*WcË357 ,K=|tgj ݛDVF@?{1 ;HɆp.2zkGu <Ж;ILpul'O'玉w~j 9cG  g\U$O 0 `w{ W BJNer}߶z@]?F0PaIDATje}o&$mBCzXmт EWх!RB\xށ ހ"BAEFDbML&3<͸!ȩu*Χ[ʈBH"|NntZ'g!H"5яN/KNd)ffRZy1JDğ B( TDN{=o||] .Ys&_+*Th ߉,GIFJqs*rPAD,xU% "+)B͞k fflnn\TY/ܙZﳧޚ>5 2#KZ{}O1: /եU]3Z Bs[O~_D[`HBs)!0n$T?'[֭7 rRn]\.÷F`eguݽaw@n phdp5g1 CF6|g*(7:h^B47"z}} *Q@3.Pi;bn"@>@P hw IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-c++src.png000066400000000000000000000026541237252063700275410ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<dPLTE L M PQRSVYY[\!\!^"_#a&a'c)d+h1j6k6l7n8q=rAr>yJyI{L}MY^\]bagr~ބ݇މ̓ޙ֢㞽襾չ'tRNS $'(+/189::;<>?F̑[IDATxeMHa~Z~Aѽ`uSd ][t $>ܾˏtYwٙijw;=bYzW^s YSD $AΉ9M}} @0 YiZ: OM Ct%$IArD/ğTѵ[u?B@G1!7"G2 ^ "Ngz4WYAZ/S;VВMW ߭7 NR gW6ԩ(twikz$T0Zzo\3Q&yuBT`wt$wCxr1$ȁ/iyAD4Ϥ:%1$%N?nŦH),H>6/783l HXxUm* 1+5՚h>_Z-Қ=Y.0mmRe RtTJ;(?ssllv>Jk囿*@8'݇b+}q4Xh\_ʩ֬VЈ$gL?.rE7-&ZIni~L`YiV  ;Z1mO(x{ƛ IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-changelog.png000066400000000000000000000120511237252063700304000ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-chdr.png000066400000000000000000000023561237252063700274000ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE jqqtu xx}m㎹|~W~'t倳VDJua('tRNS $'(+/189::;<>?F0PGIDATKke<;3\jB5m " EWq ;GQ*tSԅRAHh\疙<'59WB4L0[QRI8h=gOtm.BQVgdQ3KUdRZz!PB;yѺBP!%3dyz-BTК|Y2O[wSDHp.+nID@V$T(33p Y_<\znA@33]w: sznɣ: Xڀ-^u< Qvo1 76F6^1BK|i m B7+wofFBO~)&xztuJP![k~d~ԗTv} ɿӣppN\' ?XD;Ψ20m~i ʃX[ʠΕavNމfzwtHfӳ>PiƳP1i7Bv`Թƃ9@-F$o ZMIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-cmake.png000066400000000000000000000120511237252063700275310ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-copying.png000066400000000000000000000120511237252063700301210ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-csharp.png000066400000000000000000000030241237252063700277310ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k2l4m5o8n7p9p8q:q;r?F0PIDATxmMHTQ8~%TV (((,!$6.[FTJ@#ڕY %.*+$S#s>}Λ{7KތY~JZK+f+!#iDd"f(SfB}9dv *R@ DSMg@0D`@!%AKMqÖQXau 2ya %TlhZBcA>&#PȊx5,mMC }S[}<|qIʠ2҄ jsKf}d#SJ ҁ8".=Ӻ~f̨0m~HW΂^kA(~'8bf[W-7v}j5=ѦeKݓ-ecAyrY=L G}Ϣ4b&meM=֓7LGp%ԣ#z=nZvLy2n?\7!$BZ1+oxj >_~\ܢ-׷\90 !psaᎠE-g.ʻs1d-19P'i1j$,c'#4!K Av s-IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-csrc.png000066400000000000000000000027231237252063700274100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE ""#%./1227>?ABCEFJKNOPSSU^chkmx|𷷷k'tRNS $'(+/189::;<>?F0P~IDATxmKHTq4 -РUIM2hZXe!Zئ"h,+aA>J'4Ǚ;;z< w_@LJv#@[%+@ Y bFpPUV،󥫕 $D? GNYEwKWZjm3*zmWhM tۘg )0}e59Koq%p VGZ @i M}bmʒY\wljEcyp@s+l''v5$E3`ǐ`I,8GA9 k@<ۗ@͟Tb1Z>i'>#S I gRldn7НAlTpo<3߽8=PPdbוk T !ۮ`~?3u ƒ^C)d`n% ~j2MU1@7_f|}<6{hQ-{ XFaej>{(:z5&znV wP`I+=-/̊R>*RAFpֺjJ~!+&9>/ KWT>5_QڤbhIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-dtd.png000066400000000000000000000015751237252063700272350ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-generic.png000066400000000000000000000120511237252063700300650ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-hex.png000066400000000000000000000026621237252063700272440ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<FPLTEpppkkkvwwwwwz2.tRNS  $'*./1389:>?IMrIDATxuKHTa;Gq2-˨{ڢjAJB7JL6ZV2(+iB SJ8s\d{x?hĿ͗9À8#!Bo=@,K@4P G0 5]jR%2Dc2 4rD4sȗm=B6[0 PO_K+?i4qu{}&I R+7SϣWl-qUe 3 tBx\()BIGjwYĿ)f/O(][^=]c{ _wFI{H唻 K e~W4z"7sB._(˽GΘU(@ bWHi x/Be֜ U6?X'*;y!?HmS{Vt]ZВ5]< \xoQqMoY>-d_܏Ji"5]!7?M cЅΝ^~j<{z@ۿ0}4{ *J:)13YSi^6uFD-yW50C 8NZKh4q( ޟH#u1 Io3n88፲=_RLWIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-install.png000066400000000000000000000120511237252063700301170ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-java.png000066400000000000000000000033071237252063700273760ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<DIDATxڵWKOW0+ A"*YFJvMD".hWhi7IH+,W*V0]f\f|^-/dYV-6\.&'h4888!g^x`&< >Bڵt:nKKK/,h\DHq h#FGGQ0==jt] q(!Dz166W?A3cytAcXJpfzx?d)ׯ_Fj''Q.P=>FU&S%z I^/D$9,èI,˺8QG1LjDm6X1ɘssst@REF@%Rxszz p!%@-7nP+ 4H0jr@@튡Vi8.091cA~v b$4&xQ*fLn ryVObh jO! '@XFU*/ _(J=xΧwv $R ,TlK ggg h3vI_~{ m X %Y$~RE?=N'#JIjTs2JlK@#Ԕh|J[ 5W0"PJil.?*ʷ;̢Z.I9P-UZL"$b"S7j8m6`TL o;hZ*Xѩ7"ey淥rA A'6"z0wu iEBtk⒖:Nj8<Хi6zN\H=;o^"E$#ygV{b1bmm ׯ_u=EE@F牙 d O98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-ldif.png000066400000000000000000000017661237252063700274020ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sIDATxڵWMkQ=4_%RbJ؅.B.EmEJ诐R".QZK6LީFF饇7o&}3M&1u!U,&)MYJŖ#&J"*rW&'' ~Ća DIMMM]E@HBd-@?񠏞`Br=P@@xjw0m5_w庀 XFmdAAEuN-Qnj 9x\Nj_:yڽf;0K29w;4LSljײn4ޝK։x ٔ|V#! FS׹M.$"ׁmrвluNŇNrA h9x}.<Lk/py:W81Z.QxlbtAe&-ܸr. C!t=j!O'&Ay;~k;cm(d=D`[EPZ.lB%*9[񰤋N[0r!m;H@=`[!G_¡%|0(Bv8+"BK_V*}&F˲nvTā݋!a&n6h4"jZ 0Nzi"H #˱#|J"@~Bs0;;aaͅ^o+Q "w)dars~~gDUT~{9P#09]^^`ț_F+s a2DZ`Z+> 7"Flic-..2#"Gz)wD}ts Bl@䏉8[U.gff> QgHҮST /$_IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-log.png000066400000000000000000000120511237252063700272320ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-makefile.png000066400000000000000000000024531237252063700302330ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE j['tRNS $'(+/189::;<>?F llIDATxm=OAvn' /+ cޘX'`Z; BLL,+Bz޺;337 LvO2dh'}1*m61DƠ-zN"0 "e\[# !Œ'  626h++r&1TD@5ߧ9c l0 LOoz1VNE ʕjǽmUv `_ |(a:wE2(0y9o9D1;M? 6[Z _-~ @gDĆ]{"N,hF/FP ֲߤӻ0Y{ *<G` XctzhVD`ݳ1Zk75첌?~D1dR2`GDrX@x`odH`0,1F:h_IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-nfo.png000066400000000000000000000120511237252063700272330ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-objchdr.png000066400000000000000000000023561237252063700300730ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE jqqtu xx}m㎹|~W~'t倳VDJua('tRNS $'(+/189::;<>?F0PGIDATKke<;3\jB5m " EWq ;GQ*tSԅRAHh\疙<'59WB4L0[QRI8h=gOtm.BQVgdQ3KUdRZz!PB;yѺBP!%3dyz-BTК|Y2O[wSDHp.+nID@V$T(33p Y_<\znA@33]w: sznɣ: Xڀ-^u< Qvo1 76F6^1BK|i m B7+wofFBO~)&xztuJP![k~d~ԗTv} ɿӣppN\' ?XD;Ψ20m~i ʃX[ʠΕavNމfzwtHfӳ>PiƳP1i7Bv`Թƃ9@-F$o ZMIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-objcsrc.png000066400000000000000000000027231237252063700301030ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE ""#%./1227>?ABCEFJKNOPSSU^chkmx|𷷷k'tRNS $'(+/189::;<>?F0P~IDATxmKHTq4 -РUIM2hZXe!Zئ"h,+aA>J'4Ǚ;;z< w_@LJv#@[%+@ Y bFpPUV،󥫕 $D? GNYEwKWZjm3*zmWhM tۘg )0}e59Koq%p VGZ @i M}bmʒY\wljEcyp@s+l''v5$E3`ǐ`I,8GA9 k@<ۗ@͟Tb1Z>i'>#S I gRldn7НAlTpo<3߽8=PPdbוk T !ۮ`~?3u ƒ^C)d`n% ~j2MU1@7_f|}<6{hQ-{ XFaej>{(:z5&znV wP`I+=-/̊R>*RAFpֺjJ~!+&9>/ KWT>5_QڤbhIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-pascal.png000066400000000000000000000031741237252063700277220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[O\U]̅aJiSZS XS륱iҾ*j7h&&5i4hME(DJ "rœ˸wd xۓ}f9{o}}Ea%A0X.'p *[UX Qֱv@F0 5Qu4rBHTQN#jlly9$!@&-ZY&#gbrM64 ڻ2+A4?fQLu]D"hll5jl>VOЃrcGGx%Xe'EW&P* ĔlQeTe$- >SnJQ<8B"3 x/ 66$DT2jz?"-8kXK\5si{|tdD+|> lg7 j^,Q@pJ^vuu$]][#)\/-ra=X&Umμ# eF)܋X^^FOOfgfH zP[[ KNܼy{E]]d࠼VUU%׫M&bJRHBBU]]M<{!^#}x]EjF+d*:8ri"yCŝyQ#h sa syu477jzƜ J۔ˏ? h;Nfܸ+bߑv-755 sdJFȀ5Q{Cc;0CR^ *TB{`]|!`;6{>C37)U }:98MLzE]3wg]´ $-`R)WVVXT4` |094jrڟ~ 'Yv#QX#s ]Y` K:DC[,"^4҇Ȧ#Ӹ2,/x6Tܵ\qmG0 Bj8S@ 2z1&'C%IgϾ`\=TJ^UXA"m+Bzݻwow9 V'}qbbp_m# 59Yg>lQK%@ ot_lKDJ(@TIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-patch.png000066400000000000000000000032101237252063700275450ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIo[eeŪ"@ .b uifjuڍIkgp<;nS|nAι{? / GG'!n >l'y69ȵcO+*4MV. a0+}jVS/P'ask AԴ26ry,O$ GfD"=FL/RX]]EvcbQ-Io8HqWZYGP@$0" #5><.Sam}]D!"~rXuˢ*!l:P-g%R Cׅ s~SjAg$!9L$H./cumMBUYi Ȉ+҂;0GFшF|}EV7X!$gi1 h?_c߅CeѮ4n4) D1vgUYN_h"nm.t BiQ#Hnht崗`NSH07q l 0jązl\x1/ `? eT&!){.FjqB0F`NܹYmnݲlJ<0<ȡ?2POdG5Gn# eHFr.r2~"^mO賗ؽhQB~ Ϟ=,S9r'м8={*y:N?Y%5=BV劼<cgQp}Gh}y.de`8jL:Wl6k mgT.r v W }ID9zO<="7Q 9Q  )O'~FI9 ]DVeNNT ɫN299 ;!a`f%p"`UYr"x2k핫 ?~1G Q ;q^Pp듽^Ņ UCW ߾䴜<+\NUNgdp8h3 նDSv{Yr%E ܐ%o6 ֚08 bX%_rc*VO>kI|9` LD8[7 3qr,,*"PP윭jb-/3>3&{MډłĪ(Egw> G$eȎfTDd:xBRaHzV YM&Rne ʛ E|_}3.1], lu%|Q~! M(R8Jd)&wxtSf|޾Af,"mʕTP4~+ȷ3@\B _ JA4N7Q2Z\o`\YqהƈԗwG4͈,Xm҇hjiA#K*),ttxA;hiAd+spz+̎ ]W7m^0Fey fju(h߼gptˇj%[8#1E)35}*1H[ERJ 0e "H(8/Yފ9%N|n8>t?_}sixK$I6t: Jc& C4 a:YE˘_KׯѸzfiJK4>y۶)8MU%K-!D$=O,LJvP;6 k}߳ 큻J]/]x+J9tvs'rkQ0[VEv"E |_?կIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-python.png000066400000000000000000000031141237252063700277720ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoUw}R-EP!, 4v磔$Ɲ17ƍpGԅ.X_ljB"Eyә-$|3Ιs5!D i cAxxP@^g=;p? UUFOXs uu44MEWW7ЂZ[[ 0ppp >S<3hO!BQq}͈|M47 w~Rc˹9X&9T:mds3I WU\x 1p v]3ܸ?YJ@i"0p >8$a_oxcǼ͘Z/2MT, |(xW?k 7݉ #:tH$V~ gca2q U,6$6=wv\}Ҕy ~ۏn#lP؟kzc J [ LPZ /JHMDBRzPqT*ULNN^#M"ro4yLyΈMӀ!;KRp<+UJq3٬#GRP$jh؄ChTdDKH mhi@8g{(B#|ml߀Yhjb&aE!0\$A+(N=Eۀﲺ9BL&eB@,+  #Yk . J~7" aЍU+2 *ZF.Yq% yoE*b} Unԗn#pa9.l46^lVJ[6v7ZBZ}#{LbR\32c:3(RMa4'V-ܪƑ=F9mEk(&"t.Q0Q۰x k:g `>7AR; ÐӲTx@?Zѕ8;A:8ޞceD³B-ik{ 35#o"a\F_4422rBQXKT*H>_>`īV|p:;;FS]Ĥ=FIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-readme.png000066400000000000000000000120511237252063700277060ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-script.png000066400000000000000000000022451237252063700277610ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<"IDATxڵWKoU=~6qLM I4$>찢 ʊ)E}@ *`XPEm6y `(uc'3ԟtgF~c_sƑn ED (41m)BEB8S=?j%`>鳴 E,CjxC¦0ZZ}$q\^^""lЍx{rCCax&a F0==Ŭ\$~58;Gqrrd2151-%q∎ߺc*enĐTnAd2T҄߀ڋ Ju7i4H[ wϞaB2fdf- q7u:҉KKK!ř}<1H)fY(X[~҇7+dnߞf"̘fm0QVQ.Ci~wfAB$ 9mB[~NCof:jPZ-4M[b jP+Q߾k};3,YV׸EuX4Y{T7px,,Ϊgdue?|oŻI}Gz;md-B+x[ g}ßǏr2ve_(|/!>r y t=MX~^A߈\yHd`g;6, כK1n=˃T*ї/_ `_h C]fLPLgiNzR)C}#4fy֛U{~r~888_" $PS0??//T)}@Tr.C{Awt &FFF(N#ǫ+2%/_#]@lnnr9|5 !wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-tcl.png000066400000000000000000000026131237252063700272360ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<LPLTE ᄒIJKOOPb3d6g;g:j=nDk?sJtK݆cރ_ކboz|}䠅壈壉框²ó鰙ŵ겜ƶ뽫쾬°ȹʻ̿ƶ˻\gt'tRNS $'(+/189::;<>?F0P~IDATKe?}.X:]V!.Ej2hӦMhoAjA(AZ it1͜q<̜3yQ!hەHҬ~d6"T2`D ~L\^ќy*GӾԼQBAXdMdFR !Uln3??pӝ !?/;ٔ(P!a‘W[|3s92yh* ԚM "ZU  p 8:ӟܻԗP]9̮Ϳ|>I $4k燻G)($\i<ԦRmP$DDƭB % ?M9l+M)T_Oo|;k D9Eس{4jBBA҆;Nl ?^_mIX _"A ]c͛4wd7 q@(XYY2ZH3(ʧ'HPvڶcn4n FnwqSK׺ w>awW׻@Ҷ5./Er'=@bYEA[rzKJ {d] F@1IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-tex.png000066400000000000000000000026611237252063700272570ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  !!!'''(((***222555888<<<@@@AAADDDOOORRRUUUVVVXXX]]]````aaaaadeeeeegggkkkmmmnnnrrrssstttuuuwwwzzzz{{}}}Ɋ" (tRNS $'(+/189::;<>?FVY\mIDATxmMHaIF$Bx nBCv .a$!u$%tcUD(xCBu Us?ٙ9< #4 nO}S `"f quV;IAP@^!!# l[( !JSVv4Cy)JN:3舦V; ;V tn! J\Z*ۻ~d7&z%3V\1#`s? ݹewy>Z_p*WcË357 ,K=|tgj ݛDVF@?{1 ;HɆp.2zkGu <Ж;ILpul'O'玉w~j 9cG  g\U$O 0 `w{ W BJNer}߶z@]˺R)&O|y{ -Apg[;`L]ap`Lݸuߔ[n˰#:_9"G__MlV!1 SKZF>-m4: d=x|/u8!}PjεX`-EЗ*I!,AՎ[BQı@9~_DPOpSqTU㡏= _KP~<%d}ǼwOuwkf Q$ K{\Ɗxq/=X 9iO>GLLL.ޝI [syO>`ƫMXH+ւ!_eG$؏$}#"?Nٍޙ֢N@L^ZDD_n}^2~8%IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-x-vcard.png000066400000000000000000000027151237252063700275560ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<JIDATxڵWKoU=3?NjP %E( TlBRȊس= V,X@B ڠ@B^<_>{):3s|s_DB%` TH 9uaD1OW4 pu_~v| @4 -@*i"Mw2sV@etr؎"iko`G԰N2 #HyRC!m_k"B٦:*[MhQ. `V PB B!H\1<$q]𻺏sp0y2dtNhS!ܸ7kBV^ QʽJ? PWx155y {&2V_˕)t]u]RpHH>߷x0v*g&Qۘ4)޹^3}8CiU6w7e&M|.4ڞH_^ݗz] 1hi5^![lv1p{󊔷O`eJOؽC BɡV@<*a6f\.FVbj7k=a0^p2Jo# \!=,>TfT*>|;L4 5 , `L슔4RItNDAv*nܾ0yZMO|5i|K2;@WeL& յӥޚȥOKˇ/f8 ^eI( @A74loL.JL@.yONNpk27'uIMCYivJ;w>Gm rB9!dqT*DannWY[[{L 6܉NLLHB-ͅǜǘ}BakkhqqԶg(cwV"!Ha O.bDBGP!h+tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-xmcd.png000066400000000000000000000025511237252063700271430ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWmL[U~huP>:YʜY2513K?c(1 ?l3dS1&lDa )0nBim{q{OI-9.K R"e`zz: 0Nڂ>CCCg#0oh [.w nu9;ʷ<8OWO-hGp lLz̮Z@X,/$p/<bː&)dT!8xyEZTWW0HG6ki >ćHI,=. al~M"A88Nǃd2}M =rg:DKۉzc\WXLB$l.O2U"@݌4 ȥ%oL N׋L&#W92%? !`Ɉ}}}2u(Uuf $yHŞőȏNuAydnWNpcJIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/text-xml.png000066400000000000000000000030211237252063700270010ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񮮯ֵߜᒳ᥾☷z[_aeeih녯mnpu|쌴v|}터{4(tRNS $'(+/189::;<>?FvLIDATxmKTqu:8c|vQ-\*VQm6EP@[XEh(e䌚C33\'s|@(|tռUdN$ IрPm3@Z\({R˻_(MlZBrJ !4JH` o L 1pV]d?hId@$_$U3]pSqB^!/W%W[ F cgTU@TbfInYzYnjgGzY:ǹ0cZ<`@TG|؂g&sW; #ԫK`N%$lr$CpzTwWLu/mhpOsmg@}&&4,] 98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/uri-mms.png000066400000000000000000000031471237252063700266210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/uri-mmst.png000066400000000000000000000031471237252063700270050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/uri-mmsu.png000066400000000000000000000031471237252063700270060ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/uri-pnm.png000066400000000000000000000031471237252063700266170ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/uri-rtspt.png000066400000000000000000000031471237252063700272010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/uri-rtspu.png000066400000000000000000000031471237252063700272020ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-mp4.png000066400000000000000000000027751237252063700270420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-mpeg.png000066400000000000000000000027751237252063700272720ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-quicktime.png000066400000000000000000000027751237252063700303350ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-flic.png000066400000000000000000000027751237252063700275240ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-generic.png000066400000000000000000000027751237252063700302230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-matroska.png000066400000000000000000000027751237252063700304300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-mng.png000066400000000000000000000030321237252063700273530ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-ms-asf.png000066400000000000000000000027751237252063700277750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-ms-wmv.png000066400000000000000000000027751237252063700300350ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-msvideo.png000066400000000000000000000027751237252063700302550ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-ogm+ogg.png000066400000000000000000000027751237252063700301410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/video-x-theora+ogg.png000066400000000000000000000027751237252063700306410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/x-kde-nsplugin-generated.png000066400000000000000000000034701237252063700320300ustar00rootroot00000000000000PNG  IHDR szz pHYs7\7\ǤbKGDIDATxWmTU~νwfvctm2H%~"Q?~ _[l0q!hˈXGX!Xd~`ۺ+̝羽m4:3{9>{Μk6E ܹs޸qD"AGࡖNW{ <.ZR7$8"5ك`y?Ջ`/K sd3:f/v e܀qbkL) Ru*=%?eEyZe-m*$eLH|5i01fe*0CK@L qTXuRZ(of@͸pG9+3X!0*6sat[ЌAKL> Ф3@e1<^yqwJ Ay"`C &˅ȤTR3 )¢24%_` g2AEmD.`Z&E3`ؼ9-ќNWD[0{,Y dSˎHFK"Yd4@@F TfB(ڛaU qI]( Zri[^9 Vnocs85h3OBhx7ghkJ x, Rvm<*I _^=Ջ zrlD\^]K,aH?J ) F#cС0J%FR>/LP񪉕HjxfX86G>}_(:t%Uxief#Rc'WE@ %߅|ۇ e&<^)2_JrNJx-ˊ_JHr>UumBwix&D{ҥ+D$ئ9MIHLkXnO?y̱U%V4M1s.:2e[c~}]vQ*jxY ,|t_TmAxVŶm.WuKoO=rYyE?$yw>UC/}RȐP|<=JP* BR~mֳf͚@c;!m:JkY6li͛7bŊk'Ot^]֭ѣG%@l(Sjmjs|_> ]'N|u7:uJyZ ܿjvMׅajBM}~/JCA я?ǎlٲ~7|``?~x\.k[V]CQ^pG:thΝ;?o ]^~X~=QoF̈́e˖V'wp#˙=gϞ\ԘNdنF6ʻ(,28є̡޽ 1y"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/x-media-podcast.png000066400000000000000000000025311237252063700302030ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڽKPup e}1B#@BB«"(i]@^.mSzrFy! vyb"6uVǕc3rW(! G7@uM=̆gOs!AVH PS[-b07I{m<>G.tGJ|0 0okpNX`,'S&QO{=[𦓼\ֹӔ0}j]wk\U[Qϲsbf]y$vY1|UXkP@ P墳.qe ]xOk |  HRxo ‹u6uT(uFk|7DΙ @;|"?5@I6:dv|{.N.Rx} uV3g=A8 [|~og<0R "-t||fGX%bSq|:F3@W^Y,u_zO\| -`!oC4wxwϝ;yT_|YxF/Nbw>Do`ipsǸ1|Q>^4Yv^ tvr;spKlN[x(`2g-p"胉f27(s90gXF{ ;?pMe :a\c#f c[~lz-{ ,z{oh 4;K`:u^o]ݏu΅i@e Y܂ &1@yy]\. >Yc߇@='7AGGaSˠqFB ȺV "Y" v`1 XOO,I VʟZԆR+J<4" ɫ)iBh5blD2^rеXxA 5 [P?#=΅+0Pru'*cq tKzL}|L Z^T{2%( %bO F`H$}3]R5F$!Æ}K|MJEY3 , k*9U #')Jlhe:^dThtNӋ([5xHY>AJGf=j(WA@B6q 4n'k SoTTJ`)N /֦Ϸ/[Z r]{vXUTSx,0A<0ωm/!P`"^ij݋:Do{&+_+Wn b!|0^7 p&F%d:=C5|ɯ2͖ҥKo3ہi~awIJ9ab?#clߌJ)2\`i?_~h$ҔciY!F2,&]ĬC2g.R "zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/x-office-calendar.png000066400000000000000000000026461237252063700305020ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&|"@hbDH(l \teڹϹm̙N O ]={{o[L5!ɞl#d!br忾)1, W@]y ԏ3n2ɟxO twmTύHiܲLM6G/-Dt$KMZ4F|*G8Ŧk$#% j#fer%,JF'Zf;1 b1tm4S}O@C NK h7)p! X8:n7pAEA'i_߷rCA;,?2Ut:]VQPknWZ(eL\ZE>"bͣj-)ȥ,]z Hea 3j ), AX@@C哵 ^Ⱦ.yz@*K Z |љuty_ՂՖ -D EI/]>ݟrCR90-Ĵ՗ܹ eBz>@\Mψ${kmxWDll#I#A,{?NͤC3tz&I|ti$B-fO?, 3RaflxqfHpY8">SN-*ј^W?t0'z;}mMcuܩVVFGKZ'|=NUX|;$J5&/Ɓwf͓MW;6a@f=pZ]*훏e걽kN:rU>vcIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/x-office-document.png000066400000000000000000000014011237252063700305330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<~IDATxڵWn@%R k?6$'J 6k1XtrSV띣 }"ޟ4XN"KSr`8яK#D!ȗľ:`B>{MauyIENDB`Collabtive-2.0/templates/standard/theme/standard/images/files/x-office-spreadsheet.png000066400000000000000000000023321237252063700312300ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8[NCedEpYhnji@.Cegg/kohhyEچ/&~$4~itOjz*ިrΒuR[@*vk*T(sX:?/)u9Oe ptkwIiJM|6O&4ÝJq/( *)?^3LmI]R(".XSmT*֛MsRs\R֜TtrpnuHt?#O3@A_ Bzc7۽I)jn'S#ڮpe^}(ݏcO ˿?6wItGf6eIENDB`Collabtive-2.0/templates/standard/theme/standard/images/input-bg-a.jpg000066400000000000000000000010231237252063700260540ustar00rootroot00000000000000JFIFddDucky<&Adobed        yaq L ????!MA?!?! ?:??)Collabtive-2.0/templates/standard/theme/standard/images/input-bg-a.png000066400000000000000000000002361237252063700260650ustar00rootroot00000000000000PNG  IHDRʚ%tEXtSoftwareAdobe ImageReadyqe<@IDATxL @ XZ\h6줵JXϹ3gfˋ(8ـk٩8v"?:UU}.>\q{?|) —^Zy<*===?D"!zx-,LO7wwwVa -?B|6t4)#f 4:8VUUܜԩ| `Z'෶BeX=~}Ι 1H]`MDŽ5e/˫ @tii)H$yϞ.I,v>@m2'*1{BI_]]><<K`iWǵ'xz"섀&sTqs@8v@333oGFF8W3"[W*]JJVlEӽ<*bͶS=@)n}vv6W*VXx9+9ug/@hv 0*\qoŚٝ*ǹp{F Yg"v0 W>7if9QqhVtWwO)毯W.|ŹZf\ Q1ͱ= _`"捝FgM4ڭRX?>*/ϊ/Dv5@$;!,*;@iQ?PlY  qKqLgk&\@~ qx2ifÁFuP` ᄐ |1]#~iΙ4 'CK:#'''3ft_EE&LB,! h*x!j/bsQӽrv -77ɭht !X_\\@I^OJ ,D. I"vcjT}p EDjvI4D\I;l nTW1_4Qhd! n"yC?>>Yupsaa;Ut@K K\}<{>>,//ot{k d5cVg|+N>TObЄ546r,x5~l D½EաhO^r6==i$ .DU<`屩̧IENDB`Collabtive-2.0/templates/standard/theme/standard/images/login-keeplogged.png000066400000000000000000000011161237252063700273340ustar00rootroot00000000000000PNG  IHDRЊtEXtSoftwareAdobe ImageReadyqe<IDATxYMK@6UAA/b'=Wx " ~xb mI&,tξ&& c(JwJB Q 7b!,xMEX~dMwbX i Kf<ݢv`)gȲpf*q ^I OI9'|DFN%A&яXNH~j0 Cֶ~RcڶA0, ?C4?Ftٜ8eb(͔I rÏiV>ׯďX %O8>쌸,G?@IA)J 8JcscVe(k3`HHɠ#`͆_FE[S e\jC`psG3"*{2 ,N?"`,.ugEГHƸSpR[GK;k9 ƅ|feGY[s (lQkıFAُ<iq5D}@fU8z&y?zA<a|{u}?.t!10|c .gP렦"mb< F(epZ0p_ؓG߀Ry7P3͟ 4|бyo5KxbJ{n {MSAG>ooOV٦;e.g!sBmݍ -ܧN y`~< &䩡r5}Z?3<LIqjYoV8Vo mӜ641BSNgg̑F\E.sӬS|@)=iӆ6͇]P cJi3Un[?ܖ>3 RODylrSL/&W@>|XRMk/*m[eZgzX{g~)sҕX]+%\⺹"LKQhζ2,NF)ѐW?&{Z5=Nbx#1:yܴpzƚS5 |E>>ߔYkisYhcqs,iVl!J3+7C?r U&hA!+BEv1Hm{ |)Dl"1#-gyOs_dd 6ṯX^js!]#ݮJ_7& (&B;|dmj9N2֨mvיLW3ʦ(tl`<ײLhOy MBͨS1'7EƑ`R|S9ՆSy5 !h'j>E669*B}umBZOL)CQxT7"_8RQ&IQ[7UL8lad1{Jֵ\Bd.{->m߷:#>LhbdzF+}XWk1ܿMm< |w#kVED2fQW`NBDdqNE֝m)xmP͍u+qaBUG?B/3<ǻۤƯSYEe;@I+ҋW=bʭi/ȡ1,(ӘDO{kT_N;Hbto{@Q|^1Ճ—A%j~cCK4{nQ)8Ҭ<a>7ju+Skoߵg(yЗB8__]tz}Ձ`Dy*B2VZރR :#*I{lwv幏+B̋Ҟ :.O8CKcgmmK؈%\xO,h5G^]/~mXDbF#V7$9)wϞsw\1ϛ-N.5 qGԺ>('"::bR6@̄&`4"bץ;MX%\h8){?ŋ't <H.]`Ql޾T*׮,ܸ8\"fnAs( }G' 7PB!ly9&2idY$Ir9Tp4zhh=wMS ';;$zL@A8ABR9kgo@25;zimL5Ӿ]аSUɩ)(˘dK*Tn.h9R ヹqD[O`u`GD[@fhpDj쥖6 01Q^IENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-admin-b.png000066400000000000000000000026401237252063700263540ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<BIDATxXKLGv~6`p D!A_JD{ȡRKHMK(jm.9BҨj$D!IH%m)T `cX{׀vMHoZofVPUIʮŔiH uGDiDKh(4{.(H:g)K )0Dmρ: w*i4YL}gtT.FL9U+LyB1y hYy9%R,LV6c$"EӌFhTj׍02-u[CZڹv>CHn@ev޲v-P2am@:#Wڐx=!*[z'cf[*>I ?Dv`J!XBL̺=Jt[>t8û3׋}ߛD9)l||3zuRyz~mQT,?^F4t5fGmu-74@Vd,|!.]T,$8twvx<~4h֭b !'akBiڨsץ#,>߶evVUA01=EQPJD)I&z8ұ 37 9wFWBs* `DA3'b߿cW䳣G;ᰕ聼Bf2%irUc9F4C,F,gډ4{! *UILsOz*xi *%]ybB(jW&)NjD80E"[rGTLn֩S,YA,s[+Hoi`2dLfl"P SJC$X%JX E2NRT-Hv үQ%eF$(lPR [R`wL^kCF>\3Zk0wrV;HVǁ罏q~?" F~ 'OD-/bAH;Z/njs{hڍ\+~]^KwP91 h2L6>uޯ0*fɌCD"k^hFfOb}wbBqZ ̨G&]{ǎ:x_(ȿhmn7_|y<)ᘴ45r7 |ibVsgm91 F{@ --G أOʰs3}@.}~8,fs?'0IENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-admin-c.png000066400000000000000000000031741237252063700263600ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<IDATxX]lVIAPV(4 MC4D>bLB{`HѾwW!M-iRЦӤayR ]$IC'N5n4mw9A0JvxQË ܃̈́x&mU껥+ffފIWZBG^BsB3J'EDP{*Kz֚l+p*cAY_\O I4pZoX9@R Rv+hh9Hp0ϊZ+f*F=X,ęf IV*:,|.$LO/8X9@I |9q Gzζiw(/I咆) dˊ-#Np]F{+r u;3 ȁLp%Rߚo=HJn 1NJjm$c$-+ds g VE(9''u+RƸE:QYۋv.(`pEpV.֌NtnWCG>pHGUŋ. 0gnB]ό״wxbg{glE x%|盛w~;)^04:~/rf MV:uOHp`?}toJ,v.I ,vjj- C/#}y}@1{&C喙Ґl|)4x`n坂 (F!M0W lyj$N:"Ka/Y>66֠ہ kiF: @PXJfr F/i ݺ8, ܛ ^Y/oc9=qOeP0 iBp7n4]p799}ҹ#\3) :F3lwC]?}V$DLFyڵ3wWym24 JG^'r<5Nx"a<p477/\`1#㸮ˁrŇoBS$k31I1 HӀ\AWA 0kooJ<+/ߣjP[[ |>e2|P.L`WW׈n!?o2XF'nݢ "osU3ɷ|9K1T9,T2"$ՠ|Xsr*\u+!k_X{V鋙U jfcte0Ⱦ+H*P.~`zk3O,g~ݮ>-3ƽj?0'\t;~C慈̴{SthF,#y(.ه^vāKu Ӏ&z+*ߣq|Qz*]%סP y?؃ΰ\8Ք BgG糿|pt{[s*ZTϡZ[[/J< ˳WVP.%Y֊([?lsV8_< 9๹DeIENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-admin-d.png000066400000000000000000000033251237252063700263570ustar00rootroot00000000000000PNG  IHDR @{usRGBbKGD pHYs  tIME /UIDAThXml[g~{mǎ:N&qta]!l&:N*HhHlR5>Mt_4b EH+e:?cdkŤѬS*4mǍݴ}?r#UYcl_sD^sC:cJt9N:V:|gZi&W $"3 A1 BD7F"ŘFA46oef5\.FP'T{ Fۊ-V@<[YE(tfцrU;p)ڛEn2Bt[H-s"28"#ܼ7"*7 mIbm`HDDj4>6wȈ\.3WH XDMU7dc^Lz6[qIc: c5v: kDs ,^Z:o\)nTguvi–/r#"OKU[lLb+M0Ot97&'O'biքB%qoKmwU ]@JS7Oxg-DO=m}t FL }Lm۶2ݞE ¶q\8 X)⥞m kD"ADaT`:Jf]g|vç*Mp{]4N!4 c>G>GTaKYٲqt B m*!XU:=r'wޭץzALwiC 2\9No>X#gE mA)% =EJ` 0 ^U uqP>t ͷ!|{m7QH"M!Ce/DG?shÞ'|EK峐J"tt6I?'OM0*(B&hj\M[/篨릊Jwjy^o_}=k׫jQDRiΗx/4brt+|魉~lݫ$qyT/}㉃G>633_ouK~x\~]Z xS=? K_o_v]xǙٹ-y;v~C67&־rЋ 딒]A ,UXhÆ\6""èl9B̙:WO{ zl|6.b@*J!m;KdhJ)MTTTz?vϣuuC+ @J ^JI03 }}$#,M\6 A)fRJA*IBӢx][pHZ}#x % ᰆٹ9.\)0hb x0XJ?T.ue`~ٟdT`VPD05uF6ˮm[)s9EJ(xҲdR]Ǐ~4qV]7-˾K*sB_'0V.K ,J)%HW$ ='veHE.FD|X(FA\7$u] nwp͚ȈNV2TM$^{@C <hb8٩_fIENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-bg.jpg000066400000000000000000000006411237252063700254300ustar00rootroot00000000000000JFIFddDucky<Adobed       WP ? *"X PPQ,,U@E((,A XEXCollabtive-2.0/templates/standard/theme/standard/images/main-desk.png000066400000000000000000000016141237252063700257730ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<.IDATxjAOULpbB1,&`0\E D | .&A>m)QD"!2)ϩ1LjPU]uBk]I23xdGQBB6ed!AvL~f v9@: jd5ÎdnLٕ@l$>RwF Ҭ$_SIfe -51k)sh۔(d4PC!_g=jglDyjfS?aeҲɬlQܟ'AѼ MA.h+ l@JndԉhPcBc0MUͳՅ40D:ӏ#LyUv z&#n\!DJI 6Žhi2 +#,U1GIe 2> ED< ^u R>(LOTmG v Li rN K5Lk@T*!pG*^PP\mKiz-v=FSxv(fw wN:Զ@Y )̒+f9 TU$ e_ʛ1bvӦӺ;K!VOCǕ許=;;K(HY8.f2d2hS([v&nmm N~ޟt]廵Zm_%Q { `m~ttwIK \UZ]h4쯿@ೞ#ʪҚC(!өs'O EQ^"1 X]RFodX,2đkq(ρ?" ƹYMX95b#j'n$rll,Ht4P|OD` KR6s>lmbbbs}}&|Hq=n76UU]Cp"&@EH$Zϧ[>x'mtuu٢'y ۥA()ռ<8~F !GXܛ*Jn%\ <8~%\D!2!D"E>x#G'R)?NOo m\c 7~rr E`"}a6lo.r5Ԁ"KxEE Ⱦ!oSb<>>ƒL3s~z}?>>^w܎wvv`WCn5XxS ՍØ'|3hb~ffW[*v5"X=Ө~]4;X$9\I|lʷj*߸s+pGG2!v'| dяb jЪp S###6s (k/H fO)IENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-prof-female.png000066400000000000000000000027001237252063700272370ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<bIDATx{lU̾n%KʂƖ *@ $Z!BƠb4+?j(H[@BMFSWAY;ywi)l;tcI~9{ιs/H$$GHQ 2c"At.9ݮCq̂d-l& 1\H|hyFHVю2mRCۘFAm0rU(aXExE/"-V^m)N Y)v*{̬aIחS5SQr\HO#J&0*! EvGlQc"S-8:9:֛X:L:VQ =fK\y% "w'/,4 _KV&4S493\nEPe H/#%s`oaɪayH\é;@ˮ]98(n=r5%//Az#}j1BrǹhZ!|w-`&+ -;`8l{ <ylEA|9z;HNPjx"Et; Mh RZRVLfp8]-}hFN@EH HqDɁỲpWSy.-tZ'|x s& gh!H 3-_L]8n16uG G^"wa?7i{i[?Qu/u:,-ʳg)`8:x}sgO(|~nyb,v9X๰ȡ ꎵzF+J}.979 h 8/͙R6wv.W{=8x#IK rANeok΂斖q2c?jm[Kѡ[SD W 5P/$ זMCy< HK_؈~6]LË.0%-8\HΥw^Ұ=9AGH^t 7x:%s\{/TSWzp//NgBy?w+[IENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-prof-male.png000066400000000000000000000023771237252063700267360ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<IDATxX[lUwҙ-[CMbR#a#R /1PMJKA iVbm6l-nw2sf<;X {NL_v9r$v {9-aژHiH.%y K1%@& b{B6@`=@~"Qbl!- ^ ! 1Ak,s4Ia UZh9y*ϒK112/FW\xКa~CT4 P-iȏ(%RAp(4HY*Rj4!lfXm OqeC۞@1>ФfcW~B0hK49:d}o54ebj:$p}Hj͚bJoLSPF&  ׹y}K-x}mjtQOQ]GbNXl "DG$ CLSmDIVk!&zsQHc$HB(DSǐqTrx9!>:2+"g/ \ AHF0̀LU8 [يJ_BK0 =]ۭ^Ukc5VK?:.2˲{} I'`wNcΝ?j(h;fÃ'O>@(| m -C3={6S?vNLf%;ly@M>>>G wsFl2.ِwk$d'Ï?Q-?;PFFש v}rjr_T hjl|d4ĢehwOOǛnL{c5Ȇb6AnZӹord}}%kȟz9H9JNHIENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-settings.png000066400000000000000000000016301237252063700267030ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<:IDATxMOAm@E5ME1i{܋Gc@PWI4lbR,%-@DFX]v ]-qН&u'Luqqqc#v &g8'q[(Mnl>:8"@礪v@\RCMRC vZ 0]y"CE`ܕ3N#Fp}:<pgE D [ TQO_>*~*xߛM#@Ku[fD;f;f]ོ8h9q/'(FT'nƄ= vnCkl^{ 6}[:$I,|8niozc<~4F}5["@BU6[E9B t:oZiMRm$ X鹭|glVVSDS eaTGU"">^jKP.;3(JȾDGy&ZUUAN:^/||86%>C8cx<( #d2nuu5g=|vv8677TV@PP(>P g- r${2(|ooMI; h6gpuV닋67 B6yשj;;ӌC"3KQ̓;;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/main-submen.png000066400000000000000000000002611237252063700263330ustar00rootroot00000000000000PNG  IHDR ڛg`tEXtSoftwareAdobe ImageReadyqe<SIDATxb<n H<8ğ82A9@Ƣ[g`BD7πP>"/`@ ڨ6HIENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-files.png000066400000000000000000000004011237252063700271140ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbOc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@#xiIENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-miles.png000066400000000000000000000004011237252063700271230ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxblc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;If9@?bә W@ AlfJ6ɧ@Ļэ dc]#IENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-msgs.png000066400000000000000000000004011237252063700267630ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbLMc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@I#ήf<IENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-neutral.png000066400000000000000000000004011237252063700274640ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbͳc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@$_8IENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-projects.png000066400000000000000000000004011237252063700276430ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb/,c``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;I9@?bә W@ AlfJ6ɧ@Ļэ dc]Em#|ZIENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-tasks.png000066400000000000000000000004011237252063700271370ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb4*c``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@R#hxIENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-timetrack.png000066400000000000000000000004011237252063700277750ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbwc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@#9IENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side-user.png000066400000000000000000000004011237252063700267700ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb ύc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@##Q;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/next-side.png000066400000000000000000000003331237252063700260200ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<}IDATxb<31:f b@0IxO/6IdSI tbk IP1(K 4$ >ĿI2 M.X]ןΒ'EIENDB`Collabtive-2.0/templates/standard/theme/standard/images/no-avatar-female.jpg000066400000000000000000000060021237252063700272320ustar00rootroot00000000000000JFIFddDucky<&Adobed j        0` @!P" !1Aq"0Qa2BRr3`# S4!10AQq a@` q! S#[S[esBJS#׫T6ئv'b@2>U;7F]q#o~~S^A ]^AZHQUP_# ~d^S2!`~i( w_t5_50Tp*RAG[ %?4?4?L6~ZlJzk9#-Z򄜍ePN,4lMg|)Ȉ-(j :)$_fZ;K2+ݡ:MiXm'I }V43hv)͔BZOvkp[`hp)v" ]C =d<"EGt1fݏ; G1"CJ3w9L*scte+p X#k--AAAF<;I2@1uuZ壬^R*8w11TV/o'%{Ԫk5ޥr,Gq 6lx$Y9b8;t\;yxԸt,{GS-c]N$4gkOs+ P?2l+nhuS?_B";ܹyF;72:V={-˗._\a?!Rt\t5~yǨ*%:x砣W,CùrYr?!NRt~Q>Cgn1^+JҠ KKБo,E w ݖi͎o > d]>~./kM#Oɸ^@mk [e@$% ?WpJ*T\3@*TRJ @Ԩ"h%܁\]y-gEL1M$HBt7jr!PPYxIuX˾T;o̎\ODHH*ڏUUW(U@űTfp2su3KE/AA4HRxb:JܷE _%hi2&>i$c! /S{z̤"ňvfuo,0Zڥ nm}$!I ~y Svd9۰e2r{_& h 3PK!u'GY^HjGj~|Xs ò <^c!RC;|n͊;D g"CKnc9<=UXU&*19<} VLcA";eJW(yYU?~'6.:Bx5 }<@3>噛 X;ӬX:`Xc /.,X˗.\r^.\rffffff}?Mj)o2"EˌA a,i$\e%PAa:/]; G9$)?g1h.2u 8քұj:|MW꼢},DPڑI@ZLҪƔ겤D2r Vz3+<2\޳iŒ#/Dmj̅XtewlF7==VU&6 sB}BuۣȠtyk7>KT⤥x+PҔ+I&ixdžTa]Su/?!DO _b&G{ ;h}4=XAʓ]㓴GR"C:.\Gr/󎛜Rѥlqo|<!i ũuxvꓘ9>IbYEn~n/߿UBj\Œ\*c Ad˗/\?! 5aSGg|!쐗:3}+ ] ^3.\z\r%?!{ 5H)- `q ZE2a̪^;auqu|cGS/ Ilg %, ?@_` g`?[]M fH lodO1ӎ&ik!]ɼm{ [d}@$$ ?ֵ*V4RJ+Gh J*$H @)W.ΑǐbbUnw$tx3TO.•rAcԉ7~vǀ@9BKFAL U:&bQлx+| 0 a, BKςK` xP@AYA#:A2+·VF1QbR=e`MKrB }$!`į(64Bb,cԧ!q+_::;ce:"sgcNnAJFn m}%%׿V ww'#S##CB]0ۧtW֊U*fB5*; ;n%[[&GKMl.1! qdY䠽cEAKyD&oxP;;6Ӎ]pyI`VR] :ȱu4 @0bGA_\Xc.\r˗.\ r˗33333?+lµT> 0xߤA{ 4d> e*R^Dse`DD\M=45N"eO?/n#6<{Ƿ2 Dz[euePv!Dcg *Thrʕ*kEyU7TzNҧj:/Collabtive-2.0/templates/standard/theme/standard/images/onlinelist-hover.png000066400000000000000000000001561237252063700274240ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb@ %|IENDB`Collabtive-2.0/templates/standard/theme/standard/images/paging_last.png000066400000000000000000000002661237252063700264150ustar00rootroot00000000000000PNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTELKKyZtRNS A$IDATxb`bbb`b &ÙL &*Y ^ P :IENDB`Collabtive-2.0/templates/standard/theme/standard/images/paging_next.png000066400000000000000000000002661237252063700264300ustar00rootroot00000000000000PNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTELKKyZtRNS A$IDATxb`db`b@hqHj" `pIENDB`Collabtive-2.0/templates/standard/theme/standard/images/root-arrow.png000066400000000000000000000015771237252063700262460ustar00rootroot00000000000000PNG  IHDR+fltEXtSoftwareAdobe ImageReadyqe<!IDATxXMkQ&$$MSZԝ ;qZĺWJ]UDETDDE)ꢥh4z^|5R7fpfy}&'bc#eppwjy6%0ȁk~o겦MWGXH `0,T8YV_P;%TB$D'y*FyCCK!o\BpISkF @ C'S<0P"&FGxCwъ_h3] ReÃE1/zwd@ERMks7l:RZB!0t]3dπq#ΒB؝5%ť/=e$բSf $() XoiL^#cN^ (wvjmGV*բ_y'fPn皽oӾqJJQc`RGG_/ Bnie 8O\P&^l;]Fǫ<,#W=mR<"fD[xJ%^*sYmŊ-DnSt-e )ZՌ4`$imٶ8p.lK/'NbjԐm m)8-.lKY-Ao٪],C %aA"A? m murHnmƖ,nw DaYJlńmDz%k4-Yؖ,lKeE~44pkM&eW2Ԇ"`jN6IENDB`Collabtive-2.0/templates/standard/theme/standard/images/scroll_left_miles.png000066400000000000000000000004061237252063700276220ustar00rootroot00000000000000PNG  IHDR,9&tEXtSoftwareAdobe ImageReadyqe<IDATxblsc8؍21 j 6 F6$6,f=@?a@< a@ &,VMa?.ĀJJEI6wl@܋-ۻ| fBS=w$=\5ڑUKVBKx..~dSk{IENDB`Collabtive-2.0/templates/standard/theme/standard/images/scroll_right_miles.png000066400000000000000000000004021237252063700300010ustar00rootroot00000000000000PNG  IHDR,9&tEXtSoftwareAdobe ImageReadyqe<IDATxblsc``?q+c> b)0b &r' w%!]5JtȀ 0*9*9%Yb Mg2_bW\JC3~\v-gL&x7sX$l,\5kQT##LIENDB`Collabtive-2.0/templates/standard/theme/standard/images/search-butn-side.png000066400000000000000000000023741237252063700272640ustar00rootroot00000000000000PNG  IHDR".M˹tEXtSoftwareAdobe ImageReadyqe<IDATx]U3/L\Lm b?HExWR,4{'HUtY,(Ue!+MB^%̌9O;&$ҽ9o908MN$ԛ{9CpmC f_IÎSWg\,gV8@`f9L(gF(@`9^YIENDB`Collabtive-2.0/templates/standard/theme/standard/images/statusbar_complete.jpg000066400000000000000000000010331237252063700300120ustar00rootroot00000000000000JFIFddDucky<&Adobed         $1!1 8`i?????T??!?!O?!0 ?/G???Collabtive-2.0/templates/standard/theme/standard/images/statusbar_complete_b.jpg000066400000000000000000000005211237252063700303140ustar00rootroot00000000000000JFIFddDucky<Adobed        ] S&!" ?099}l޸&ɃCollabtive-2.0/templates/standard/theme/standard/images/statusbar_incomplete.jpg000066400000000000000000000010171237252063700303430ustar00rootroot00000000000000JFIFddDucky<&Adobed          z"a  __???????!'?!??! ?F??Collabtive-2.0/templates/standard/theme/standard/images/statusbar_incomplete_b.jpg000066400000000000000000000005061237252063700306460ustar00rootroot00000000000000JFIFddDucky<Adobed        XR$! ?xJ[)Collabtive-2.0/templates/standard/theme/standard/images/symbols/000077500000000000000000000000001237252063700251035ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/standard/images/symbols/activity.png000066400000000000000000000025561237252063700274550ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxsUdz?ݤI时VJ*RhZ$L[|_/ʣ'htJ8cb;eH2Hhj+_l~'q>w{=`$/ { `9R/ `0kL3IŹV_3 5ʽR-*tSz{7(̱5[-0nZɧӜ(KQP+JQT (mEOs\!5V.[x=Z,h4f.;TBx$ŲlEAj5{<'BCFЗUF޵p$)hɕG@wouuO5mnh2ix> 4$-qL(!w[71Nϟg`9GS8qэ͍ĝt|S.f }}} C`$Ym!\4񰧧jlhS$iMO)X,|\&\糙L| rR",[W6 L/_Ȼ*N-lYZyC`,dy*5REJ0E#0* s&A8V\hR')0x\Tj`PAM[ z  K$;ṙ0&̖W(vE vc1(!ٚvmmMuz#XդNvp{K陙HN"z7bX9MBo|~Xxbiwv úľ˵ι©ոÿp ! , "^1YIL[j[&u︞ŠmFNcT5imv_&e[= )z-~}ffyiwrunpv­IJ͢ȷƹӴџ߻{^!3A!EVd ! , ='j XWLYxzޯ bXH#6LS ϫtEqSpj=pBeM۳x૿iuyrwz~~kpdqʵ̷μɽĦƨO^AzA *Xb`0d^>b>! , =t" Wj7YI;ݽ69O4B n"iz%eX%bwfolotuxSy|zcfAYpeijlnI7 µ׹H]Ywo~E$(513tGĚx%7_{WS E^t{Tzvgn}rDjxaƿ·־֣׎;_9xb 惸O._3miB'M*~/iD o^IK~ ,! , =ɤ|7 $ '33URL+#(t+);HMJk9po~^Wْ9]-vAyNzQVpm%q)}rvk\~Dh%̼ӺлѾ8`s۷P! (1ٟtw_fqiyk{~dfEpz|&Ŷʺ̼ΨҴmM[|%a|#8`a?*Ȑ]D%cNw&ݕpJ!i! , =ɤ|7(j%amɦ3wF,cHC( Kb^%5Mw-f7.\LM᷹{_u'WmQ~rv@jyYZg?²ĴƸʬ׼սߺ][!z :h7 a w BƏ5^8! , =ɤ|7ٚuqpc 79[^Lp%LFͫ/Bۯ;NtX]lg^G<gqZxVzd|S}btôȾb޾ ilṆ*pb+<! , =ɤ|7YIk˹@N#6ZvdtE'yVJ49W5]oY ^j,gϻ>~Xxbiwv úľ˵ι©ոÿp ;Collabtive-2.0/templates/standard/theme/standard/images/symbols/basecamp.png000066400000000000000000000030031237252063700273600ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxXK$WUvk/Y\G@( #(2@"%$7=)B%#xPA\pq[^guu$ ~^+ar]Qޛjaz6wXfd_X6w/be< DDknn-..|_:|.K9G---'x%`28-774!!{]_-.$$D @隦 Jw@ammmePXwyyb2UUaʛZ[[ o @!-)ixx8# z,a?999Cߛ7tec6C=iooůPt; i憒o7B[02+HvvvhNNKHQDDI! eQQQljjqSmllp`J7sĸ(V  [\\d,::183g,3330Uj\\\iyyy.X}E+++ *sMfgg[__@,,>>P}I K}^UUɌ&鸓 *++`\^^櫍+a]\\ v||WrVIrrrymmm@IϤ~gU1=hg !2K^^g!'!!0'v3нcF"en?0~fO4!#r%&$G8#oG_ sn+49)11I[2+| kMcЬUZ Hz҂ D`U?h§pZ "{`gB ɔg} e ̷}}}PKRRvJJAʀX0zvQ(b/--mvGb)צB]ʾɯ%pܯ1$pj4MA $ǧ kkkMMMH T@/ f}BJe DDPSS (ӥ@[NIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/blank.gif000066400000000000000000000000531237252063700266570ustar00rootroot00000000000000GIF89a!,D;Collabtive-2.0/templates/standard/theme/standard/images/symbols/closelabel.gif000066400000000000000000000012111237252063700276720ustar00rootroot00000000000000GIF89azzzYYY҃䌌PPPTTTVVVRRRXXXQQQSSSUUU{{{```WWWOOOLLLfff___KKKޡlllxxxyyydddZZZﳳ㇇iiiNNNsssMMMggg|||ccc߹pppeeevvvmmmnnnooo,/2X]$(Y';8*'G?,T!'M&HO*DS0 4+8FB( WN1I"\0V#>[+EfiņPZиjH *806ܐAARTAP8Z0ń%0Ƙ$h"XD 'P2ȀPT Z$ = ꔫWJ;Collabtive-2.0/templates/standard/theme/standard/images/symbols/customers.png000066400000000000000000000031321237252063700276340ustar00rootroot00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME6.)!IDATX]l\Wsνw׻ήc'QDI!HiqJU  J҇R B^RWZ7uWJh&|ٻw93y觙93]܄X3l6Ud IbN8?wn.=ݻWDx@[DB! ybpr ܾ}Wu'$IJ0乩y~+NZWuƘCm~,XkATfAXkFP *w`rr硯*8F@~C8fkdժUnZ9$ẒwJMv5vi;" " bQ""޲=03O{DyªH]8&fglyeݏ-pfe(( ! !Pڕk魞@D@BVgMe_; uM6Q6# d3(NEL }tV_%Ӝl&$P&ٌl-[;z K/ )aQl1޾47{> _-xW[Cq]S K9ԈS{|G}Yn¾={..2ͮ[Bۻ*َ|?ћ7> e$~ꕺZr$Żf~[ނo|pexx#s;$n-T֢\{PWv N>=_G{d}gt3ZOWk5<3r&7.Z+S*2>ܯO/,,Ȳ##X`~4f ^Ҋ,Xc7J {{|S}(1c203@)(yV˸K$N7 k- B-[Mg M3Fҵe4@lj3zkh[{" z/5:G \"dBPIB3VyFZ 0D(J""`=8sk 7@ ]]łWxHiEf ꍀ_!k a*^FXdy**AdYf4}!˲yv?9"z]N*k PÁ߃gvHN`+bz[kf{Z;e锰˲dJU+:Zۭyrɵaj H3y9֡y y+Œ}/Yk6IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/empty.gif000066400000000000000000000000611237252063700267250ustar00rootroot00000000000000GIF89a!,\;Collabtive-2.0/templates/standard/theme/standard/images/symbols/files.png000066400000000000000000000022001237252063700267050ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<"IDATxXk1Ɍ~ڃ -D*( AOxB$zVP63M N!f"cDű 54`r2#;sc8yFV I CDſYo옻0`M( \2g)@*\5TkOi)P EM3N̸b{ *S_&ݻ;sl9sDzTUnq#bqVq--a?] ++\aC8^:03*'WVw!s j_T?x*Fª|҂9~LLOXV8vdCO>|R)t e!L#v<)騹 jjPo,S؆ T[n%-‚$%6 .?_(@ M077'Aʒv#t;f\j./} hfP/l0 e\H>wWf%A&RBPusɌJR/PHhP.Κy:gE(D@DGQa(lT_8)W&JJr7Q8\!޼N;A fK;5m5Ojj!v[Iz7̴f0[:jݽg3cc&SE٥ѡq(L,ۀK}+wOg2uIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/folder-root.png000066400000000000000000000021111237252063700300400ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxXIo1~L2ҽtAe ~!! Ul*4M[d~NO!/=;dDWEvF<1۶12JPoEhEXQ[AFIk|jgS;Haj[\L)J~5FY|Dli)|X먑"XHEy\--xTꓧ&[WȞ.fL3Vg3~r\?hM]bz(X& e1M 3q(6,,aޖ? {{dRr#lB: ih,|asB"aA%}/Qf"lMݻa<`YA|/u\VA$ϝb9 p tvA|eI“ojؓgp!ر#Y gOR DŽg܂3܆Qu4|\U2qi*RJ^-(BA?G"DRS6U\)NNj J(B⽫+˟@Gj%CO(i'!1$rZZ Ҏ!GP:TJ^"H%V2 &:o,.qA܍@#4jPkoqv=IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/folder-sub.png000066400000000000000000000006261237252063700276570ustar00rootroot00000000000000PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<8IDATxb?@&pFFF@J=2z\\933s?6񇏟2|򍁓Ov/_1>~p=>^nG:|VżIaC3 b@Ѯ٨WTImIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/indicator_arrows.gif000066400000000000000000000034711237252063700311500ustar00rootroot00000000000000GIF89a_\'Gm7$+!! ,w Ie9*, (*(B5[1 ZIah!GexzJ0e6@V|U4Dm%$͛p \Gx }@+| =+ 1- Ea5l)+!! ,y )䨞'AKڍ,E\(l&;5 5D03a0--ÃpH4V % i p[R"| #  6iZwcw*!! ,y )䨞,K*0 a;׋аY8b`4n ¨Bbbx,( Ƚ  % >  2*i* /:+$v*!! ,u )䨞l[$ Jq[q 3`Q[5:IX!0rAD8 CvHPfiiQAP@pC %D PQ46  iciNj0w )#!! ,y ). q ,G Jr(J8 C*B,&< h W~-`, ,>; 8RN<, <1T] c' qk$ @)#!;Collabtive-2.0/templates/standard/theme/standard/images/symbols/join.gif000066400000000000000000000001051237252063700265250ustar00rootroot00000000000000GIF89a!,(,Gj4bIA;Collabtive-2.0/templates/standard/theme/standard/images/symbols/joinbottom.gif000066400000000000000000000001021237252063700277470ustar00rootroot00000000000000GIF89a!,(,GjH扦F;Collabtive-2.0/templates/standard/theme/standard/images/symbols/line.gif000066400000000000000000000001021237252063700265120ustar00rootroot00000000000000GIF89a!,(,G}W(Ndh;Collabtive-2.0/templates/standard/theme/standard/images/symbols/loader-cal.gif000066400000000000000000000034711237252063700276020ustar00rootroot00000000000000GIF89aNHWRb]©䪆zuﱑ˵! NETSCAPE2.0!Created with ajaxload.info! ,w  !DBAH¬aD@ ^AXP@"UQ# B\; 1 o:2$v@ $|,3 _# d53" s5 e!! ,v i@e9DAA/`ph$Ca%@ pHxFuSx# .݄YfL_" p 3BW ]|L \6{|z87[7!! ,x  e9DE"2r,qPj`8@8bH, *0- mFW9LPE3+ (B"  f{*BW_/ @_$~Kr7Ar7!! ,v 4e9!H"* Q/@-4ép4R+-pȧ`P(6᠝U/  *,)(+/]"lO/*Ak K]A~666!! ,l ie9"* -80H=N; TEqe UoK2_WZ݌V1jgWe@tuH//w`?f~#6#!! ,~ ,e9"* ; pR%#0` 'c(J@@/1i4`VBV u}"caNi/ ] ))-Lel  mi} me[+!! ,y Ie9"M6*¨"7E͖@G((L&pqj@Z %@wZ) pl( ԭqu*R&c `))( s_J>_\'Gm7$+!! ,w Ie9*, (*(B5[1 ZIah!GexzJ0e6@V|U4Dm%$͛p \Gx }@+| =+ 1- Ea5l)+!! ,y )䨞'AKڍ,E\(l&;5 5D03a0--ÃpH4V % i p[R"| #  6iZwcw*!! ,y )䨞,K*0 a;׋аY8b`4n ¨Bbbx,( Ƚ  % >  2*i* /:+$v*!! ,u )䨞l[$ Jq[q 3`Q[5:IX!0rAD8 CvHPfiiQAP@pC %D PQ46  iciNj0w )#!! ,y ). q ,G Jr(J8 C*B,&< h W~-`, ,>; 8RN<, <1T] c' qk$ @)#!;Collabtive-2.0/templates/standard/theme/standard/images/symbols/loading.gif000066400000000000000000000023771237252063700272200ustar00rootroot00000000000000GIF89a&&&似̪ظppphhhFFFHHH222PPP666VVV! ! NETSCAPE2.0,@pHL<á ĨtW`4S退-k\J%<f4c`𸜛 GyXg{wQoX  hDd aeTyvkyBVe vC pyC yFpQpGpPCpHpͫpIp pJe֝Xϧe p X%ia6Ž'_SjtEYB!  B !BvGur GA! !,XpH,(q9XP2TDK%fPGC P~@D@XĆ۩S~ S  S!u~! A;Collabtive-2.0/templates/standard/theme/standard/images/symbols/miles.png000066400000000000000000000032141237252063700267220ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<.IDATxڤXolSU?ڮؠus`aP B_ DB ~"L4bhI B8`0Ǻu]o֕ۜ9wN9W"sKaўohd#?^!R[ut'i[ ۇa;8N=I9{څydTtY!f^U}Sa`SCCq\N>ñ]w&@=+/UTWɬ]b_ˆ1ڷW`c4j}xgǶP!x,SdݾuvzDR$DJE0LHD0Xj_ʊVH?bd~JẺi` K&8Pwh1JƤ8Lœlr84SǿDî1 ~?R48v- Htt^ ަȅԔgc*(/gW˝[ аr'Ri`2[xk{& xkjPԄ&"b+6669>T2 rɹz dg3`5dotEV"0a1:4z(^MZ 34cr6` ˫iՅeH d9>*}6/7[rιqboxkJ V+4<5 3HFXHLM2?}Ͻ^&7eΜt@ٕ7l;w` 9oZ'{c/_da}6ĢQw]E3B; ?Q0RzBNe>ִ' e3n&˴R$14~?Hpl<5.E6##*A$DH;H&8ٌvW&kׯY[W?/Klny=rsWd<zvb8IMĈճJ $˹7GƫqZ }E 0N^wo\'x붴p(рeIbgvť#$apuiI$練wWѧ[sJ6`*ܘlF"CVHblִOEBlTӖD)PFy##Jgc F,9јfl.]]{q9\p jk+) s%IFZP'HP_=1иV_'_ ¼ԤE_ LdC ѶFgjjs1Ħ%8YKeazI<ŀgshR#>ëk$`O GZۈI^]W  ( q|f BμST%*Ύgȳw1Vj2$YB+sd$@`&D =KUO.b|$cF)գ,%Yu&Ȱt*dδ@!?ڔڢtbERS:̓JV`P:k6Qeu: *3f|#m+E!\.?MBݻw mt``ff=A*55 A.G>FT(ZI?L` gAFMbzO^9+سw?6Ds.jg#3H&&SIttt L"E;"Q(FFF|صkD m"*rmjI&I!њ6г)I@EDVJ 7v |?SGx ˔*W (hʔPk4ȷށ.^Dn\@:8}χɛ7B>Gy]98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/plus.gif000066400000000000000000000001311237252063700265500ustar00rootroot00000000000000GIF89a!,*/Z"'hny&gSuM:+;Collabtive-2.0/templates/standard/theme/standard/images/symbols/plusbottom.gif000066400000000000000000000001301237252063700277740ustar00rootroot00000000000000GIF89a!,)/Z"'hny&gSuM~_;Collabtive-2.0/templates/standard/theme/standard/images/symbols/prev.gif000066400000000000000000000005631237252063700265520ustar00rootroot00000000000000GIF89a? bbbmmmǺyyy廻WWW333!,? `&dihprmx|pH,ibpdӦ@i@0CS +&vOR =Dak# ~Xb%| BLbs# i&`LQ}eg|X""Nhr#\C&d"&x \j$j&~ȄrXtu`YJ"+*$H0 TPaÄ#JHS;Collabtive-2.0/templates/standard/theme/standard/images/symbols/projects.png000066400000000000000000000026171237252063700274500ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<1IDATxWMoE~fv$N\'$*R  *T =rF Hpp)D@PUHJ>4M4;gzgg?…_zvgsc ?k˹ Y SBy R <1"XJlu jm(L[  {{{L~  踌7~eX6%:T*|/7;?|K\oSCXaCD|G5Ɔ%lVԬ=ӓO%ɤΖ\4S m6-+cp>=yZ+ s[!d)0fbNOL:y̲9~Hh`L?dsL^^< 1??qLs ~'yUh[6-W Hxu $Clnn~0ͽYVclEDŚH#^91N*dqsaOMN"4vb!Q>6Yn]Y× Nc⋨jL; QF40U`Ƹ\{u2pxx(Ad2q>f403yӀ拏9, q6(J3r~i5OSfXG anתUk/\x"ba畉3"ZX41zj){{իs[<ۉjwX+сOKdrclomT( =24O~}Y|偏RXo՜ufFU;sh騀DO~+k+IR>~WȊQ==g\O~xzz5U"Y7k*J7##}^$la.=L]^>_T.6vccӓP;VcۉRU \y!-P"cCoNON&#T*)g|$z `ag31kx-s0[nGxJ5EWI_Işi^ ۺugʪXBP9lH(f8Yp}le[t&`j3Jʼ5NUF1 <4Un1b&O6yw-PͰDq<ğ|lZ;s=\z1atQJg!X+qc]]k}("r 8JW# HS[)%v#t@ dXs 4nj9qT4!'cM0;IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/search.png000066400000000000000000000025551237252063700270650ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx_L[UZI\ EHfHH@`6=%7.|@gmIA#5Bs^ϽMl=?$ˇ?CD^k|G?2s2|?0 @"rOYPTaIjŨŭP(~왻Yj(Ww$m򄍍 PZZJ~ \=SFPIQ{矺Az  > T3CF[[[Exe3t> mooQ@c' h  V0~cLn7k+.U魷yMUMS%GyEE9,W0vf7ȁFou2<=M=BӴ|A-X s=+_! ʂ(X҂!pqEQ `>8hssI(Bopx[vFT^ٓp@ nll,z>ޕJvaN*SI~V,y}QU'pxJS45h 6t;_f;VG4 Օw= RʼnW$2RBzt>vYOUh斛 S~,$ 4=g{<ޑٺ:C`zzc^2 S*;us{WV&''_XX0ԃ0Ef::;?dYN$芍z C!h z`P eD{ #^~@"AO8 @2ud0@ah*c Dok\ LοEzp0 093tpIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/system-settings.png000066400000000000000000000035661237252063700310050ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘p WKT$K1Eog4a 5=E QRQA38EDB ITR0)I]rroEtf{`Y+ ޡx7yxYq W@M0JBlt}j%k6?-5so\\@e/!*zRAS({hkzRo (dslCC ;j7nݹdF&|˺rvvC\]ۻN0Qb2rؓ6wnDevXс()z:0 MTorO2`༥[(fPoFchawRS&$$`1| &v jTP 00pJ'd@Z֢~d-fQ)*'&B+:mYݿs"ۥ)Cʩ;Ŕ\ISŸAZ]Yu.%xdt\GtP0J0` 'w<3<1 FuG_MԔOf%$^gw,gO-;˺~V Os߰477Attomm]ǏX,Ks 0LOUa x0%k!H1#[nR*Up}%(**ј!̏ mY:n@@U8k|nx\SƏKy榾 88'OaaƑ>ƍt)/Ct7Ð Zyi4]Eөܼ ].' zwUuu5ߙ}0##rKiʂ;t S𽊿D0\˿R`=بbd$eee(&YP+SOĠU,Wn5t:`̘1D^tXN0m.1iyݾ}ݻӛ6mJ>^˹Tۿr^NUmZα]Kg{ewE N5L 33Ssp9+w\Mu)jgFz@$܄*FZ^a#VYPR7Nj[ERL [S{͚q Nc=+.dDXC :ɍy77FI κ%Ό&[7J,`pkD{m6ͬ5۞??D;ʳo'?!ޠxt;/JP-A:I] U4NunJ""Mqn@o5bS uY"8^O]72Ar HmĐ$K#HCDM6W Nn' 9<ar {Fm(:Æ\?^.,S;Iu֏+!Ig,Z }{"rȊpim )]XMvz;lW(FeLP(H)¥9Ml؊U]axm̸ F~h+/ A@ /"ԁԢ&WjuJ7p#7uq$zs*HH Pc▣Rd3.mcA?N.:]P ^k]5BvO*7ݭUPyfnaXo<_ya"T z>H1>901{+ o7Z," R"RVUPtAͦS*fdhƆ6}-yRK}{7)l&>^OwdhJY&)*3ہMϰ|3R.R~Oў%dR!=f6Fwl}?]Ow\4o<47[l/&"b" |_Oh7.-9& CB8bޏ8ff"F)gJ{Vt>Fۊ!\Q͎jv_/'IH b!_*/.5ts7Ju0kx>Sf2d s!;u::sO~6^MåwxUA@`? bnB{^<Jb S!1LY :B77Z d+~/)֑TaZaE EqL3_<5ٙ} I;081a(U,^Z.|[;>DVځ4N[Xf]0J8┒Աŕzj 9qaO6S C{$is^mc$i¦Iqi5qFkdZ0  "&B/V DI*Dْ雓9WFT4"C=Y`z3usiBY[@B;m&]x&"gky9bnd}s9Nr)gi3z$")I@$꤂@ R(@PLDJLp"I@p'VHaXR_ s}'UF1JT] _A(NIcC. a.I ΁Bʲy`02ixibKu%ٚumu2NR399ՎSwv}jZj 8D( NI}:HVBzj9* S)sG,F8$umd'𨂜<ϣmS\XYY^[kmNWU4xyH!qx 'PavĜB<844+`u^Z8aN@. %焜_F+H2fZISq{ij=k-)Q#Wc1F|abs}ρ ũq#$&ML[d%ABU!d03 \p"s<1rY{a()HSgR+e8ƉwkAjW/EDu﵀3^DʜAI vCGy2g>VZ7Z d6p*&TDe 1%л/]W de6Juõgm J*lczhfDk'-[ꑪ VͤbtݛI[]{gQu[7se'-ϵrSxwŭqkƭ.yä\l Y1`@@ZTbMu!v288|\v]VrΥQWW]+E-fDthtt|3Af.qYkpT8l]rW`jz?ht:HDs9XkamʾZfW|wE?]dê8׏_YXZ ,tWgw-V+pQ",4Dn.'8*Q\.VkVZbeejzj ^û!ô&L0ayٺ4>w\liA&G 'RØ^<\5]NxN 2`c=įO~?Pp%5ݰ/~.4ȝIXh=G r^qb e=q`G(>Oڽ_vE\Uug0~30W_}5?X?uI @9Jݷ|ā] n]s/?Ea\pѲ3MNNҫNVo([:!q fw3I\ i'Tw>[JGnʪ?HX,Nr05Ƙ>HObHS?<ٮmCk4IʛԱP($x@l {Ÿ}t"gcUXpi :::jg3w/ )ff.aFrP ͸BvdAIҹX5 SU/" jvTc2n!"Z\\Sx2`\Fed^!pzzZJB݈]"[k(ܹss={l~! > 70_©SjI9'7{#t!c4 Z\\N'<>| nqE$|| 삹?*SSSZTX,nuۦΡnZbaa^~v45jh4PULL{箇w~}sCnHWQO^:i]za<17rKwNKKK8iG/`f 0Dŋ/BD>K_‘+q+Gavn6kl'B$ ^~zLJ?v \n6}݇Zz/7&'&0::Rq`=-d C}kkk.oIH,C֚*nO\]w-gK%TB7`0XZ^tN\lvu韡j9 {x6&IҍZ+>AW^E2@ss]1 FsyyNdA:X{-靥4/fw'3avvV?*lB7볾*t:m$"r980VkIdDtuŋЉb4ν O#\]Zr41eJwƺJ>0y8ws3`f8k9 38vlE\) @T@ 8qYfF?z Je I(= nQpE9sI\00FK ؏?pO?AG@뮻u7o T\.@Xľ=8vgw dvQn# CZ-Z-" C$I4M\fyh |?yJ% b``R R B\n={F=t/6&lf'Z;vۑwΓ统ۋIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-desk.png000066400000000000000000000070521237252063700273070ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe< IDATx[KodGۏ3!RD~bM#~@$xX;:DH#ÞĎcV;Uu}$J}ޮ;;ꖥsN|y  /@N [?؛~W>(43 cնZ]mG|/UM(;iwXQ/J[:TXg n+,ߍfuug7o ]yՕo|?Pi @N3ι|O c V T{l=y.g:WpwwlCПL,v' Ks@SƃcPƟ5`#`r)#KɁ%0!PTq`Df]Ο?y۩0 ^fy} PXg Ö,ʜ| d4tT@:e8 Qk*NX {a/ q$,TSVQGa|MW퀯8˨8*Ƙ,Kr ++3isGm;=,ٳgG{Sd,;?eBT^Onnn굵EϤ7WT:͟m6T3E\Ă)z۷ƍtnnnTSy_SY( Lf,6fS! 1(x֐+- QUB?FKT^Eg7CQ:$+b,Λ'E]glT^ڟG7I%7ft/Apa'zH\e~yl0Ub䤯 Tܪۯ/Bg BR8,1v O话d2!5~J@^x-8njD73V낙RRLRlP]u|L0"Z=͊'`^9i3 Bꈹbݤ/Jm"=n{IPsY8YWݝ$&YٛuggGs n]Ѱˢl/*HOھ D#IPW*7FL Gc~W߽;wijϮj̕NꓥL!Da?<4{{{b&x ϊ%`j51;;$m#`(`~kkKλ.rY@Ph u9j׌X9Ue.)ٜ-=quȀNSNUA9$uave>&ƹߝS}+C @nln}og⯨V˹+j[ArcAn%xn"&~~֓ĮڿxX8$AI|2T֭\a#s.OwΪ%F `J!ݣJ̷r/e@ d-YbeA0SE_\N1@x ٌC^qeLrs$7\ZF7|z:x YQFcsIQK1M&S_>AyDA ځ@mpnղ X`n3MOXl,x[70pĢ(O*pǃHkwfo -MLm:.*j 0AI, muJYĦ(؈c+hρ$'aqli&b<qC^s-!w@hoh Z$gk{|2SD }4߸fYl}l_nc!THFEד%CDP%B,?N` t7OM&j'pL!!s^֨5M= r) @0s11w@jU\vGWV8:?NEFTNu Dݴ_ z86F )eKAicxS=;2U#zs}Ey,x4?ܵhA#q]SF)!@OxL$2/_RƏ#\|4;ɓ@s EhEI.ܲi)j\c^d;o)>+.| O,Ztq(=O&% 4#*#q@P$& 9>#C8ds.hZ|an6HVta E6)й$9Kz{ d*-lZ}ؾ]oE @X%?gَg\HOȏzH"xd%EA1%ykQi=} sgR~ wo?=(V!ZǁDMdl^Ԉ&gsd ՋO(嚪}btVkJteù6{?xZPA2Q(L3IJ FMsH{tG~k{Yx76VaRr$ Ќc= #*|L'8s92<3cg- i`.dȚ ]mgd3WϤe GtQ)+l'{]ueC]QdA,sڤZʹ8ǢGw:_Ə2j'BƆ鸛lPc#qi۳;_u׳-ЭC~}Yl; c,QS4_IcVO7Vh} Os'@OgYL<ܼ ]' [ڿ#oͽx-K0*PE z׀0ʢpKi1Ye !sǏ"zU͜}y }yhe$O@VDdltnr Ki+H%6iAdY`@ȩl6 H6% ¶P`{=MceJ 7AcFve[Y q>=𚝁% a/@4EU F7l9N `< .TV~gwՕ"]j-c2 djy<~ȯpC1!鄘Kl퐖 ܐ1/FvG;j"vCe}%K5TIPE@O敕,X 2䆆*%d-36hF1$Iv|"WՎqA UeIі%&R?*x]umM~z*e % Q"C!Gnn.Fahp q$.{z P[?05>x5fCh B\ 0p'X2̕]Lkg.&BN. J°˳®]HᆆsrY[nR0pF͂`ւQMW Se ] ;X*ز.ɕ$כͻ b1MSDEHt wMڽ{wNaQ mPmVj04s !3±acm)w]e!>E䖾YwM-|jvC7nd@o&Xntttֳ#Y_aQgƛz-%-Andd4ğ4Ot Wf=vZ01Р`QQyQ^WQ!mիWC[[\N> }}}i@jkF۳-HG]qHt\۳Q@qN6ˍc+A C|eq15kְvЗ/_* ]qLπ^{; wn8t}4Ȏĭ@w{[ WnڼTQa9Z`Ds9Lu&j xS#pךq HDمOY(WKAN&?)Py!L)qYYQ{h # ChO|?C S."& 6 vF 13'4g:ocd ᕽR}eğ?@wiXkldʵ $ ܌AZuѣ)q*7~ɗ;u>[ P:5"Ơf "֒p|ƾƑ3&pwxŘ%γ|j75[CQz؉A?Ȩ? 79 @Μ*|&99duVLvqmx 7v`iaNͼ2VX>xu<@؝5la-ʏOR q8&ɓ= (+ᮯ. `U}TA8m :dCyQ14zXV_999MC;r#LA׫ Dt~Pڱ:&>!7VY +g:}]u5FM1kB82W1t`b-b؟]b1gEK u 3W XevI`>e>l5U {8'D1v.5H 03 YSzpd]+i{s_ }WPu*l4{>.ʶNhwy\} [(Bi(DSrQY~Kx],z DSC@S@I $xPi~@?6 Q*ݺQ0=m ;o]" d6)m_qȒ6Y*?3$@dJOh/䌲K1 J0n`󎃾RWcl%nk+wlr(8na9œ DbI{7 WF3f3cr%߰sֺTiUј',Ibr FV>#-ftEΊUyI,MI60:nLC3АK(3Bw ~694=s{d~XS`ΖZUywދ][/6(ԄK&0ZYaeƓB4 }vy\<6|5/j0"=mh 0|SNm)}%tc^b"ڝP0;czur2 ф?ECMϣ 3 Kw:.$(o J?n pz3t( U!PPU;uwd,ώ,@T }wwKH8H-Hw+j54)N޵<8f&F!2.S@ichBBI8xR]qb:>PtDPU oQ2گwxbv_EIvN k,8HZd$mHhd"q,Ah7;²KIb՞m5QT(:(`w3b2 "%ek ;FUkKg@EIFr LNjjFvN77 tmxlCE7l>y$0Ľs?~UwL'PNb/wDi孮=X#F`n6#23LAwioF HO=_mwUw0CWv^v#8 T>s[j{4nS6Kej@rչY<%׺{? h{7[G'[$7&-%ԫ?yh{Tܿ. J 3h~YUujF'VŅĘM=cc0e~U3{}~C}uBL(3CfL>~aQ& /ډs}%Ȑ^W7ȦQt$)$.x.lyGcH uFWr}'g#ܦH@tkj&9#5m30/=JifCEmRWCd1%\+TsTg߿=&n  U-C&8 1 tUK?b$A"+fL͸!/2J[)zδvC~cD"#Qr^0"1JR)"tPB۰#(ʼn?,-Qb` }r޶n_:.}XďK_mFĜYj+@$ԆƧT^ . mUO^;+鰡Y eDd(XɄ^BϘ+ )( WGSؗo^[{s5coPdUP4ʨA:OcFk@%.$X+&J'#OM%ljJq榁8 /q0u@V$=g]_㣆HStI r+ le' Qt$1J{ VXR1&%Q`F"ai$"5SwbbFM+Kd` /K'tkfD)I gQ1903": UQU E%`88d1;d*/c٦Qb3ȲEʞ3!9"^=r^0[<_Rd^/cM683sǏXr钞&p*|O`s B^Egi9Xy19l1"--͘&8@]?˔)e ]jGEs\ue 0[Zxebţ52Rk#: |W}k^[w<mxr1Ikyؽe;kXZj>3A &8M&ͽZ%H9F_uxw׻vG*+06kFX.k!lзup>w`K[>Jz/]/ / 7,J ?L{G>w.mXe~=ggo*#(+]fw4~]g/ .jn*FcqvE|wqx/$ V9N_|ʪW'ކ_k8R 4|S=dm6B=zp7*~'~mjˍs$t~oPͲɏZAD~h|\$;Z:}Xٽx@]n7E(XFviǴoܴJJ=7P>ɋ9^!R /hx}#eP6^s{&p艧~Ux8PwtP-mۣuYJ>߿\ BrdD;ڧ&;yb' g!13W\~@NV[y_iYL&Y FRTDuU0hʈTTXM )x*ԅʝk,slcYa/ xElDۋ ׬f(I`I]tfzRgJ"555EW_-ٲߙ$`d "|̅m2IV@6~`)b<+1켵Ξ=ksr"`N)PT$$[N(g.߻ZvDC)3@`R4@udGޯ5.:JKN˰lh4}Qرc蠠QF~ckb|4n,PАpuTO* nI]B:\ H}[ZuA 0IYI& 0³>+Kȧjj,։kQKt  X0_O_fGF%:%U Š -}Lx+"^%ƾ>DaffիWQȑ#[2qu)RWb#7N~x$.<$?>5e%:i .`XWok+NN`bbn޼is3JJJdL) [?s>/vӏ=g|&e3:z[*Oj7n@[[$FΉ'×\kbqxt^<~S3e>墑(f;DA7TV—>SS_7aoGl޼"V#, "w!L0|vEs`u5ѓO:&@.lZU%OzʕUь-?y)}8s`jfa6jfs@P{V:^ g׬VUXms3~Db&wzn~~` 6r<+B=x:ʫ_r_>`qeli61dF&` 2{awܝstWէO>gE35]OwU}Ror #zc]05H`:9g?g:c(| +?raٶ׽dT疝g:~$7kx:*P b\~]6U*$3Au'5|>zr=A,xXt@>=Ȏ¤.^Yf(Cf[f d?c"ʣ`OX!r]U'$6Z;l@YűkE][\2:@'l _tXcX"φu 93 g˳% ( èObXYW^9"#jkǗV8NVS:$-.;l.|g>B\'9| ^'clZM!9[K/m,y9 R%n ku' 6')*[΋w421qG I+cp}nO ӛ[g'(D1odd~Zʧ-59Oby.8fE@n* *Tȱ٩ 㡉P4y'8E2(b9%xd8@i @S^]aR4ԧ,CB-kIt5gf1>qłmq1H E|ìXbvR(sdl6 C|皆HQ #E#rbgvZFȠYm1hfc:jiDI.LY#aFԅtߺlX0jҲ bF;]lKw.nNNAPgr\~MrO&q%M@ HIMEIȡ̛$ng#}֕D1 2e+P&. q0:7Ad%VoU  {zbE־Og'z; ; h[Ӥ> 㒁S.#0ZNB<0`mh!"W#I 0o/.c??{٥(`Rm@ӬQ]k7 lLg0lw\)$UdѶ:ƅK$قi2@oߦf5ZP'eԽ~Xְ?m2|dhsES&Ó$`IA 6$_W7nŗaj'Ų7Y4̤5XI8dAU&2kg#1b,˄s~a0B?0d 1ԛݫ"",>q?FyZT&ِkRPQi1ҵ.+|T^ym쪫? >EAʄgAgڨVVԳɯ8S>8AmfE]2;/aw_ʓ q_P<N=N8[lةH;9kf:g Jhw Ͷƻ^=d89\Դ-90V-Dh/lN>ʂ\/ˀAo*w^2p~,2 6;37~AzjWXƘ-OCrm`0D[] + Π$s  '~QFu;{ϧO&1ma_ő}3ʢ./Wd,PX&o:~͊ tR fuIl]ʵ~=O{QON:Bh xYMɻu۶mf$WuI *SYbW$oA-=)[P2\} {>sGvSHuXzb6졲 X=$6g7/~B){N(KYt3-y`#1[[&庆qБm3$[0a|>MgR^r!~ mkIa@NavнEsY/Jf! Zuh"A'[H1)99N^'08cBL6/|J^wf aXMWe_ qԩwOY WAAEYEnˈ?ޡA"ttydj[oT7MSB_^._y?#Te$=WwGV1g`m'L仏!?oP, 1)6,S 2^s=uNR$N`K"TgBog\" erwYuy;wap8rZIh1EѬaBP7 1(C&{Yme8H mgo}TU`UVVV8}֓vX dXd|>JVt ,௸駩c3PG[Zl`%Ê+a?Mc /|hBJ,SSS,.d吒aA"eI[z_XD7u:p zֵ%=cK&נɱu\d1>z!5QPR@#7T8HU\/} P}1/ٷUIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-miles.png000066400000000000000000000111701237252063700274660ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\ylyؓ. > '/,:4V ;895v*rZmKo<^R+6G[9UsϾq9hZ*$̊QSd_PX|+"0B7Tomgj PRY= 낶//G[`[_`z/9v*kIuHxT#S015s!S " ar# pGsv | ΟHGՑek&% 2$Q]Rano;wu@e;w?[&d"YG2U)dTC]u*4Xnh|g[WBa8\쳔U;=׵$V-e %c` UebI$m)0:zW`R#@ڝn(mNd/@7 v_ b޾JȹdDH%n2nj5van}':~9FQH#T5TzM%AZl׊{?$ e[F*pn 00:M>g{_;f _A;}UUQ&V+mj2ZWU!%$iKt/\+a8_;v ĶA `R{=Pq4G!}t2G̔!B.ՐXt<VJH]ހadP}ѴH&! ]<=C6GŔ$RCI)O8RTQDbBJYg'>FfaCxQ1)mл~O2g#H_A>+{S6LɤhI G9.sa`cS6.mu9gJGϞڷ\t IQU3xLII$$r9K3m̑ l#bJK$ۈ."Tb*L'%SeU ,Jyث}pk?0gi]vBCUAIHW&D[QH])I"\,.80<2$eвS-@7PuJdv{C*.t<TQ4@Iq Ia ގF3;Mi֐نDJC;C`6S̆)&ѬQA"W#aX$zK9]*"s6rdltK#d '0W.Ì lJ>G!{&Ӻ)I*l\RvI\΋Vs ܘ]g.Tv$*YI8MD MBZ% !% Z \VT2(J fdH=^1iX,$|!P=bQcPªcW2D"H+EGcc@L;KcE͂`ٽ׾΃frJBUQqPUsdմI&vm0cJgUmJie8vm))Za5{KUsŚۓ[2/B]h;'ZӬn(I[vMw˕\X&de`Mٵ,PtwA(+ Sx>酇OAT?F_򈙛F`Qt]YxRBaCI5C_26}9*+3J{`Zgŏw>WQi$ >ʫgv~/x{ƣYSrDpiNKL@yy=͒1xPS 4g:GHuEz_z;ZxgM@;ޯD:ٳg!Y\\Rډ8S=6 A 0;pAWmskPX\ #ס'an2 ;,ɶ nNJ@J[:x>(ls0-hi?)ntv]<9ohjZ1<zd}w4X_cd<y0뚙ROɉLe[bha.h3!P~VggWV~l~u ±#Ʒ4I H:@[8RיqO Ox^CuUovXpG`]龙Mj <@zk)iEm远>J 6>"pFqB0 _gm6loQHad0?6|/<dۤizkw!V N}&˝O< 3 CN8𕯂tC͇ wkW.{ v|>`PxJMtے`xDJ. u۶|ov, v]&ؾyn C ?غMH}X],q.I37Zr3s(}ܱCƼ7?7w>'b>S 5C4/P~pꍣ0Ixb! Z+O9>?g/}yɻDG糫'͠%*L]{:C}K+gwdϩP{u5d4g0󓗡htNfzw91*%>oӮ-nymg.Zv[擫]!IC )R |eQiTo~^IW/I9x T .كqq%h{t?Jo?Kx\ OO:ikͤIB:+ ^EG@U kg|0 3b%u`'`eh%L@Syz,v^H]u$IFRsak)ibZ+Z͘~lȮ uan>i$1GL޼.#75ö rv YL,>Ǘ0TJZ,dF0uk b$I@AW%[%r`٘ժ}Zi47Kz?#LhA~˧ 09̆8IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-msgs.png000066400000000000000000000101221237252063700273220ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\klfvvsc;qEx*6$*Rh6IQ+?*_ZAD! $Ďޝ~ۙfc';k JW3{=qqe"E A.\9;=޻{vqDccf#^֒2 เPm urnEʯxW:WH$rf48[3)CiLTգ1%,@r03KQi? |ɕh955HT-QY9g(5s95*SQA4[7&09M GwN ,Ɔn ]6uѲ%>j帝nq =gi5tקRυIc6 =ec= LÿnoZ+:oXJ=A޼ E$kh*8NZ:ɵ& E%x lGꉖ떖Kߐ*J @&8_<Ƈhl`5WW&cf+NJ?!/;2:x}vnٴCC up_V ˎQlk2++`{JG`>yPK4k2!bhmE7}ƘZGf3U<,;wS&N*Ǚ1ff2B.c{OJb^vV,i,hNO3C-V ۩z ˱,S)"OxI|-~pMٰZG')"ӚJx&6|%fb%@vb < (7hPrs`HPSTkggHygf-UW @sqN1S{w0c<˶ HvJD(@r**=0@(Nfe4$ ^MTdJkW,1Il9Ч8c3 b+7*Ϫvi]IȵoU*hx,H%E^x$`hhtp:5$8O ᕯb ho_1|Eb0Zx| lۺYlj)%84s{pN2@Ss~ xvAZ6Iiq@bg/X[6 A&ɤ}J=9m1in[M›b̎04dt'j 1M[%nڦFp@3 *Lr83ٞ1Gv ̨xVY-l6MPHGR(Egڳ 0i.>!N,+9i]m7Xv &ql,0epha.u["NM $~h&Va9in @Q9Lo<abb.d2xz*`I\8Oddb5gKl$X<*10 3qoŰɉc),n߱Mn oNNq/2maDao eE;NG@F"a/`)eK3Eܰ4!yH) l=E@[±}옼XjddHeNL:i%Sz[QbC Dt v*e"E d齻GNELXѣQvF6Fk|~k7|1)#ҊϹ̆'K}=TĀOS]]=_J<$ZGh[k Dk׮] U i ʕ 7^`8{,(@UU(SS\X 5|E!OLÏVU-ϥ !nEve%LTVVFKy#̞G=]r-]|C|/R,3qҜnڵ{MNN&=pz;fkoFeK P;::+ًzfڒT#ORoo  2=.#+4:|,F3亜3\ X.=uuu,=\͖3M6%mHv[S]Ko.utQ08! Sܳ{Jq;+Kz 񃙲7C"wks @icM2-PawO6:Wt{/yy0+38EkUե*XJtَ SIIwvv94 #e;m`یm`"A@Br>&KKK Z/r$$v|MMۗ8Y6uu͛o5ȴYFtIՂB<Nk1vbYPCv/[ O @fRvv:Dgϝ?O~V_-JEuKsrղ͵!l~,BG\SYEz(Tݽ}.2<<,7Y+ionndF W&|,D#JJ(C#OizzZu,?~ Fi`TZf Zǎ ,^r={㔗祁^ +WɪOXC40mKhMb%Hא|%$PWw'g9518_I9܅rc:]Nh;If>\SŹ: =$<-_ﰿ UGϞ[pQPWr}C^Ko$IQm4dP N,2AGFOJ۬T\/_z0s rg'$k>>ArO!b3nP$!`1{!qOZ$ X] `3| /W\"4XcJbrOސ<Жn8h. lS6XX\rЁe`r4`1*9uA}Օ, QPTҘ<+ &''! mOIo:֝:e(.aưlRc.=ɑE((nl3 :d$1* Մ(rUZurRPL9LЖl=+J),,/-"2 3c%?>끷EdF]HT6Yv\RW25kעm0K:S߭' 6e|N 4TּeL6IYw/fR$&>k"TWr K := MC5w:Ob&@b+Ke5T٪pD/2fNqړ'Fu@e2EG9_[r%1&IW7\SQ3spWi3tt$H Vb&&N E_])AGFMdN,O Co+ ـD=hO0F,2iGC{'[ϊrPHMH]9.rj~HUK RbǣY/,*k~(%B(fq' NAVwJC ?P%%5"V/l}<(H iU>@hω{ 2Q3}NG& hrA0@tf3kЦOK4a50 ?E[Sg/AY_B婶GzM8K,VYr91I5qמ@n0ӠleR'N֟?&Q ǹWh5̀Q]R/ H,V*:0 ,)HRe g(T +o5[{h<7:6ǎi*/%&a/rja{|* {ش. w0s4\76 =}}s"KexW3 3T oe 0I۲4dРS>t~{7 %q#?GBg$oyW9 8 4Q;eT%s?1kTXw%>L,/Νб^a5ʐR|UVa\miFKhL8ܩ*$ oD;fSJ;rv\>2Nl%j em:.-0MJ 4RĀ.]DSIT0\>ǢʄEL0RQ۶=(І6OT[>7 J Ä4V 'Ϝ;;:޾0l1^H&/a Ecr(8ZOO7d(wQ"tvu'˶3 {peH$j~"gQlWh5?826t54F$S26Ro!S|)w>}>ieKYw,Wm5X=X]cE:t Q g䪓UWV]+ZbKfQ;i"~@V򕪖VEP33 Sx:YєL'&sUY\eMEIeMjj%UYOe#;հȡwp޸M%T` ;ئ|llӆ捰XPv1b 2fyY:дCFov]WζQW(Rah0؆/5 )rPOuzsZjdQl e峲OP˜ IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-settings.png000066400000000000000000000064601237252063700302230ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe< IDATxilǟyw׷1C ID*jDhVUJmoij!FCP%6j8& I8X|zPۻ^$c\;#J_MZ\\\\\\\C>˿,~.-˹9UA5xJ&gP)wʃn< ‘}v/~ԇ*2 (}[?ԺsUg`30F7{sC%L'd}z}|mKgމ VTd'ܬP8U9 wp|1!i:&x6` WkɤZdFd=q\SP"]x༦Twa"8aX+m\YKg.׺(7}WI>`uiu=`FcȉaUdē/C X]YF+6:fvgLPS}{]ծs H-P0U{Y UHaM :yzϊ& qZPddQF) "P $YE]T OޒfRc<-M J]{`֯.|&'(ZbArM %SV@6A\O¬B(ʀaE8 U=PD,0V:( $inUZ`B$gJrpa seXe'*,BJo4CaifbLߋ7%5H=/!1*2 z>ʀ-xj@a0n-hPZy<:L XM6[GQdON<@_=/4tl-0=(Sk¦jP Ik|ʠ$,fWy@TkkGplha)mK2fdR Ƞ0QNmSSV̦ɁFkQ4DLC*qH \L0qq-Aժ!sn!Մ[;6A)*iI\L?ތOFĤtXL.f|O" P2Gۀ_ނnĜ2F,I;z;%(*{BT&pfbc%:=Ӫ$cM_ȅ~3p?n222ڒ~ٓ/zlLUfw%<xVd4ZHTE4`N4{ٱs7SDo:$o 淯xd˖<^)dw 0>91q$ANI+۷3.^/ÇwOk! tf@E_@Gѱc>5S:92Y\++K\. Ú^r%y桺qs8,ܥ!YVw: {zzl,R" CTт̑HY&USH7 m!; W ׭[7TUU*"l6hӝn^6nFtU(O`2@^qiӦIF&I`oo`,bNOOS\<|00l(]bBArgz/ h?bQ](^jPH+pl555ڱ{ 2$re¥$l@Lp#)A2 W% C߶֥$&d6.m-K0%H^A=Jc,iڵ~zmF) y͔o 'Nf Z.3}}}H(yKtIڲex4TkόAAZp8GbG{졊 m!2v0qrrRk$[STo^#-$ (-C.CG K/#c>IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-system-settings.png000066400000000000000000000132621237252063700315430ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<TIDATx[ pՙ~}̭gt[d$\NL YԮͱ@ڬ8Bva%$. pc[aIHfFH3{[<%"i~};ɲ / Է>}q~/I r ȝU{wq(0*^y  hp> o_򁶫~W|[l*35>WZ7~7QqJ ]Vw+ؾ/+eԕ$}x_}ٛ_n6#L =g_K4*s󡭸Z&\`4{4=gC=ξۼc=ګ*ۓϽ~6./@#nl GbQj=UH;m9C__U_Qh==bdMD/8AsQ0 v +>fԅ3=o1oeMRդ Ac\4foc6K]e FR R3v`68hOv@Ɏg )f1OE89ؙIaCyd*S©)XS .>t4SaG#B(M.3Q{+1d E>DL %R\<[<U,EHH•: ̏?F 4Ga9)&˫JT/.+FB8=0Il=NIDQbE"!T9J4+ZFLeh*NKfNc;:6q5c RF^X3 -AD}yjmls?//MRLg88E/iMwdjмZ+i$a _=0Z&ճ7 AK0EhPٜ֜ I5&P\:QB?4%w$ --]HG!6.S@$h嗣XҘ&13a?IhW!@ [L#m){} ϊI^j&Aa~!w0K賟׀N iz˹!_":8.Lu/!J^Ae:X]cuHӺ }$\VE⟾?v pYC㳖")>C4$$g76iƀLpH3]`$=VUe,{ uАOR]Fsl~ (ɦ~քB+zT֐#3G; Cr`%4U4 4ҍ$G΂d|~!XQe XL)?jB^,yԀw%-ӑ#c T4(iYVf]ͶT`ٰb"xL m@aA0G AI@f`&UKYY%R>szdisJ{-wpA$R, %I)OdW 9 ԵGߠ PVC btwrZYTMɤt3 N"S]ѩyIһ@@;i5!Olwy5YbH[Vz%4W5y~a˔ <*ZeYNkDX* /ŕ _.בuD{n8 9ݳfzK}"KP2`i+-Nb,sR@\bS|G>dF$O}O*PZ,%U:pKݥW>j/W6!~jsORZn_ :M˪`:ʿ'ЀQ贕SGQx`N,fZ&ҏp뿺iͺ63N(jquU;s뗷Tvȯ~e*u&9'#C}ǢHd2xq 7ɻrZv&cڸq*[_ގWKk0Mk>~䓟DEkEuV!QV0sQh-HDy ]vyC?|_cSMcadxm-1-M{lOlڱ n~v~]]DEqeڴi]?j0hylN|&a픕juجsJpӟsUt0{Ȱt"}=NZSA6]xZ4ǣyRĤ9G'I#tt`>4 V^}Cqa!e̺:OϿtv\sڲe۶m.-]9 77.Ysu K3l|"2i$ [i5ʖg8(rav'j!}7o޼n͚5?yU[LvӦoZy/zj57S/+;Ҭf:Dq7޽ZjkjL"EAAc$U >WzV[$ )UqyVܴb͹DK[KO>: O8ԆmK%8Z ]{Vybh[o{|LfF x<׹J*V-9γS}R-R5Ygۂ8tvvbQZ\nPt:w=Jht{YwW';cέNIf!Z8um[mmŖkUı۷M Ȟ[%X++-% )W^===M 3!v&XOwW;T( gâQ@D}ιvNX,tw"~OY[?VL/`0А ~_qG[e]t`v]#am l޽boƁ4-M냎 aT\uȵs_`I.91yFFǐ <T}`>Ki F˱Wu(!Ϧ\K$\<S`630P8cQk#r`PF\ǫDd koogGQd6 Zoذa $3QJ ׫gK(7l'Ҧ3ݕd6ƪA> 9KpٲeO#5J?nDr ''A(2zQBG4@~H\6RFM2y<ƬtZN>"m0ʴ.OTvŐH`r ;w#MMMY4Ea 7L(*`ת8( SN1*Y S Z# H*@.˖ ]dlhhHMFu$ p*Nqn ҬadlvOf@7r ϓ^7s"l,ɘq0)|'hP |APN ;J\AHdޏkL;Ŷ D->O8RϝlVTTrرQ ScJaVHeHӤ'$ ajJ B tJY;1h(D'١b547ȪRȿ⍠hXQ㊪4's -CD 4H 0 'ͬj$-֎Ȩe&@yΩ_cE݀ʛQP@SŒ|]NpJ b!9=>%$rcwtGb'lBI%2UR`(aqv¥Ů89@6@z&ͣ&fZL#yv?b(QLgx($ Ƨk0 &&ŬtN$ZF,&hEHZ2&ZZ)x#.)~we$0UqYrdʼNfaRdT4KNa/a iyL2s\<`^( 3,R:G>&ƱI=c~^G\ قa]jeHrQf+3ٳG>y }i1V6B ؙDYԴI;yZQsoz UVz6!#L^o=slYz+-r3u6 "NNFʕ+%Ʋ) VaY,2˞\nCsƻn7$?%Ns?ZZZ؎; 7ܠ'I 㱛Yx\7-j|OmfZ91yH9xI-iСC 8ꪫvH+~Rk 2"Ֆ2ZI:KuAjq0ʀB6E4OGɁQr2KRӨS4>HI]<h x/ 0BPA]IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-task.png000066400000000000000000000122741237252063700273250ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<^IDATx\ t\ym/h,nج&RL9(9,M!,%p4pڦҔ 6^wKFϛ^{㑬6=3}ܲ,ا g ?~)_?>͍Sޤcn4 'PL) 4W[r/yZS(^_5w>X.~>tw~#a*E|g/|#(1 23#\Q]`ْԡ-]jӥMJSEGИOSVnnSHUE5گeɚ@_n&*>~d.Ma*{~%:6tIGe׸֜9eE% ;-Zyn=U&C25 ڛNs YlVm͑Y.CN*g57zuu/h^hޯǹo'JB$̕8eǭ3u!42́0)?xd0|w~hmVdfKcM:xk]F ~uwG.>nBۻv;h$Tx@$A4yζ%5Ar6gOo~\!T"ЕW^*4wĝWa3˴WRҡ:2p^'3Za|O9/8< {v KgK.UJGkWw$]R]KQ5Kh.zsY˦ywׇd'Е7Lcݗ򘷶hm5gͨ5gϬ3a ʄ +60O%BBzi$ rpD:Ζ}ݾ=C!Z晜NR$$xh#Y\%z#A|"HKVmʙ#).M ݕ(9JAHnb O:9dO0$A+pd1<Zi ڃuP=KP' ii8dY &H?*ۥZ| *iqhK|f 4yj-1#*3O' 8 ZW,, P2-L bqB]78D:vu~#}c+Y ܂07]JaN!Aed5>)% f%gnB4 (/ Y4-,}uE}SU|h*o'@sȤMQDŽtN(iEhE')Qdu>Ahd(3QjY%ʨ*@D$3"\◃ PvR;޲0iR1x,oj&',H ZxSmHDŽO?aݚhifRU4W$@R6#3ҤB&MCi"ˍGIo4 ԣ,IE8(e#Ax>2F)g_bWIJA3x@&FUQ= 0Cnw+"|l M ܀4ԟޑcL^qiәp|G|V\#RQB")4I~ 3jpQr&,νI&*XqRh#J(-?wHȷځbdEe] [tQA"^c%P=خ«-C}M#+",{($G$WCo'F6ABL=i,Mb@@46@Oab[* G]: ɴ({?ZȪD%~>0 MXKƞՀ$$r4Y i 10A4vQ,)T` a Dvb@QSor2[(.+'z&"w!wNt.4@1Yn^K͡+r:7ɔ$r`(j  #(@L؍ /}.`&FS t xz)h,`)9KpL,, U0An [edv86 X=t6U ƥPD@$ :v\MrC{@b^QOLk~$dx2$'aGР0UҺlU4Kfݶ_mdNTo ڋ`X1MJV''צA,9!O$wJD)̈XQR9JKw&$7 p$ʅE3{ 48aJ$3r2V21X#j0,4 쳙z0&1'D[4'xWᓺk",8ZH) Pܲc+ ]'1d*&[DYmɖ"ZeVe56K9 ES.jPY-OO@̈́P6~7+o?1EG%|&{}~C5s=mĺJIl z/_뾋gM(^NdLtU:zgӴo< W6?WmV Xf߰iG]ހve7\ұH]ifF۾tuR%{IêhƵya=lo٫l]ڳmS+NG&N^{]yN- ,]l.r^xϦ4 Tmqu닱^Ixݚœ <^>ͦ~_k}ML2;gwr"ۯBRS`&X貳/]E>[~٤6!2R&`4S.f_{W@o6=}!= ݏy߻m]M3g?k^}O`" D|p~3N\wuN nYv|wa C͍ͭ^o,) .C]we+$_;CBUt^gm?S~g߶-JzQ;af{/-\K c Mk.<5!DϫQ-԰3Բ `)T6zW=uMz)JR9:vO{ O28h-oʨ2δi( 䭬}${cI-l+ +N-U kOl* R}M,z=Ob .U,lt,d ȳ>&T*%8 $M DȰUF p`8;n[ָLKe&Lj=yȦNHM0rTX8."aRY=8 T g_(.23XqYabcrN/2ض(~)]iVUoynXOCĪWI~"Wb|z(Pöd25I"b`m'1yRoQ!RcB x e #2k;RWTU+٩-*g0;bjȷ폎OZ5W@drx{+ MR-lZ(U>C`j)7,a 9 ,t9+,IRGd4_lVW!)S-Y@̃Y1p{P?N6|.+;e~ab!AJfY8`˳lp%%s F% Au ln5n6w_Ϲf {odܙnv_ι;sϽYy 7@N;~wj[Itb/̺~&Zrү(p!`Ld`ikʦ(z <@;tB]Slz ̔m~m;R[2b a2afLłBӥ\ӁsbLz>_{LfhhM!h8>vT2~Uarklkol1Kå/΁ev9_ws PZ䗙 #I ÂVE`9c=/9`&)ЉO`~#׭ 8 0<9Llw&ClXdTCJ-q ׌䮹#C@u#aJ!ܾ. A*)̖5aS˂s;RuLdȩNJڎEpG~^FMWXC2b̔, W{`u3/ή>E _FtEA)eB(-Of΂LTm .5֜ڊB.8273Y,+|$Q)My\4\9 o]'}q )Xu(Yլy|vMTUqK$2lX(hhhLkC#qW@>80Ρ2ZuJ8C [ǙeX3\ϨHY! >{i`D"|#HvC2{ >h=04e,hhhIToɬ$o7 Cp iޘNQ>SAI3&S90AFid\׾^y}ߏZ •!l9_|lDV+p Y*{$hJrgJ)v((9]v>텄<݇V@B1@Մih;*]X&2Xb0znM[n0 ϖ3c×u~?#M'Hblɽ۞\rST͵0Ae8tlaC?jh4 LbJ/ -O3M1L"crL88©Jv*H|]9$ne=F}͚},榹P74e9p v?Rm= 2.O4 ܩ^|vwɉZB6HO׳{X 1qr}耤:a b%Թ6)*6^zf,S%Jm{@N}N*Y 2 \Vc+?[TKg(t;LZ3id&_ayкmzq7ښJ8Zny8+OZPlI-]8 ߂#ܺy5TF#ug_t|uar'wlduuuYO$ g o~{?ܾ~╯{Auiu!fCWGԙwUU b"sA(Č=+#Lg6۾=446CpA> 3<ᄏ"f[ڐ< s?mOLۚbL,^160Ƈ|nؔ(} PxvpM4kƙshi(Rb n';zðY,ale$Ig/)ݳ8D(*,@֘t̚0*7)Fw}7S3V;6Xh2|Zܻ09=jKmmT@:z}:{ L-)G%gLJ ǡbT㙟܅j*b|qI@}ϧMPqEpatX|U5b7?6]Y`M䌾!VX+ʺ&@3rQQșM>~u#li $G/k.. 2xXY()C,,;"Π?{h#:dv=|OgE|0 4 hZ%JQ}Đ 1ʅ%5rLdL%Ce7V'Lɔ>wzF&ɾ&RàI`ιrdJ=|l2Tdu55*BG^q~0$˒DM!P.~B;NU⾅Dzyo☑"?NIÚ-GJ4S|k.̞8Q!"68]T  &%l9$Ne5j)Af2Oҟʟ\Xjhj?'v]*%r_6HZi4)9:H"$U7Jn:(zF(žChȫ [ˤҹ$r]l!4$=.b4ؽRA~>&M3̛6lê/}xň 1/0dĵqqa];)ћ:,{~wj5~I mUT8XۈO!5> m"JnϷ`lV&#gp8G)wOW^82RTVWyj*kqg^uk{f +]p1J(ʟG5S2@n'ǥF(JTW>4,rChSd|[x^Ca0q9NIvUvH:q@w0Hj\9>ҡ`a[WTcէ;p0HXBY4::}`LXq$Z6UGU&.KVeI7]n7Z:(0UTMn="{揿DPxWQ0?p#98VPPXVJ!v"*' )9Tf@u$DŽfgr9Lt-T)cq4/7|5R7[{;r&;;O ,A&ڙM u$? I1i 4U$:*1L"b+&&!>(;krN\8vjR:spS,a$’4/fW&D%{(qǛᶙŶ3t)#hwPɕ +5(DÄE;|r!0p^^XE I谲 {o}T#vUfYv]".)I&΢L wb<ݷKoo65IUURrȥsPeHGX`AڻTm4:WHB[ +}N J3pL&rcقoeI uNZl6l#ŒN*D:@?1w EP~0״զolNO4J@rNH+sӢ{Z-;畼j*(8V5+kORʹPU;'1RJg ’]#%`}HI*w ;\q jXh|y[h,K/+r;,7z˱qĠJAteE`Ao& K7 B Ε4Saⶊ 9F d7dE+2XQwV\^dtZ+Q+ Lʅv'sչZ釲qB:!ƀٲN~Ԥjm-9 >n^j&̑;7t4htU8xp@JVG !ta[춬NR r0Un{5Tru'l.*mm$t.۴N6z"ы8t2IC.]?%Qǜ6r+|; b7띲?9s0bPSmtiquC۪eۻ*u H"c#2T"9.%U\HCZSSw / T9v}߳.kntA/+KvbA{7@$mWo~s= lվ   D|M Y`Kjpƥ;\Ň}UhR[t~U+&.W9y =bw+{Q/&cPKM3YYwX=?T{˧ZѩsF<[\e/yw]Dz'{t34//ۗ,+4 T=kb MEV\z,**@}aWr80"c죊r`Äzix<=0-2h9â=X-l“u*:_|#6%Uoٟ}k Կ²z{nXp;}3 %` =g›ncaꨌ A1J$YT$n-^ 59nx7ؔjH5@O++7]Uٺݿ篤,s̫ko5k,˜8- (9s 5tvFҕitzYS̚/7fǡdDw7_XU1W+H@/ypج6<5@me9!@j4Z 90~KFִq#R^K¼Fwԕsl<%w.Z(`/6Wow,FEQʋ XY9(^+vT!gnOg0#qÏO^בv:EpD ~EEs%؆ +E}zWM6'Qt8*!650a`4yNjy堢 )c ":ePv ښ0"k2nZ06dL샎czͼAlE. d=y1+\ @wü@K>_f&£8z9|< ՊT&-ESfaKƯ?;K߯gUX2b@5zMFs =)Qn喧XEgk Jc|#vRC#&M%ACjELѧF!PO5Bq1ʅ1) (8~Ly-fmJ긨+QOX6~::Zx ^&ٗeq,xtT[OwtP=8݈R+L9>DF7CM9$eNĢsz{/S^>+lEqǟM=mX焰]g̔ F7Tq,rZ N+ǯiY1uhKk+>2ݡrH?O*hn-+[V!s,eˌ0 w_f#~~ h C<8sFg!v(.;>ǟAPte5O[r/^k8hH_ /De' T n:rRaDWSU/ŹR5-FO͜?IMCV$̹ MbF\jBa1"' 25ŧs=Yݮ!  WhV1$񨪤& Xy dMıc.A,1Kʼn_JK˧"DDĤIazBbζf&H݈C`Yx(6 Hbѵ6ԹyՁڪrx~[7HJJ MM-2)}?~I0sﯤNF|J5Űl]y}o2e%h)iԈԤgRl_Ii'}NRɒaftSq]Iss!QzX"#z*D=x?uNVCȋ@sto5ekJiTZ@1LZ>wG{1!MS%ފ]vxɽz'ښnvvUUzz:A"6 ?n_QDMkյ~WȢq(͂2MPߗcZ+-[k^ASjٹYm0ȒZr!HJsC/J$),r,5*aS١3$N߯ے|f)~ysZ[ZJ 5US+ j(Q DKdr и.߳S|#%!7wTSQ,ù'Mop~ٶɷEV Iu%dIaJCG[ /woSه8yּ˻JGT"wjpte WGVr O 88Xpwwt:K4`'V2n^MT}_m@xL|ypyy'GDiISBSm5܈ae$HY۩wz;zjҜ*,>Y>o{mDك:SL<(+p)r6wIg9L& HWUWcĘų^CXX&ރZ/ס(?c`E/p=\_=$SK`:<}H*F_w *C^;w6hTZG Aw/>o,n=|up,y[ńEw#<*ZP ;tR4͵غf%-"GdXN, P_[&?ZO=|4%hliC֬)ܔ^3ǿ݃}hLG}x<@6Q5UYEXLQcD80r^-kL͔Of!Y;@)1BnE=i]e9j-<HtP`q5] m[eySYQTgbs}Y_^)4.f_a5*8~Wd_lYWΩɓ`W e+1Z k9됳2{?u-}o ^0U> l:IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-userlist.png000066400000000000000000000101421237252063700302250ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\y^3.͹.5 *6FU4䟔ZJD+U0&@D "ž}3}ggvfvg2֣gz^ޱ29_< σ<rAȳ+'E&IY}WM| Bml:OYfx_'ףGU].S68"n:/t\c<8t%΍$&]O[}ڊRq*aL&cs̨&wMTJ*BZX7>< ۞ ̮'p}/eIuifM F^ӾKҍ$B%> (B#P(.[#uR:jHCB=l;qC:#n:yT9:MPTZ z7ёS?,SnNawy3הȺQ?˜S9c(%5 ,Ɉp )dèBτxY4#O=j/z[ZT4W6A&^Zzų$lCz(W~p6IąϩBc>J PP**ȓe l/x}-*IL YD°+ }aa2ʁ|\!.y=3)cQ*MDc"Vt=YEp d䁘M̨}c<,\2WqFhpUU&`̟\GZIbJP33!N9*nP}jvj<'*`VF5c?(XB5w;kX{A#H(rƘdX2Āo`qr$VV1dŰ`_ep$/y#OE,u~\lN:6.=UK&y7>Ҹd#X]% ,%"s[I$"poW@u>p6_fȡvl>2o&\R\Sq`"@36R]W'SBx,T֭k7CaińS;RWcA1d@ 3P[S z,|Gv .$mۅB:-@攠sHVWC6G 1x@̑!82j)ɔ`R5A;flf */@SX$cbpg[]i rUqP(^$’zKl˶3F#ݭD&1IsO('ҹ#Xrc)rrka? xa<:/Pϛ9ёϮz,wȇf󜪞k6ȶL7\נaDbߥ]i'a@+%"բ6ĞeV/^lh #VQ.kj -&݂ 930MZҤ S] kiQu+sУȱ0qa{`(E@/imف,IMe'B]A!qO+O !f=!U2zL&E!4+%TVfgoDMA! P{جd1ɳdx!"'t*9vA(Ccr -#P5*ӱL&!q5p]l14mK)/zZS0 30(O3L2ɬPo]2k9h6Yd5G 9_aXٰ6%cT6nY֫uY%rf:V\^~vݓTCk!O!`y[ `7 ΛHan4b?$atڿvv ׉{(JzpF'˥o:UviiR@Lu^Z- ŦMNTLꦖ&/&ǿ:n&`'[O[Uܿ>urz!)2:qSUUG1[ Adk'us+`uj^Ȃi]ҊNde† @vvwcGiҟj=wj*(U!@&ǨQל@!IUSY-E+/JyoA|a\&uFQD֎? }Qrd6wri/\_/Q8NQEr)I^jj`*>$Ic^׽y a9>'=WPP{-Ь@8QD'}w1eTQs6*?=g)tKNIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-userprofil-female.png000066400000000000000000000111741237252063700320020ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\ lyߛcO)\DQ$KEbYaǮبuIE(6c@)NF ,NR)4)Rk{3C-)J]2j_3;_Obi¯vw@y7VM?3Ksy_α+/AP-ח=p+0sPȹUr>0!~k[8g+=};lPJ])&SU>4t CK/}{g%WQl[wid~24$QHĦx R M춰y꽪B|GÛ>su9Ny@aVb5ljO?Ek: k^J" PU5qC'<7 Oڭ׃OY 62U5`]("CQ~엁iU$>&%I)AfD(zUPt@܋U6ٴÓѮeTcH'oJz Ǧ` Udb0LIOO^{|0x|Az|Ö[fBaˬ $!xvW0}k/P@8Zd^d=5K( LKüwpJ]g4Ȋ,CgOsĠHP!AlH^YZ`U"kLWmr`c˶жףqW=cCd8q__dt=N R %dt?= yA8(PRǂ~ICD 71da˼iKm O_.SyLl/2% pRV,9 PyT\XS~G !}SeU|[kMtj .4CxZ|C`_&)/I p'-:1Zٌ;8#[gy3nəh")52t"[ݙh3PuC:0f&_0#BFM+2W׎Gq {2{,=zvz|6w'Tgzg8yY ouuvmX>LȤAΉl +&)ߴX4ENr -j;GgfH&b.|!&TYVf6Cl̥h 7-I?mRr`PLg|&pXYP= 5& d)2epm;fbǨeJ+mp>dڵqlEYi^pax75Z$ [3DJԹuxֽwMn3Xp@9-w9A\4g;Q~=ȦiUM a_ʤYiu8ƜY9 Yͤ9GklV=n sZӀ@jIҜc{--: 7vc. 7e2B8\9xRYcU&۷{\[0;k s:}\A,y: Kں_-+Ǔ;gr֩gN R{3[ukF+Q^LcN}d$p [R`?>&H&WuՖH7S5Nܥad¦mjc5ȧq/Y %&{ UݶVY(csGas6HѴ% iiEVI^-PQɑٗmYWK-;I'}ScY;g!-.+ UR9'vu6 F[]ea~y d#d_f3fv\j܇{>(Qz}hU&ZvKܶQWZ-Z y7D_@o@o%<zԝT-81Ƨ iE$(x͚T(2r otL QE(W}^>ućC>HbP.*\.0:0$*_Rx<2j,e3bE%"UY󉺴6=$S(5}M_@dTA?]]p|^E8myi'"4@>`y.AQVZUw'Z㟋\EQU"@bp7@U!w\, L,[YeA?GSL:x8 3h4JВQr;dHƓN9%U5~zI c\m{Śkco L Z" :e˵ukz/ C ++-{**tt6W/OBK*9KzZFdzz]v*qHJ  \ZzwOu댒#:sӼBȒ62C+0FYB^Y+i>&|M<5 d@r]Z^hH?PI;!_ՆT+N+<^~zW~6;kyyy&$K&yQ/1NS9#SSSΙ7>1ݣxvz˧paߐ0R 5ƧmזKblR ˃ǻ{dx]d:p:掎ق׊tFee9<֋Rpޜ/+.㊆z9 [6ɶ6S!>xpϽиu+ ed x(#inoQ>1N #%k ꪫ1za3+ $;{'qG%\Dl58SHH-3$Nr>`Gαa3ٽsiÈxϗ\@-;l;"ӾgW=2߿- ?#)IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tab-userprofil-male.png000066400000000000000000000077651237252063700315020ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATxil}Ξ]H\HuR۲#Wv@I@jFIhuP a#Q#"[LZ$ݙvvERy7\q_Yma\3%yN19EOWBu]sdPM6[LaV ]sPȮ"Y$tAyuN((QB",O϶lOz(J\d<g;&V}Ć@ yVkoZG!L41T0&f oh0\]8t߾K &:#ECUAdV,Ȩd<EvnTpC.\Ϛf=qҏ] j.Ar:$EC9l0cOԎQy&/Ļtu Eӡ*z`c)q^Qjs8:+ˢRhX7ݦMޔ:Tu-}-=bՒ$XAC8ϗ3!ΥMm{.BXg.w?o<"GD*[H+>2*`oo!{-m62Z wsb.1^OfkDma4e:^ʣUg;"uM[Al6H5ki&@ s; =WHG.olf%Xm]mpoFiYLPn[eZ1EX݂$ls;s{$O'bm|Yв]/*aH&eIՕ$j.sBMM@ueEnotH5 ;DXaZm!j}eVzFk1ivӓG8Mxӕksl8@8=_EĞ(w%@Vr:\eꘔ17_Lbr Eud"PA/)H *pb_m:6YPkeuqL ^dtՊKR( uTQ,uU yGLcZTy"9,oloo!7ay͒Б8_uuB+@׀tfpkG<1$k,תrvIn2U E{:&וMֶkO3?Tk#$mAlu<#}$ kj`[fuCV(XE> GCit! [IҔ hFKouHH\}@X;l~tNO[Ē]&-xF7{ھ|wjpOWFT>w}OPV6j p?*ߡ`gǺ:C/Z*m zׅĜM+ M(|+ *vp8'G7ӐH a@4/,s=Xjη*n5}ǓƏ~@Bt`E8˟Q̀)P4/;C{ pYm!?Dڅʚz\EH̍b54#ґc/F{LG"911k;9U$@ET]S/OC!ӳ}`2NyCJ6cug?f̮1|~ldӸ^ȉPbiEBQKA{^Mлr˳׍Jo5,vS.5L1:VյMb<}; #KL?!4 X"4TQx=Nn.2(#E 2qlPȚ loEhpEuTZrR G-I:6yPW-hWrŖ̅Uq5k'ϝGmX#l~aAzo I\ RUCz H%UKg+h[kW'߂'5܈Ffg˵1w-wށKeyEU{WF`y-GU(PS=q ][ YV(ԅ,24%P#5!Ld+okyN= DdCSO!B%;z{O?é)X<ɚz }5C;v@G GYO=!uH]8!z>HX|g\:&:rvbhD:B[nȵH||[(/zסk;)ϭU 0iM憥IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tags.png000066400000000000000000000027411237252063700265530ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxڼ[H\Gǿj/޵ [#UMJ}MADlUh^|(y'AX)-AxkŪD&sx4&g\7o)c\z`SczQyU0K@0o+2H2J2xή<{liiiejjꮸ @P'n}}\\\>s^cb+xYJKK׊D̔gdd R>?o3AN͛^iiiߚLP:Ƙrpp@E(++[c3E ;;&`3쪱Mqqq8_Q-@O xzzBPPݏ=uVFkkkт8ll6~9n~$醯/> 4 bZ}$Cdd$ihh `ޢYampp{zxV1: =#7/(5!cDDZ@˂< pFAff&s:.84.v@@`` ;RRRNat@@t bAȬbaH xbbx0θs@NXp7+vA bx9$ttt۷osɞ-LgG^e^OppO<5EEE|x1ΛyJpq' hGFFVNt"C0ިN+uXXXS,՗%''cJE d/gB5 T. y'Epi^U )jۘB-Tt. AA]]UW3CKBmm-pD9¦vѰ,7Q^q-+//ghX&fXXii)C/~ C~!0uGECPP1F F=@Tj:djrVWWܪ GGyPEg0.OԻ0To:F '@< -3'`7D8"P.q%;zE7GX_f ݻ|Yt:8ϼ*3YĨu_\mRKv~LtB%=F_TȁK轀Z(E\DDgAtwcg6iti0I#dH~"7DH_󎢧0<"j !C`*{4c[C~@1z.IE|KkrzMBƓ:v (յ#Fw35{1mon80 g8lE~' $Ԅ3"1)wwS/$Eϭ/.o,CT&(@\'sDeER@E@xf=> gfOwFǶ6MӴf /5 /IU@Qf@wb ?)xZi\Qjk6{DޟmOֺ^-i8NhcoڬL wWSJޕ~)YkAwYX[H(;HPڥ n$$pZ/Qו,Y q׾ЖZ3`QzJN&U9$IxA|CIL6d{{)kӟF]UrT3Ўbu͔K+]x]Ex[xNb!rIT=htփG@!T TJ ThNbŹlQ+=-0 ˾z`XS0R (+ ,%x=:7 *@ΐ"u*IOP9YFtJu6|ޞ_  !7WL 2F_IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tasklist-done.png000066400000000000000000000023721237252063700303760ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘]h\E̝lm>M7MkEPJ?,`RJcTDACA'%>X*VS-mEЦ56dΌ3nfo}:93g/0ݪ{8AQ@x5pa0ƃQ&.&1iwak` 8>满umoI>sgO? f@A0:ef7l{ CqP_7oH`v  %6_Ks?q %9H@*iֶ ޞ9of`j6" ǺLѕ!)Z`h.BXW' ӽ>rfS/XL]? mzqu a`)fYsc0͙H$mTQ@$`{j1`xFm+*;j)IՕ1SV1=eeROSe I#FǮ2qL3'!@{ajf!r0ƫP@A̅yuc?•PhKF4JäbF3kĸ0wx@Y=Wq&R&2۫ ;2[}qf&0Lէfo{ۓprȽPkK3+L* F:9z"|5~ oa7> ܚJ ;=MeuRF̱Gv¿ֶtZ 7aǟ/6<ۑ1xKp~ P&^j,fb9mA-Q$s +- /mE9tnV'8H\~n-Hu$!%3(TFn}!859[O~;2Hf[$rKkXcUޕL{Gc:bpqrbۙLGSu-<Í1ab%UϿ5 BzaWRI}@W?b{/Ja/0-}k .{ķm4:V,lŵu׋8U1y V ?Հ ]9TQz@D$J utCV yfG4 " l(DIT1;  0S+V^IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/tasklist.png000066400000000000000000000023471237252063700274550ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘k\En66MZ&6ѬZ VBh-AZ"YD_ED|DZ+*R@jM&Xڴv,ޙq77}pp={f)%_ABH]ѷj`Hg% Y \m{  5 vLF|?cQwWЅ*0${m?;x%TUF㐁m=3SsWoFPy* kr5듋>S]xP-`!As;אָRZ:džd  7&(0@Lew eP.ҟ ׽-Uf>H&sO0$D&G0VH$M/^it:R@"b! *ar9m5eG#eQ܉zcpS3:Bp) Qf>'glHTD2ٿtGZˋKVuz6TT vx)8==T yn,cR $ $ R!…ؐu80-2Qlnj6ʃgݡ&/n"TftgUe.^jRX}6B+ʤ: ӿąYTwjok2_0lɹKW`zvv3*nU|8У74 TV,g#{Mjq R* BN €w ފ*R#e 9k_L+;ڣsO2ae3'Lj  F=/uLfȨ B*Jcz}E`dF}s5 +:g:/Sz3@u ׮'6BkUxR˫Ciӥ3_k15)KiWQXI? ʒoM|/ށ-1]߱Vk `alMYѵw&iqԨ @u*Vv+DXE1Ò8U1r ,5zQG 8\U GR )Y']D#IENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/timetracker.png000066400000000000000000000043051237252063700301250ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<gIDATxX{PSW$W@+X[]+;řnngmήmwǶ>jk3]XQVv|2<0 $$@&Эyf~sroN;0xZ"f 6A`,xλCaxd!ĵ②N[s}IXhcP/> 5yF'. D^ueR6f}^͛yӢs߱w)GY/:z wCIrn ŋUO52ơAFc8t6dתNo"-k[^yk y'+9N"1zBwPbڲ5&6B U#7Ѧ+ΕUG.P#&!D3<8p,+9~w~+qnGNBxa~D$>6wJdZ &y71n3Cx]fQm['hoCq"B"+C2aL,$xŐ@%ƍ{R3sLT|eyN_+=v( >($ - ΋;wC탈|/=Er01FHh'ci\>O_ /^gGLYtQRB0LX ZM(X"2; %D+D3Y,F*54]mCth!u&MPu Sl ]-cOj/w cc1[ Cɓ)([ y*|oP?m_BhTsHADT4:v п~w ~]>xIoc_& ahrb{PB`CI CH'1$#"ѷJ͊C:;|%⢩1]jh^!ث2 l2فVGC< 4b4!G;"+8:Z\_m\Qq_Оӈ2e_ӟ&]jOZ'ca늋8ˆs\:Pa6Ѩ;^LK]Ŏ Sc:vj!'N~SzlMV~!@Q]Wwz汫=JC[Mõ*K*mMā-3Z-HNO]+_ۭU54ڛtc55T#$x-Ņ/>rqv`"mjB8 IJ;|AD/!ї(^ 2"dMψSq6n$FאTZ_EB@U(BHnz͝0E㮮Ow&X>"93 )ex4chR(rVn,:Fw:~p9$$ :) *o@MJ V#J>mBBV>̣F9SRL.2."vw~ChbdXdJh5K>D__?qaGbӽNV\QhDGſ`BWe J( i ]8wGN]!5S=ֆPn oV'*"dgXNP%Rخ<Ǩ~VGh;b凍95Փxs~ԄHujW{mf<.P`r}e^[ y3s 񃜻;gk*Ń;2\Ij9ff03|!E:O8huPbIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/user-icon-female.png000066400000000000000000000027011237252063700307440ustar00rootroot00000000000000PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<cIDATxWklURB (P( [aJb`$1FmL ш@b ЄC!1V( t1> a)ᵯyy '{v^;8?}#''^ ( Ľ-w+mcN,PpHIu֦ؼ쥠miL]2 Y(Q k ܓ1@ư`,@$h*!^@ceeFS)i` =Cg/Re|dE ݋U>{$ u錅tMXyvּ?>ݴg @&J5=4K*M$ $ȗ›[G%'m* 3XA,#1 -8,,eAmFAV!EXbh԰441B҃CMgf>1cnQQ۰T%|6]ouNY` IS1C>@e j=Hbby9Brq ^GRڨ9!24&2Z(&EȢ#Eg"8o˴ADy^ \d>b⹋t/̘[B8L& W.L-9|gS&T6&R>* "Ot2pPPH I;O?'I(vZ^ZQ8"#._$F9UKN Y͎>Ȩtu_}>%6}ڸPO 0yi"N6&VHX0![wJ4WCfl2{q^D~ݹCՎh[t_O;_[)ٶߕ~Lg v]qO7Q,J iŢL}s4vmZݾK} IG"2\΢gr;xf21kG^*[zmJFD}$was{~e74@9d |IlUU5ܹi#. خ'd.GP-,;,aNop)l8`; ŕo>՝ @oHnN=L%ǪЉ`PUU@QAo{%OK!ұ"m&dO4piimIQAV44kк^G{@zz!=D´h% W{ 45O 8Q].,CRG׌1=8P?lT(ATP06ƞ]=g`O2Fa!?**o`EI_c2ib0@H<;&0v 6P2l Y@:No GwNP:&:7Y= qj jÊs\U Y4Ѻa4p"8jct UnOj`Kﻂ`MP+v\DKPr9so[z[kGm%3c ^#ka-(u<: ܷiÒk:sLn{+_UedϿB05A 4* j?%S0HsG9Ow­OKJ}]*T|JIDF` J!4T~DBDCPPhx.iSvcfgΌN/2.[nLvYu]8(w[\hS{<{a,o#NfBx{?am;+=£ dB׮{Tg!VԶIJz("" _G!"H1RT -!ݡ& $lS(l^y}5"K62H/X@B[ao77[E-WY}BQLʲ&޹t'>{Olh&rokRc^a Tby=eO>bC <*|7+OKaCcs/K8o\``&8ȃc$#rF(̄;0?pR}|Vn$s96$G9 9ȥFVbT1T^<im_Iz`@PP4؈ |ޞ@Lʾ?=z@UD/]520s#q&{XxK$Sc{{ #sciSl:DOVְ,?!GTO_j:^Q 'Vm3ey "\ɔ6n=9-1A <rD%--ͳV_S"eh&"?x+Rj-"Û`5 ݽ#\}}W#QKt#эTf`ޢ Dc۲J9^-I'nb1 I\DKC5KH$**JXT /XQ42FzOXF&F `(hz*5d)s & t j5IL"k' 09(^m:ЯӗPdDT?C,F,3S #14w '#E`P@|=Sm1#xߞ9Sp7Ŷ5)x>hIENDB`Collabtive-2.0/templates/standard/theme/standard/images/symbols/user-marker-male.png000066400000000000000000000023771237252063700307730ustar00rootroot00000000000000PNG  IHDRr ߔtEXtSoftwareAdobe ImageReadyqe<IDATxڬVkhU>wfvg1; YjS["4i,T`J_ Ђ H1"+DPhQ[iZkMyfw=㹓$n6ޙs7;u^(sw Y:F`۶Ӵώe].8 RqABcq%RyokbFZ!U胮&m5BnP޹y;tHd "j0 BAcoAh-0ܸ^(U s/rM 醟~q3#L#2O8*'PA!|`[ JԬMhO%뮎wښk qh ;60Jugx`xw[҉7rlo72#+v]ʜqsmb9xoؚ|s̃}+Cqm\K(1Ual2N}'Nky9ȃV!G{JOL`S^RB 1|vJ3 3`= гixOqĨЭԇty2g 7>>9h8p,h.;?81ctԊ3 z3{r) ZC/ }S:l=3NޛSĨl^U_"V d]u]SGDF Q0:|(`h|,TXI{oIYᳶa_8~QAsD$`Ԉ/`bFTw2PH/"+"#_(`$Lȑ&Fd@)IG}}:Ya/x{mU@T1%"{G GV!7V_E [QĢ3*zŭ2a{v'p)}h xq'v04++(3m^uiw `FN<3 +7"WY<%xviHhC$Ȅ<8 A2|5R̃0g6eV|Jd0ܜ]<nc+UqZ2͜ mT N~?q\*[=xdk$Μg1nL#q/#ЦAݍ'GJURһ89O>#s08<'NųKW.΁xzdأsf@\zTIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-projects-bg-b.png000066400000000000000000000001561237252063700300310ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb|U@w 9 IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-projects-bg-c.png000066400000000000000000000001551237252063700300310ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb/,0V?IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-projects-head.png000066400000000000000000000001541237252063700301210ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb/,0% IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-projects-sechead.png000066400000000000000000000001551237252063700306150ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb/,q0fGIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-projects-secthead.png000066400000000000000000000001551237252063700310010ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb+ 0{scIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-projects-thead.png000066400000000000000000000002661237252063700303110ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<XIDATxD 0T&#GAA8x- 1//MJL [[٧t=`fJ}yU(6^TIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-tasks-bg-a.png000066400000000000000000000001561237252063700273240ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb:{n@妙IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-tasks-bg-b.png000066400000000000000000000001561237252063700273250ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbzU@k tPoIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-tasks-bg-c.png000066400000000000000000000001551237252063700273250ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb0*0!:eIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-tasks-head.png000066400000000000000000000001541237252063700274150ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb0*0+!,IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-tasks-sechead.png000066400000000000000000000001551237252063700301110ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb6*s0&JGIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-tasks-thead.png000066400000000000000000000002651237252063700276040ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<WIDATxT 0 B0t!q A 60O/.M-Gn Y@am{ϺLg޴Sjs W?y TQIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-user-bg-a.png000066400000000000000000000001561237252063700271550ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb8~x:@Ϥ=IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-user-bg-b.png000066400000000000000000000001561237252063700271560ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbxE@dIENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-user-bg-c.png000066400000000000000000000001561237252063700271570ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbxLE <IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-user-head.png000066400000000000000000000001541237252063700272460ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb ύ0E!S*IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-user-sechead.png000066400000000000000000000001551237252063700277420ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbLf `lͨ IENDB`Collabtive-2.0/templates/standard/theme/standard/images/tables-user-thead.png000066400000000000000000000002621237252063700274320ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<TIDATxt 0S$#e(~Ng0ϼ D9Fsi}`šQJr_y^x hIENDB`Collabtive-2.0/templates/standard/theme/standard/images/win-down-side.png000066400000000000000000000003741237252063700266110ustar00rootroot00000000000000PNG  IHDR MetEXtSoftwareAdobe ImageReadyqe<IDATx1 PD#OH] vepYeI$,b* s|^mFL@iB%qaÁn?H&RHC, M/`dva&b!b' ֛23,Z6i3`_")kXc6m4CH~ndcw]8ɴpji:tgiaB^b@O^M \ \ 6=za-S!6y{%DzyM5 䱄WEzT.+y<)* [ EA-Hp,V n;tvpmV`Ko$+Z IEpoq'pՎK%Q|xCa3gk `YV(u]ϩ)Jgn+X}KSeZ6{_k|/[Bl5~x:f5j樬BÕnyV.jVȈ'2 gx?I}n{WSqԊŽSKH8\y|g_l~[$(njLbΝ+jܒ]6bL;>%f*VZYLS_ r2;eb#MÍyŽ+DPQ31pfckfI/7V~(JKA6?\tb! JKAuzEvIF pűru#1W BÆ8saɵLH@AVi\A1BCϬvv$ǀcCp83&pJ]Iɉd=9A@)k/&z,)&ۣms;f@!筩0qUC:eY%d\em)94瑮*q#X{xD38 Zvq5p2 *;ۃAn7Tx2`]ΠGV_I7oiM7:/;jˋfXL@ą'o*G'n%Bp2oA[r׀(BE 1zs3,NZNJrl.\Y!f "%g oo-1@8.f'wp,Den(\'u3Ƙ`E _8HD}5}kV&ZLYZF!gz{8̓Fn@jʎvu+\Q;&a:gZU ֦HW>4$cP穮v 'IENDB`Collabtive-2.0/templates/standard/theme/standard/images/win-up-side.png000066400000000000000000000003501237252063700262600ustar00rootroot00000000000000PNG  IHDR MetEXtSoftwareAdobe ImageReadyqe<IDATx1 06EʔVb*^*f#x'C&` gxyBb hv;H=]Z! 'i4mk!? 5(~0k=fyAxGjwi4p`"(#IENDB`Collabtive-2.0/templates/standard/theme/standard/images/win-up.png000066400000000000000000000010201237252063700253310ustar00rootroot00000000000000PNG  IHDRp0K8tEXtSoftwareAdobe ImageReadyqe<IDATx옽JA7WHHa!D0O` b3؞`" 猌.{[a۽%do{u]+}.щ@V Ö`k}CT. {7Cuo =;5m\87d6XY/7e=;b y[D \F#^R^!tmRyJh rE(j-{ f =;87dêD aSȖJ`JN7wś>m1dgɨyʏ=c`:0Sש24PgCY09',T*vq }{ȁm@l#ȉmBAlL:8L]f:BjB٭, X7O~~w!IENDB`Collabtive-2.0/templates/standard/theme/winter/000077500000000000000000000000001237252063700216565ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/css/000077500000000000000000000000001237252063700224465ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/css/calendar.css000066400000000000000000000076211237252063700247370ustar00rootroot00000000000000/* CALENDAR */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Calendar JS/DOM v3.0 + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (C) 2005-07 by Michael Loesler, http://derletztekick.de + + + + + + This program is free software; you can redistribute it and/or modify + + it under the terms of the GNU General Public License as published by + + the Free Software Foundation; either version 2 of the License, or + + (at your option) any later version. + + + */ html, body { font-family:Arial, helvetica, sans-serif; } /* Fuer IE in IE-FIX */ div#calendar { } div#calendar table thead th{ font-weight: bold; font-size: 12px; text-align: center; background-color: #cedbec; padding: 2px; border-bottom: 1px #8b9dba solid; } div#calendar table thead th.weekday{ font-weight: normal; font-size: 11px; text-align: center; background-color: #e7edf4; border: solid #e7edf4 1px; border:none; } div#calendar table tbody td{ font-weight: normal; font-size: 11px; padding: 2px 5px 2px 5px; color: #0E224B; text-align: right; border: solid #e7edf4 1px; border-width: 0 0 1px 1px; background: white; } div#calendar table tbody td.weekend{ color: rgb(198,36,36); } div#calendar table tbody td.today{ background: #c4d5e3; } div#calendar table{ /*border-collapse: collapse;*/ padding:0; border-spacing: 0; border-width: 0 0 1px 1px; } div.calendar table th{ font-weight: bold; font-size: 12px; text-align: center; background-color: .cedbec; padding: 2px; border-bottom: 1px .8b9dba solid; } div.calendar table th.weekday{ font-weight: normal; font-size: 11px; text-align: center; background-color: .e7edf4; border: solid .e7edf4 1px; border:none; } div.calendar table td{ font-weight: normal; font-size: 11px; padding: 2px 5px 2px 5px; color: .0E224B; text-align: right; border: solid .e7edf4 1px; border-width: 0 0 1px 1px; background: white; } div.calendar table td.weekend{ color: rgb(198,36,36); } div.calendar table td.today{ background: .c4d5e3; } div.calendar table{ /*border-collapse: collapse;*/ padding:0; border-spacing: 0; border-width: 0 0 1px 1px; } /* DATEPICKER */ div.datepicker { position: absolute; text-align: center; border: 1px #8b9dba solid; font-family: arial; } div.datepicker-header { font-size: 11px; font-weight: bold; background: #cedbec; border-bottom:1px solid #8b9dba; padding: 2px; } div.datepicker-footer { font-size: 10px; background: #cedbec; border-top:1px solid #8b9dba; cursor: pointer; text-align: center; padding: 2px; } div.datepicker-calendar { font-size: 10px; background:#e7edf4; padding: 2px; text-align: center; } div.datepicker-calendar table { font-size: 10px; border: 0px; margin: 0px; padding: 0px; text-align: center; background:#e7edf4; } div.datepicker-calendar table tr { border: 1px white solid; margin: 0px; padding: 0px; } div.datepicker-calendar table td { font-size: 11px; border: solid #e7edf4 1px; border-width: 0 0 1px 1px; padding: 2px 4px 2px 4px; margin: 0px; text-align: center; background:white; } div.datepicker-calendar table td:hover, div.datepicker-calendar table td.outbound:hover, div.datepicker-calendar table td.today:hover { background: #e9eff4; cursor: pointer; } div.datepicker-calendar table td.wday { border: solid #e7edf4 1px; border-width: 0 0 1px 1px; background: #e7edf4; cursor: text; } div.datepicker-calendar table td.outbound { opacity:.4; filter:alpha(opacity=40); -moz-opacity:.4; } div.datepicker-calendar table td.today { background: #c4d5e3; } Collabtive-2.0/templates/standard/theme/winter/css/export.css000066400000000000000000000130301237252063700244760ustar00rootroot00000000000000.export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: ; font-size: 12px; background: ; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: ; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: ; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: ; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: ; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: ; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: ; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: ; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: ; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: ; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; }Collabtive-2.0/templates/standard/theme/winter/css/lytebox.css000066400000000000000000000051771237252063700246600ustar00rootroot00000000000000#lbOverlay { position: fixed; top: 0; left: 0; z-index: 99998; width: 100%; height: 500px; } #lbOverlay.grey { background-color: #000000; } #lbMain { position: absolute; left: 0; width: 100%; z-index: 99999; text-align: center; line-height: 0; } #lbMain a img { border: none; } #lbOuterContainer { position: relative; background-color: #fff; width: 200px; height: 200px; margin: 0 auto; } #lbOuterContainer.grey { border: 3px solid #FFFFFF; } #lbDetailsContainer { font: 10px Verdana, Helvetica, sans-serif; background-color: #fff; width: 100%; line-height: 1.4em; overflow: auto; margin: 0 auto; } #lbDetailsContainer.grey { border: 3px solid #FFFFFF; border-top: none; } #lbImageContainer, #lbIframeContainer { padding: 10px; } #lbLoading { position: absolute; top: 45%; left: 0%; height: 32px; width: 100%; text-align: center; line-height: 0; background: url(../images/symbols/loading.gif) center no-repeat; } #lbHoverNav { position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 1025; } #lbImageContainer>#lbHoverNav { left: 0; } #lbHoverNav a { outline: none; } #lbPrev { width: 49%; height: 100%; background: transparent url(../images/symbols/blank.gif) no-repeat; display: block; left: 0; float: left; } #lbPrev.grey:hover, #lbPrev.grey:visited:hover { background: url(../images/symbols/prev.gif) left 15% no-repeat; } #lbNext { width: 49%; height: 100%; background: transparent url(../images/symbols/blank.gif) no-repeat; display: block; right: 0; float: right; } #lbNext.grey:hover, #lbNext.grey:visited:hover { background: url(../images/symbols/next.gif) right 15% no-repeat; } #lbPrev2, #lbNext2 { text-decoration: none; font-weight: bold; } #lbPrev2.grey, #lbNext2.grey, #lbSpacer.grey { color: #333333; } #lbPrev2_Off, #lbNext2_Off { font-weight: bold; } #lbPrev2_Off.grey, #lbNext2_Off.grey { color: #CCCCCC; } #lbDetailsData { padding: 0 10px; } #lbDetailsData.grey { color: #333333; } #lbDetails { width: 60%; float: left; text-align: left; } #lbCaption { display: block; font-weight: bold; } #lbNumberDisplay { float: left; display: block; padding-bottom: 1.0em; } #lbNavDisplay { float: left; display: block; padding-bottom: 1.0em; } #lbClose {display:block; width: 17px; height: 22px; float: right; margin-bottom: 1px; position:relative; top:-4px;} #lbClose.grey { background: url(../images/symbols/closelabel.gif) no-repeat; } #lbPlay { width: 64px; height: 28px; float: right; margin-bottom: 1px; } #lbPlay.grey { background: url(../images/symbols/play.png) no-repeat; } #lbPause { width: 64px; height: 28px; float: right; margin-bottom: 1px; } #lbPause.grey { background: url(../images/symbols/pause_grey.png) no-repeat; }Collabtive-2.0/templates/standard/theme/winter/css/style_form.css000066400000000000000000000136211237252063700253460ustar00rootroot00000000000000form.main { display:block; margin:0; font-family: Arial, helvetica, sans-serif; font-size:9pt; line-height:normal; padding:0; } form.main .row { clear:both; } form.main .row-butn-top { /* Button top on forms */ clear:both; height: 38px; } form.main .row-butn-bottom { /* Button bottom on forms */ clear:both; padding: 12px 0 0 0; } form fieldset { display:block; border:none; padding:0; margin:0; } form.main label { width:140px; height:25px; float:left; padding-top:4px; font-weight: bold; } form.main label:hover { cursor: pointer ; } form.main input { float: left; margin-bottom: 6px; width: 307px; height: 17px; padding: 3px 3px 0px 3px; border: 1px solid; font-family: Arial, helvetica, sans-serif; font-size: 9pt; } /* in Userprofile */ .userwrapper form.main label { height: auto; padding: 0; } .userwrapper form.main input, .userwrapper form.main select { margin: 0; } /* ## LOGIN - Form ################################ */ .login form { width: 200px; margin: 0 auto 0 auto; color: #0a182f; font-weight: bold; text-align: left; } .login form .row { height: 38px; } .login form label { float: left; display: block; width: 34px; height: 23px; margin-right: 1px; background-position: 0 0; background-repeat: no-repeat; } .login .username { background: url(../images/login-user.png); } .login .pass { background: url(../images/login-pass.png); } .login .keep, login .keep-active { background: url(../images/login-keeplogged.png); } .login .keep-active { background: url(../images/login-keeplogged.png) no-repeat -68px 0; } .login label:hover { background-position: -34px 0; cursor: pointer; } .login label.keep-active:hover { background-position: -102px 0; } .login form input, .login form label.keep span, .login form label.keep-active span { float: left; width:153px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; } .login form label.keep span, .login form label.keep-active span { margin: 0 0 0 35px; background: url(../images/login-logged-butn.png) repeat-x 0 0; } .login form label.keep:hover span, .login form label.keep-active:hover span { background-position: 0 -23px; } #stay { visibility: hidden; } .loginbutn { border: none; margin: 0 84px 0 84px; width: 32px; height: 32px; background: url(../images/login-butn.png) repeat-x 0 0; outline: none; } .loginbutn:hover { background: url(../images/login-butn.png); background-position: -32px 0; cursor: pointer; } /* ## SEARCH - Form (Sidebar)) ############################### */ #search { position: relative; margin: 0; } #search .row .text, #choices ul { float: left; width:137px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 1px; } #search button { width: 34px; height: 23px; background: url(../images/search-butn-side.png) no-repeat 0 0; float: left; margin: 0; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius:0px; } #search button:hover { background-position: 0 -23px; } #choices ul { /* Autocompleter */ width: 184px; height: auto; max-height: 300px; overflow-y: auto; overflow-x: hidden; background: url(../images/color-a.png) repeat 0 0; float:left; padding: 0 0 1px 0; } #choices li { width: 180px; height: 31px; line-height: 31px; background: url(../images/autocomplete-bg-a.png) repeat-x 0 0; margin-top: 1px; padding: 2px; float:left; } #choices li:hover { cursor:pointer; background-position: 0 -36px; } #choices li img { float:left; margin:2px 0 2px 0; } #indicator1 { position: absolute; top:0; left: 150px; width: 34px; height: 23px; background: #3c556f; } #indicator1 img { margin: 3px 9px 0 9px; } /* ## BUTTON ############################### */ button, button.inner, button.inner-active { border: none; font-family: Arial, helvetica, sans-serif; float: left; height: 22px; line-height: 22px; color: #fff; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius:3px; font-size: 11px; font-weight: bold; margin: 0 5px 0 0; padding-top: 0px; padding-bottom: 1px; /*padding: 2px 0 3px 0;*/ white-space: nowrap; background: #384e67; } button:hover { cursor: pointer; background: #001e40; } button[disabled] { opacity:.6; filter:alpha(opacity=60); -moz-opacity:.6; } button[disabled]:hover { background: #384e67; } form.main select { width: 315px; height: 22px; border: 1px solid; float: left; margin-bottom: 6px; padding: 2px 0 0 0; font-family: Arial, helvetica, sans-serif; font-size: 9pt; } form.main option { background:#fff; } /* ## FILES ############################### */ .fileinput { position: relative; float: left; width: 315px; } .fileinput table { width: 315px; } .block .fileinput table td, .blockwrapper .fileinput table td { padding: 0; border: none; height: 24px; } .block .fileinput table td.choose, .blockwrapper .fileinput table td.choose { width: 10%; padding: 0 0 0 13px; } .faux { position: absolute; top: 0px; left: 0px; z-index: 1; } .fileinput button { margin: 0px 0 0 0; float: right; } form.main input.file { position: relative; -moz-opacity: 0 ; filter: alpha(opacity: 0); opacity: 0; z-index: 2; height: 25px; } form.main input.text-file { width: 100%; margin: 0; } form.main textarea { width: 307px; height:90px; font-size:9pt; padding:2px 3px 2px 3px; background:#fff; border:1px solid; font-family:Arial, helvetica, sans-serif; margin-bottom:6px; } form.main .checkbox{ width:auto; float:left; margin: 1px 25px 0 0; border:none; } form.main .radio{ float:left; width: auto; border:none; position: relative; top: 6px; margin: 0; } form.main .input_error { border-color: #be4c43; color: #be4c43; } /* ## Editor ## start */ form.main .row .editor { float: left; margin-bottom:6px; border: 1px solid #000; } /* ## Editor ## end */ Collabtive-2.0/templates/standard/theme/winter/css/style_iefix.css000066400000000000000000000007561237252063700255140ustar00rootroot00000000000000#sitebody { min-height:100%; } * html #sitebody { height:100%; } #contentwrapper { width: 980px; margin: 0 auto 26px auto; /* same as footer-height (for IE 7) */ } /*# Form Button # */ .butn button { height:24px; line-height:21px; padding:0 8px 0px 3px; overflow:visible; width:auto; } /*# UL LI Tables # */ .content_left ul li{ float:left; } /*# Calender # */ div#calendar table{ border-collapse: collapse; } /* Datepicker */ .datepick .picker { width: 187px; top: -239px; }Collabtive-2.0/templates/standard/theme/winter/css/style_main.css000066400000000000000000001521671237252063700253400ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Froehner ## URL: http://www.visional-arts.de */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#4566A4; background:#FFFFFF url(../images/main-bg.jpg) repeat-x 0 0; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: #4B6EB2 ; color: #fff; } ::-moz-selection { background: #4B6EB2; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color:red; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; background: url(../images/color-a.png) repeat 0 0; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background-image: url(../images/login-alert.png); font-weight: bold; color: #fac3b7; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: #fff; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: #4B6EB2; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: url(../images/color-a.png) repeat 0 0; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: #4B6EB2; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: url(../images/color-a.png) repeat 0 0; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images/main-admin-c.png) no-repeat 0 0; } #mainmenue .submen li.customer-settings a { background: url(../images/main-admin-d.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: #4B6EB2; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: #fff; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #6d7f93; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #FFFFFF; // color: #4566A4} .content-right-in a:hover { color: #FFFFFF; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images/color-a.png) repeat 0 0; padding: 11px; color: #6d7f93; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #6d7f93; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #6d7f93; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ .export-main, .add-main { float: right; width: 30px; height: 26px; position: relative; left: 0; top: -41px; margin: 0 9px -26px 0; background-repeat: no-repeat; background-position: right 0; z-index: 9; } .add-main { width: 19px; } .wintools .export-main { position: relative; top: 0; z-index: 1; margin: 0; float: left; } .export-main a span, .wintools a span, .add-main a span { display: none; white-space: nowrap; } .export-main a:hover span, .export-main .export-in a:hover span, .wintools a:hover span, .add-main a:hover span { display: block; height: 21px; line-height: 21px; position: absolute; top: -34px; right: 0; z-index: 9; color: ; font-size: 12px; background: ; padding: 0 7px 0 7px; -moz-border-radius-topleft: 2px; -moz-border-radius-topright: 2px; -webkit-border-top-left-radius: 2px; -webkit-border-top-right-radius: 2px; } .wintools .export-main a:hover span, .wintools .export-main .export-in a:hover span, .wintools a:hover span { top: -28px; color: ; font-weight: bold; } .export-main .export-in a:hover span { right: -30px; } .export-main:hover, .add-main:hover { cursor: pointer; background-position: right -31px; } .export-in { display: none; position: absolute; top: 0; z-index: 8; right: 30px; height: 100%; float: left; } .export-main:hover .export-in { display: block; } .export-main a, .wintools a, .add-main a { float: left; display: block; width: 19px; height: 100%; margin-left: 4px; background-repeat: no-repeat; background-position: 0 0; } .toolwrapper { float: left; height: 100%; margin-left: 5px; } .projects .export-main, .projects .export-main a { background-image: url(../images/export-tasks.png); } .projects .wintools .export-main, .projects .wintools .export-main a { background-image: url(../images/export-headline.png); } .projects .wintools .export-main a:hover span, .projects .wintools a:hover span { background: ; } .tasks .export-main, .tasks .export-main a { background-image: url(../images/export-tasks.png); } .tasks .wintools .export-main, .tasks .wintools .export-main a { background-image: url(../images/export-headline.png); } .tasks .wintools .export-main a:hover span, .tasks .wintools a:hover span, .wintools a:hover span { background: ; } .msgs .export-main, .msgs .export-main a { background-image: url(../images/export-msgs.png); } .msgs .wintools .export-main, .msgs .wintools .export-main a { background-image: url(../images/export-headline.png); } .msgs .wintools .export-main a:hover span, .msgs .wintools a:hover span { background: ; } .user .export-main, .user .export-main a { background-image: url(../images/export-vcard.png); } .user .wintools .export-main, .user .wintools .export-main a { background-image: url(../images/export-headline.png); } .user .wintools .export-main a:hover span, .user .wintools a:hover span { background: ; } .timetrack .wintools .export-main, .timetrack .wintools .export-main a { background-image: url(../images/export-headline.png); } .timetrack .wintools .export-main a:hover span, .timetrack .wintools a:hover span { background: ; } .miles .wintools .export-main, .miles .wintools .export-main a { background-image: url(../images/export-headline.png); } .miles .wintools .export-main a:hover span, .miles .wintools a:hover span { background: ; } .neutral .wintools .export-main, .neutral .wintools .export-main a { background-image: url(../images/export-headline.png); } .neutral .wintools .export-main a:hover span, .neutral .wintools a:hover span { background: ; } .files .wintools .addmen .export-main, .files .wintools .addmen .export-main a { background-image: url(../images/add-files.png); } .files .wintools .export-main, .files .wintools .export-main a { background-image: url(../images/export-headline.png); } .files .wintools .export-main a:hover span, .files .wintools a:hover span { background: ; } .export-main a.export, .wintools .export-main a.export, .files .wintools .addmen .export-main a.export { background: none; width: 30px; margin: 0; } .add-main a.add, .add-main a.add-active { background-image: url(../images/adds.png); margin: 0; } .add-main a.add:hover, .add-main a.add-active { background-position: 0 -31px; } .export-main a.ical { background-position: 0 0; } .export-main a.ical:hover { background-position: 0 -31px; } .export-main a.pdf { background-position: -23px 0; } .export-main a.pdf:hover { background-position: -23px -31px; } .export-main a.rss { background-position: -46px 0; } .export-main a.rss:hover { background-position: -46px -31px; } .export-main a.excel { background-position: -69px 0; } .export-main a.excel:hover { background-position: -69px -31px; } .export-main a.vcardmale { width: 28px; background-position: -32px 0; } .export-main a.vcardmale:hover { background-position: -32px -31px; } .export-main a.vcardfemale { width: 28px; background-position: 0 0; } .export-main a.vcardfemale:hover { background-position: 0 -31px; } .export-main a.addfile { background-position: -31px 0; } .export-main a.addfile:hover, .export-main a.addfile-active { background-position: -31px -31px; } .export-main a.addfolder { width: 27px; background-position: 0 0; } .export-main a.addfolder:hover, .export-main a.addfolder-active { width: 27px; background-position: 0 -31px; } /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: #fff; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: url(../images/color-c-green.png) repeat 0 0; } .cal td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: #fff; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: #fff; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: #eaf6e3; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: #fff; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: #009359; background: url(../images/color-c-green.png) repeat 0 0; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images/next-side-user.png); } .user .datepick td.back a { background-image: url(../images/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images/next-side-files.png); } .files .datepick td.back a { background-image: url(../images/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { border-bottom: 1px solid #3c5570; float: left; position: relative; } #onlinelist li { width: 184px; clear: both; border-top: 1px solid #3c5570; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #FFFFFF; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #FFFFFF; /*background: url(../images/onlinelist-hover.png) repeat 0 0; */ } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: #fff; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted #fff; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: #fff; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 562px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 562px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in ul, .descript ul { list-style-type: disc; padding-left: 40px; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid #fff; border-bottom: 1px solid #fff; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: #4B6EB2; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images/symbols/tab-projects.png); } ul.tabs li.customers a { background-image: url(../images/symbols/tab-customers.png); } ul.tabs li.tasks a { background-image: url(../images/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: #4B6EB2; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: #7F97BC; color: #4566A4; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: #7F97BC; color: #4566A4; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: #4B6EB2; } #modal_overlay.useroverlay { background: #bbcbbb; } #modal_overlay.tasksoverlay { background: #4566A4; } #modal_overlay.milesoverlay { background: #b49591; } #modal_container .inmodal { background: #fff; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid #fff; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: #fff; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 0; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 -1px; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 0; } .statusbar_b .complete { height: 8px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 -1px; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid #fff; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid #fff; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid #fff; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid #fff; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid #fff; padding: 12px 9px 18px 45px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 230px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 176px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: url(../images/bg_table.png); } .projects thead { background: url(../images/bg_th.png); } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: url(../images/tables-projects-sechead.png); } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: url(../images/tables-tasks-bg-a.png); } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: url(../images/tables-tasks-bg-b.png); } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: #96B4DE; color: #4566A4; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: #4566A4; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: #CCCCCC; border-color: #CCCCCC; } .projects .datepick td.wrong { color: #CCCCCC; } .projects h1 span a { border-color: #96B4DE; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: #CCCCCC; color: #4566A4; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: #7F97BC; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: url(../images/bg_table.png); } .tasks thead { background: url(../images/bg_th.png); } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: url(../images/bg_th.png); } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: url(../images/tables-tasks-bg-a.png); } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: url(../images/tables-tasks-bg-b.png); } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: #96B4DE; color: #4566A4; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: #4566A4; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: #4566A4; } .task h1 span a { border-color: #96B4DE; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: #4566A4; color: #4566A4; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: #7F97BC; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: url(../images/bg_table.png); } .msgs thead { background: url(../images/bg_th.png); } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: url(../images/tables-msgs-sechead.png); } .msgs .color-a, .msgs .statuswrapper li { background: url(../images/tables-tasks-bg-a.png); } .msgs .color-b { background: url(../images/tables-tasks-bg-b.png); } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: url(../images/tables-msgs-bg-c.png); } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: #96B4DE; color: #4566A4; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: #a3a19e; } .msgs h1 span a { border-color: #96B4DE; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: #a3a19e; color: #96B4DE; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: #7F97BC; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: url(../images/bg_table.png); } .user thead, .user .contenttitle { background: url(../images/bg_th.png); } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: url(../images/tables-user-sechead.png); } .user .color-a, .user .staterow { background: url(../images/tables-user-bg-a.png); } .user .color-b, .user .content_in_wrapper { background: url(../images/tables-user-bg-b.png); } .user .color-a ul.files table, .user .color-b ul.files table { background: url(../images/tables-user-bg-c.png); } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: #96B4DE; color: #4566A4; } .user h1 span, .user h1 span a, .user .inmenue a span { color: #bbcbbb; } .user h1 span a { border-color: #96B4DE; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: #bbcbbb; color: #4566A4; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: #7F97BC; } /* USER PROFILE */ .user .export-main { background-image: url(../images/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: url(../images/tables-user-bg-a.png); border-right: 1px solid #fff; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: url(../images/bg_table.png); } .neutral thead, .neutral .contenttitle { background: url(../images/bg_th.png); } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: url(../images/bg_th.png); } .neutral .color-a, .neutral .staterow { background: url(../images/tables-tasks-bg-a.png); } .neutral .color-b, .neutral .content_in_wrapper { background: url(../images/tables-neutral-bg-b.png); } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: url(../images/tables-neutral-bg-c.png); } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: #96B4DE; color: #4566A4; } .neutral h1 span, .neutral h1 span a { color: #a9a7a8; } .neutral h1 span a { border-color: #96B4DE; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: #a9a7a8; color: #96B4DE; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: #7F97BC; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: url(../images/bg_table.png); } .timetrack thead { background: url(../images/bg_th.png); } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: url(../images/bg_th.png); } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: url(../images/tables-tasks-bg-a.png); } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: url(../images/tables-tasks-bg-B.png); } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: url(../images/tables-timetracking-bg-c.png); } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: #96B4DE; color: #4566A4; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: #4566A4; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: #4566A4; } .timetrack h1 span a { border-color: #96B4DE; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: #bc9f8f; color: #4566A4; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: #7F97BC; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: url(../images/bg_table.png); } .miles thead, .miles .calhead th { background: url(../images/bg_th.png); } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: url(../images/bg_th.png); } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: url(../images/tables-miles-bg-a.png); } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: url(../images/tables-miles-bg-b.png); } .miles .color-a ul.files table, .miles .color-b ul.files table { background: url(../images/tables-miles-bg-c.png); } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: #96B4DE; color: #4566A4; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: #4566A4; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: #4566A4; } .miles h1 span a, .miles .content-spacer-b { border-color: #96B4DE; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: #b49591; color: #4566A4; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: #7F97BC; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: url(../images/bg_table.png); } .files thead, .files .contenttitle { background: url(../images/bg_th.png); } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: url(../images/bg_th.png); } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: url(../images/tables-files-bg-a.png); } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: url(../images/tables-files-bg-b.png); } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: #96B4DE; color: #4566A4; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: #4566A4; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: #9195a2; } .files h1 span a { border-color: #96B4DE; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: #9195a2; color: #4566A4; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: #7F97BC; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images/butn-reply.png); } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 4px; } a.tool_edit_active { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 -22px; } a.tool_del { background-image: url(../images/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: #be4c43; } .marker-today, .marker-today a { color: #009359; } .green, .green a { color: #009359; border-color: #009359; background-color:#e0f1db; } .red, .red a { color: #be4c43; border-color: #be4c43; background-color:#e7dcda; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images/infowin_green.png) repeat; } .info_in_yellow { background: url(../images/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #6ab0c5; } .footer a { color: #6ab0c5; } /* ## Footer ## end ## */ Collabtive-2.0/templates/standard/theme/winter/css/style_main.php000066400000000000000000001541761237252063700253410ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Fröhner ## URL: http://www.visional-arts.de */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#4566A4; background:#FFFFFF url(../images/main-bg.jpg) repeat-x 0 0; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: ; color: #fff; } ::-moz-selection { background: ; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color:red; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; background: url(../images/color-a.png) repeat 0 0; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background-image: url(../images/login-alert.png); font-weight: bold; color: ; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: ; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: ; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: url(../images/color-a.png) repeat 0 0; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: ; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: url(../images/color-a.png) repeat 0 0; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images/main-admin-c.png) no-repeat 0 0; } #mainmenue .submen li.customer-settings a { background: url(../images/main-admin-d.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: ; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: ; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #6d7f93; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #FFFFFF; // color: } .content-right-in a:hover { color: #FFFFFF; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images/color-a.png) repeat 0 0; padding: 11px; color: #6d7f93; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #6d7f93; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #6d7f93; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: ; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: url(../images/color-c-green.png) repeat 0 0; } .cal td.red { color: #be4c43; background: url(../images/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: ; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: ; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: ; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: ; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: ; background: url(../images/color-c-green.png) repeat 0 0; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: ; background: url(../images/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images/next-side-user.png); } .user .datepick td.back a { background-image: url(../images/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images/next-side-files.png); } .files .datepick td.back a { background-image: url(../images/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { border-bottom: 1px solid #3c5570; float: left; position: relative; } #onlinelist li { width: 184px; clear: both; border-top: 1px solid #3c5570; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #FFFFFF; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #FFFFFF; /*background: url(../images/onlinelist-hover.png) repeat 0 0; */ } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: ; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted ; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: ; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 562px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 562px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in ul, .descript ul { list-style-type: disc; padding-left: 40px; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid ; border-bottom: 1px solid ; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: ; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images/symbols/tab-projects.png); } ul.tabs li.customers a { background-image: url(../images/symbols/tab-customers.png); } ul.tabs li.tasks a { background-image: url(../images/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: ; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: ; color: ; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: ; color: ; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: ; } #modal_overlay.useroverlay { background: ; } #modal_overlay.tasksoverlay { background: ; } #modal_overlay.milesoverlay { background: ; } #modal_container .inmodal { background: ; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid ; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: ; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 0; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: url(../images/statusbar_incomplete_b.jpg) repeat-x 0 -1px; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 0; } .statusbar_b .complete { height: 8px; background: url(../images/statusbar_complete_b.jpg) repeat-x 0 -1px; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid ; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid ; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid ; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid ; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid ; padding: 12px 9px 18px 45px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 230px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 176px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: ; } .projects thead { background: ; } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: ; } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: ; } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: ; } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: ; color: ; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: ; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: ; border-color: ; } .projects .datepick td.wrong { color: ; } .projects h1 span a { border-color: ; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: ; color: ; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: ; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: ; } .tasks thead { background: ; } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: ; } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: ; } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: ; } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: ; color: ; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: ; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: ; } .task h1 span a { border-color: ; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: ; color: ; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: ; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: ; } .msgs thead { background: ; } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: ; } .msgs .color-a, .msgs .statuswrapper li { background: ; } .msgs .color-b { background: ; } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: ; } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: ; color: ; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: ; } .msgs h1 span a { border-color: ; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: ; color: ; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: ; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: ; } .user thead, .user .contenttitle { background: ; } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: ; } .user .color-a, .user .staterow { background: ; } .user .color-b, .user .content_in_wrapper { background: ; } .user .color-a ul.files table, .user .color-b ul.files table { background: ; } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: ; color: ; } .user h1 span, .user h1 span a, .user .inmenue a span { color: ; } .user h1 span a { border-color: ; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: ; color: ; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: ; } /* USER PROFILE */ .user .export-main { background-image: url(../images/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: ; border-right: 1px solid ; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: ; } .neutral thead, .neutral .contenttitle { background: ; } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: ; } .neutral .color-a, .neutral .staterow { background: ; } .neutral .color-b, .neutral .content_in_wrapper { background: ; } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: ; } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: ; color: ; } .neutral h1 span, .neutral h1 span a { color: ; } .neutral h1 span a { border-color: ; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: ; color: ; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: ; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: ; } .timetrack thead { background: ; } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: ; } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: ; } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: ; } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: ; } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: ; color: ; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: ; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: ; } .timetrack h1 span a { border-color: ; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: ; color: ; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: ; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: ; } .miles thead, .miles .calhead th { background: ; } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: ; } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: ; } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: ; } .miles .color-a ul.files table, .miles .color-b ul.files table { background: ; } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: ; color: ; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: ; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: ; } .miles h1 span a, .miles .content-spacer-b { border-color: ; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: ; color: ; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: ; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: ; } .files thead, .files .contenttitle { background: ; } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: ; } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: ; } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: ; } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: ; color: ; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: ; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: ; } .files h1 span a { border-color: ; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: ; color: ; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: ; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images/butn-reply.png); } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 4px; } a.tool_edit_active { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images/butn-edit.png) no-repeat 0 -22px; } a.tool_del { background-image: url(../images/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: ; } .marker-today, .marker-today a { color: ; } .green, .green a { color: ; border-color: ; background-color:; } .red, .red a { color: ; border-color: ; background-color:; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images/infowin_green.png) repeat; } .info_in_yellow { background: url(../images/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #6ab0c5; } .footer a { color: #6ab0c5; } /* ## Footer ## end ## */ Collabtive-2.0/templates/standard/theme/winter/css/style_main2.php000066400000000000000000001552461237252063700254220ustar00rootroot00000000000000 /* ## Visional Arts CSS Framework 1.1 static ## Author & Copyright: Marcus Fröhner ## URL: http://www.visional-arts.de */ @import url("style_form.css"); /* ## Basic-XHTML-Elements ################################ */ html, body { margin: 0; padding: 0; height: 100%; font-family: Arial, helvetica, sans-serif; font-size: 13px; } body { color:#082343; background:#F6F7F9 url(../images_frost/main-bg.jpg) repeat-x 0 0; background-attachment: fixed; } body a, body a:visited { text-decoration:none; outline: none; } body a:hover { text-decoration: none; } .hidden { visibility:hidden; } .visible { visibility:visible; } .clear_both { clear:both; } .clear_both_b { clear:both; height:15px; } img { border: none; } ::selection { background: ; color: #fff; } ::-moz-selection { background: ; color: #fff; } ul { margin: 0; padding: 0; list-style-type: none; } td.message ul { padding: 0 0 0 5px; margin: 0 0 0 10px; list-style-type: disc; } .error_message { color:red; } /* ## Basic-XHTML-Elements ############### END ############## */ /* ## LOGIN-Elements ################################ */ .login { width: 460px; position: absolute; top: 10%; left: 50%; margin-left: -230px; } .login-in, .login-alert { width: 100%; background: #FEFEFE url(../images_frost/color-a.png) repeat-x; border: 1px solid #D2D6DF; text-align: center; padding: 20px 0 20px 0; /* -moz-border-radius: 2px; -webkit-border-radius: 2px; */ } .login-alert { margin: 3px 0 0 0; padding: 5px 0 5px 0; background-image: url(../images_frost/login-alert.png); font-weight: bold; color: ; } .login .logo-name { width:100%; text-align: center; } .logo-name h1 { color: ; margin: 0; height: auto; line-height: normal; } .logo-name h2 { font-size: 15px; color: ; margin: 8px 0 18px 0; } /* ## LOGIN-Elements ############## END ############# */ #sitebody { display: block; min-width: 980px; min-height: 100%; margin: 0 auto; } #header-wrapper { width:100%; height: 70px; background: url(../images_frost/color-a.png) repeat 0 0; } #header { width: 980px; margin: 0 auto 0 auto; } .header-in { padding: 11px 0 0 0; height: 70px; } #header .left { float: left; width: 742px; height: 70px; margin-right: 18px; overflow: hidden; } #header .right { float: left; width: 202px; padding-left: 18px; } #header .logo { float: left; } #header .logo img { float: left; } #header .logo h1 span.title { color: #fff; font-size: 26px; font-weight: bold; position: relative; top: 20px; left: -5px; display:block; float:left; } #header .logo h1 span.subtitle { color: #547AC3; } /* ## MAIN-MENUE ######################################## */ #mainmenue { padding: 8px 0 0 0; position: relative; } #mainmenue li { float: left; width: 32px; height: 32px; margin-right: 6px; } #mainmenue li a { display: block; float: left; width: 32px; height: 32px; } #mainmenue li.desktop a { background: url(../images_frost/main-desk.png) no-repeat 0 0; } #mainmenue li.profil-male a { background: url(../images_frost/main-prof-male.png) no-repeat 0 0; } #mainmenue li.profil-female a { background: url(../images_frost/main-prof-female.png) no-repeat 0 0; } #mainmenue li.admin a { background: url(../images_frost/main-settings.png) no-repeat 0 0; } #mainmenue li.logout a { background: url(../images_frost/main-logout.png) no-repeat 0 0; } #mainmenue li a span { display: none; } #mainmenue .submen { position: absolute; top: 34px; left: -6px; padding: 25px 0 0 0; float:left; z-index: 6; display: none; } #mainmenue .submen ul { width: auto; background: url(../images_frost/color-a.png) repeat 0 0; padding: 0 0 6px 6px; float: left; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-left-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } #mainmenue .submen li { margin: -6px 6px 0 0; } #mainmenue li:hover .submen { display: block; } #mainmenue .submen li.project-settings a { background: url(../images_frost/main-admin-a.png) no-repeat 0 0; } #mainmenue .submen li.user-settings a { background: url(../images_frost/main-admin-b.png) no-repeat 0 0; } #mainmenue .submen li.system-settings a { background: url(../images_frost/main-admin-c.png) no-repeat 0 0; } #mainmenue li:hover a, #mainmenue li a.active, #mainmenue .submen li:hover a, #mainmenue .submen li a.active { background-position: 0 -32px; } #mainmenue li a:hover span { display: block; width: 200px; position: absolute; top: 18px; left: -222px; color: ; font-size: 12px; font-weight: bold; text-align: right; white-space: nowrap; } #mainmenue li .submen a:hover span { top: -16px; left: -216px; } #mainmenue li:hover a .submenarrow { display: block; position: relative; top: 32px; left: 0; width: 32px; height: 7px; padding: 0; background: url(../images_frost/main-submen.png) no-repeat center 0; } /* ## CONTENT ######################################## */ #contentwrapper { width: 980px; margin: 0 auto -26px auto; /* same as footer-height (for IE 7) */ } #content-left { width: 742px; min-height: 100px; background: ; margin: 0 18px 10px 0; float: left; } #content-left-in { margin: 18px 18px 0 18px; } #content-left h1 { padding: 0 0 15px 2px; width: 100%; overflow: hidden; } #content-left h1 span { font-size: 15px; } #content-left h1.second { line-height: 34px; margin: -5px 0 10px 0; position: relative; left: -8px; } #content-left h1 img { float: left; } .content-spacer { clear: both; width: 100%; height: 27px; } .content-spacer-b { clear: both; width: 100%; height: 13px; margin: 13px 0 0 0; border-top: 1px dotted #000; } #content-right { width: 220px; min-height: 20px; background: url(../images_frost/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 0 0 23px 0; float: left; color: #6d7f93; } .content-right-in { width: 184px; margin: 23px 0 0 18px; } .content-right-in .cloud { /* Tag Cloud */ width: 184px; overflow: hidden; } .content-right-in a { color: #6d7f93; } .content-right-in a:hover { color: #9daab7; } #content-right h2 { font-size: 14px; margin: 0; line-height: 12px; } #content-right h2 a.win-up, #content-right h2 a.win-down { display: block; width: 100%; height: 16px; background: url(../images_frost/win-up-side.png) no-repeat right 1px; margin: 0 0 5px 0; } #content-right h2 a.win-down { background: url(../images_frost/win-down-side.png) no-repeat right 1px; } #content-right h2 a.win-up:hover, #content-right h2 a.win-down:hover { background-position: right -15px; } /* ## CHAT ############################################# */ .chat { background: url(../images_frost/color-a.png) repeat 0 0; padding: 11px; color: #6d7f93; float: left; height: 100%; } .chat .row .text { float: left; width: 217px; height: 19px; padding: 4px 6px 0 6px; border:none; font-size: 12px; background: url(../images_frost/input-bg-a.png) repeat-x 0 0; color: #0a182f; font-weight: bold; margin-right: 3px; } .chat .chattext { height: 200px; width: 300px; padding: 5px; overflow: auto; margin: 0 0 10px 0; float: left; background: #fff; color: #0a182f; } .chat button:hover { background: #6d7f93; color: #0a182f; } .chat button[disabled]:hover { background: #384e67; color: #fff; } /* ## SEARCH MODAL ################################### */ .search-modal { width: 202px; min-height: 20px; background: url(../images_frost/color-a.png) repeat 0 0; margin: 0 0 0 0; padding: 12px 0px 23px 18px; float: left; color: #6d7f93; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } /* ## WINTOOLS ######################################## */ .wintools { float: right; height: 26px; position: relative; top: -28px; margin: 0 37px -30px 0; z-index: 9; } .wintools a { background: url(../images_frost/win-tools.png) 0 0; } .wintools a.close { background-position: 0 0; } .wintools a.close:hover { background-position: 0 -31px; } .wintools a.edit { background-position: -23px 0; } .wintools a.edit:hover { background-position: -23px -31px; } .wintools a.del { background-position: -46px 0; } .wintools a.del:hover { background-position: -46px -31px; } .wintools a.filter { background-position: -69px 0; } .wintools a.filter:hover, .wintools a.filter-active { background-position: -69px -31px; } .wintools a.add, .wintools a.add-active { background-position: right 0; margin-left: 9px; } .wintools a.add:hover, .wintools a.add-active { background-position: right -31px; } /* ## EXPORT-MAIN ##################################### */ /* ## IN-MENUES ######################################## */ .inwrapper { float: left; width: 100%; margin: 6px 0 6px 0; font-size: 12px; } .inwrapper li { float: left; width: 92px; margin: 0 1px 6px 0; padding: 4px 0 0 0; text-align: center; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .inwrapper img { float: left; } .itemwrapper { /* in this are all the li */ } .itemwrapper table { width: 100%; } .inwrapper span.name a:hover { text-decoration: underline; } .inwrapper li td.thumb a { display: block; width: 32px; max-height: 32px; overflow: hidden; padding: 0; margin: 0; border: none; } .inwrapper li td.thumb { width: 32px; height: 32px; } .inwrapper li td.thumb a img { float: none; margin: 0; } .inwrapper span.name { display: block; clear: both; width: 100%; margin: 5px 0 0 0; height: 18px; line-height: 18px; text-align: center; overflow: hidden; } .inwrapper li .rightmen, .inwrapper li .leftmen { width: 30px; } .inmenue { height: 32px; } .inmenue a { display: none; width: 14px; height: 14px; background: url(../images_frost/inmenue-tools.png) no-repeat; margin: 0 0 3px 8px; } .itemwrapper:hover .inmenue a { display: block; } .inmenue a.more { background-position: 1px 1px; } .inmenue a.more:hover { background-position: 1px -13px; } .inmenue a.export { background-position: -13px 1px; } .inmenue a.export:hover { background-position: -13px -13px; } .inmenue a.edit { background-position: -27px 1px; } .inmenue a.edit:hover { background-position: -27px -13px; } .inmenue a.del { background-position: -41px 1px; } .inmenue a.del:hover { background-position: -41px -13px; } .moreinfo-wrapper { position: relative; clear: both; } .moreinfo { position: absolute; left: 0; bottom: 0px; padding: 5px 5px 0 5px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; width: 82px; z-index: 11; } .moreinfo img { float: left; } .moreinfo img:hover { cursor: pointer; } .user .moreinfo a, .projects .moreinfo a, .tasks .morinfo a { color: ; } /* ## CALENDAR ############## Sidebar / Datepicker ################# */ .cal { width: 184px; } .cal tr { height: 23px; } .cal td { padding: 0; background: url(../images_frost/color-d.png) repeat 0 0; text-align: center; font-size: 11px; } .cal tr.head, .cal tr.weekday { font-weight: bold; } .cal tr.head td { background: url(../images_frost/color-d.png) repeat 0 0; } .cal tr.weekday td { background: url(../images_frost/color-c.png) repeat 0 0; } .cal td.back, .cal td.next { /*background: url(../images_frost/autocomplete-bg-a.png) repeat-x 0 0;*/ } .cal td.back a, .cal td.next a { display: block; width: 100%; height: 23px; background: url(../images_frost/back-side.png) no-repeat center 7px; } .cal td.next a { background-image: url(../images_frost/next-side.png); } .cal td.back a:hover, .cal td.next a:hover { background-position: center -16px; } .cal td.wrong { color: #3c556f; background: url(../images_frost/color-c.png) repeat 0 0; } .cal td.today { color: #52a454; background: url(../images_frost/color-c-green.png) repeat 0 0; } .cal td.red { color: #be4c43; background: url(../images_frost/color-c-red.png) repeat 0 0; } .cal td.cyan { color: #529ba4; background: url(../images_frost/color-c-cyan.png) repeat 0 0; } /* ## BIG CALENDAR ###################################### */ .block .bigcal table.thecal { border-collapse: separate; display: inline-table; table-layout: fixed; } .block .bigcal table.thecal thead { background: ; font-size: 14px; } .block .bigcal table.thecal th { height: 37px; line-height: 37px; border: none; padding: 0; } .block .bigcal table.thecal .dayhead th { height: 27px; line-height: 27px; padding: 0 6px 0 6px; } .block .bigcal tbody.content td { border: none; width: 100px; background: ; padding: 6px; line-height: normal; } .block .bigcal table.thecal td.today { background: ; } .block .bigcal table.thecal td.second { } .block .bigcal table.thecal td.othermonth { } .block .bigcal .calcontent { } .bigcal .scroll_left, .bigcal .scroll_right { display: block; width: 100%; height: 100%; background: url(../images_frost/scroll_left_miles.png) no-repeat center 15px; } .bigcal .scroll_right { background-image: url(../images_frost/scroll_right_miles.png); } .bigcal .scroll_left:hover, .bigcal .scroll_right:hover { background-position: center -20px } .calinmenue { position: absolute; height: 0px; z-index: 1666; } .calinmenue ul { position: relative; left: 0; top: 0; padding: 6px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .calinmenue ul li a { display: block; height: 22px; line-height: 22px; margin: 0 0 1px 0; padding: 0 8px 0 8px; white-space: nowrap; color: ; font-size: 11px; font-weight: bold; } .calinmenue ul li a:hover { text-decoration: none; } .closewin a { display: block; background: url(../images_frost/closewin.png) no-repeat right 1px; } .closewin a:hover { background-position: right -19px; } .calinmenue ul li.closewin a { height: 14px; line-height: normal; padding: 0 0 0 4px; margin: 0 0 4px 0; } /* ## DATEPICKER ######################################## */ .datepick { clear:both; position: absolute; z-index: 1000000000; } .datepick .picker { position: relative; left: 152px; top: -210px; padding: 6px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .datepick .picker a { } .datepick .cal { background: #fff; } .block .datepick table, .datepick table { border-collapse: separate; border: none; } .block .datepick table td, .datepick table td { padding: 0 6px 0 6px; min-width: 12px; border: none; height: 23px; line-height: 23px; } .projects .datepick td.today, .tasks .datepick td.today, .miles .datepick td.today, .timetrack .datepick td.today, .neutral .datepick td.today { color: ; background: url(../images_frost/color-c-green.png) repeat 0 0; } .projects .datepick td.red, .tasks .datepick td.red, .miles .datepick td.red, .timetrack .datepick td.red, .neutral .datepick td.red { color: ; background: url(../images_frost/color-c-red.png) repeat 0 0; } .datepick td.normalday:hover, .datepick td.today:hover, .datepick td.red:hover { cursor: pointer; background: #fff; } .projects .datepick td.next a { background-image: url(../images_frost/next-side-projects.png); } .projects .datepick td.back a { background-image: url(../images_frost/back-side-projects.png); } .tasks .datepick td.next a { background-image: url(../images_frost/next-side-tasks.png); } .tasks .datepick td.back a { background-image: url(../images_frost/back-side-tasks.png); } .timetrack .datepick td.next a { background-image: url(../images_frost/next-side-timetrack.png); } .timetrack .datepick td.back a { background-image: url(../images_frost/back-side-timetrack.png); } .user .datepick td.next a { background-image: url(../images_frost/next-side-user.png); } .user .datepick td.back a { background-image: url(../images_frost/back-side-user.png); } .miles .datepick td.next a { background-image: url(../images_frost/next-side-miles.png); } .miles .datepick td.back a { background-image: url(../images_frost/back-side-miles.png); } .files .datepick td.next a { background-image: url(../images_frost/next-side-files.png); } .files .datepick td.back a { background-image: url(../images_frost/back-side-files.png); } .neutral .datepick td.next a { background-image: url(../images_frost/next-side-neutral.png); } .neutral .datepick td.back a { background-image: url(../images_frost/back-side-neutral.png); } /* ## ONLINELISTE ######################################## */ #onlinelist ul { border-bottom: 1px solid #3c5570; float: left; position: relative; } #onlinelist li { width: 184px; clear: both; border-top: 1px solid #3c5570; } #onlinelist li a div { display: none; } #onlinelist li a div img { margin: 5px 5px 5px 5px; float: right; } #onlinelist a.user, #onlinelist a.chat, .chat-user { display: block; float: left; width: 167px; height: 23px; line-height: 23px; color: #6d7f93; padding-left: 1px; } #onlinelist a.user:hover, .chat-user { color: #9daab7; /*background: url(../images_frost/onlinelist-hover.png) repeat 0 0; */ } #onlinelist a.chat, .chat-user { width: 16px; padding: 0; background: url(../images_frost/chat.png) no-repeat right -23px; } #onlinelist a.chat:hover { background-position: right -46px; } .chat-user { background-position: right 0; } #onlinelist li a:hover div { display:block; position: absolute; top: 0; left: -119px; width: 100px; z-index: 8; background: url(../images_frost/color-b.png) repeat 0 0; } /* ## HEADLINES ##################################### */ .headline, .headline_lone { width: 100%; height: 35px; margin: 0 0 0 0; position: relative; } .headline h2 { position: absolute; height: 100%; line-height: 35px; top: 0; left: 0; } .headline_lone { height: 100%; line-height: 35px; } .headline_lone h2 { height: 32px; line-height: 33px; margin: -15px 0 10px 2px; } .headline h2, .headline h2 a { color: ; } .headline img, .headline_lone img { float:left; margin: 0 7px 0 2px; } .headline_lone h2 img { margin: 0 0px 0 -4px; } h2 a:hover { text-decoration: none; } #content-left h2 a:hover { text-decoration: none; border-bottom: 1px dotted ; } /* ## Block-headline - Aufklappfunktion ## start ## */ a.win_block { display: block; width: 100%; height: 100%; background: url(../images_frost/win-up.png) no-repeat 678px 8px; } a.win_block:hover { background-position: 678px -23px; } a.win_none { display:block; width:100%; height: 100%; background: url(../images_frost/win-up.png) no-repeat 678px -54px; } a.win_none:hover { background-position: 678px -85px; } /* ## BUTTON ####################################### */ a.butn_link, a.butn_link_active { display: block; float: left; height: 23px; line-height: 23px; padding: 0px 8px 0 8px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; font-size: 11px; font-weight: bold; margin: 0 1px 0 0; } .tablemenue a.butn_link, .tablemenue a.butn_link_active { -moz-border-radius-topleft: 0px; -moz-border-radius-topright: 0px; -webkit-border-top-left-radius: 0px; -webkit-border-top-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; } body a.butn_link, body a.butn_link_active { color: ; } /* ## AVATARE / MESSAGES ########################### */ .avatar, .avatar-profile { float: left; min-height: 1px; } .msgs .avatar { width: 92px; } .user .avatar-profile { width: 122px; } .user .avatar-profile img,.msgs .avatar img, .avatar img { float: left; } .message { float: left; overflow: hidden; } .message .block { /* Block for Userdetails in Profil*/ margin: 0; } .msgs .message { width: 562px; margin: 0; padding: 0; } .user .message { width: 567px; } .message-in { width: 562px; overflow-x: auto; } .message-in ul { padding-left; } message-in li { list-style-type: disc; padding: 0; } .message-in img { height: auto; } .message img { float: left; margin: 0 6px 6px 0; max-width: 100%; height: auto; } .message p { margin: 0 0 12px 0; } p.tags-miles { clear: both; border-top: 1px dotted #000; margin: 12px 0 0 0; padding: 12px 0 0 0; } .message ul.files { margin: 12px 0 0 0; } .message ul.files table { margin: 0 0 1px 0; } .message ul.files table img { margin: 0; } .message ul.files table td { height: 30px; line-height: 30px; padding: 0; } .message ul.files table td.filepic { width: 35px; } .message ul.files table td.filelink { width: 502px; } .message ul.files table td.tools { width: 23px; } .message .toggle-content { border-right: none; border-top: 1px solid ; border-bottom: 1px solid ; padding: 12px 0 12px 6px; } /* ## Blind Toggles ################################### */ .blinded { overflow: hidden; clear: both; } /* ## Breadcrumbs #################################### */ .breadcrumb { width: 100%; height: 22px; line-height: 22px; margin: 0px 0 15px 0; position: relative; left: -3px; overflow: hidden; } .breadcrumb span { display: block; float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a { float: left; opacity: 0.4; /*filter:alpha(opacity=40);*/ -moz-opacity: 0.4; } .breadcrumb a:hover { opacity: 1; /*filter:alpha(opacity=100);*/ -moz-opacity: 1; text-decoration: underline; } .breadcrumb img { float: left; height: 22px; } /* ## TAB-MENUES ################################### */ .tabswrapper { height: 45px; width: 100%; padding: 15px 0 0 0; } ul.tabs { position: relative; float: left; } ul.tabs li { float: left; width: 57px; height: 45px; margin: 0 1px 0 0; } ul.tabs li a { display: block; width: 100%; height: 100%; background-position: 0 0; background-repeat: no-repeat; } ul.tabs li a:hover, ul.tabs li a.active { background-position: 0 -45px; } ul.tabs li a:hover span { position: absolute; right: -258px; top: 25px; display: block; width: 250px; color: ; font-size: 12px; font-weight: bold; } ul.tabs li span { display: none; } ul.tabs li.desk a { background-image: url(../images_frost/symbols/tab-desk.png); } ul.tabs li.projects a { background-image: url(../images_frost/symbols/tab-projects.png); } ul.tabs li.tasks a { background-image: url(../images_frost/symbols/tab-tasklist.png); } ul.tabs li.msgs a { background-image: url(../images_frost/symbols/tab-msgs.png); } ul.tabs li.user-male a { background-image: url(../images_frost/symbols/tab-userprofil-male.png); } ul.tabs li.edit-male a { background-image: url(../images_frost/symbols/tab-settings.png); } ul.tabs li.user-female a { background-image: url(../images_frost/symbols/tab-userprofil-female.png); } ul.tabs li.edit-female a { background-image: url(../images_frost/symbols/tab-settings.png); } ul.tabs li.edit a { background-image: url(../images_frost/symbols/tab-edit.png); } ul.tabs li.miles a { background-image: url(../images_frost/symbols/tab-miles.png); } ul.tabs li.files a { background-image: url(../images_frost/symbols/tab-files.png); } ul.tabs li.user a { background-image: url(../images_frost/symbols/tab-userlist.png); } ul.tabs li.timetrack a { background-image: url(../images_frost/symbols/tab-timetracking.png); } ul.tabs li.system-settings a { background-image: url(../images_frost/symbols/tab-system-settings.png); } /* ## MODALs ######################################## */ #modal_container { overflow: auto; color: ; background: none; text-align: left; } #modal_container.tasksmodal, #modal_container.milesmodal { background: ; color: ; min-height: 150px; width: 500px; padding: 6px 12px 12px 12px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; margin: -50px 0 0 -126px; } #modal_container.milesmodal { background: ; color: ; } #modal_container.pics { background: none; margin: -50px 0 0 -126px; } #modal_container.pics img { margin: 0 0 -3px 0; border: none; padding: 0; } #modal_overlay { background-color: ; } #modal_overlay.useroverlay { background: ; } #modal_overlay.tasksoverlay { background: ; } #modal_overlay.milesoverlay { background: ; } #modal_container .inmodal { background: ; -moz-border-radius: 1px; -webkit-border-radius: 1px; border-radius: 1px; padding: 8px; min-height: 100px; max-height: 450px; overflow: auto; } #modal_container .inmodal h2 span { font-size: 12px; } .acc_modal { width: 100%; } .acc_modal .m_a { width: 24px; } .acc_modal .m_b { } .acc_modal .m_c { width: 150px; } .acc_modal .icon { padding: 0; } .acc_modal .icon img { width: 24px; height: auto; float: left; } .acc_modal .content_in { padding: 6px 6px 6px 31px; border-top: 1px solid ; } #modal_container .inmodal img { max-width: 430px; height: auto; } .modaltitle { display: block; height: 38px; line-height: 38px; color: ; font-size: 14px; font-weight: bold; position: relative; } .modaltitle img { float: left; } .modaltitle a.winclose { display: block; width: 19px; height: 19px; background: url(../images_frost/closemodalwin.png) no-repeat 0 0; float: right; position: absolute; right: 0; top: 8px; } .modaltitle a.winclose:hover { background-position: 0 -37px; } /* ## STATUS ############ Statusbar Project ############# */ .statuswrapper { width: 100%; } .statuswrapper ul { float: left; list-style-type: none; margin: 0; padding: 0; } .statuswrapper li { margin: 0 2px 0 0; border: 1px solid #000; height: 23px; line-height: 23px; float: left; } .statuswrapper li.link:hover { cursor: pointer; } .statuswrapper a { display: block; height: 100%; padding: 0 6px 0 6px; float: left; } .statuswrapper a.close, .statuswrapper a.closed { width: 19px; background: url(../images_frost/butn-check.png) no-repeat center 4px; } .statuswrapper a.reply, .statuswrapper a.reply-active { width: 19px; background: url(../images_frost/butn-reply.png) no-repeat center 4px; } .statuswrapper a.edit, .statuswrapper a.edit-active { width: 19px; background: url(../images_frost/butn-edit.png) no-repeat center 4px; } .statuswrapper a.del { width: 19px; background: url(../images_frost/butn-del.png) no-repeat center 4px; } .statuswrapper a:hover, .statuswrapper a.closed, .statuswrapper a.edit-active, .statuswrapper a.reply-active { background-position: center -22px; } .statuswrapper a.closed:hover { background-position: center 4px; } .statuswrapper a.desc, .statuswrapper a.desc_active { padding: 0 12px 0 6px; margin: 0 6px 0 0; background: url(../images_frost/acc-open.png) no-repeat right 9px; } .statuswrapper a.desc:hover { background-position: right -16px; } .statuswrapper a.desc_active { background-position: right -41px; } .statuswrapper a.desc_active:hover { background-position: right -66px; } .status { width: 130px; height: 56px; position: relative; right: 0; top: -47px; margin: 0 0 -56px 0; float: right; text-align: center; font-size: 40px; font-weight: bold; } .statusbar, .statusbar_b { width: 128px; height: 12px; background: url(../images_frost/statusbar_incomplete_b.jpg) repeat-x 0 0; border: 1px solid #000; margin: 6px 0 0 0; } .statusbar_b { float:left; height: 8px; background: url(../images_frost/statusbar_incomplete_b.jpg) repeat-x 0 -1px; margin: 9px 12px 0 0; } .statusbar .complete, .statusbar_b .complete { height: 12px; background: url(../images_frost/statusbar_complete_b.jpg) repeat-x 0 0; } .statusbar_b .complete { height: 8px; background: url(../images_frost/statusbar_complete_b.jpg) repeat-x 0 -1px; } /* ## CONTENT ########### without table ################ */ .contenttitle { width: 100%; height: 37px; line-height: 37px; font-size: 12px; } .contenttitle_menue { float: left; width: 33px; height: 25px; padding: 12px 7px 0 6px; } .contenttitle_in { float: left; width: 652px; height: 37px; font-weight: bold; overflow: hidden; } .contenttitle_in a:hover { text-decoration: underline; } .content_in_wrapper { float: left; width: 100%; padding: 0 0 6px 0; margin: 1px 0 1px 0; } .content_in_wrapper_in { padding: 0 14px 0 14px; } .staterow { width: 100%; height: 23px; line-height: 23px; clear: both; font-size: 12px; } .staterowin { width: 352px; height: 23px; overflow: hidden; margin: 0 0 0 48px; } .staterowin_right { width:50px; height: 23px; overflow: hidden; margin: -22px 0 0 650px; float:left; } /* ## FILES ################ Specials ################## */ a.dir_up_butn { display: block; width: 28px; height: 12px; background: url(../images_frost/root-arrow.png) no-repeat 2px 0; } a.dir_up_butn:hover { background-position: 2px -31px; } /* ## HEADLINES ############# Specials ############### */ #content-left-in h1 a:hover { border-bottom: 1px dotted #000; } /* ## DESCRIPTION ############# Specials ############### */ .descript { clear: both; width: 100%; overflow: hidden; } .msgs .descript .avatar { width: 98px; } .msgs .descript .message { width: 608px; overflow: hidden; } .msgs .descript .message img { max-width: 608px; height: auto; } .descript a:hover { text-decoration: underline; } /* ## TABLES ######################################## */ .blockwrapper { /* in projectfiles */ margin: 1px 0 0 0; } .block { margin: 1px 0 0 0; } .block a:hover { text-decoration: underline; } .block a.butn_link:hover, .block a.butn_link_active:hover, .block .inwrapper a:hover { text-decoration: none; } .block table { width: 100%; text-align: left; border-collapse: collapse; /*display: inline-table;*/ } .block table tfoot td { display: none; } .block table td { height: 27px; line-height: 27px; border-right: 1px solid ; padding: 0 0 0 6px; } .block table.log td { height: auto; line-height: normal; padding: 6px 0 6px 6px; } .block table tbody.paging td { height: 27px; line-height: 27px; padding: 0 0 0 6px; } .block table td.finished, .block table td.finished a { } .block table td.symbols img { float: left; } .block table thead { background-repeat: repeat-x; } .message .block table thead { display: none; } .block table thead th { height: 37px; line-height: 37px; padding: 0 0 0 6px; border-right: 1px solid ; } .block table.second-thead td { height: 27px; line-height: 27px; font-weight: bold; border-color: transparent; border-top: 1px solid ; } .block table.second-thead:hover { cursor: pointer; } .toggleblock { border-top: 1px solid ; } .doneblock .toggleblock td, .block .dones td { text-decoration: line-through; opacity: 0.6; /* filter:alpha(opacity=60); */ -moz-opacity: 0.6; } .doneblock .toggleblocks td a, .block .dones td a { text-decoration: line-through; } .doneblock table tr.acc td, .block .dones td.info, .block .dones td.info a { text-decoration: none; } .block table td.tools, .block table th.tools, .message .block table td.right { border-right: none; padding: 0 0 0 9px; } .message .block table td.right { padding: 0 0 0 6px; } .block table tr.acc td { height: 0px; } .block table tr.acc td .accordion_toggle { display: none; } .block table tr.acc td { padding: 0; border: none; overflow: hidden; } .block table tr.acc td .accordion_content { overflow: hidden; display: none; } .block table tr.acc td .accordion_content .acc-in { border-top: 1px solid ; padding: 12px 9px 18px 45px; line-height: normal; overflow: hidden; } .smooth { opacity:.6; /*filter:alpha(opacity=60);*/ -moz-opacity:.6; } .tablemenue { clear: both; height: auto; border-top: 1px solid #000; margin: 1px 0 0 0; } .tablemenue-in { height: 21px; padding: 0 0 0 38px; } .block .addmenue, .blockwrapper .addmenue, .addmenue { margin: 0 0 1px 0; overflow: hidden; clear: both; width: 100%; } .block_in_wrapper { padding: 10px 0 10px 44px; } /* ## TABLES - COLS ########### ges. 706px ############# */ th.a, td.a { width: 31px; } th.a img, td.a img { float: left; } th.b, td.b { width: 216px; } th.ba, td.ba { width: 216px; } th.bb, td.bb { width: 92px; } th.c, td.c { width: 190px; } th.d, td.d { width: 190px; } th.cd, td.cd { } th.ce, td.ce { width: 121px; } th.de, td.de { width: 121px; } th.cf, td.cf { width: 91px; } th.e, td.e { } th.tools, td.tools { width: 42px; } .user .message col.a { width: 180px; } .user .message col.b { width: 372px; } /* ## TABLES ################ Block - Colors ############# */ .projects .headline, .projects a.butn_link, .projects button, .projects a.butn_link_active:hover, .projects .inmenue a span, .projects .moreinfo { background: ; } .projects thead { background: ; } .projects .second-thead, .projects .second-thead:hover td, .projects .block_in_wrapper, .projects .inwrapper li:hover, .projects .tableend, .projects .statuswrapper li.link:hover { background: ; } .projects .color-a, .projects .statuswrapper li, .projects .datepick table td, .projects .datepick tr.head td { background: ; } .projects .color-b, .projects .datepick td.wrong, .projects .datepick tr.weekday td { background: ; } .projects .block, .projects a, .projects h1, .projects .block .tablemenue, .projects .block .addmenue, .projects p.tags-miles { border-color: ; color: ; } .projects, .projects .block td.finished, .projects .block td.finished a, .projects .datepick .cal, .projects .block_in_wrapper h2 { color: ; } .projects h1 span, .projects h1 span a, .projects .status, .projects .statusbar, .projects .statusbar_b { color: ; border-color: ; } .projects .datepick td.wrong { color: ; } .projects h1 span a { border-color: ; } .projects form, .projects form input, .projects form select, .projects form textarea, .projects form .row .editor, .projects .statuswrapper li { border-color: ; color: ; } .projects a.butn_link:hover, .projects button:hover, .projects form .fileinput:hover button, .projects a.butn_link_active, .projects .datepick .picker { background: ; } /* TASKS COLORS #####################################*/ .tasks .headline, .tasks a.butn_link, .tasks button, .tasks a.butn_link_active:hover, .tasks .inmenue a span, .tasks .moreinfo { background: ; } .tasks thead { background: ; } .tasks .second-thead, .tasks .second-thead:hover td, .tasks .block_in_wrapper, .tasks .statuswrapper li.link:hover { background: ; } .tasks .color-a, .tasks .datepick table td, .tasks .datepick tr.head td, .tasks .statuswrapper li { background: ; } .tasks .color-b, .tasks .datepick td.wrong, .tasks .datepick tr.weekday td { background: ; } .tasks, .tasks a, .tasks h1, .tasks .headline_lone h2 , .tasks .block .tablemenue, .tasks .block .addmenue, .tasks p.tags-miles { border-color: ; color: ; } .tasks .block td.finished, .tasks .block td.finished a, .tasks .datepick .cal, .tasks .block_in_wrapper h2 { color: ; } .tasks h1 span, .tasks h1 span a, .tasks .datepick td.wrong { color: ; } .task h1 span a { border-color: ; } .tasks form, .tasks form input, .tasks form select, .tasks form textarea, .tasks form .row .editor, .tasks .statuswrapper li { border-color: ; color: ; } .tasks a.butn_link:hover, .tasks button:hover, .tasks form .fileinput:hover button, .tasks a.butn_link_active, .tasks .datepick .picker { background: ; } /* MESSAGES COLORS #################################*/ .msgs .headline, .msgs a.butn_link, .msgs button, .msgs a.butn_link_active:hover, .msgs .inmenue a span, .msgs .moreinfo, .msgs .inmenue a span, .msgs .moreinfo { background: ; } .msgs thead { background: ; } .msgs .second-thead, .msgs .second-thead:hover td, .msgs .block_in_wrapper, .msgs .inwrapper li:hover, .msgs .statuswrapper li.link:hover { background: ; } .msgs .color-a, .msgs .statuswrapper li { background: ; } .msgs .color-b { background: ; } .msgs .color-a ul.files table, .msgs .color-b ul.files table { background: ; } .msgs, .msgs .block, .msgs a, .msgs h1, .msgs .block .tablemenue, .msgs .block .addmenue, .msgs p.tags-miles { border-color: ; color: ; } .msgs h1 span, .msgs h1 span a, .msgs .block_in_wrapper h2 { color: ; } .msgs h1 span a { border-color: ; } .msgs form, .msgs form input, .msgs form select, .msgs form textarea, .msgs form .row .editor, .msgs .statuswrapper li { border-color: ; color: ; } .msgs a.butn_link:hover, .msgs button:hover, .msgs button.inner-active, .msgs form .fileinput:hover button, .msgs a.butn_link_active { background: ; } /* USER COLORS #################################*/ .user .headline, .user a.butn_link, .user button, .user a.butn_link_active:hover, .user .inmenue a span, .user .moreinfo { background: ; } .user thead, .user .contenttitle { background: ; } .user .second-thead, .user .second-thead:hover td, .user .block_in_wrapper, .user .inwrapper li:hover, .user .tableend { background: ; } .user .color-a, .user .staterow { background: ; } .user .color-b, .user .content_in_wrapper { background: ; } .user .color-a ul.files table, .user .color-b ul.files table { background: ; } .user .block, .user .blockwrapper, .user a, .user h1, .user .tablemenue, .user .addmenue, .user p.tags-miles, .user .userwrapper, .user .block_in_wrapper h2 { border-color: ; color: ; } .user h1 span, .user h1 span a, .user .inmenue a span { color: ; } .user h1 span a { border-color: ; } .user form, .user form input, .user form select, .user form textarea, .user form .row .editor { border-color: ; color: ; } .user a.butn_link:hover, .user button:hover, .user form .fileinput:hover button, .user a.butn_link_active { background: ; } /* USER PROFILE */ .user .export-main { background-image: url(../images_frost/export-vcard.png); } .userwrapper { float: left; border-top: 1px solid; border-bottom: 1px solid; padding: 1px 0 1px 0; } .userwrapper td.avatarcell { background: ; border-right: 1px solid ; padding: 8px 8px 0 8px; } /* NEUTRAL COLORS #################################*/ .neutral .headline, .neutral a.butn_link, .neutral button, .neutral a.butn_link_active:hover { background: ; } .neutral thead, .neutral .contenttitle { background: ; } .neutral .second-thead, .neutral .second-thead:hover td, .neutral .block_in_wrapper, .neutral .inwrapper li:hover, .neutral .tableend, .neutral .paging { background: ; } .neutral .color-a, .neutral .staterow { background: ; } .neutral .color-b, .neutral .content_in_wrapper { background: ; } .neutral .color-a ul.files table, .neutral .color-b ul.files table { background: ; } .neutral .block, .neutral a, .neutral h1, .neutral .block .tablemenue, .neutral .block .addmenue, .neutral p.tags-miles, .neutral .block_in_wrapper h2 { border-color: ; color: ; } .neutral h1 span, .neutral h1 span a { color: ; } .neutral h1 span a { border-color: ; } .neutral form, .neutral form input, .neutral form select, .neutral form textarea, .neutral form .row .editor { border-color: ; color: ; } .neutral a.butn_link:hover, .neutral button:hover, .neutral form .fileinput:hover button, .neutral a.butn_link_active, .neutral .datepick .picker { background: ; } /* TIMETRACKING COLORS #################################*/ .timetrack .headline, .timetrack a.butn_link, .timetrack button, .timetrack a.butn_link_active:hover { background: ; } .timetrack thead { background: ; } .timetrack .second-thead, .timetrack .second-thead:hover td, .timetrack .block_in_wrapper, .timetrack .inwrapper li:hover, .timetrack .tableend { background: ; } .timetrack .color-a, .timetrack .datepick table td, .timetrack .datepick tr.head td { background: ; } .timetrack .color-b, .timetrack .datepick td.wrong, .timetrack .datepick tr.weekday td { background: ; } .timetrack .color-a ul.files table, .timetrack .color-b ul.files table { background: ; } .timetrack .block, .timetrack a, .timetrack h1, .timetrack .block .tablemenue, .timetrack .block .addmenue, .timetrack p.tags-miles { border-color: ; color: ; } .timetrack .datepick .cal, .timetrack .block_in_wrapper h2 { color: ; } .timetrack h1 span, .timerack h1 span a, .timetrack .datepick td.wrong { color: ; } .timetrack h1 span a { border-color: ; } .timetrack form, .timetrack form input, .timetrack form select, .timetrack form textarea, .timetrack form .row .editor { border-color: ; color: ; } .timetrack a.butn_link:hover, .timetrack button:hover, .timetrack form .fileinput:hover button, .timetrack a.butn_link_active, .timetrack .datepick .picker { background: ; } /* MILESTONES COLORS #################################*/ .miles .headline, .miles a.butn_link, .miles button, .miles a.butn_link_active:hover, .miles .calinmenue ul { background: ; } .miles thead, .miles .calhead th { background: ; } .miles .second-thead, .miles .block_in_wrapper, .miles .inwrapper li:hover, .miles .tableend, .miles .thecal, .miles .second-thead:hover td, .miles .statuswrapper li.link:hover { background: ; } .miles .color-a, .miles table.thecal .dayhead th, .miles .calinmenue ul li.link a, .miles .datepick table td, .miles .datepick tr.head td, .miles .statuswrapper li { background: ; } .miles .color-b, .miles .calinmenue ul li.link a:hover, .miles .datepick td.wrong, .miles .datepick tr.weekday td, .miles .content_in_wrapper { background: ; } .miles .color-a ul.files table, .miles .color-b ul.files table { background: ; } .miles, .miles a, .miles h1, .miles .block .tablemenue, .miles .block .addmenue, .miles p.tags-miles, .bigcal tbody.content td { border-color: ; color: ; } .miles .block td.finished, .miles .block td.finished a, .miles .datepick .cal, .miles .block_in_wrapper h2 { color: ; } .miles h1 span, .miles h1 span a, .miles .block td.othermonth a, .miles .block td.othermonth, .miles .datepick td.wrong { color: ; } .miles h1 span a, .miles .content-spacer-b { border-color: ; } .miles form, .miles form input, .miles form select, .miles form textarea, .miles form .row .editor, .miles .statuswrapper li { border-color: ; color: ; } .miles a.butn_link:hover, .miles button:hover, .miles form .fileinput:hover button, .miles a.butn_link_active, .miles .datepick .picker { background: ; } /* FILES COLORS #####################################*/ .files .headline, .files a.butn_link, .files button, .files a.butn_link_active:hover, .files .inmenue a span, .files .moreinfo { background: ; } .files thead, .files .contenttitle { background: ; } .files .second-thead, .files .second-thead:hover td, .files .block_in_wrapper, .files .inwrapper li:hover { background: ; } .files .color-a, .files .datepick table td, .files .datepick tr.head td, .files .staterow { background: ; } .files .color-b, .files .datepick td.wrong, .files .datepick tr.weekday td, .files .content_in_wrapper { background: ; } .files .block, .files .blockwrapper, .files a, .files h1, .files .tablemenue, .files .addmenue, .files p.tags-miles { border-color: ; color: ; } .files .block td.finished, .files .block td.finished a, .files .datepick .cal, .files .block_in_wrapper h2 { color: ; } .files h1 span, .files h1 span a, .files .datepick td.wrong { color: ; } .files h1 span a { border-color: ; } .files form, .files form input, .files form select, .files form textarea, .files form .row .editor { border-color: ; color: ; } .files a.butn_link:hover, .files button:hover, .files form .fileinput:hover button, .files a.butn_link_active, .files .datepick .picker { background: ; } /* ## ACCORDION ################ Toggle ############### */ span.acc-toggle, span.acc-toggle-active, .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { display: block; width: 97%; height: 100%; background: url(../images_frost/acc-open.png) no-repeat right 10px; cursor: pointer; } .second-thead span.acc-toggle, .second-thead span.acc-toggle-active { /* for darker backgrounds */ background-image: url(../images_frost/acc-open-b.png); } span.acc-toggle:hover, .second-thead:hover span.acc-toggle { background-position: right -15px; } span.acc-toggle-active, .second-thead span.acc-toggle-active { background-position: right -40px; } span.acc-toggle-active:hover, .second-thead:hover span.acc-toggle-active { background-position: right -65px; } .toggle-in { position: relative; width: 100%; height: 27px; } .toggle-in a, .toggle-in.acc-toggle-active a { display: block; height: 27px; position: absolute; top: 0; left: 0; z-index: 1; } /* ## ACCORDION ################ Tools ############### */ a.butn_check, a.butn_checked, a.butn_reply { display: block; width: 100%; height: 27px; background: url(../images_frost/butn-check.png) no-repeat 4px 6px; } a.butn_check:hover, a.butn_checked, a.butn_reply:hover { background-position: 4px -20px; } a.butn_checked:hover { background-position: 4px 6px; } a.butn_reply { background-image: url(../images_frost/butn-reply.png); } a.tool_edit, a.tool_del { display: block; width: 14px; height: 23px; float: left; margin-right: 4px; background: url(../images_frost/butn-edit.png) no-repeat 0 4px; } a.tool_del { background-image: url(../images_frost/butn-del.png); margin: 0; } a.tool_edit:hover, a.tool_del:hover { background-position: 0 -22px; } /* ## ACCORDION ############### Marker ############## */ .marker-late, .marker-late a { color: ; } .marker-today, .marker-today a { color: ; } .green, .green a { color: ; border-color: ; background-color:; } .red, .red a { color: ; border-color: ; background-color:; } /* ## Headlines ## start ## */ h1 { font-size: 21px; margin:0 0 0px 0px; height: 25px; line-height: 21px; } #content-left h1 { width: 669px; overflow: hidden; } h1.head { font-size: 24pt; margin: 0 0 0px 0; color: white; height: 35px; } h1 span { font-size:11pt; margin-left:6px; } h2 { font-size:11pt; margin:0 0 10px 0; } h2.head { font-size:11pt; margin:0 0 10px 0; color:white; font-weight:normal; } /* ## Infos ## start ## */ span.info { font-size: 12px; } .infowin_left { position: relative; top: -72px; right: 0; height: 40px; margin: 0 0 -40px 0; font-size: 12px; font-weight: bold; float: right; } .infowin_left img { float:left; position: relative; top: -8px; margin: 0 0 -12px 0; } .info_in_red, .info_in_green, .info_in_yellow { padding: 10px 10px 8px 4px; border: 1px solid #fff; float: right; color: #fff; background: url(../images_frost/infowin_red.png) repeat; line-height: 22px; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; } .info_in_green { background: url(../images_frost/infowin_green.png) repeat; } .info_in_yellow { background: url(../images_frost/infowin_yellow.png) repeat; } /* ## Footer ## start ## */ #footer-wrapper { clear: both; width: 100%; min-width: 980px; height: 26px; font-size: 9pt; margin-top: -26px; } .footer { width: 980px; margin: 0 auto 0 auto; } .footer-in { padding: 7px 0 0 2px; color: #6ab0c5; } .footer a { color: #6ab0c5; } /* ## Footer ## end ## */Collabtive-2.0/templates/standard/theme/winter/images/000077500000000000000000000000001237252063700231235ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/acc-open-b.png000066400000000000000000000005721237252063700255410ustar00rootroot00000000000000PNG  IHDR R$tEXtSoftwareAdobe ImageReadyqe<IDATx1 0cp\z+(]]"NP@;8{ktqI6A!^%$N))>19s #Mc8Vhf djצƨjVC&&Ƀ7̑Oڒ-Cwq~7w:yvS, W.!XfqzGg2[gNꓧXk.sڐ%_GL5RE5REh!ZC^`\&=%(L5RE5RECr|IENDB`Collabtive-2.0/templates/standard/theme/winter/images/acc-open.png000066400000000000000000000004611237252063700253170ustar00rootroot00000000000000PNG  IHDR R$tEXtSoftwareAdobe ImageReadyqe<IDATxb\fd`.(8ċA,i@jEn!!!a<,*H1} #HւvQ0 `b3sVTT 2'k9[+@s Un!BU f)mJDF[̈́f :@vA-DRȕ"F*$1sѬ!?s0|fٜTIENDB`Collabtive-2.0/templates/standard/theme/winter/images/add-files.png000066400000000000000000000026211237252063700254620ustar00rootroot00000000000000PNG  IHDRP3qYtEXtSoftwareAdobe ImageReadyqe<3IDATx]lTOl7%YZ)_6/ZCPih!xDEoE0J4 e^Z^@T뀎)Hd]˚&n?νv$|_sϹEOΰϠӅQ uAhBfPGهm]5Y 7oo l0b(ˎBZ#,;g:]k32&F@3&JpCrl%vZ뢙oW ݐwiK8Y+ٍ%ujSxS9QBZ@Z)v1ЄHlRL)3 =bnw1+ѕ҅%ct4+҅@NLi z|^ g+&D};{x<@4HG?:-I;c;`xx~?<~tc̻xw;acQ\/^e3k7~9vY7 FLH|[1%KRxV,' OnwtسPJϖB F}#JʹxKQ'/UK2}[HQ;laVEo|bXu'B],˴7Rm㓂 chԱy(c4nj)b嗯\չeEjl @`wyՕ|Qܞr!:jQȹJ|:ˣ*jVp箕voN;nQ6g!\U>jIYM{h\Hnl $-@EgEp8ƴ՝pnuc?u ": ƒ :>oc>=|e:XQ K7kH:ݴ(Suw-Z`$>uϑ`.eX``NZS cȗ(MAߞ>wO]}4za|#1ԃkQW7#u|I.KKIxϿT' >xX雚1 !T3xS֪Fwp8Jl?\0ږW[  8I4I[-d0-JŬ Id6rSV OYګ/8s[ nB/IO-ZlL(t.8rMs+CR)jUEhSt `0uAU}gQ~h`9H&e,oBULhy*c^ PLk:?K客IENDB`Collabtive-2.0/templates/standard/theme/winter/images/adds.png000066400000000000000000000004541237252063700245470ustar00rootroot00000000000000PNG  IHDR3u3tEXtSoftwareAdobe ImageReadyqe<IDATxb?]vbi y ĻYDP(CB` 01PPe0aDHaxs4iPOT2ȰM@B@7 df4Bra5\7$ۃ2 Qf s` Hн`DbXÌáIJf=/(4? z24יIENDB`Collabtive-2.0/templates/standard/theme/winter/images/autocomplete-bg-a.png000066400000000000000000000001661237252063700271410ustar00rootroot00000000000000PNG  IHDRH7B-tEXtSoftwareAdobe ImageReadyqe<IDATxb1 -b ?_bIENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-files.png000066400000000000000000000004111237252063700265470ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbOa؀؂ 17 j ր F6$i,fS@ b'@o`_@|f #t>M `?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 HH ȢIENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-miles.png000066400000000000000000000004111237252063700265560ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbl`؀؂ 17 j ր F6$i,fS@ b'@o`_@|fGut>M `?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 ĕIENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-msgs.png000066400000000000000000000004021237252063700264160ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbLMc؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-neutral.png000066400000000000000000000004021237252063700271170ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbc؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 ߴʓ\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-projects.png000066400000000000000000000004051237252063700273010ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb/,a؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNš8?bK@<T] Wvd蒕@Oqye7k\\)Ȧ` )5zzIENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-tasks.png000066400000000000000000000004021237252063700265720ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb4*c؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 _stIENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-timetrack.png000066400000000000000000000004111237252063700274300ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbwe؀؂ 17 j ր F6$i,fS@ b'@o`_@|fet>M `?.ĀJNG^lIz>K3Ļ@IAȪ%+ n ⹸SMpS ~IENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side-user.png000066400000000000000000000004021237252063700264230ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb ύb؀؂ 17 j ր F6$i,fS@ b'@o`_@|&,VMa?.ĀJNG^lI49@ $4Ԏ]݀).bm ˟8l7 8IENDB`Collabtive-2.0/templates/standard/theme/winter/images/back-side.png000066400000000000000000000003141237252063700254510ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<nIDATxb? 2X$XY%X&F6$) %YLP'A; (23vTr%ـ$(517$X5k Wn6 : Iе0~dh1FIENDB`Collabtive-2.0/templates/standard/theme/winter/images/bg_table.png000066400000000000000000000005211237252063700253660ustar00rootroot00000000000000PNG  IHDR(wg pHYs  ~gAMA|Q cHRMz%u0`:o_FIDATxb. &l vQ. @E(@a ] vQ. @E(@a ] vQ. @E(@a ] vQ. @E(@a ] vQ. @E(@a0tDmIENDB`Collabtive-2.0/templates/standard/theme/winter/images/bg_th.png000066400000000000000000000005211237252063700247120ustar00rootroot00000000000000PNG  IHDR(wg pHYs  ~gAMA|Q cHRMz%u0`:o_FIDATxb= &l vQ. @E(@a ] vQ. @E(@a ] vQ. @E(@a ] vQ. @E(@a ] vQ. @E(@a0IENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-bg-side.png000066400000000000000000000001661237252063700261140ustar00rootroot00000000000000PNG  IHDR.sjtEXtSoftwareAdobe ImageReadyqe<IDATxb1Е!IENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-check.png000066400000000000000000000006611237252063700256570ustar00rootroot00000000000000PNG  IHDR(tEXtSoftwareAdobe ImageReadyqe<SIDATxbYf  9xBA^@j? ^Man@| 6" rjD ď` e @,$@M1 ~Pb1jTA`r#)hB].$6  *r Nx% Y@0P[@IP rI8+"Y5z8Mh7_i@ [0'QPVI⟸ X7Wm /0z({+A ^/;>d 3P 6jبa3arh>Z=#2ԩ O0@IENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-del.png000066400000000000000000000010131237252063700253360ustar00rootroot00000000000000PNG  IHDR(νtEXtSoftwareAdobe ImageReadyqe<IDATx+Da3n%YPv(QH)ʎvK(rll( e5)e+Sr)6V%y}lNsu l˲J![jWT9*,C?\4MX ?^(wC1=q <ɐ C$=24:M:)ÃMsba 4G6xq!|$(u .=yIt( B^;g=kwe2 v u5傭ZR!u x?1ZjO:"4K9P/3h4F-/uU<%XP֬t{gO<Ep9e*!ר&^@qGNzOrHNrJ$k!K}…$s.nYqִW`4ꈃhIENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-edit.png000066400000000000000000000012241237252063700255230ustar00rootroot00000000000000PNG  IHDR(νtEXtSoftwareAdobe ImageReadyqe<6IDATxϋa̸jEŃAQ?@ʈy@)Ùخ1-QО˛d(bWF[Нrٲ,J_FGr i.{IENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-notok.png000066400000000000000000000007051237252063700257330ustar00rootroot00000000000000PNG  IHDR ,sRGBbKGD pHYs  tIME;~EIDAT8ҿKa{0hpph 7E J EgMD  ¥Q\DA%.w!*45t[ ߻ܵ9y9Z-\zm0=c?vc_pcs\+ ;Xs 8wc)ޏPͱ$"p7*>b %ȖBO ln N zx|J5qn*!JXk}K!a=1MwE`XFM;M+]:Ni`$ѬLW+FlGm}?2EbY:IENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-ok.png000066400000000000000000000006421237252063700252120ustar00rootroot00000000000000PNG  IHDRmJsRGBbKGD pHYs  tIME XE!"IDAT8ӿ+Qu/I ,, An&ժ`-hڕ@B_˹:}~o7|yޝW.IaMAٖ3h$Zq!E .m?CF-uBFB`G Jdg茴 ,\y銴nDtR 2~iXJQ)T]bT8 ؍)F=xXЛ1)"[5:wy׻kXMiט[٨ fPΚVd K=#I53IENDB`Collabtive-2.0/templates/standard/theme/winter/images/butn-reply.png000066400000000000000000000005251237252063700257340ustar00rootroot00000000000000PNG  IHDR(tEXtSoftwareAdobe ImageReadyqe<IDATx @ElZ%hx` &IgO2E'1f7yN]<45N%@5yJ^ b4@;AJDӈ tg/`)*yNp+8@d_ٸOLh؉נ ,amU,d'W%5p 520DZc=iJ&T":oF=l7KLDTKIENDB`Collabtive-2.0/templates/standard/theme/winter/images/chat.png000066400000000000000000000005461237252063700245550ustar00rootroot00000000000000PNG  IHDRJetEXtSoftwareAdobe ImageReadyqe<IDATx엿 0"v1b|#QG; EBХr\i>r_XJDF-Pa[UUqT|G*J@OuVR_d*!7EJf\|##dձ2w *j:氱V@BcP`(Ft sA`l3"wU0fW'6!h]=}%GD@{hJ7I'2zw SG,s `l37b\ /wH3wIENDB`Collabtive-2.0/templates/standard/theme/winter/images/closemodalwin.png000066400000000000000000000013331237252063700264710ustar00rootroot00000000000000PNG  IHDR8;9tEXtSoftwareAdobe ImageReadyqe<}IDATxOQƧ3m qQ`#M#ܹ_bBH\ $l *PX[-7̴YItfns9\=y%wt mE)hK@-"Txi 5Q;=. t݆.C%3h hn;yD ^.8M.t/a5WaȴmhOֳ*b,t"k4L$hEix~* }7y&f00gYcf? 7újf r(ZIshˆK -'Є@U[g>Qudf_Kir Mif+%V mf`,etn71a폟Vva:`T":WO覺_z#hČyjlZ8{EV]H*д,[7ѮCcЌW>lقpyHfτʰ)9z8}>굜6Gt^,A/b`ʣ,?ן5nK(Ú֓  [1uDm#JʴÅ$ؐ LvQ`'4n呛`m-{n͚1Abt#KDM~UQBr#i$m˶Ti **l*4/ŨMԪj)@cu7lYoYkٙ{g׎5t4;=s~<=k_,ʅ4Crؽ$ h63#dl?'$*dDH1^-d0nLn+ҽ= ,`fN-%B )#Эm9AlNfZn '89B r06 ݺFW $J.gdƃ#2hdLPdyA!iO('RQo`-Mgf.."Yd#&$_$ vrOŦ{ HJZ!KV_t!\#:J|! 4-=cyHu=Ʀ~X垥tsDh BY/Tz=C5$@ZD+ M?tH!y%]# he#$UgF,N0e@ARk,cjnFpE%!aՆ+5tX*3(cI|P6Ssc&wE*y1!Af0#㎀umJ*v6M,!PKVb}2^i<Ҿ$E~y\2!]HR-Ҋ8gĖs\kT{wSc$ib _N>%(YR?7&MO54#c6^}$4XS$ Y2Xd,sHvP7XcmE5;Of0C]#D*O/lq,g;B -{YIK"|rsDj$HFR2Ib5&wXe.[XaŹ%VV8Cl&]lJH0۰e(Lcy;JYUHYWcBw (\t-du1:Yݧ*A_ZGRqornR3Ȟ%B }&o/ g-ADZЊڤg' AV;6rCٰ|W=̹;鿣Xrϛ]+.nVgD^IB,v露b ?|]q/,N1W''D2bx=mTnjIqZcWG]9ف ~c~^#bź,x f/Y[">] -iYg%%RInH-U [i2|[Aw~7oVm@Bg[v͑Ecw 'xV|ʟK$H"]!"^[EACRa;R4xp0 m,G}ZĎܸ-*R |b ImɌz"1e茻16 ^nHXmu߾ha-+#e~gsO@M:1i>8^8WPa{RXq+U!"!C禆Hm8V7i3%>"Or4Ě&O<|McׯYw _Vybߟ3b7?>d̉W!Ɖ.|rB##@,UBVm$qs5i5Sy^x$$omnu:K}j|yTlӦHִMd`zVHTc%f5۵L-XՖ$i+?Dj^ "ZrBkN& V=wY#a"'P z2ɢy+Q”Tk9&No6>+)qOH_/22D&ܨ'XfnwZXώB߭ Ģbrdbc~ 'Nɀ\ XSB3 1@lYk?Lchw:pn^euAk3 _a}mDRibz2C"O>[;u(pDX"CFf9.qNbWdz/D9O IENDB`Collabtive-2.0/templates/standard/theme/winter/images/export-msgs.png000066400000000000000000000051621237252063700261250ustar00rootroot00000000000000PNG  IHDRv3B2tEXtSoftwareAdobe ImageReadyqe< IDATx\}p\*&B*`` 2f# 2SZ upZ'w38u%І1g$JifETb#$޳7ݼyyHl<= `õm=qNJu-Qq)T2c1x?c>~¸1m;s#l3@˸Oz#5+[_``Ο ڶh~nN@XGǽfsfSߜf,e|Bǘfn v4Ʌ0>Mn[=&ݱEiKOl?vГ㎖3b8wIjD]H~C On(98ad="7и^A ?(뎠!Ezq5t1Vz'=(IăD yn +Ft3n☛$A$< 1dnǴ>78FFOm+c;Ulj3@t"O-uST0CXQ tPcb,r_smrуUL)m"*7DUU.,UX DYt1%w \<5j $?&X'-?i9fȸ,6,i-*1\O!8lʈu9LR- mqo|cnL.6Ec'B ?H*uFodJl'sh봨\FXF>XXuw7 Zm3m I+Ȓ "nNb9G!A|5}d5[A(B])p=$*@UЃDL↸iGct~w7s)M3QqMkD )6X4*N=+R\ 7"}1JKrńB%:5n?7*8kMU '*OiKPH%xA!U\K$Pdk[>y\wq:utXԎ^ctơBlmzm!]mv~3pĥw.xq8ǵFmR*<>߂y#/lya 6 Nxc/?;ߝyPǍ2,Tqy _q{@7;߮x[ޚ_hld`LIc"'\!G.tmgiy|@;W]1vqo .,)n#|~`tƕ}&Q$9!|3Y\qzH@W\qjt.Oi\BUS|0t@1֬XVErry_WW]#GKA4@zD.O)3^3kÐ Z #FyN6b3+g@=pضzX^ F8$;?~K !Y((ůjTi|~ZƧX<֡@cg͑p0t̩٥vNlڕ.k CfXx3#C7@X+Ý4蕧Q/= -5쌹=$f\EBN%MQJ@Jc{HwzD[q}kHN9~iUƣݩz_aTRAfSlj*R'B58؄^-# }%}fN(y9h]]'DU,R=QZzYW}Q-pJOBK>D+TY R+fNPDJThIXu^4wż K Nt%~] Khl^KOgCj۩Uo' ܵSdlֺ#r!IENDB`Collabtive-2.0/templates/standard/theme/winter/images/export-tasks-headline.png000066400000000000000000000042231237252063700300450ustar00rootroot00000000000000PNG  IHDR_3ztEXtSoftwareAdobe ImageReadyqe<5IDATx[klU/RG[M& KH $ !QIiB`Diń$J4*-(e@.tk-)Ҳ]ﶇqv:dNevf;s9]O$QTR$Р /F۹EA$Z;1 @XO _ =hF[O7I>pNqs{@@@sNGU[O "!gvjr:r2ZLpkVĮ"maǪ"79C<dލDL-D%*p8!awR`YPy ϵC~FN!#0FF9 `/F^(PbdGc%Կ$YAm&].wA%MGpӡ3 z4d˘C/DXBy7a3B (hd3|Ixј@QM$rCh䂩pԍ^M :NZGB4i1=C,;]VFA0OC;y(%CƼ!v}EL@Ofm}:0&Fi -idXH¬F>M=̫g 2@v2<ڇ |r|ئ}Wr(9pf;./'5>xdγLz}BNs5ԭ'ݬtP+xJdKKK+..s?2֟Yϯ?0`+:>^ ~=Hį%Z;~]JbpjϧV ™yZWkO )po6)CoNXYbvx"NN7*_ VЊ`rWDm\12A~yvJ`l퐏󡉶tQB-C-_((.^/im/L`ͱQ N>Fb @u6uI/ i|"֧mR`@5FU+P"'&/ՌNڕT *CC;jA?m*zy%ٿbcѓgXHK] )?"4̇3a*."4@Ľ}8Y…ЩW-8M):/XTH?cZ2(#),?3QP0SXKZl80+L:Fue9ʪ׶IX\Er0 WJ35"k;RJoqU>eʤ Pqߡ;oZWm$000^­opg Ju]oYxv.~U0}s nY#/-Yܻg^:!ϱ"` ܇:#x$ΪTW*{0*:5bOF"JNةs~:;pF}Qx$Jsmh A>UIS2'SB"b@f@͌70alc=fṳz~iQ(n+z a>=O91~y `sr]DDITq%/3>In}6ݱhOO<F?"qC+2dN$N.!?&F'QJ%{,NFX?Y|M4Wbn)Z1^AiNR$^FI畨@!bD/.+IO"`@ǁ<KQ]cb|'1w3Ν0J4u v08[<ͣ:C q3]U%"[ݲH CQ!gS~ZOZ?z`2\' P(B[,۬xv2W1ݹ@'^X-֝K(T 0&ya G^<6/l OFcz7uXNj2,֌&=kim߯y~ -';k7K|_}e|tgN#C (2>θX0>xݢ0iJ \~4nM0x23~xgA[V1l!I:) Kh;dU16#YpG:| w=u_èx̅w>[>>qBv ~?J0(_ [i6H=C=q&~oTw.]Qu \4$?r%=~WuZn?m:+Z5,]5HkVY:Q.d=ol:K12TQ,uKJf%k0,)5B< % IBN-2>5cnj_cꍑ3Xl\7MCMI?/`g˫&D.mn]juz/ar[f?[RHDun\4:>q<-v+ ~{a,eOOן;W+B c8IКV=b-pQb2ZtSq AW4^=󪡸\EYoi'q;Z;j+ypB/:;ԉ 9m=I[,7j0fc5۵Fb VܱI =\׬ 0g‚ŷüR1BD:r8`{hcvEBtz-k) C3#akWkcDbS4ug > \JAcvSl]r ]czm8DX@ PŽ gxQ:Wՠi|ɧU B\:Tt†8kȊc툚hoPy".mJIB i!8m qD  kwױ9- DcځS N$= G@id Bzm4O{_{خu VrvIENDB`Collabtive-2.0/templates/standard/theme/winter/images/export-vcard.png000066400000000000000000000026311237252063700262510ustar00rootroot00000000000000PNG  IHDRZ25tEXtSoftwareAdobe ImageReadyqe<;IDATxZhU&6M:6$Sl/*E@!fUpbg9D&fP2e)FܤJ]lmRkm,^ۙܽ{7~サsmkm.k/FPHtãm!kH0"}I ٦$g:5*o7NQg0' bJР't8^eGd=y9:D^eE hB[țhmeIG4r;D}B/I ;Qie! E9:dZBO.2R/M5Aq g'IE9J=F69x "{TR;0Frp'oB!R]<U1+O ~E1d{]1S=$'Gh=n)."UJSD$_Rp>IXwQ 1Un~=1 B%A,g0' Lۨ.(3[n7Pxt5XG;b\vAM}qī#7G"~_sOPKUJ<(%޹ݟuJe{ hޝx$Eh[kMX9<3IP ` Nw;F/unW+k8+!aGS=@gƘH[D%rQ6Xj% Hn?GGN\/B4J̰h.V,rNV.k6~%]b78QϞl^p#_0>/o}.Lu^agk>,*q>0WGF,O t ~t(~4h`.ƽm]scC-}iti <L`Rn6}ďCW+(lf?9ix9ADBi0 ~S28]ݏq*.J~ȹ2E@7d90ʫ\s,'~.~-9zo!n,Wcizq)uα>܏(ΰcmecƿqc"7c9;:V#d}_xpa75DP_\wGIENDB`Collabtive-2.0/templates/standard/theme/winter/images/favicon.ico000066400000000000000000000015761237252063700252550ustar00rootroot00000000000000h(   S-Q-Q-Q-Q-R-Q-Z7$vW5[7$Q-Q-Q-R-S-R-T.S.S.S.eC*lAS.xX6zxX6S.S.S.T.T.T.U/ T/ U/ U/ MzM˵iz˵imBU/ T/ T/ V/ V/ V0!V0!_:&V0 nC|||||NV0 V0!V0 W0!W0!X1!X1!}Űp΃ى{zM|[:zMa;'X1!X1!X1!Y1!Y1!Z2"Y2"gFޗޗнc=)kH1sPkH1Y2"Y2"Z2"Y2"[2"[2"[3#[3#nI4mI3jLל_D[3#[3#[3#\3#\3#]4$tėĖ]4$˹­]4$˹s]4$]4$]4$^4$^4$^5%fǟө^5%ıͽqL8Ƞyz߳h^5%_5%`6%`6%iA/ƅdNrM9ֲֲoW˧|XC`6%a6&a7&a7&|ͰjC1a7&}YEa7&jC1Ͱ¥a7&b7'b7'b7'зͶkC2uN=fSkC2c7(c7'd8(c8'c8'c8'sac8'c8'c8'd8(d8(f8)d9(d8(d9'°禌{¯¯iWd9(d8(e8)e8)e9)f9)f9)e9(e9(nE4iYe9(iYiYe9(e9(f9)f9)f9)f:)f9)f9)f9)f9)e9(e9(e9(e9(e9(e9(f9)f9)f9)f9)f:)f:)Collabtive-2.0/templates/standard/theme/winter/images/files/000077500000000000000000000000001237252063700242255ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/files/application-illustrator.png000066400000000000000000000124001237252063700316150ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X]IDATx͙ tƟ!DcI R%f%T[Dj+JRS'5OfRTy*THdLy}'9wַ-ϻ_Diwpy篫u<QT T)lwҨQM^WqbR|/)1ˎՎ5pc8;-J![]F}tmvVFQ_ [ ~"~hA+uAhM]}u(N7s _#2w/`}=ɞ^go?Y$'U:P%7;@.|wgCk8T@Ȩkph! -~`Xbm0LvM5YXGVxcoF՞ܟO%<YiԉZڃ`lEsԚZׁ"R )D %Ժ}F?TG+\B]]7h$0(Q ನ-ZyQ1fǧ`Urna~zE/\L]ox= R r%vcjvm?4P=' ɝaH`_ PɟĸAk`)J S+E:M:F"UrY;BNAG!%N 57C'kzq1 >l8l檙o׸\qIP)qq24&;AL$Elyh `@ +A:t1uU9*9C2OL j'ES-}BDhOCʊ.ѧn`#vԖf:-'yڈKb:( O)(4}[[ZZH#h=ćԋz> 62mzÇ@z`aؿpKgIȇ)Cr9u [5l()O y xn@;k  XOT[g1 tSo}%h)ZfHJP_ *](C1Z!k<^ dW^J%TDKOOO;R (jRuF q<__졎s3SkzFSWʞOSua>zROxWNvbx^N;Xp"k oi"W&L.Li;-pijg\˸Ǹ ݫ.O$ <yl  J6`OutpaVs˜;@ u`' Ԗ(< JV@"ϕJ@p}FT X!VD 4ʀFW7o1tO>> Hgu:_Rf \)Ю?AT7L7 pq3Yrsod3pđi5qP 0DB !Ia1UG ' p6flA-vnj:(J;vѹn/At r,* - jڥKpU\8ŸYAZx>gn%vG Xre[S`4o`Eho(Ef@g8XlM2lO 䍘1֡B G,8kc>r7H2?P=*xeqj+;^v)}.rgGWTWj0{z*n)SjM^1X̀%⡫!TjQkUGzzUA2S:ͭo4a#@ G>h4HoQ&r;1F`3x=XC}6`ޒ}2Z9 8N:z_]._V2ZzHe v]եC%/G}f, KpYgkr2p'q @SMBBFϋ 7#Z `9"c!`Xmo(+2[/"Z :AW)ڍ HB]0P}n]2L2{ bUpϢ8j@ogPMC! *|xp`TS= ׇ_Ώ\Q? rWCt m m+D@+*}{{@{W~qe3Ic 2 3t_!L)~ѹ@)~ c i: Pn>+B/Շ}Bw_g ^w}oWͿ;ǫ:ϚgmvnmN c+kr.EԒ%[ѳ8 `/@7'gc.O .8U &@L\=༪bySPғpLvD;fjP&Nj MW7UWm?#m5"d࠹qL켪rokP(ځ Dr#?l v;e 1A@kU:0uFwcwc1@^ԝ~ğ"OD2Q"':Hk<(ϜTw`]RAڻ]t@D"^8n5b Lj yZO'TI;!wBGߐ (wm/xAU<o пedU=׼5զM=RV[ÁmpImv`jz[fUHKGpJp퀯h( e'yPc,fh/Q;̟*x{G-ZzOi+e#PEqpV4~Mu?4z{!)=6n@Ʒvb[m @2tqnvha:P>{YwǺpy2LJ_15G1ubI3\_Fa0 "(_`ۃ$ q@k`[e{&zʟWW#`n#ы5`;e!bK{kDY%hFR?8iI$@yh@Xɇ? ZxLA ]7@Xް|=h5W(|/24qwaHZ9q%rrSԹsa'p)@l.W@@gta@U;A,0L]9P[zm zzB.{!2'O3g0`d^d7+y?Xj[T؜:+wJ x$ylHFSϼ&zMƟz~Q(#0xG`od^ֻ̌[X¯KBm] q=m鶥q|RDw~"ZNBZO5!37´3/։zg̓wxkǗV+F,3g_Zi[*l̟R˜_0|MWMWLinYŖ3 14pߣR~_nuwE:>2 ty.OU(_0,YfzA^%BhtpDp [KEۼ)@~yFv*L4U''TSscklkhI$Sږ3|fϨ| z<:'2 lɿ@k Wftz5o 7p8lET]rKG 6~>uPyx+79 V #+N@w1NhPYko+O.ߕ]wrT;3vFL],9ˮp# P ;-zN[C-nņ_t Uj_e'</c@FC"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-javascript.png000066400000000000000000000030661237252063700314070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[oEv^{}K'1 %!REj+Th/Tx ~gxPQJU(S'i(;{㜣VSc"$'L(0 0C=`P$x$xtp$KsS 0v6Zv, 9 i;y`ZM3Oǂv0W X.D\A0MaA$9 +1@!h jA?VQ(PC@k76r]lb``@s4oRd2qmLNNbvvt}h4022¾BzŢ|KDB,IdRݝ@7a)e$B CҶyj@Sqi+lxaeeJcc@\?"q@0 X,,Bj2_ű%DsI),dB; "Hp%piŚUsxċ1Ir-pdlQ8& Su&,|1$KjmW) 3mbů#*OWϠCc?rikLYTWD]7VaBO 80B~!l@JS¹x V9C%R>D^ nVJ\.N~yds,: k) N(q# V K $/J)XWjH د!ۗa,Hr'lŒ &a"(ymc$J%i:&,3)-\.##W`ceD7%!d? :{mD ֩WWWi Rz(Go H `fs 7D̔TTBЀxqDH`[|hυ{wc{#">=@WoaHؠcr_|!P/)w0{LL2Z:x=a[/DZ699NWC} q=[uOo3D2mxqqKRlY)J'*sv409`}<۷X ЗUP:%0e X\rkkkX@*e]wofzzCKFܕ-wCuܘD[ܨqixZ.s[tfkSdqF .Àg"$Ȉ俪w,rF0zv?_H.]zr;t CBb|(w ϟ?xCw8tgΞ=.HjԒ(k$]%4x$ώ{QG U5IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-msword.png000066400000000000000000000030431237252063700305470ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIo[U8C3IJ EZBbZXPʤl邲A@l/@ @tQqrR'q'8ߑoڴye8ѽ>~~ιׯRc.1`R& ]P4y=s'a#6\%t1:Um̭+\ߪ&@Ey/ u'Õ_w-n @1˭0VEEw O4|/ 1_+t{νroʀe59h[l_&x|AiL's^b gKcH"9d4c6&SJ/Js (@ ALA8 w@6\jgcuأ%xr_}W- L d; w7φp._&G VސtV6l»n7?nXdjd|qx::(k;s9+cw#@|Ws ;D==zT r8B갽 ^nX]]E Б= 8ǦpX8#S,a~~t%133׫/..M pC3mYHc9ɐxDBDZ0緶Z*")%ly6evW3, mhjjBkk+~7;;gIBctsssw҄qِ56ҙ U͗L&޽{$Y U1sV(8&W 477k#~q>GVVV $g:T guօ&6˜`)QYL'iCC{$iN1$xֹS(z{{ eg)97攗@< |1I92s:Ccb%C08hUgeW/H]ƬK@)}S{jY :鬯q捫f%@hr6|IS@pR:S8هOL`o%#QFIB_Z z/Ԃ??b%t+H} oZOc,'9^Jl{*y u؉@3TM/fcO8`BNAtr N lφgz;-^>%ko9Ug$x3NUh|27?߇L6|S?O~Uvcd' V5o=G.9WO h$212r;yQ^H ޿%Xh\7H$[<֣xFk;|F|QsN_L6yɆ9whaQIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-octet-stream.png000066400000000000000000000114451237252063700316500ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZݶS۷؈77·s't]s@N@%or}r7<ĝ$~_fFM3G.iRx XMN*J́mJ~& Ey}s`:ٽ?…Ȝ8\< õJ͛Q~M߽͛ ]g,>#m{^f:*u+41κrK"J+\먔JjBe^skh ^^ sP?|Hk@M pb^]GF WĦ#C" ƈ0RD4{ PQj,LOܺk(qGeQd'&sq\ \}*,`0TJsD }H$pgyBb7xqAɦ*!*$QIb@Ezp8\E(vt؂1 HD1 .t:zfҜt ˜;|{P쵐mخ͟5(ϝE|V" ձmZ-@HQ[NRFV3eYp #2'A@`_x)eSLLHߘiB|rrcb8ꄥůD0@2[MqsVeU"0yHBmC5&$cyD a;kwP'3UGukp"bQkZg}}}4 ӃBrlPzO f6^)D U}bkk[:(0&9wwr "`z\./U"B[yQ\ZZ ⵐSٌgɞAu.Jֿ:OߗQ @IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-pgp-keys.png000066400000000000000000000036351237252063700310020ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-pgp-signature.png000066400000000000000000000067061237252063700320320ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X #IDATxݘy8"KII2-ZUP2nȒ)cI*Z$4-;c .TsC̔QJz59\}|}?&lV9t3;qomn!_|]ML>c н=*v/knB.@ux-*GUejxxOc62YƏM$ԘzmYR/T k23/8bb@MU~siBvLP>tށޗݖIqwkzzz irEwN7 tcqEJB{^H`P_)aOZw\ԊY;x@G ё  Ɔ:1ۜ5@]^N^^((B2 ) Cج=thHteI]uuu^**jYM3j8IFRKRGؙ,tzxNݒe'-Hց wBv>y;AP_EHTK;fZZ7Mi"ΣZGjjũEjjj> 栭]@fbF opcc5+;$'$CC5=Mׯ]?COCe*N$+:\ڠ5=pߟ=(i.Grl|q@Hh3V@_ٕ@YahÄSORA>֡HJ~6V=/>(>;6U6@H`a_M0Gmb{tQՇZ:A\7N sp\Hm@ N8Ǝa0Ƿb)FvY8JTl3%^ w§! D?pƻ*{ rVJ cwEq0P?c<*f"1nXԒ ƧQAePzB$Bf.?9h7԰ԕ ~pzw3x6>k3Z 0aee]0qX[a.4و_p^6騺^WT~i>s:S7Jj!IQQ<[&ox.ːKn,P2WR+j1afRclnbPs@UF$vaY#?NSSV4Rsi,ż%H?HG"CCq۬S9HI lDp %DRoh+돟Sq;0pCCm4!OA 4szz٧%2»‹Dm:vr<ѝK,laܦѳ1[cMx|-TGd^^ʟ?KHyxw7:9BZW:Vb%9*N`|@p4afu8 Pf~]B[o`'bxGxGxz˿NBÒ yJmB;D~myh:j~yrRG*h8 1 ƚOZ(qpECujuj_5NlPӿػ!wWL`6^h@md9ckVdE) W8w;gb ]|y̽_3BW6_I(6LjcҳH21Q\qϹsҾ;|wX[ZnrihH\x4ѱkg !ZRg.;qDS*bt:r->!6y PĀ8a$Oxayy3W]= `|bkWW]]CHƍu7R{іZ4zI/xN9/[{1&Ęk[[Z^z+Ljd\x xL|>+6oLL!2 .y^چ L$LW@؆ՙ 2r%y>_|>fMmzQ0-`8E)OI __ *D _Zrmm}%WӧݧԜnBT?11 J+"4jD!P~_A6WwcZ:j082vfb6z]pw.Z.e.e g+.{]ss6Ϝvo}730!EsUO֦C}SƦZj$>-tvAO{p>fXX*cKӏ|s@4&f gYϒ] 0Z rҌ" +xvEBB`$/$ZGD?a]FM=(4G<:1>,a z#Ac1L1g22evSuJEi҆WO2j5Rn+r~,iMCtL..35"#XV3ZƆ jE#jژ_HR MqFLާ8[^̶W^a~ncW{yRuj}MGtذة*Sݨ'x&2ՂKH/D'H=s[mI zO4VڒHJG3'\#LeP^(±xzrjG1K=z\j%C,=|ɰ0i)]b?-X#"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-pkcs7-mime.png000066400000000000000000000036351237252063700312170ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-pkcs7-signature.png000066400000000000000000000067061237252063700322730ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X #IDATxݘy8"KII2-ZUP2nȒ)cI*Z$4-;c .TsC̔QJz59\}|}?&lV9t3;qomn!_|]ML>c н=*v/knB.@ux-*GUejxxOc62YƏM$ԘzmYR/T k23/8bb@MU~siBvLP>tށޗݖIqwkzzz irEwN7 tcqEJB{^H`P_)aOZw\ԊY;x@G ё  Ɔ:1ۜ5@]^N^^((B2 ) Cج=thHteI]uuu^**jYM3j8IFRKRGؙ,tzxNݒe'-Hց wBv>y;AP_EHTK;fZZ7Mi"ΣZGjjũEjjj> 栭]@fbF opcc5+;$'$CC5=Mׯ]?COCe*N$+:\ڠ5=pߟ=(i.Grl|q@Hh3V@_ٕ@YahÄSORA>֡HJ~6V=/>(>;6U6@H`a_M0Gmb{tQՇZ:A\7N sp\Hm@ N8Ǝa0Ƿb)FvY8JTl3%^ w§! D?pƻ*{ rVJ cwEq0P?c<*f"1nXԒ ƧQAePzB$Bf.?9h7԰ԕ ~pzw3x6>k3Z 0aee]0qX[a.4و_p^6騺^WT~i>s:S7Jj!IQQ<[&ox.ːKn,P2WR+j1afRclnbPs@UF$vaY#?NSSV4Rsi,ż%H?HG"CCq۬S9HI lDp %DRoh+돟Sq;0pCCm4!OA 4szz٧%2»‹Dm:vr<ѝK,laܦѳ1[cMx|-TGd^^ʟ?KHyxw7:9BZW:Vb%9*N`|@p4afu8 Pf~]B[o`'bxGxGxz˿NBÒ yJmB;D~myh:j~yrRG*h8 1 ƚOZ(qpECujuj_5NlPӿػ!wWL`6^h@md9ckVdE) W8w;gb ]|y̽_3BW6_I(6LjcҳH21Q\qϹsҾ;|wX[ZnrihH\x4ѱkg !ZRg.;qDS*bt:r->!6y PĀ8a$Oxayy3W]= `|bkWW]]CHƍu7R{іZ4zI/xN9/[{1&Ęk[[Z^z+Ljd\x xL|>+6oLL!2 .y^چ L$LW@؆ՙ 2r%y>_|>fMmzQ0-`8E)OI __ *D _Zrmm}%WӧݧԜnBT?11 J+"4jD!P~_A6WwcZ:j082vfb6z]pw.Z.e.e g+.{]ss6Ϝvo}730!EsUO֦C}SƦZj$>-tvAO{p>fXX*cKӏ|s@4&f gYϒ] 0Z rҌ" +xvEBB`$/$ZGD?a]FM=(4G<:1>,a z#Ac1L1g22evSuJEi҆WO2j5Rn+r~,iMCtL..35"#XV3ZƆ jE#jژ_HR MqFLާ8[^̶W^a~ncW{yRuj}MGtذة*Sݨ'x&2ՂKH/D'H=s[mI zO4VڒHJG3'\#LeP^(±xzrjG1K=z\j%C,=|ɰ0i)]b?-X#"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-postscript.png000066400000000000000000000024201237252063700314440ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE b_`bacddeebdedeeefffgrv}}~__!!__""~~++,,--KKOO99@@ᨨ㨨蝝'tRNS $'(+/189::;<>?F67IDATxmjAsn̘I ѨWJ@to !D+.(Q!FD4AHH2{I%v~uOW7mPJ@چ8V1|XC <@s'b +)`!4Ɗo7$ !DM0Ԁ҂5BPxBϯD@͟Ի~Wdh,P #@Xvb٧ctRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-rss+xml.png000066400000000000000000000021601237252063700306360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxOh\U&$E4ik@].DӅX(7J[ BKEucD*6شD:q6:I23)"q| 8Ѕ83{=s{s$,6RS01WRJٚ[jl}3Q07釬Q^S1ܼ}*/ZO~W>}XXZ@qV=>هo=4<"A%p>Itc`@KObphMY< 0InkTބ   1y0BMF@XD6z0 0Q9@Q ":hQ[#E@Y/ h\%C D˚B]%uҙTOn2aa(1} l[-[u 7 YM`C5Yת^%@1 C,5bV.EnB~|mC56 Ȥ  [{l} z_Ν0:9Xug @Q8* ÍK:"%̕8~ = ,DlN"Uԥh,<{ACR$wtgͷRʀ&=m5AHg&{7i" ͝n9E=yjSx'z`hD;]'AϞ 2AH@-<8f@ _U/}AXz5 $kkQ^ԺmpUTbXhX>sZ7WVU&vQQh}@ۗgvZY"5#Z.=jsB*#0#^k}8<8DӖE Xɷc_Xn|t2Vl7j]čy.2'GD & -'pBvRL;n/ە^IIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-rtf.png000066400000000000000000000027431237252063700300350ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.ms-access.png000066400000000000000000000025611237252063700317040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IPLTE xxx}}}ֳ'tRNS $'(+/189::;<>?F0PgIDATxmNSAtW(  BD !!F+}/ h/54* У3vW&̗u1bq*p :Ub" &bF(7,0 ZК@xgHT:D!U=W!#@):%;ş RYoo.u :0VF)}pRW$z%&2ue%nˈ|#;ǭ!BYha8' Qʀ:ql_ 2aEtgMLZn_"Z'w [{2 eWRqvDD}Bn<"T[oA7$&XB7y^Si=e-;NA37x?'=kx|¾ fV*=umJBՀKyy$P)|hƇ0lu)n} @0yC=h[FHۣ&˪qaf#IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.ms-excel.png000066400000000000000000000026031237252063700315400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKOdUy3Ûf4YeD3+WY111.0I\ ݻQL!m*Ts{o|S{: XZ j!2 5g'NJ&4qpM}7浆j!S.H\t5u }W" O߹X \mܸz6LMu)Oj>!vqKco7yJ~{K>ԥ[fZ(ћ 8S\qsS-3qaogMzV{PA@C5AL)mJ.Y``paY.X%4_Sx.+bdP/Hqhx@쐱i $sj[k3گM y`UbD0lR U[*M^ŗP Up{eƐ5uNctDW@5޹a ù0/TmTSfBdjмZ4Mm%áR*B?4,^$yEai~xx\ǽJ!/Tf b.&jBGGeGRyr}2Djq vkCHGR;Ԯ.\@CǀSRF1&ȼ?tww$@/%HAz߹̝ f[[ \v_j8\=~ +܉FՅR,kR TbT@4wfM p,@ew6O3cǐ3gTmD $&k7fgAeг7o|ڠLX\/o^ TvuX'[KKE8r&mvtTr-SU@O"Bc͌qR aQ: ..~xᰘ˹UVR+liQ@PmۤQؒUE]V:w{l T.ccdddRٗRgYfoC@-ᮭaa!6988!c8D"hg299UZH]&HlपAݑ$>[[[E~ @kƳ Plg,-, H gVEm_]0nX.#?J*@Ev)P9' ."܆4Q u?: cccf'sgs ,E?#x>޵f8`nӪ}ûe8IENDB`application-vnd.oasis.opendocument.chart.png000066400000000000000000000031251237252063700346610ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵKlTUyvfBiI)C[jR B `7(F6;,YXX F1!$KK-VJi>0;370Co<9}s8LI2f\=v ּyV-D"tM!=q(?,7Ϛ(TxZ P0h+rY.e{ӭ"su $E)/ x^8 oѾ9+NE!=q5؁z"yj@ 0d KuWYP  $s UOpud'xjs[%0qv_V7TŨC* 6/cq. Uf.~ HmR)"M1i_mmJgLp<$O N $/AQF@ɗrYLA42O~R!fzqWj-WpH1f"!R1Oun@;ւdS`$qYs%9MJo7`&zޗf"͸߉㡡ٯw8vд UվH= b@/uThG5TzcPIe @ /_=g۾ޫ$Pvyt sa;LrdEͧe.].c+**p\  vuu} d2/$p=ZZZlU*~rcU:0lUUΝAlޜ I8;|'0,iBE ODgIXL&R(ݵkGx* BvdDy"ów8uqlVB O^{V;w~(od)P­ܾ}]1N 2? 烨q͡|70"H.kX& 64@B{YIENDB`application-vnd.oasis.opendocument.database.png000066400000000000000000000025611237252063700353270ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IPLTE xxx}}}ֳ'tRNS $'(+/189::;<>?F0PgIDATxmNSAtW(  BD !!F+}/ h/54* У3vW&̗u1bq*p :Ub" &bF(7,0 ZК@xgHT:D!U=W!#@):%;ş RYoo.u :0VF)}pRW$z%&2ue%nˈ|#;ǭ!BYha8' Qʀ:ql_ 2aEtgMLZn_"Z'w [{2 eWRqvDD}Bn<"T[oA7$&XB7y^Si=e-;NA37x?'=kx|¾ fV*=umJBՀKyy$P)|hƇ0lu)n} @0yC=h[FHۣ&˪qaf#IENDB`application-vnd.oasis.opendocument.formula.png000066400000000000000000000031371237252063700352300ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe ĩ"q@ܠ pJzhPT*q8A R%mR֎ݸqx=-I}ge "=|xA.={fL3ng)^8/q} hB7 :*z%LYlb4lDnQVMmsc0VU b"22 ,f˂T"WA!WQ$rȥ: e&Q %`xK =d%TTb#OGj5 GJÎPnN`- 0I9bRVƠRYg˵A6; xn?.cO:q⮇‹>|4+O:985'I^k{5VZ*v;ORPJis)1Fz1՝8| SQsDT(@ݮU,?Šhyyyٚw,HnYkR8 bq-Y-jM-q>Zzk%N湗s.:W9M J+++TUk!Yk;O?uF&?PXv̍vߚo3?\w]mh\lp%RېT7sH Bِ^,r\DyQor2K @o>qDi *Tx*0N=z8:b4Y<VdpL!6F'>kB8749##*жe04^:YԼ^uyJ{P(HsH0>>")vo뀜{~wn]0I`/ >=ou}N5>.L#k(ȹZ^el!+W>5 ]a1 .H;\fŋx,zq'fp9sS5K=1 rC/ `ƺ4fXLQ#4 FR) w12h xlT2P5Ct(a1tMٙ u"!W UV&puL2KKCUSM&2u`w_oASiUpCz3ELtO~լ4!in)q6 õb^V5,}%̳,2LȺhimE,]`#nh`큡uԕ4"F/!t T*s(HX^^N2͖9W8zm8;i acc;/Xa}𲽘xdoXú'֘'0%%zF;3<8y@ uا/ HbkfhLLL<4s.<UE 5EY?0,fyFlLfyL *&$7`7}CIENDB`application-vnd.oasis.opendocument.image.png000066400000000000000000000024521237252063700346440ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<:PLTE 9-;( E/ I/I;#N2NG9PF2R3^<`>b@ bN/kDke[mf\oMofXrKtNuL wb@xL xo`xskyqfzrf|xozp{nwxyZ y_ c RæƞɟѺ'tRNS $'(+/189::;<>?F0P/IDATxm=kQsGb!uBtEh\ vZXK/kbgcK$DB%ffv ;L8 )Ef'2%)7HECnз)/"-PE0Kp\È YHų'` 9a=.nӼ+N]"d#0mih3{39PVJ&nBPCR/VS7%@WY~pT&b,a[bte&ԯ^-?$y,cwi^j'A F5s ۋ/\@1"yu/з "[AI5[= +-:(lֺ &H_A*8A)W Rm@@dsr`{] [HW!RBv)#026IENDB`application-vnd.oasis.opendocument.presentation-template.png000066400000000000000000000024131237252063700401030ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKoU=NGDDj〒böHHH"!ʢ ~Bac]~D TyTj7c^ 3M=pOwFs=}߽c#hS.@ D*4K?=ƾy}6ΐb$?Q|먐T9jQXl~ei}lp45%7 0L&Cς_GLj8d0yx\x\FWe^D@6"'ພ8*v8YS8Ry)H&@3  |WAQIB]ceeQضu!'4Y<,, \w@RyiB5CnG;LEh4[xOJp!*2|q"=o_H3Rt:L@qbQ<60!\ȍxO=BĵQV155L&Hq:{Z{ H#$,:;w(kmފHul0EaܾjctI&N76`̣;.=G~wBr^sV|`U(,`Z LO))~l--пK*q:;!lCY[{al>{w$7tdu[tWP|-dmkɻ@`v~(maW >`^ Zo_\dl]ITb D}X̉ p2NGG0 !=!7 W |&ʁt)8=_gLږ$ `}Ejwl۬9UՁV4i/^\MIVd`$8oq\G}^JG0qVsM*""dW"7HS.~Y^~ı6+r!<3yݰ'5/<یۊ0AD!A~㼓;aƠ+.@" ͢\.o~N?;yB7$*333?xDZe*H Q" E؟Sqc1ڌ-KT@X%F=‡vh耨W/۶uXW;b} #_Ko4 #fJE!,' u}zz5LMM3 ]l[J%,@сcu\\2Q#d[.1ZKȽ\\?!y" ۸(NXDEܡ2E~ͷ8:H̍ m z:;e|zB*C ȯ}GQd`rܠIАt<|?xa:3{{'#?*oN( &$+ӝ̛!p ʙN.3 ܻ9, <'ֆ$m{;KK0t`O7o(KnfĻw}e;\Вe4ZnƑ~VATH;tNŠѻwi΋PBn%{UG`:F99 ܁ :''09pd޹x@?-Zn+R" Z_K9b*%Xӧ#SS!`&K]Ua&\AnkG$ ǰo@4Qʙ3RkO8PINjf~~kr"QfLE"Y%$9s`gg-/sk$N'̌7b ̳8_vwwPٳžMτdMbETP~aaK:'  H$I/H)493@x7C+ޟ8Dͨ1M9U zWG _I E4Dϩg ha-bd "\N7[IENDB`application-vnd.oasis.opendocument.spreadsheet-template.png000066400000000000000000000023031237252063700376750ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE _װdݸef໡fgɽhh¨kпŒÌ‹Ǝ9(tRNS $'(+/189::;<>?FIDATxmKnAa{ǀ8A=^#p .#@ [XۉQ~ݣZjA⮨ E|U%lx'B@,\!4Q l/cyO?Bϼ੐0>K{_Բp?څSpHDXXy H@’Zk2#Sb">DZteEkIĥ:رg; IcCtشg鎝TDT1A(z3=2C 3ۀ]ݟ̡ ȴa974[puoY.fC7ꪜTy%eJ>rn 2#0)0yckq`UFQ%>)>8\l .oh٠??&֐Ơj|??3:`nPdᨈ_oy9 Ynh 9=T-uڑFq"Qe% )bIENDB`application-vnd.oasis.opendocument.spreadsheet.png000066400000000000000000000023321237252063700360660ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8?F0PIDATxe]O`sv[>At:xa2N4^_O !F@%mL9nv>5]:?M'$3pT: @= FDIWxbs*@7w:IBDN>E$0 ڠұw^dE80q^tjs%"_f [3 DM ͌$r\\wmk5yrow ?%l~@R8Ez៤li8A ]P%vX/2ޑA<4֬mxy9s5dYv:vEpK$u*a)oj* xis@a#dmUNcX%uQ*iPv8֞LAL;Fx8ZP\K40THՖQ˲pr1}FSBךTknSLI8`vf] 0u-$e.-mK{3e 06cfxasx ֒PQVy^U3ZJ{0JBWzɀm'@@qibĔ(󪭙U6--$ۀ˅]AoIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.rn-realmedia.png000066400000000000000000000027751237252063700323750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.stardivision.calc.png000066400000000000000000000025121237252063700334410ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE pppuuu꟟שּׂΰް龾`='tRNS $'(+/189::;<>?F0PjIDATxmMOPs 0Â(`ٻw`Ԙs1DIgD 23 N{ ]pŚ#{V'oӫF' mPR hJwpO$@ VLUguBb`LE;@Xjzл6EY$ lNxl,Fw¢얷T. &ϙg + * 0T{*dėI4rLpC@"Y`T!PFlX 9BqĪ# b`J(Gb2a6 L q؄Xs MmȅߒfD4kC]-9~q+2`aF:߻Zk6l7n@$XT]k{N=58 #:}iۣl"fBCN]֖_5d#}h" Z/d\O/j@ BZ}~Oډ? ij;~(pZ!$+p+oIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.stardivision.draw.png000066400000000000000000000030321237252063700334720ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.sun.xml.calc.png000066400000000000000000000025261237252063700323340ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<+PLTE ݰз龾ꌴ뗹똻z슲쐶쑷쒷쒸쓸킮햺z'tRNS $'(+/189::;<>?F0PjIDATxm=oPsnԉJ[:t mNJ UEX@ #(02 !DB+Mm'vQb,?yϹĄN$#@s(R7[Y A潠lu2hDA?q YEc\FbIS BU0aennhg̈>@WrCߠO`V@M$07ʌ 4W gK2%D 3Jthe}@TfFGL4\SSaM1]#Vf3(1q7RD%YV uG9e()*8p(J[0lU6tRye)T"'JȆ6 VQ'eX :_UQʷ7Q3p7]I_syAj/l5p]|Y[ vj֚oYFm#bCޯyՏ'[ E}2|susdC҆zލ  N] ~hBqQ4Bt%i{~-BDL>X]cwBIENDB`application-vnd.sun.xml.calc.template.png000066400000000000000000000025121237252063700340620ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<CPLTE _ݰзd깠effg齣h龤h¨kпŒÌ‹Ǝꌴ뗹똻z슲쐶쑷쒷쒸쓸킮햺'tRNS $'(+/189::;<>?F0PFIDATxmInAWf%7H >`8`'qd,X 9`{p*wuEI_@pVI!E8r pJ e`dxqh601抴A\H'8Y@U*;.1vhHbe58fm XnS {ѯ7[S#rV';lC#V0P+SV~}`o}Qr?꜄SV'b2=*^*7W-^z@Ek>eKMbWꡏ"Pu&mF&hP\Rjd Pp&wդ1t!|9ky4fgPvD\teF=3+% :_ ?\'sWfb<[fPn6$d ~&!r`ZOdwi@J X2T=Mz~%ȁE4oD^(NQ0!K"?ޅ IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-vnd.sun.xml.draw.png000066400000000000000000000030321237252063700323600ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`application-vnd.sun.xml.draw.template.png000066400000000000000000000030321237252063700341130ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/filesPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-7z-compressed.png000066400000000000000000000034521237252063700322070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-ace.png000066400000000000000000000034521237252063700302350ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-applix-spreadsheet.png000066400000000000000000000107501237252063700333060ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-arc.png000066400000000000000000000034521237252063700302520ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-archive.png000066400000000000000000000023611237252063700311240ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-arj.png000066400000000000000000000034521237252063700302610ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-awk.png000066400000000000000000000031611237252063700302640ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񯯰^_`abcd d e hghjklmnqr r!t#y,y*z,z-{.|1~45~3Ά@ΈDЊFЊGыGґSԕYՙ^כaםdןiעo؟hآmإs١lڥqڧuڬڭۭܩxܬ}ܰݭᵊḐ῞㻔㻕áĢȪɪɬɪ˯ͲԾӻӼѸӻԼս{'tRNS $'(+/189::;<>?F0PIDATxm_qbhrFȕ3rE!h+aDÄ\˙3h[M[|oc|7 |]k^}|Y AM`;$kox!lp Jah4fΓ0D<9pEԭSf(z {,ȧ*U*Vm@ZOHnPwTk =ai4Qr9EQZehͺ:l'>×; 'VH3 drn'`lAX=;  w %"/ȝ .eɬ 0PY'A/K*AWIo8y`[uĸ/i+wVCgΒAC><#ތR \t}:6boеC>R>t?!rWC5VI16c 6Ϡ<TC}pwEIwG1|A~Q87+C.E 8਷J'\bi4;$ӧ:d3@o@7 pbBk,fL*V(tqVJo ޖbgL ND'Dulb"i1KQY~yV\W%wnm>@zvqXԲC_ڵhB| ݨG ss4IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-bittorrent.png000066400000000000000000000026051237252063700317000ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWMoE}=3@A@p ā#B"倄DrO8!$H"x"ǎb{?磻y3&=UlwWU]{)4 Z#"&74ĕ(#_ZEhZL||xt[exs"i^(Nf5vKK/I$'A`!^p4tb%1q.@ #I]Th- Vs2a09[y_hn+!ow#d [ fG8D(Vi2nVB<kI(X Ҝ'М",!'ڣKhӰ!š$uD"lh8np (2$DF A v^]Ql(:l4ZpFI$(vPDFD%*^sLx-K ў}*@@JJCTb$UKZK @?A3e8vC["paUpGFU@_'1Rz{>- jSRs0t oE:b;?)hDT5}B^a4z3x|wK7DGn]4b /X?Ե~%WF kBUZkE :?H yq'< _DS'/qd!N|'PR Uȝ5Aso+å’$Wx>fSW 205Rp~9b:½{wCgLHJ)+[,XHK 8Ghts}IG>u(. hBJ֡OoCԑl1Tcz8x !m"CMpLuʳ!x S>Dac?Te)b>coo6[ܳބF <œ}l6'9s 5LNɄ __`:`gxw/wq<0*g?׮](dyrOc86 >;~$SnOߋI4vW{5ᆳ'g5|1_,~ gsPj<H7"zWaͧp8|7_(ԨЋ>mv`pm#8ytFS(XcR%8ɿ4y[""2 1$evƬNDn})IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-bzdvi.png000066400000000000000000000121351237252063700306210ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙itTU}N )I') "* n" 2 8WAP0 dJM}wj껮wٶdz'*I  #–aWsgG{a>m"B >|#a [v!7®SMa;l@ pCSK}˗{Wm-5"0}4%}mm [A{J<+^s誮8'A/AAt`CA ]@kt+ ^ AI? L̒' /)|E>ϻL͡ /L`'&qbҩ[}v3?îvj՚U?;ŠV@H?oDM ƍ2{u[\6=rc hOhP Dme7fbzԚo<&?zeyiK]톊tϓM 07nM c~ȟ8];vWG'~8q")Y..5卸fk:?8=c+VLFΏ*ƒw`M~[OztH.IޜrTo B ml(ZL(jYd$(\T0V50bA(\ܫ8 s7vqN. Anz{+y/y2 .®0cU*[红?\j$R$Q ]=*VC٢'߃&{QT?>~; o_ҿW.6k~Ww.ecK-Aw魡ڻԄ_=j}I!]vի/[SaW[]w"j׌O@?^? D6X'3Y@3y1 ǵ^ZIb "QD(( X/)K\=~ж*oX(d?{PRCm?z ojcK]}# @E8 t{ $mu8+62020)(;*ڠ3 &o\1q(u.2g5+κN(ܖ}ʀn/W./=% 5^7(K(н2.Xm%)ARs[@ɈƂ"g`3zz9f@CCcPK0Oíc >SQQ-QI"pGo2a@W\esb4Iq~G~m"Rus3'HAz#Fu]fcȫv: 'bV(@G5qkpr#T*C|xC`4"_d'{L-YoMkwyEf: p*E|!#P,Psv*ɿ?4 G6ʺ_v|nw|xg7M6E_Dq)ү3>^Z_}*= >1ǨλΘ֙+gAyAPϳ*oәū@1?s@,%&(\h utуj=8/΀;3󎀾)seg< ->`3JG~QC.x'hNl)=Yqt?7!uocp௾ ӄi dC)1N< 3' 2Lsū 5ʻq;΃IzycF]*U㾈Sǽ|1jF̷{!i|/D7/f;㑱.uo̷hTWʋ]1꺨3y>GЬxU5Ғ4L%)sxZjHM leDE58ǜl쎙qEDt߈O!G٨~.w4؃Poz "s\[%OS"%ln ż~3*sXt0L/+aֿ T@;@$W|! ҄9`MQh֚> Q&U1`jVk:!zњbrU .ljAQ\ Q,  o /A@HuAظN1d*bx'b1_eLd߂H7Ժ>^$S@Ѝ;3b+KebGC7X[Zv<zx05o)5 W)3.ٖs@vn9QݭdEmهζ?[b{9\nW\   [@DQpM`Q9 XijfR41ԂQAp;6̾En5[78$%&EɍmBLjjY`Yḙ8z.ۧP_)&jH.N;7_BpPh&fj* u3"^UknCs!0.n{o`!ȖLUץw׃mrzqvƔi5+׬ZrO_dӢFY UYzHR 7aFF{ $R4ٛ P+LmXժG^Wb  Wˑ_d:N?AFFy0Sͼ7Ks>?SɆ*)Q@%J_ңgI/\r˭o+HF%l2JFe)k"k1h^& XLJW uHB'u |#|}alqvMEWqyͬa2A#ތ{s&ۇ]>cwumoxnù ;[n9h%/VJ40nt|VKk5LJl+ZA%wW|e%B3F[]eޑrW[I>jJy3 6EEyERugNͿh+J/]KPJۼf%۱ {/s_?w\mmε΅΅c1٘ ח\~ c~kĤMEޚRsgʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-bzip.png000066400000000000000000000030111237252063700304400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-cd-image.png000066400000000000000000000027531237252063700311560ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<hIDATxڵoG3{-N@KDQ_ZJ}C)-O:łn`lRVe 6޹kRE:@@e-.fe>x6Cy?'U)1F#r#ɩ O6OTPZM8~}2! "TbAv"%-U_9+> scWs 0S)Z۞E7 7>Ziwyh!bݝHzadMP(9yek§)UC6%)^=ajF7J0!ɑZ@ \@<@sm NǍ+@2Uڻf$F8Ή^B_E1?awlLH]Qr=6Y"jrvLl.YujQ_q1 +[䮝+g.L&pyR%GuDhl."x&Zs ڃr5S܅qn>HuӘd@LӮ"2&OX+bS>yNꉅ35i<ͤ~C`־'sQ=@ɦl;20NwQr&v H@Sȯc @.!M:zg?@ qFzd#&18(g6qd:y)zŗ,gj6ښ{SnlluE! MGϬ;Rč!ulq]$ fZWVVݻCz  E8.p"ժΝ; ~:'H1R[n} ,ɾ > { ?es_T>a~9∁k!O(P6FY^HܜeDRIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-cda.png000066400000000000000000000032301237252063700302260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵ[l\G3s;*4Q_Z '4&ZWxEЧB} U7 ϷNn8''Na)lmHiLdD}B¶ B[\~w::?2):^rz:CBĶ1n@y'p}@`z̋s }~ B4Ci_4Qfƭ{YƊ4ҲiyK2,mT2C pf6M2"#G̪إ3MPhGn̥l1(oi D<VJg?EPA[ j鴳}H[F (q/8qSOdN$V6N j ֛HA]';+銫4QF8;eR $BYm~We')!!SG/:k4ArZOvB""jY<%dzf(4LW+tXDajfXr5[8|Oro(+$UJ :lg _W)̞n|oû୛k!~0 d> Q:Z&ֺO'\+-{p1:$3?%9 ]Ao8fZNZի/'lƧon?^}\K7=㌃Hq#'C9++.]-`Gk0{dP=hڏ[lNr~zA}>;/<ϳ~9)Y^^.E`Ո܄}\ǥ,oq==b _=&O?%7kkk+W| e=R1O5=h=R$[[[lll$uuܹs,,,RZZZ{T>=s:A~^__/...>_V5m0YvFŋnviJ!Af{`7))e_6L R Z8 > 7C 5!s>tfP?)IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-compress.png000066400000000000000000000030111237252063700313270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-compressed-tar.png000066400000000000000000000030341237252063700324310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[Eܝ}eѨ#!QI@b|D$$11Dd僘>B|#D ,,ٙ~W4‡=s9uު"[z*z>m4yQMFiVަMḰ/?ygOdW{[<Z& lF.̖skh>t(T0O < ڿkT!$к "t-锎RB6X&W+v Xy׽?M8 80K. ebp虨:-$<[Yts,6>!cD"T@OOo mXfG6 & px!%XUx_ZX Srƽ =:שl9obA(uH5Ds"<?EApL-h*@pԉ11U~H8.8.#.Z6#i;$w>\hMEhU B%3 ĵ5 @B. Ռc9gYo,}iK%ɛ:Bp\ (F}៑' !9Bp^L ".sLZ5K!T輣w: YxczXԞ_ E!x̓"C3DZ2пs#|9xo$A6c]Fǧ``ƒ`G-\<){ӟ,@XŮVxǂUqueUsWP[@QOiLނ,qDpq,@f)YhK3ܲbb^L! =;gPW'NԈ>.)|Haʮm&`xd6- Zs4EH47qQLx Ҍ$@Ҩ Ŀw pHq 3,_A8 NrONY޲ADߤ0)r35hrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-cue.png000066400000000000000000000120301237252063700302510ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XuIDATx͙ pTev H$KXDPA gDP #숢8"ʨ3A$lCCʹE5zU*u[i~gP_g{^oѪ *6X#{CTw<ڼ SM-WLɪK>`E?\~r#(~s;{<#X= a WwIC* |UխZrR %BMl tn鏳뿴"*F_ttqw|"~~C S%.N[g@ Z+fԯ9 cTHIuZ ƌѩ8%-Dznm1e84Mif._nٹ6 lZ} "|[=PpWp:m1}rA艈F_x+rc9ȟd6NMwҷ]{99 h` RAgirhcYy [eVwd+jݬw`JVz@HJVg/}\^h1gImLUgMx{{KͳJV!iV yU=gΜxjʀxWTXY( dP`s#Cls<FtĶ={n;5`tA"XΕ`t!bbmv6 *ƞo>DWӺ[u*s(kk5K7kw~z;*--)qh x^mh1N: [4!I lژcAt-(?J8}z&{;@֫㮎O~E!zW} PmBTߖͲ(O\*ȷRڈCBu>w`6$xǖ畟};"ႴO׃Oֿ+?X ̱".:<ѕ' ǶODHQkxf*VOCa%a?ĵ8!ͥ&*pʍL@ptI^0^1^S}8@qENJ05t~FǚYB03/엊?뾙SjBvn̊(9Y}{Tۧ잛u騿EAt dclK//9ǂ_{AkeK mG2*h@ 2,T]]mfk1 ys|u*f-99+Tw<@i-:Z:8jsw%NuOr8_X (@d.XF!ws-F2]A>6BP%oI88&.N*zl DEԻ1Lkڧy28={3T1fx!|)4eWY֫&g:JMH?~KlV2*5`vqLG#WܶG7_4iȰbP@D@Le_K4Pڈ*1g$x&m/ 5Yq=:j{e{gMdO^+p{7%ow+A֛aa`ZrM)x`e䄄]:ւgL*ϋ}`:L[͵? ^=_r;Hx9^>Ole|yn/?]^ EDohMh=Mpz\-_ kFa pda`~0Zsm3g{sIjgAŢT.59/l-1\YYӬ q==_>#͆‚j]L< ~IZ}n745mxf.u~{-aDeu}!e p*0yŬ]])>tXmtOUJZC/&Nx~GtX| Ì`)fל9Ws;+^TOP}o@Eٛ q$(FpA`ooҺ?p: !sKπYa_":GZK.Zqx|ܢz|ioyTsTW0%KIbzssR1[* meu6o mZ߇ӕOͷjCKmXU\/P>*p*lncZhCgn;???!nIgWB Dhj.,\zWц}>d]i_+-1[B~/LtAVLO#qHm+vqۡOo~v_HzIQ⼹[frus# !G.SKs`+d̗V}޹Uׅ;P sXPtlϱP}6wԕP1e;j!m?ju-N!uY)ϛ8kڮKS3cf}%Az|zR cgLqC8SjQ~B)W#=٦=4;1@>7?B/CFQulsMj6m*mFP!Y<*Tê]C -yϛ`dY'vOq>zG5 3/m_bYe}/}I\e%*+p+xCZZAH(XbJ*Ii+L Jjx40L~_}} C+W_Q# XDwY_#52[ԡuQK5>uϴ=lwIrKN;hѪ >!q!RvlJ4hpqqIÒ.}>>r_uKͱށYmc٨gc ܣpfV) <;,7*p(pȲgLkye{l٨fr-ZZJeT~| [ E r׮6ZǦ L;CSua ]#7A{ǷJY^j8Y T  F Z2DFpqm{jC檭S^ڷזOzmI݃vN6PoNnWP[_-6û܆ҝ=o6L nنq l< 7=#c"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-deb.png000066400000000000000000000030371237252063700302360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxWklTE>sna*B IDD1c"QGL#?R_jhLD?bL 5 "H HKҖ>g33ٲ ~{v͙sδDsftuuFP/Sh`F69mڴ݌8omk(1iG c9- , J)X)(5q\qέ;?yt6gy]=D29aB.{PLJ”,*\}P_Xp9(0k98" _E(׈߉i‚7_y]/\LPiiJh&5Pku^Wv.X-5z$NA ν,]Č<CHEo`#M22Ve847N5ww]pvj;fy̝ P9m q a[t2U5=+z=a55zq>͏O{;`FC =} 7F!oI7UQҹEs=>{X1xa,^%<~Tfm^!W@hAXy>|wwq68r';\Θ/ ذvI=|xcajXAD,R8|{pix ϵ8etѫ+wup>=NȪ́y^eEx^ kW-(WAbE[r>2Wq`~>@1.[L݂L_作p|FF&k$WFd]ڲ#δDD!#@:n٣W*?86ƭ(`MD䠀e?Cy0=W FkwP,i.:a$]r:D)EI"H%7g.˘ptR=X;i $ &9:Egdt_!TM=B pkCH+˪cBp-b m_Kt RIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-designer.png000066400000000000000000000025361237252063700313070ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sPLTE nnnpppz{z¾ƿ8'tRNS $'(+/189::;<>?F>B*IDATxmнkSa7M֠[A R$RPI.VpRJ'ŵ9ChBSHȹMnj.Ϗ+6D$tY 1C%yr[ahiy\( a2`b=<"\ڀ,uAW";^(1)ޏ&f_z o!WZ- CtA[w gUBq <ߝY,yuUD|8T0 H0qf=zx{27¡À7Sm]wqpD\" T H ٕ[ tTmQۦ??V m[1\>eV/gg\vG$8ۺYYrfr4w+DuNl~?({;M`sofl64mX][Zl >h b[A}Ui nS 6]7dWM;33on.N x?;}s*vS{fZ;yyiq(3aD%{qC e;{LX-|S-Nsr0Cw%M|o`Xϕ\ ϑGKO}8|ANk@<;:?48{nidXz(O!6`|![me\HD0!cLxRsV,,#^'N,R-""6!l hwmq1PD@"ffİmu|*/dDǢ>7YUnfBW01PE7Eb|{!aBǏժUWk9ukVr9tm(J^I:: Ux5Nᤷa+܆Ll 5 z8n<9v. &,TloˆU^$s# t̖-R,2y#ԃ/gDl|pXUMm:,wgOWQSPA +;U|~N,]HȰ A:``%xE^-qX4!Q6GYM<6 $n>iag"≈"r =w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-executable-script.png000066400000000000000000000033011237252063700331210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<>IDATxڽWMLTW3 QbbL+"6 iu4M4j-E 6WMݔEaacEC#A-tCd`p&3`Zwa紴4JxYH_ؘ0yΝ;~)g$=k=tP\mkkkɓ'[,wܹ^yzp{{sssM؊)..;x`3VCCC+#Go߾x>/--)6BmrNNN2CZyfIcccWDtUyykCd?\؊^/<}UzI8Vi5JU'''=!gr@y&/Cpƍ?X VۭS-[0S=qDeW/$XXXM )pOy^ml6YWW) 5˚^u)}5ڵAt-0=H8++ ٟ ]6XVVMi ˉ ccc WGGG/,tDd<-HCzEfF0̙3fpeq@jar*k*~8y䧫_r䣔``(3è%Z{n.)dH%«݋?}- $@ t8&HEk8,6>>@KWa>@>uS ؠ8Đx#R/ι2,Yj/nȍ2 Z = Q oݺ5d><|"Q1{t}DoR  neb^AgiۚJllRTUXH8B[Pư`Jʜd b ϸ2U\ɳ~jt9::z.8!771"IA̍4Hj&&G Vuuux{)ƫ4-ajÒ;w|800jZ| m@x5&5(yUfDj>s Q}B-~-o~)=?X60Dmh[WV;pl!uJH6dR"x#NYnQQe &R pXQ$^+nPKKKF:[XIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-executable.png000066400000000000000000000022551237252063700316260ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<,IDATxڝU]hU>sofl64mX][Zl >h b[A}Ui nS 6]7dWM;33on.N x?;}s*vS{fZ;yyiq(3aD%{qC e;{LX-|S-Nsr0Cw%M|o`Xϕ\ ϑGKO}8|ANk@<;:?48{nidXz(O!6`|![me\HD0!cLxRsV,,#^'N,R-""6!l hwmq1PD@"ffİmu|*/dDǢ>7YUnfBW01PE7Eb|{!aBǏժUWk9ukVr9tm(J^I:: Ux5Nᤷa+܆Ll 5 z8n<9v. &,TloˆU^$s# t̖-R,2y#ԃ/gDl|pXUMm:,wgOWQSPA +;U|~N,]HȰ A:``%xE^-qX4!Q6GYM<6 $n>iag"≈"r ?F67IDATxmлkQs;3kV!A$ةu,bgoc#&" ;%3iԨ yϽfnyH)8{.uPhi+&t܉;CQBzf rh) @.@H Kh'dqP?@BIi[WbdqZJdG%`YK̚<X 8?{lr}kasE1%;u嫨fCYkZ h櫽U?_"m$ Ltk8~'SrxZHȦ(O?ΫCSnU|u/4(kk'l4Dnl'+E*1cח%e Ӹkg~\鍡hGa:Nz[r;vHNm;.|!m/6AR$v /]jo/,q7%(h{Gà A9$ k'3eHІʻ I(E dA0F96`IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-font-bdf.png000066400000000000000000000023261237252063700312030ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-font-otf.png000066400000000000000000000023541237252063700312410ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE AAAEEELLLPPPYYYZZZ```aaabbbcccdddeeejjjmmmnnnqqquuuwwwxxxyyyzzz{{{~~~S'tRNS $'(+/189::;<>?F67IDATU2(*"rP+J;1,L| /Xjg@023 gޮՐ }ШS1qO5UR%H`vav:j)I^Ii:~mRuxѫ<]*A=~"qtt-dw 2<7lt@gC.m|vAvǿA%ߝ^%_\h~vUjJp*5p}R)z_@/~|e+4*0UAInOUt@ժĞ  TU% C@ hTIx4ه1 DΒw1hU뭕}n}CE݅ywrzp3ζ}[ L?spӀ{MGO>|v Hb?}ZAۭ/zt |4@sb hM#4|thM`\m4vuvy=EIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-font-pcf.png000066400000000000000000000023261237252063700312200ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-font-snf.png000066400000000000000000000023261237252063700312360ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 000111333444666777AAACCCDDDEEEFFFHHHIIIJJJLLLPPPQQQRRRSSSTTTUUUVVVWWWXXXYYY\\\]]]^^^___aaabbbdddeeejjjmmmooopppssstttvvvwwwxxxyyyzzzŘ'tRNS $'(+/189::;<>?F67IDATxen@ƿ˅BE DE$h(9(y^Q@C u@@Mz-䳵#iyV GB䵯" zx29@|"\:6?x P1?k`'ƿ&S0*e--K)CD&vze3fЮ vIJ{K.y4p*=*@9n~D=# h'5!=1/k K@3 э ٝ7`,n:ypw~^Xy;Bw RW.VLbݛŬ 4 ؝Vu6 JܿWqb&M @!\E>uIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-font-ttf.png000066400000000000000000000023541237252063700312460ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE AAAEEELLLPPPYYYZZZ```aaabbbcccdddeeejjjmmmnnnqqquuuwwwxxxyyyzzz{{{~~~S'tRNS $'(+/189::;<>?F67IDATU2(*"rP+J;1,L| /Xjg@023 gޮՐ }ШS1qO5UR%H`vav:j)I^Ii:~mRuxѫ<]*A=~"qtt-dw 2<7lt@gC.m|vAvǿA%ߝ^%_\h~vUjJp*5p}R)z_@/~|e+4*0UAInOUt@ժĞ  TU% C@ hTIx4ه1 DΒw1hU뭕}n}CE݅ywrzp3ζ}[ L?spӀ{MGO>|v Hb?}ZAۭ/zt |4@sb hM#4|thM`\m4vuvy=EIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-font-type1.png000066400000000000000000000024241237252063700315110ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE 999;;;<<?F67IDATxmлkQs;3kV!A$ةu,bgoc#&" ;%3iԨ yϽfnyH)8{.uPhi+&t܉;CQBzf rh) @.@H Kh'dqP?@BIi[WbdqZJdG%`YK̚<X 8?{lr}kasE1%;u嫨fCYkZ h櫽U?_"m$ Ltk8~'SrxZHȦ(O?ΫCSnU|u/4(kk'l4Dnl'+E*1cח%e Ӹkg~\鍡hGa:Nz[r;vHNm;.|!m/6AR$v /]jo/,q7%(h{Gà A9$ k'3eHІʻ I(E dA0F96`IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-gnumeric.png000066400000000000000000000107501237252063700313150ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSm"B >|#a [v!7®SMa;l@ pCSK}˗{Wm-5"0}4%}mm [A{J<+^s誮8'A/AAt`CA ]@kt+ ^ AI? L̒' /)|E>ϻL͡ /L`'&qbҩ[}v3?îvj՚U?;ŠV@H?oDM ƍ2{u[\6=rc hOhP Dme7fbzԚo<&?zeyiK]톊tϓM 07nM c~ȟ8];vWG'~8q")Y..5卸fk:?8=c+VLFΏ*ƒw`M~[OztH.IޜrTo B ml(ZL(jYd$(\T0V50bA(\ܫ8 s7vqN. Anz{+y/y2 .®0cU*[红?\j$R$Q ]=*VC٢'߃&{QT?>~; o_ҿW.6k~Ww.ecK-Aw魡ڻԄ_=j}I!]vի/[SaW[]w"j׌O@?^? D6X'3Y@3y1 ǵ^ZIb "QD(( X/)K\=~ж*oX(d?{PRCm?z ojcK]}# @E8 t{ $mu8+62020)(;*ڠ3 &o\1q(u.2g5+κN(ܖ}ʀn/W./=% 5^7(K(н2.Xm%)ARs[@ɈƂ"g`3zz9f@CCcPK0Oíc >SQQ-QI"pGo2a@W\esb4Iq~G~m"Rus3'HAz#Fu]fcȫv: 'bV(@G5qkpr#T*C|xC`4"_d'{L-YoMkwyEf: p*E|!#P,Psv*ɿ?4 G6ʺ_v|nw|xg7M6E_Dq)ү3>^Z_}*= >1ǨλΘ֙+gAyAPϳ*oәū@1?s@,%&(\h utуj=8/΀;3󎀾)seg< ->`3JG~QC.x'hNl)=Yqt?7!uocp௾ ӄi dC)1N< 3' 2Lsū 5ʻq;΃IzycF]*U㾈Sǽ|1jF̷{!i|/D7/f;㑱.uo̷hTWʋ]1꺨3y>GЬxU5Ғ4L%)sxZjHM leDE58ǜl쎙qEDt߈O!G٨~.w4؃Poz "s\[%OS"%ln ż~3*sXt0L/+aֿ T@;@$W|! ҄9`MQh֚> Q&U1`jVk:!zњbrU .ljAQ\ Q,  o /A@HuAظN1d*bx'b1_eLd߂H7Ժ>^$S@Ѝ;3b+KebGC7X[Zv<zx05o)5 W)3.ٖs@vn9QݭdEmهζ?[b{9\nW\   [@DQpM`Q9 XijfR41ԂQAp;6̾En5[78$%&EɍmBLjjY`Yḙ8z.ۧP_)&jH.N;7_BpPh&fj* u3"^UknCs!0.n{o`!ȖLUץw׃mrzqvƔi5+׬ZrO_dӢFY UYzHR 7aFF{ $R4ٛ P+LmXժG^Wb  Wˑ_d:N?AFFy0Sͼ7Ks>?SɆ*)Q@%J_ңgI/\r˭o+HF%l2JFe)k"k1h^& XLJW uHB'u |#|}alqvMEWqyͬa2A#ތ{s&ۇ]>cwumoxnù ;[n9h%/VJ40nt|VKk5LJl+ZA%wW|e%B3F[]eޑrW[I>jJy3 6EEyERugNͿh+J/]KPJۼf%۱ {/s_?w\mmε΅΅c1٘ ח\~ c~kĤMEޚRsg b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-gzpostscript.png000066400000000000000000000033701237252063700322570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<uIDATxڵWOTwsy<(", *Ʀ!тƤj[æ&hMiMh+kւ*4 <<ܞs¥35I~\}j(%`3,tX,8=i" Qu  zv_ɽy?'Kx{vR),..+`ʝv>`YPH TlZT!|YYP,VN|1 HZn#$~@9CTxu"\u&09`^.E(&bQBN`۩a\,Q4*p;8=x`~oofhn"4 xT!X?\8?ٜ[ QIC7^Jr8`em)Q! !x$H?F)[p8xlBR 'Nx}Ob͋H(JPÙ(aF~3u@f0f% Ek׋&@/dHj6ǢKaJJ IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-java-applet.png000066400000000000000000000033231237252063700317060ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PIDATxڵWKoUlόv켓6N!TD!*m)EFb #B)R%TRRWK&MbKJm8ɽ{|3q#)cS\pn??ɳ[d\>?m3u4¡9wugi0LsPpӣj `<;Yݼf'♻é' Po?61$W* 8RŹZz%~xVOA ?E ||$T148 GW36GoE8LzJEz-xB+]xmP©P,05sUlHv/fxs0Z@G}!tG:Tŀ; rL qIXgd %|-GdтV^qӇN@o7PV9 Okp膁M%$H~AYf~dtjAb[L&ܛpy0t$ê´HЇhЏ5`%و*>g 4hS>IcmW#R oDv@N#/WX`n"::kkãP\.qz/Z繱P%|IXE.7ds͛-=>r CQĻI$pK#>}7`uEtP"Q:g_E2+bkk Í kDda_eh8sB }O IʹLضͤ $hK+R[ЫXj6N ʚ Ԃ,-Qiy.keTt a!6p dittb@Jw, ViF Z}6 A,-GH01^\4QÅ|ۇ`0(~@&$ $̶-D@ƙcd2L˺9a*oٖU 1Ax.~JmcttPaYLU4#w3:1HBv7rq x+ 䀊x?`!C h/f`N"}( wW\̦5|ddD;%*q큍H2Kc4FI-^Úkoog.Hh{wn&ٰvuuP(p21(X__;UWYYR Ä~|ll1D@"b(:N2SSSi)insEpD˜h"Rw/+b8&''yD,5"< K}2;+%ֶY…4.Ц~pU ʭ&q s5H&'\tf Ԓ_6E7iC. 2IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-java-archive.png000066400000000000000000000030521237252063700320410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lUϜn[XhKi D( &(#I BFBjAQ o@/J/`YBms;gϙÌt0!s:FplЗ/<$s]\Ims_v\5ܗ˾*`hVRƹxS٩oذuΈ20Vb 0,7+r.5ԾJDx) 8IO #D - T cVWhe q;Ule/˞"1 Sb0ElSHC0؂mMȅD )' M3^Q~ aڕ$' b1I0¬V aƴI;:2 :QK[AJSi8uG? q |X!YC>S`{Z)OmKsܙS`\ڹ/s#w¶vF7_a6S`Ϩ;*|YDH a+Ric\\8k"<:H&>{$V<-zߗ\˲iUꀉru+*AbZ@%l0.}"$x^-F!e|IcytqvQԒ$ْ$$SE3I8 Kkt6͂ z)rXok@L@!n`AsH&wT@=F,iӧx 2*\I0B876w1>} T<*I uM@1kmOpev/LBfɊxO.SKs> 5u*$P>YPk3 2[5 D"!u$ĸTI1 >rjUe> AǦwƫ4b&}*l6rL/p8K>D@Uc#-Uq5+ KruՍME$8*|ZB.{ 4MV2ȥw.c|bd5rI(sUi0\e5LgAMu^Xf#ѳb%8 h\8vKّOOOKNi+`DXeaxxXd, F`-}0Q!&ϐкrֻ%%pCy'&{(IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-javascript.png000066400000000000000000000032671237252063700316570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<4IDATxڵW]L[ev?EÕWKL1;F/4ƟhLvX Å~dȘ2M6m&tP R -=Ү(ɓssysx@o6#! 5Cl j6 C0D0B(FxtD$H4 N-#O`Xi\k x3 ܇jλЪTBގ6( }}thS)7^YDBAlx+ & Fny]r% :"R099 rkM|/... C~6wa8B1猤Oi"2x$]Hr$FlaL $"I:7\9sǎ~0~9(E{QH@ϟ\EybOPNJy@OBW&%(}ywǣ᫱DJMא}ԍ̿sr9GSmM"Ѕ ?%ǃᤃ%kZQ׳@Vx\NA wY(T!wxp q~_ao m"ĕo.ݟ *$&% ́f]hiE(yAܺu!9ꉭ+a8=K"0< -8OJ~}}}0;1r"px?]PW0پszg'#b1FWWW}Ze 4_{2(fff#Z r|/Ih۷,'l$+@c9o7,Yuy_k|?~M@Y>3b',} &a2//\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-kgetlist.png000066400000000000000000000025741237252063700313370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIlUfǞfEJ %,ŤJ b\8 RTD/ZU 4%FRocیgi< vͼlٲ,@@dTv3H;1A `5)}[ν:cW$IPGA(9M/d.CįmUraw+d<N/(<׮+ <:%> QUr{[@(g7Љk/__Rb&Xΰ]#{wH`2f֐9JKZ Mtu0-tu4(Wb: ԙgmm~^ cuE z6i}x{9[ȒHX$sK'FDmN/𾦠D;M'"_mHN Z>L@&q!s|B dH;)ȻP_z^dsHA R0M,tSU!d@W'9$֗fR}} :]~P0a&P2=,Ip?on|ˤ{ Wx3NP!l"2x0L)OnXy>I.H؟eLTvF18>>^,Tv "(HKCq}~{06Õ.xV]Sx8SO߅tNXpR$d O>fFz9ЄKg?Fxn`qq@nqa]׹7"~vv藸8z[r Ԍi2r=sڇzӼ MMT.s0C42"l&''~'ٓǞ@ב܁^œx(_i Ս顡W$Ioѓg$> v<c|xh|DSSS<`ȵzR=ϯ} o `Bdsss###/&b}-Jrf'"`||`@,T534wspEC{@QND*cjhSιXE" `Bdqx^N'ۧOE}T²$2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-krita.png000066400000000000000000000027061237252063700306200ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  y |!"&')2$;(R96S:7T;7W><[DAdMKkhlWTvca u|-- BךΜԣЩɬзɿ%Ӣ֨)ܵߢ྾!!⽽纺齽ﶶz'tRNS $'(+/189::;<>?F0PSIDATxmMhAߛ|y Q"DHRR)ED$GE QjE$-?^4_Mv7fH; aRR8nV]j [Xc! dc7E@*h 0 &:PMnB8Rq410 D$202t@Iu=u lr@D hBLqB@ZgH NvN-ud(`HًfxKj3t?kg#Kɡjt6^Niɟ G%zuXpLD~qr,a1? F[_U;9J|P؟:VΩݾRm0r~GZsM;6(JH>݃}7h0MQt̏XW,MMY3O|cIW[79) ߨv}vfZP?i~V+WLȕF-0`5ׇЬ{(_ڇgqSDIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-kvtml.png000066400000000000000000000016651237252063700306460ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<2IDATXoG?onQG"%%Q*T$P$: Frr:8r9 D|ֳRvlNF|3߷O3A,`5 ϭB"x lH^ۈH؉CEUmvV1\p!"#)д'"jH@Sxz?ZLh'Yiu',pqNLw%G 8MbInvl5 b5T*@$^ Gp&jÈ7KpM0f//_P 0lJ_ONV\9Q] =}W7<|뷋_٩&0ySjx06 LĔP f|iڇ?@ _G=2xPy5U>d_ 68Z4Tl8(R J9LtO:Թ"T9t`FcL)#GCJ5v(1qY666X[[ZZpq&Z0XkJتCH6gΞVvff*df+t&=Bu/"w$I1VzRV_a=ha׌ғ0 /v DV\*Lj{}εoRIZT<!+0b-9(z& 7[]TIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-lha.png000066400000000000000000000034521237252063700302510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-lzma-compressed-tar.png000066400000000000000000000023611237252063700333740ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-lzop.png000066400000000000000000000030111237252063700304600ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoUƿ۱ǭD}︡X $*J> b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-m4.png000066400000000000000000000024531237252063700300250ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE j['tRNS $'(+/189::;<>?F llIDATxm=OAvn' /+ cޘX'`Z; BLL,+Bz޺;337 LvO2dh'}1*m61DƠ-zN"0 "e\[# !Œ'  626h++r&1TD@5ߧ9c l0 LOoz1VNE ʕjǽmUv `_ |(a:wE2(0y9o9D1;M? 6[Z _-~ @gDĆ]{"N,hF/FP ֲߤӻ0Y{ *<G` XctzhVD`ݳ1Zk75첌?~D1dR2`GDrX@x`odH`0,1F:h_IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-marble.png000066400000000000000000000034731237252063700307520ustar00rootroot00000000000000PNG  IHDR szzbKGD pHYs^tIME 2ʫxIDATxڵW[o\W23g34--/)?(!">O'*** j(MI|̹ͷl+Pfoַ屇s;73E[֣uk8~u0(JxY|΍>37sҨF^!-?@F$\<:*4(K ܺ23|=đZ"1?p.s#YdtV`Ц9ǔR ::yvjb{kZyg_#sF>ɬhR7(E# 0,+"CxhXUi3ІMJ Utgei1Sy,3\&66g}U0| bJѕƩ?NXeL};E+$VѾm:M;b8rt03H7`?>k1:;'qYqG&N- ԏrCe3«@w?->|(AoiZaoo>y*JKᜎiƅOcܺ{oEZ_ifSa\)ϝ/րp9`%h',S%Vsb}c, (~}xwHzj3jtk/-XTي2ۡ0 |v8v`iO='Ծڀ+SkH#i2 ȲK@g2 a?Q(5,׳¸Y~7ԇã F@^J+ihnc*3xf+ [Na jIZkW}kw+pJ@! Y-vA"KlDb#1t93+WcpA$I0Ќ|hcpkx?AIWjǃw  Y2ҮvtRBbիB\ku:Iq؟a L^qY⥫u -E]Z`sˠ,`&9=tݐj1j`&D G4BVʬ@ ӧ$NKP y9d ˀ+:|X 7xb`^ qasW" :-i -NdR)RF{}V1ƏZEYdskrǎLkE٪B(o,W#팩}Uޯ4( iK0rXxjtL'S,*<}"y m7 `Z͐g*/ .JԬATC(A':@,QzVqU)A~`f  i B8׮'3%EQ" Y2~F7߼K)rb v3tbr4dRG'N@b?鏿[ogӴv/?켾;K +ĊIGIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-mimearchive.png000066400000000000000000000025771237252063700320050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[OcU(--V.R:*L)d$18Nݿ$dˋјh(a LePti-\keX;!}ioΠp-6jF?Qz%eAuMMM}5222 QSS^=Vwvv}J߀u:/kIItuuuU|rp+W$̫%=\*VM Z5) 2{ k(W$J'eΤNailthxa28mb#"B ߎ@{hS|烞+ܡJG5$1vFd*`aMFf7?b7Gww^|Wrpv/oXNn$pr9= L8 Վ&\cv,.a*cjV`N~D9vy`2Cvqzz*-F@ss s` |Mq(q-m#k?*J|*q4=2V&ĊHf]EjǴ]'''dچWF# l!DpZ:E6Ϫ&*(|N~l4d"x(kK1Ykl\<צ@):QR;)%&<`<&UBff^d2<*8ߖ9UD{: 6^dBň{K%y "U?|w? JDMp ]EXTפvUd2u_p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-ms-dos-executable.png000066400000000000000000000034771237252063700330350ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڽW[LW] rQ40[Q.j,MLmSkڠ1B,1Р!M+}H<Tj@E~_a]}ZVVࠠ Yȉ'9r*AѣGvҒW^d|R:::zoݺu~|| SAyyyi`g~3g^ ^gn߾0 xřB:ccct:\JJJ4١={) Ru΍7ZEnA@|Gd6677O .8BƱ$--BZT/զԡ!m.22RygG`0 իWAӃ58>-˗/' x?33#r޽d,aaa?ԔhZC!!! m>44Ty5559bp\9Ñn/^ 0{@ɽ_Zvm$(%da !jdՑ/hRR {4|rwqq u1=a:ŋA{ccc@ 3,K*Uԓ= `Hi)Z~oKKKOˆeXe bTpx)m z`$AytAn Ufxݺk~qe W@z8*:Δw|Ϋ1?ϑr'tHwxt;Ζ$;+[,f{J7Jzzթ 6LMfW]& '1YԴV'y ---K zAay+7(nd _<ˈ{z,P5q9Ώ~,A4a@Җː![U^:Lឌ܆YF 7w:?jS<[r`//v'8mȒ:'L&Y^R8$ yGpVbav^Sm䂐f|&cGwE"$GyJHkBI"333_&z$uME'.̓42@Fl{\l߸pJ*`%30*&oM(p% Qc 6.K&nܺv¸pE\*+BhPKj1-t3};=m[nHgνϽ4 8xYט2q}gWų[[ɭVmF99sM?n>P[ bW`WvW9-n|<Q8'Nh@ѯ#^#Z" SEN m{n T<+r 5fZ\Z8lͤellly@X*c ;A[- 600q9cc4^ <^ 73gзo3Ȉ)[048J%2^pLY]>@&ZT[ %ӵ5%ðer#3Wz8/H U(;o#?='0-UN7%𢧧GeX,Z hoG>KMma:uo!r8|>E0.Hf (EV+ Q`6j4hzco.1'O}eqvBh5/0niqu K?"5%hD&T:* ɴ.H9ù>8Zb{R`Z۶@2Rp)_yggS /bҰdݲxaԥz\0qeaEXlEd2DAբ4Cxc%F ʾ'>( ttt3NЖs%n o/!u0H 300Nt&x,UOpvT*EZX^ghTx__2;nHT*;4^`TEfZC{Ŀگ!B}NMM5!!~<񺺺 Q"```j!d7m$"(WL?>8r(A.luѶ nώ@;1芁۷n1C} 2@Vxo獙L&J6eYE >y1Gܐञer>Yc8}>뤣Jlyf/ GA?x}ҮZkzz)qx3].7Ok*8.^s1Y`ֺxl/+++i,{ٳg0'k{20;;ˬXםL4d<' >388NG5C[N`:5]&( *KEO.B4_4ऐbM 'jitk5oH$ur<2("P!dU f,[_޿t+V$ Moq<-;VL FlC#96>Z4+$\A$o$]s $T9Y,ɇ&7eL$ cH "N$ fuǩt!.̓Y8tFT~R>F]*Ӹm:tGGaqIsss p2(eq?Вe 1zLK T(a. yWl!e\毞>-,4[[_]PyRǛ#܏~8pf;6K#%;P~mXs"WjDc8K5u|ɑ ]zHOktQUI9:.ģ$5 /' xk1&./ ǒJzGhaG]c f$JQ!qPht_Ld`(*dN[涺}Nf _͑$")^"DK{IMyrR(rИ߶o=vuLivSFWjW$)q-0w MFrUXwN:i6 T*nPTJ\AvAnjA,ɲP WtDT#hO}GX':\Ok{hw*yոs"C-t(2_q3:Aw  զ -xۈ5kft6.h%89mv=QYM)O) ĐrU{5qIp-rth}޹~2Ȇ5b6V1BσYޜ>Y$a<:YϥOrW`44oqt򍬐v\K䂝 nR45Nt6dj%xir\#YFT%4J}J+c)VZ0{\cx1 09 lf+@Ym9-; X}Dn ?p܅XY`{|oĂ2r[C= p;鸣]os0Cj0!U8}u  jnԎ OH/ $9/@ƳFc-qkRa>;?5ŽV9>r;s\Pj"mE;9A^5 o[v +{4p$K.ek<ۭBL)=\BS e%+ch %`k\^_^-YU?51!YI3OY@ŝVuސ2i`|&씍.C/n dNiyL=z<,`!/hƀ̓we p;o- =aSovgCZfʋ겺RmT wd5o|$S+S@>Jm`-锁X`4Ӂ xt~ odsTjn0/Bnx>*N(7hYNxL 0X @ P2PmA3OYHWH{ _YI߫8k5i]`IvN[ԢAeXSDsbUicMB})`+2 p3O2RN6TӠz"OZH5#wcQՠC!BZ 2OWɛ _-1'i$?{-z1 lT0/lw*|^^_*Cb7WWW-epux40bE%$~M [aW¡5/Ν/n:֟ }B8>ѐ0ʔsASMKUb?5>hVsüd^7 xy3JJ$=]#fvR2 ( MA2\ݨOm`)> *r2k8T n8G-^<ɷ Ǭ5E% ra!GYE} FL>O0_=-WǸFHOȃǯ\ )CFO}V g$QRS~}F8 xP)Vj0v)AEoB6{{YĭR!uQ ;vG[ֲ#w8woAU'W\=;yylpdpTp;;u!/Khc/_a38cqf+2;7;C[؁]ѡ3;B}<*/yG5<f;3Y9191`W3J/]R977a*[fmk̼s~/}f"g̊+dsa{}M>lAJ S]NrOCgrArH$U M ID⌍o1f@ ɜ_>}P63 JrEA.:s;QE*,h]ƢoR^ZrCƽ5nָ6`^eSwݲX 6*^A/Y`ͷ w׃wa86^ Tҙ=ܱ uE"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-object.png000066400000000000000000000114451237252063700307540ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZ b +*vHU !MiҦ9cpihp'Xwf<~{B%`1vExZx^ĨKqն,&5~-w}'dD"HjSk~ؖ nɀMU}! ]ŕ}XH1"pAu]wߜPUx@yyHE,@wIA(;  ]g)g ^" 1nsJ"gP[Xɧ_¶[קcػw} AHӷћe;m|OP4Ph4} 3FX|e|k  >o@+W~yܹ7n.xH&PƲ~f-z<S+C80f5׽UT76{ ضVa|Ik]TpYQ㴟nU0p؛ٙ)\t D+e8y~vޏhy9| '4eblp\GB4¡Cqsj r`uz*^fL)ipX!rD[Bv/AKPڞ=!f,Y6 4@f2H4^ABشy+ 姟2Ν;Cj)H: BYBuW\Qcrj{IP-S!6!B2JENO*˄g!g'ìyW1MbaFAT¤puV`DY`'m♒q"rJ-*Nk/Q/CVQy 5tKZfH<@ȌWҕ44MAvo_Wg׀"EHUU$9TlӷΤ☸>ۦi=زIdž I͞={CK<]WVG_}c#אJ)iIT(E,9sf[g)ť%)aɥӴ%b9R|=KKKsʅ %FVgQ. }p'<:ӬCP,ndq}ett"?H}sΧT9y; INp,?z=AjcRP7?*hŤI|@a;>ɫQoIĉlTNN!4X4*MTNzmy ~:JadZ2h4RՊC٬wX]r/Jx~ynݚ;"_,,j=$q~j$/.fq+IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-pem-key.png000066400000000000000000000036351237252063700310570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-perl.png000066400000000000000000000032221237252063700304420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoTUs93s˔NoR,J "(`c|??D /UӖr)- mgڹ3=ǽLw2t$JV>gﳾo}{}񸮋62+M0ǭ\6ܧcu`I\:~@Y^Yn[0£_fU|>a<@lƲkbTde^/f(UjDc1zi>߶̿i@< 3֞Jm7 Cg9=N4&2Pl<@LdZJmm]]rL"'T#H$O4=(0XKuFa> )v3E\˥,H\WKvͦ9we*`S\dj4Mȭh۶M~~٫(8+ ѻk6bQ@@ZZ|10`PL7%8n7I& تZr1"&49 cC*~{o t>DAhFT\PAZöʨLv f(Fa)`;!LuN0 ;LGjHi̝eY 9VsYS]dg<`;u g$++Qf#A)k5*wyU6y ^AeX` yYY.9,#3 'K$UidQDU /Q(Ufwos7D#AJ1>~#'lP]|+J ")@)R@P6k2Sw)V-NN߲^ff(iAfbJX`r'hBξƶ-^, Co@^?6Uaf:Kn.G.p&ƯI7W; +%uE@ p-A>9mmz@ |\ڡ?DDjH[2wdj[W@I^J!3J(dQ:%OLɖ\pѻ^a-~9~TWS!*`cXt!Xgߖ_ <(R͏#q Ɉ =t:#}k\LWX\` <4*6dn^a`װGKHuݹs0 [CRZ^ (eqҖ~]BNΎ sـݩӧO dULk;tvW? $䒱|?E%ógd2O4d$gBYzʈr" 昞Ν?0+ &-n2-hDEŋ(ո-e[\\ ]yϞ={FM7ښcccm\ m-5ƶifx;@yEܝfTmq ^XfO* *z>i?`[th8a7IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-php.png000066400000000000000000000034251237252063700302740ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWilTUf{3әδ{-K R@ق R, hܐDYpCM, iefZ>Ng:73K Ϩ9ᄍ~Y9L&Et$G,QU C }HTu7Tbe^2R)L& ^EYdW 6/z=Ӗf"hD2D~^B0V+~X<C͆4yf# !77yo,A)ݤe7"''' ,tg`T Me P$X$=HYG^{צNʮN@ǪF)D"q X4.Ͱ Ph ʱ0(v(FtubAd2Dco` )őWhBsCxG#"q#J(-wBov)U6━j?Z\cn6(2*<Oc=s8M}Qt2 a%eD45a+}鬒@h8ǐ/GVFOOz=3&Osg@e/]ƸD ߠiDEy%^ LN[~/a%l۵ rBlߺW;/nƎW/Ag+=m z{fmIx5J0z:0YGl_9n鳿@{^:-F}ttqՌu oM?`Gcښ}r PBo0|!{ByDHRϢfCwO;[QHDŸY0 ˹9G4"{A^)RW{\T^$Lp@Ņ gOJ`9t5ݴuKv"%vcv~!7&Vż+,AqX I[6K!BLm'hi=J,^@lpkd,mБ[ JFz0MS)~TW E:Q"@`؋X)6}ohYS lH0Is ߜ:jB)$R}m;v = DbmhllW_A]ԆUّc bXJ?zQ;^*@xn*F=8u bg?ؐxze9U0`T=l\+W.M"0r|r[]hX&(Ƹ-YՅ^3Z[mmm^J?f͈AʤT~R swwQE \iӲ.Y94 ۰ah]\)r<0{JQfn~c(L"Pp802;}Y;-˗?*ͣ4_H$&NS '(krN:HHvSv"]DN~OBUHd >6_ϹF썇IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-plasma.png000066400000000000000000000117141237252063700307620ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD X)IDATx͙ pTU}f& $B"8e4N#ACM)( Ű( 8Ą%aIط N~j*/53T}U}~?A-<ܯ~0kVhSeKj2detHh2B 1L/J# #!Q| 3J 2CDޤ@DN򆈼D@@DEˠ"!"݇j<"$Q1KbyMަ|~Ee^W 9㧿S=\r磝t/M٧yA-M4, X=hbWXޕNҝNoFH[f\pc*] IR/IvOY//~6" l}sup7+|qiu"NeRgKXZ +`W X$= ztL3D{ GW7 yROu@EzD|S9lǢ%w (`N N%o~yum Up+fs},켫ߡs $߷ %.lB+1>gZ۰_;&_dB;#u{ckK!fb:`1̶k=+$A؞u^O]]/#hG]]_Y+;Ŵ7ŠQb:喝"fSv"uiFo\yͶD[> xl8.{/~Rƭ ,jHoeb3!iֆE  jDA!˔̺]nRjڄI֒[8hnfDԐR rKPZ~^Q={F"SfՌv? ~5;"q">>=.O<}2Μ2q}d=FybחB$?v \p=HwcՌj$"`8V^9b:ډTF,r]Z(c} ~jL iw\rI`4[tq?6):8?a[%eUhv] f C -zM\k<^zrCw^,7Uqӭ)q?&EA֙SDdXڅ|A;vru"]mkpg_+0}ƚLU/^_NxmH~J~wJS2+~=B\KAWIט/t¡Ֆ_GMY-w1Qڢt >/#)fKMq?UԂ}M F?;>~fk4rHiLX=« ||Lo"b/l3*w|( ?ڪOA>܋4oq_u'Oep@@mxԓ ǵ6vu*zPrX.a] {p8?K i3FٕFΦ׵F .U6#}nihߠWŦ>9^/a)θ|M ]5`j]Bցo+"ggt0fܿb)'2H1чӧ`gP.W+d,k'l0K@!F!4f"RE q9wvD93OEG[3MGG/JM^۸ZAGMcԟe#~ o?uȞv{dgD{!S"DF|(˨v+S~R-"Uv iZ(Jr }%>w_C)SP-EMϻWh䏻sawn pm_(⾁na)`ޗ"V`&s_(DJFbuCyi< !oy oDYz"»`j ILz$8NmקXM9[c䝸ȬK,N]C1|&Z8J vaH~ &e\ѮCGR5͝6֪Տh-vi4~~~TY[צ.`yr6D M sO31eBi/@za*`(!uC{?;-n>s vSkGE `2ֵK<|/z-tDg;fT$Ǻ?uw2]>'JrѦM\߆f{kk,PM:9:^ٝ x򆈵xT! ȸ^}"m9W(J RnyHQ^U^p=LAqloQ]~} 4jh'|S \MYytZK/_ͫʳ5z4'*':'6jQsS)1&\+4?<-slK#y֩8Νhg4ϖ} B' qers5V)SrEι|6v*To{()K~Oq'Ź=|lҵQ%s5L,6; ߙblbbGlDttss$P.B`R tu:TN^ILUCaZq^+[4Zs7.r~'mK.<_w+EC XiBLP%;oDFQǨ]>w8MGB`4vH6즞Q[;]>>CQ@ _"Knn__F{zڥfv}6Kz(PqE3Wd.Ͼx,8Xcl3SZioPWg 588pv; y"PH&VwFH*BUM{U_U-MHXfZfX89|.3ygQgpvµ{'t{zBO Dt4Ǿ~&[/7p%_9ǔpW+y!!T}K{Q5^B}!\±JN5e[xo3Rdraqۛ<6O8yd0Oyw!2$][n~+:`1׍q#Z x6C>&b`!;GBxqyZQ#N_z{[6s~bn@npnG76lh}/m?N<ƴBџk/g rM'55:e֛a}"5k׌Ѭ"  ]Qw *Mh"*DBvX!i"f" %sBlL;/W۶vv^ZaզUL˝@og! lS_Yܘ%DR o^!yWd 3? C') ~M$"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-python-bytecode.png000066400000000000000000000114451237252063700326230ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZ@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-rpm.png000066400000000000000000000030671237252063700303050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lUΜn[b)ZlU|@DH$%45B">hbPmPPnQFMBJt\ϙ vh*2! p(p!(#×(]3UMٖW}t$l,q,v"4 Plvz'>qE;u<ՕdA6ڦ][Y2x|6_u[b(roYcCFuzdL8v>^ LA#)ʉ SOWghP@rH2lہx!R1qP(,]U|oZfru17{1s kѼ\D<k$VﻅR5MG\T ?" +Kȍi |Qgbr 6&q3 3y苦?fSHP fD  㚚,@SLmcf)/=ut0{o򦅙Y ã&{°cIS0=[/ |u,5% 7Ef k/=%ƱdM(IVXY >pXu*l:$M]GP@ `L̠r"E| =a]Š Y"eDM[ Tt,[4C#6X2O*Q,ۊΝGuH.C7I$"pfl vP_lіe6ᅕKBt?NdY|(t啋Ey2K.C:Mv\ih_ӆIi3g7t]/#eb\܈D33Al`?zu]6:2*m)8 *'+h6<ʦ"S h<~iwׄƼk% H%GDE1I LnCL.&JB\mt_wNxYbq "(N[.l`YT>R\LxȽ ,& PN1z0 $X O(:G"%#vWpVCfqC AbA98dL&!קyA|x 0j-Gx D>EytIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-ruby.png000066400000000000000000000032621237252063700304650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org</IDATxڵKlW~ǞW'f E@ JtB*HD.j) $*!eE!PgA$13wΗL<3̱swZsh 4tMK؅s< מѠH <~r= Î"! }{qrv? #(ƒ H ǒOtElggfU: "zȏ靍;I H!ccc?`tt*ri=WBJz}H%tK.Y^^&,]eownZ8F nhj4 0c Fq<@\?33c=@$FCZb_d]dq|6*u ^|/ #XrTɷOZm-jwi`۪p_Nvb"ՆynJj06en]\$\\8حq?q'Ȅ5y#O( ɡ6w{@v4yƍ?ˆ$qʄXJ\&吮 zכd <63FyyVPg9Y*xؐ%&C m~!Gs8 :BaS ʽ |"{us<6) 8G'~) # Ƿ-4^2DF4lw``+6DkdV굗)}uf&7K&V$9B#IpjLg_tJDbNm }x! YI$$v"q@DHBW,JNX'u6|bF*y%Ye0ȳVBDJAmD06IccQ {ShxH5FzgbX%4u#]{n̙erD{>29Z,P|ѳ%K4;adsk@t:ߧy.ĵ8v_0X/Rhm3ޯVVa>Qn߾yҥ瀲z[LV jffT.lpid7uW e`} mR.陞.۝!"0X,tZ+jaaaʕ+_nVPkRf~hm5677nF^1w^zls8gΜM=Zv8mlmmز_|ZPgi8^z=msfgg 27N4Ly昕0NJi !!p|W@Lg+=Cчlb_*@d>csPpIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-sharedlib.png000066400000000000000000000114451237252063700314430ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuC@&$!bQ H@&A!psKA@pDEq`K4"3HPy.!0$2d}4Re<-^[_uٻ9ktw?Էu?GkB !g`kкA'tLOxgKu+ֈcPt1@`dx0?V; x;2f0 zh@XP42k_1 N8sEy]UT_.I\y>ʳ-ґ."FtFw99g+_55.4,sD ~8]KXDyY pN8O#@i-fbwi %1@"=Cϰ&a6 0fL0b(Ihzn\mun Vla*gAqۑBsJzQ=@XJM(*[RґՓS14`d@ z>x2y̰h2Mf-FzUIV5"q*Rp%VCIS>>y+6ċwTpcTD]8e.8E$(S!,pZ@R(TGkyzޗpezjd2@\>U›u8~`#pGs~p4E>ݼZTtkBá'3ՏUz|ajt@1 g!)5 zPnP Ű>U PX@: 2`exp}€B08DSh W[n_dfa7 p8 Pdɇ|;mT#k6՟LdPV@ ևɂD+AJĸ K< himI=YS_ phLA4ge*CVeNAhcY_I4yvCpWVաG;TGt5l(B9*Yy#-jB &P Ѩ.,Mt@{]eX IHf70Hpi˓&aљI-n<5$UPZOVr`"@xn+b 7B|z8( <Ȅ"/8- Ov!X{3f<)%e" 5e@Fjfq~ p {a@F/)!)4eǽ ҝr_l< I ) p?iZeJ8T &ژxlj~X&ʉMqἱ00l0lq2[ H<&OlhPgh(7ie+P84T o{] `_ kqSMீ9MMkHK ZD;l$;ͳEg <6{|t>ԛc6dj鴎Oi?iV*G"IHR>OciaF#&.Wo ÿ +oŀ>I?BY^ 7:v8lǁe˒xpgA='\l_Y2oûY^ڜu3 C (J @w:|~p h3PNZ[)%so |j2cyUOxHbHah,۰a9iZ@fWA;Jp`4h9|{a? [خfi5j78[M|]cGM;FŴD:@Z#BSk(Y`[iKIsΰ&YL1޵ltgU.~@ۗC@CUcPV1؏4lTz@×gg֮q<.Pe-Ϊq)yMG/MyE^U/Jr?(r9`R7`,-+q>|fF;?!>ÅQh•/XcSLMŀ^Fiʊ=z'rYk6^-yL<,ηG- <}IlUO *[2ӎi?zϻ0J-Ufi씘GB{F<]J5 LCK;6n^mЩ!m¦8 '$̂벴˞X_'Diy*#i2l9 8 hex#z)O)|%i%%큲7KQ85w*v5M-i=\qw. +9Swԏ(oSl j@1ԛUw*Kkkp7vA[$J$r"ZУxo$*/-aMWܫ+tՑaT7ٽ.ht1m{w )0N S(zPMTOs}}&9.U11 xL64ki[@ߎA_D:^JX=00/nage 6Y UxpaeX qZOhPm87v\^ҍy3."}rGqy-;i+w:S}^}VD%h.23xa_ng<sˀ@[sg+w;/̡/_^ˀƂ̛i\>ÉV/n X]1pgOr[w0-nyMDuثFw:.;"lx*JBK\*Zw +LP/M l]XIlj@ȎK:ynu^TwB7db#W+c>zc(`^ Ƥ~vAE;{UOd!PӬcX75]oʶMtDK.^;1 haPtPDCP#Jt_6vT @tEbD0`H7lY'jMMYPllpuLж¢Y<-'lQøvYwPwMԆ=TVwV疋ŗ?Π Qh1Fhb!Jy֯9.zTc)FQoD\l xϑ +Z6ɺA]os7s7->hT~KJH;3c嵕u+G%'$VXkec[!HlθXWGT'U'YZ/YU*5"l?؎؎aIgPC!h k -}M!73 Q]Δ Q^U\"3hU֚ʦRj!64{Ӭ×+~8(015à ={.+О=,D HX% CN@Q@,K-Uu6M]K )yrjf~.(9ÜVץM_1_H}f݌ˋ˽yhM5k"%_}I4fD FwhHHt^wrP%m @¤Nb&Bbdnjoͯ皟*Uv‰'I-$^'z~ӑ#fD7>epE 92dcϬZRfh 8ppb;,jKZuDU$V{[z96KL@IzIfIe֊CYMjFvB$!6|x߽ g;:v#OAKtF%xе8֐CR'ި3,jl#ב+'$ k{9ɽZ/{.l)q"byv#;&;^&nU⭛HĸrD%*Υ7OjOa~vX5%̦ D4 CO'V&EJ i eJ8$eE(kg'mSǔkYe˂>}:՘6CE#~uуm3$($Z&Msikڃo1iZhZZO4R& ɢڐ a{Ff3J{{~~CN!S? ҀSBi??C)@9L%*?N@YVasX !E9#1K"5bvc (xUJRP{Bq"@WǏ199\EdrFn}d{‚fvR|jj Lpxx8L1uy\#c|k/~ p}4&zZ6Ȁ+WK899JB$ w9 Q86ӹc`qm[rW *h4p̾7oc>˨=qnPf#Q> h<(sدSgRW˗~9\'D㽽=0~@;ݝ5?.Bxe_C? ^w]_ؑ@dg]@ +OO6 FqgW@mǯ ߗwS{aTĄ|lszȃA ~B7j? P0wapZa||VJemnn-4x#.ȍr[r~{/k fff/T8(}BZ .-*Iۿ]`&¢QȧEWҮXdYسlPB𽈯h:T$)GInC/J;VP1٩T*/D| Ni aGXnK.&L?<3 IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-shockwave-flash.png000066400000000000000000000027751237252063700326010ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-siag.png000066400000000000000000000107501237252063700304270ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XEIDATx}tUt'% 1 YE *"2*( ‹DA{=}ggYsr~'[Tխd'd2f.sFAス6 ۴}b갎\#>@$@_l"~@<+~080'͐4 So(*(5Y۬ԀDq2Q鿻;X꼲 d+Wm6+FEܠ//yJ%3ͥ';և֧t?uxљТgy-;ͭyKjAw[puv8qa`ڢ"jF8%?@h;?7] !S,?f 5^ҽtHKO7cV'Dg 7CkfB ..;2}?&N$B'݂"C}Ci7Gu-"B[G`/Ade}əg&@_w&G}d_g]lCC&942H,O,K,?br?՟ JWJOM2u:H 5[UE_wNBͲV zcZS>=. f;P.o|w77 ܅Bp8O9R!-ܳݳMws3㇜}>o}} agP07S)p({_*&8{@Q; `{=̳uMxcnioA eX=-Xh?:P 3?LH:c-aG 1\/bspA#`,F3FVkkPxR$7iB*@w]Ns9kLc9f|0 m?) >H~OnXB5-L># @5( þɾ :8P=3vc/tME v0%Œ_#LP@l0a&fv!/3^L +/񩁟bH,M,I,J3Q@|0Ra/fUa2,M?D@BaԯPBjuC 4  (,ZZ8͜9}}}''nND~An&z +@&7 v dH~RM:X v[ƈ@d_ͭvV;Gۋu2O~Sܛ pW 3Bũy瀀Խ*Lvˌp28Oj3s;Ýẑ Br=69p~ǜ98Ya}&} X=P%RBvx ALG$ocxlTc2Zhc]`udk"?=QA=EO ja\P{XmW@g ~w;ڷfeG|۷;/&^P@ja2S[00\z7)LP09_w95#jLkH#~s+cST \k=}mt&oJ@+`mH{$SS^/v  vlaU$K$2ĩ V(_ޣwPB*UtoNϛlŎ]+. K]kin/|$uk5?x~2%@;r+V;`_hvaۅS ; ZH@!p 3b \j 4TBYAOe5$.myi}υLJo zY_]7:ߏ2N=g(~zɅ1{uW7V}=9Mssk#KpHT@z n`=,|[>~  [呿@݋2 [J_/9{R˂ vmwѸq:oU->nkoX;``rCt낮֥V ~ 3Dжm/F*rr俵 8*=W@|J8J@@jxʨ 4jY+WSn]rZMo.&wwI?~glܾd'ǿM.5&[`A0/Gʳ9c(d5W2^ăeb }yqjg"&Bo-j̻A7S^o}l5qo{>x]t_p3Q4M.|Ԝ_t2dwݺƺTr^r2cߎWtB=\K!P_)5)3)-MF?4Ǐw_VV+jb52$ϪG.]93 P0K.M %h~Lw[5rCtnmSxNjMUz>\ٵ6Zqf y~dONVC0JWUpZV~%lWβyG6,\ƂKO@/J'DZ%M$'yQk_"[(#+w|㳽{p,-t:Y4 ҙǙihSrQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-tarz.png000066400000000000000000000034521237252063700304650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-tgif.png000066400000000000000000000025171237252063700304370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵoEǿÎc;8v'o F E IR!P)\ʿ7np+AP )@HB4Mm8u굳kv6YkD꓾z3~޼7?6eY7Idrj&1MI}B.NJ< lH:Tp ؾwou;"HӶܑ($ n@7j#Y pý l4ؖHFyjaT+y=3 /˼q^<~}Ýw]Lm 5TUa304k ;{EA $!53muy b |`p4V̾w-?$)8nؾU$AK!Sŝ_^6Vk(K{k-!Rm- T:c1ʈri_(ݰmyH JVt]g W J$S!8{،cF_ZwrS]5Ryj?lArK `Dk%t=}NL؋ %2@X G˸t'pn;HБQ![D7ÕBzh;s%x>& fnZT=^p/L5'-|_.׫w'C8J_ZuRn `BMY&ƭk%}|ϟM#oMp wmؑ2 7ߑgc(~b2=xL-7~/Uq\]E؁{8 &3`;~ݖzhl4svXXX:+LloUU H B|E",MMM ǾeF+oy ^{?`XiXhj\4 l? CI-89ՎSڝg6s,7QTX L:ER"qo3ܞX ڢ Niߜycgg o~ f,g9\&C%`Ҿ499*oCGYH ٻn-//_%iK>pS\?3H$C>Y%xeIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-trash.png000066400000000000000000000032641237252063700306270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<1IDATxڭWklTEnmKKxqQSi 4(1@SLԘQ!#"򐠩6AK)hv˾ ۭp._gf2wΜs^0 ( #ɚqN1'3!ެ{ 16f-,~ml. w}4K 0 AVZ$8%$4JsI.CoG hsG,!ITLI؏,XT%x"吞+9^3R`6%`{y9Q阇4!F`S<^D60]3_AEb\noX>4 X WwU#~o$$9XbkZ\x~NT3Nt%TaQV ^t KIE&cisWh~|ux~S&a7P?bFb#I# 1Jad26 a-C-n1.`")Bf)ȕb`_ kyN1ҝB0Bj-8/RNBR Ŧw7w̚]p/!dya+Q{Zf2b8ObuMCeNXF LJՠ>Y':ӹJ EvGȷR40B]?V5(s?~F9KȱH2g4Z@wϕTg !w%}uB$"z ǺjqxC_/{A4S RkI; ΅{t[[8i6 hKtLQYbF{kD)_bŒ@(/B{OƊHFKbx?'/_S4Cwc`xlB<~/.8J<"X ETD:Eb0bCE린)("n6^^i6NI2PCF:uS'cp؃ˮoWPV<"k$J]$\qtBA\r5Wo[vH" M M7=W"omQw<-UXl yדk9fܯYm Gط*ݾ<xf_GOnx<=sm3L)t-~ IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-troff-man.png000066400000000000000000000022161237252063700313730ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org< IDATxڵWMkF=Hm^^RPmV!t -$RJVǦPڟMdh.J_ea*  ιgxd( Q,Ϙ5HLD;~N,#96?IM&pǶY)ҵVi1("X?GQiQʜjR}p%0,CRh0djQXxq` PPm5ڠ<` 4 1  " z@]h"d_t^I$`dB%+x>Vx' K*dUSڊ 8B>Hha hǞ(`)"X"Pل.Q@ Cw -7B` lL¹eD zbLhs ,yxԌ@i1H d*7z ;'BSibR.!Qbh4nN8C\vn瀐d6QpKzP>?)azfc{{xa ],s>( |" NȒWx>c4o6xxxȫxH))JHW&3~NGd+B=yY{u||| ]ل3a$,2L!ߜ.$5; dk& A2 ! }QJ)熀*oLp_{xA{qY҄?uhyqIw+ּ9Z>e?3+Yzzz_ *Q\^^KT7v{#xIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-tzo.png000066400000000000000000000034521237252063700303210ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-wmf.png000066400000000000000000000020511237252063700302700ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-zerosize.png000066400000000000000000000013641237252063700313570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<qIDATxڵAo1zCО{(!Nmo (BFTv3V&kE"dɌ1e@z+g4ߤ?݃Z>EYal?<o$a #(EYaNJ9wk--=DI cE4־ Dv{j{ouR[Pʲ>1#AYZ\.nj0Nǽ^? w,O}aX``>c4T+07)ЪnFfikLS#b8~? >6>3 sOh 8q۽㩝׍\)?"};ΧL&/`_R#x{ysKxLkfIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-x-zoo.png000066400000000000000000000034521237252063700303140ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-xhtml+xml.png000066400000000000000000000026651237252063700311750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<2IDATxڵoe9lwm#RP%FJ4"^(M^y\z?`4zxgT6RGj[3;ϯN44Ml{;;]]A _j׀Z1B*H/#+J^%B .FGC4+@7Pñl% SUC(+<Q~=&(bD̥V$sN Y$q~1Cͷ@P`pb{E M:Yc'%Q "G!%_z,3ZuIk%lWxIt];'~D|zǛ%wl3y*/mh斘)V5%E//Y=h: ʷsܓ'UIᦆ,K+L_x۟8 'џտ&f)v~,V.ZU.B7ks'|j]%N@h]F,M N[‘/*P@R.0ٹ#JW8G+_A/I MRoE[0xL&er1rBa _BhR))"/j_zO7T0-d*cEee~v&/@8L73ynu ye٢eu)Kᬦ0\ݣ,yGɼւ"PYҝm}A͍9~.VRRpbL >CSen]r|l*Wn8nG+P{ juf[xSs;f Tg=\G` iqg>g_* ꃪ#'s@C(i7,yLoFZS-7+ʱZWyL<B<2kV>2@lBiYy79™へ G6ǥ4s!||!jk2xf uV}4DBR4m'B Ds8@,[e"B ٚK3Ty277,\.NS/@<5{wʃMbjj62OH`lԂD0@B r1M3{WBƆ!%> [qi|gg{KKK M۶Wq~M|9OFrN: +_@A%  iX 8}E`B$.0aƫlf'O 4'GJIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-xml.png000066400000000000000000000021661237252063700300410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵVMlD}{IDZ*B@" !Ís{ʱ-QAphZHYIXdƛ5ifǣ}kG))TQ6nz?oט+AQ g}nNJ Yp]RE3mm@Ïa'bBhsŝG^>fGcM#}l&#nžnINT${4` H3My%`q)eP|qg%wvs-b-L̼l]a{30 rі4 8^g݄܆8vH]"<e[ \Ft{@3 PBx}hl; J=@Jxy0" Ϟ@(_xSOJ`_"0<9C%NC\opЁ)8;֍w.} !_; xg!8҅3`hQ**YxGhC8x_G`g[6::i-$v2^rWxqZXXKoC(f3ljXJVY.O?(b܎׺iIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-xsd.png000066400000000000000000000033731237252063700300400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<xIDATxڵ[lgw9ilYuk-kGĶT-J׍ .Av*'1 i&RGiLӒl9:cI68vbr2+[i{?!RB hW>eׁ8B@Vi 0%ǶADe{Q%4@*pN$> .U *PuMqXo`. Qk-Hj\ZV|u E7.x{LNtnᏑLn\)^넦 `rmUǙLsd7h0igo>$5v}a'jDWq睭>ϗ\>ywخON#>yB0uORR35Ube񱱱3g|yaaX\)^ WRʕ Dʶ>}eBx=(J{zzN+;_@iH)ke^qLӔǎ0,Up@ p?  8z<`mU9_$ kIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-xslt+xml.png000066400000000000000000000033731237252063700310300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<xIDATxڵ[lgw9ilYuk-kGĶT-J׍ .Av*'1 i&RGiLӒl9:cI68vbr2+[i{?!RB hW>eׁ8B@Vi 0%ǶADe{Q%4@*pN$> .U *PuMqXo`. Qk-Hj\ZV|u E7.x{LNtnᏑLn\)^넦 `rmUǙLsd7h0igo>$5v}a'jDWq睭>ϗ\>ywخON#>yB0uORR35Ube񱱱3g|yaaX\)^ WRʕ Dʶ>}eBx=(J{zzN+;_@iH)ke^qLӔǎ0,Up@ p?  8z<`mU9_$ kIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/application-zip.png000066400000000000000000000034521237252063700300420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWo\w=5sgy:c{VREPAXIAR6 BbH/VHe*U%g3sΝO4)s};q^( .*S'bf'z!sX!0Fy #(>ʬYCA!ɼ]'Џ5~!H X &z`> ARG) =QA ]h>9uǧg16}<荁R !H^}&;mx4\O3Գ(Q(O8wsU<#rmVa# A L.lA>7ibS3Nv. `C6wp-O5tHc;IH4RSǸoG>WZGkop]/D`w{ w815S'0]m,|^!b^0ntql8&˸gXaɬpC,[ 1}e[!xo03; ?? ѢZ# ?a %4 bx0u4ZK$&^wavۘ7PD6b:&fz(/Jh5h*Ѐ(` H8Uf&Њrhs7M &c!a D!IhJi[살<ҙ4y_aT1B~c,wlP&آ_ _/0aK?KbQW(Jciiiʕ+V = DܦTfYW¡Jw߻r8TZucc>ܽ~,;|h5} ' Qβ:2*9-tS7n|]rHs KSdeD;( ȍI,;!O y}qqk aߟU-H2"P8Gs4;wq< ]OMN˗/`;C̔?drnK9S-+| rYR\[7<" ƨBfmz|Ig13.>2~!5Lؗ>1qJj2&IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-aac.png000066400000000000000000000027151237252063700265630ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-ac3.png000066400000000000000000000024711237252063700265040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<@PLTE  rx"')-:#@?F678IDATxeAk@즻jk(-z&?xxś?SPҳ/wVA(JvtwIf٤N7Bx_2! cH]d=%)@^YN@5R Q@ V'(e= sDq&v8} Q@!PK@?<B=H@@#( *y0v׀n1yboUt(RrnOAYnP]_u8& `]$Gq=9Y|mȈ3֬|3Hsۄ˂fY ZV,wW&2I/<nq2h7s$qu7ı 6u9ݷ/ QZsUӸTVNwcMD Ơgf]u{}; |4c~Ba PD9&/ʦ'nIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-basic.png000066400000000000000000000027151237252063700271200ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-midi.png000066400000000000000000000023761237252063700267640ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<{IDATxڵWMoU=36hD I$]d(B ! EeEfb nPDQJ"S$ 3v7s޽۶!PYv )Hrc!?&o+/Y@Y(I=+EG 8ї~BhO.&)| wvMe[dkPpқN5]sv~_uK߿g^DL;0 |< rY+H$9_ ",򽆗nìp{( N_3z`}Y/UջR&x:^p8 > `Iʦn# #,Qř~>6,`nn+++F*X,5LNN"NcbbΉ8]~}}|NPh2>ݸ"y4׊<2E@V*'zMm̓D#i^i߿ #@2p81k2̌L&8HU 9b(777Q՜:#ν.}A*eeHprr#iox /m3f% 3CP(w޸'Imii}1wWWtwI03$)B|RGAn ."f& 5sLz@lF~j܄<\,6Dc'gggz7_CRXs*"9$OAIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-mp4.png000066400000000000000000000027151237252063700265370ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-mpeg.png000066400000000000000000000027151237252063700267670ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-prs.sid.png000066400000000000000000000023761237252063700274240ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<{IDATxڵWMoU=36hD I$]d(B ! EeEfb nPDQJ"S$ 3v7s޽۶!PYv )Hrc!?&o+/Y@Y(I=+EG 8ї~BhO.&)| wvMe[dkPpқN5]sv~_uK߿g^DL;0 |< rY+H$9_ ",򽆗nìp{( N_3z`}Y/UջR&x:^p8 > `Iʦn# #,Qř~>6,`nn+++F*X,5LNN"NcbbΉ8]~}}|NPh2>ݸ"y4׊<2E@V*'zMm̓D#i^i߿ #@2p81k2̌L&8HU 9b(777Q՜:#ν.}A*eeHprr#iox /m3f% 3CP(w޸'Imii}1wWWtwI03$)B|RGAn ."f& 5sLz@lF~j܄<\,6Dc'gggz7_CRXs*"9$OAIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-vnd.rn-realaudio.png000066400000000000000000000027151237252063700312070ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-vnd.rn-realvideo.png000066400000000000000000000027751237252063700312220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-adpcm.png000066400000000000000000000125701237252063700273700ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-aiff.png000066400000000000000000000125701237252063700272110ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-flac+ogg.png000066400000000000000000000027151237252063700277610ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-flac.png000066400000000000000000000027641237252063700272150ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k [ {    !"$&'%() )*!-"."."/#3166848!9">;?@3EEIDLELEP>P&RRSLTHUNVAWIW'Z0^N_U`Wg\nnoaoUqksTwcwfxdxb{W}ikjƊwɐ˒ϦϾչా׻{v'tRNS $'(+/189::;<>?F67`IDATxeMkQsLL,IR!VeqB.ܸp%#HK.nqѪP+*R*Kivd3;;p/s /K`%HrwbY`DPC_ݐ;=B&LR+ҹbs@) !L0c\( RR\QݑrhJd`rtZv%J3}iY7tɗ }P0 D@hazAz7ՠqRq`ps}cgϺ"{q3chV֊bZ}8ZCor aL)* RO1 'ڙL@de̒ wb Ѕ^ GZk= jw5dz=_!1v2&Sfk,zk4ޘg \#]KX)7WqTü1_33?Gf~x%JP6;Q$=7L-SxFBnC* e@FS{uI~)}8~z9^JNGW\]m1SFWz\RX x$%H< laX^xFi:0N/Xb(IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-generic.png000066400000000000000000000027151237252063700277200ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-matroska.png000066400000000000000000000027151237252063700301250ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-mod.png000066400000000000000000000027151237252063700270630ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-monkey.png000066400000000000000000000027641237252063700276120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k [ {    !"$&'%() )*!-"."."/#3166848!9">;?@3EEIDLELEP>P&RRSLTHUNVAWIW'Z0^N_U`Wg\nnoaoUqksTwcwfxdxb{W}ikjƊwɐ˒ϦϾչా׻{v'tRNS $'(+/189::;<>?F67`IDATxeMkQsLL,IR!VeqB.ܸp%#HK.nqѪP+*R*Kivd3;;p/s /K`%HrwbY`DPC_ݐ;=B&LR+ҹbs@) !L0c\( RR\QݑrhJd`rtZv%J3}iY7tɗ }P0 D@hazAz7ՠqRq`ps}cgϺ"{q3chV֊bZ}8ZCor aL)* RO1 'ڙL@de̒ wb Ѕ^ GZk= jw5dz=_!1v2&Sfk,zk4ޘg \#]KX)7WqTü1_33?Gf~x%JP6;Q$=7L-SxFBnC* e@FS{uI~)}8~z9^JNGW\]m1SFWz\RX x$%H< laX^xFi:0N/Xb(IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-mp2.png000066400000000000000000000027151237252063700270020ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-mpegurl.png000066400000000000000000000027151237252063700277570ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-ms-asx.png000066400000000000000000000027151237252063700275140ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-ms-wma.png000066400000000000000000000027151237252063700275050ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-musepack.png000066400000000000000000000027151237252063700301140ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-pn-realaudio-plugin.png000066400000000000000000000027151237252063700321600ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-scpls.png000066400000000000000000000027151237252063700274300ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE opUX niy  #%&((+0%1 1225557&99:t6;-;>,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-speex+ogg.png000066400000000000000000000027721237252063700302030ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE   !# $!!%%%&##&&&'''(((***+++---/,,///111444665666888999<::<<<@@@AAAGEEGGGHHHJGGLLKMMMOOOSQQTRRTTTVTTVVVWWWXYWYWWZZZ[\Z]]\]]]]^\__^``^baabbbecceeeggghigiiikkkmmmooopqpqppsrrssstutvwwwwwxxwyyyzzyz{y{{{"'tRNS $'(+/189::;<>?F67WIDATxeMhA{3IK,m F EHA֋7ҫ^{= jA/E{hA"P$iiuwٝq߬ɦ,7${h!nBWؗ$AD&Syǡ(R 9: "!W zz݁Y`rz_$2.H} hn%=Fd`" W+9?x vyV !ܣ\}8'/]: xpi,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/audio-x-wav.png000066400000000000000000000125701237252063700271010ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxYgtG=QҌJMlc6$bH6`X 6A,22HIH(¤z_i-w8ΜꮾuwCM`^6LVְ2Dw8F-yw7y[~G}^1(U wP߶}ھOWgl/-_]7±twb/ vt'7dit9vnc*ȥ4 GX2K&jiZ8 /aw]/ #x7,+d]  @wcD7P{3{ҧ÷3..ɗ3{~Z~Jś7b6ceeo/<{i>X_SG$3kHWU;Z)OjSmT(ݑ9;;c}'>"yg/-(xG* '4fDw";"ȕI|vpEi1%ܞsWu_)JKw3wC:9n``ுip,SX,DZάvwqJ@dJ2&ȱeY/Qpd6ϖƩ<=AGyE(`j:!;}% ץdqFH\_C;kl;Xd3#~ky ц&J `n6#ou R ܀y_TvTfL٦ަtZ)@N~߀G.uX][ﲧ xz99!V-@ts{ZAIiXlED\00}kَB?l=M&A>nh7(MI}4Ln}^ ;_%r,#y0q&߻R!V  "pSC+-~ |_YFdg\iyy/o˿RH_^37OpĺE4vWP sMGdHɹZ1c9`xt9TPP$@Ԓ*~VH+uko&HVE{ҡҰkk ZސTIƼL{[EʪCXZZ+?Ntݦ]Nl]֟VگѳetXzCtەV4W !fOv{Q9V~6iPcCdd%eUA僺lCm x<*LܡSQC;aa,f\]1F/%l|$DбSd rw<"8GgCf\1N^:t 4=_׾bDJ)_=Vw69Ԭ)VT3ﯮA;Ru=I.k3_Tc~uuRH'29Xp`=RQ[,c~-kKDhJ[<|_ %2tOсM@ '! 0jlܦ ';54 ̬\8/Ul]nW vjK% 3y!L״x-]uLWxO̡$~HwEfmm.zy+8=;I\g#ۏ+"MMw`T1x׽!^_K"XXIwS2%p9՜ϯW)ZUZ¾'k`=]+w9,3,) T& u3a im[Puz67D1AP '"Ʌ M9TwM(ԅ",4`A^;%Wgձ7pgT|`ADպW 3eLHQoV}[[Z>ޱ,ە|"f &dΘ. ^KC|P ²beDMz6fM".pѠK h*12eKy*Űl5 4E"`POK)nTUCf4-5}>5D}U wuDȒ `Gf =Ur(7Tƺ*5jD|6'vx ]7}񽉌H`G#W98:*FI0ѼǼ<)W_3%Rػ ,to3 fƃtF(u~a~Ļ@JppYIj@katE`yp6s ( ͟K#v 4h!x^^%?[ظ*q} }-} "g`9]PV0|heDj`?299\/CQ̓A_ 9WQgf>Q='[[[n D<獑FsTXHza<<OÀϬ# gϵY0 M`PO^,OyVqτt?՗hja>m j|M%}}_P1C~+).EFfZ~)@v=lu++%@ۧՠXH?Yfc2MpPqKl$ב2vt2L/g$/Fe>:a04zF|\VBJdvDd=ZW]@RJo B,t2v}t8*^TSddx=ؗ2Zk \98Sx銰QcLԢ?jq$+2%ko')S\FS >mI}YDI30}\U;gn$jLc['Dc'YJ !n1-ĔJA7'TiG8:hϷ^[/P_KS[3iܑp8CК7񭚾|0t9yDDƃLw{URgE^d"d1=#֞GB^7 t[DҷY)^K~/Y'Q^|+b,V1Ce-UomߖMax;]GHWԼHe&мj˶<='j_Mjv.s!"6weE#,^"jtQՆ@PRnO?:h\/Ȅ1j~ԟdB34Nnqn\+y-yuΕEit~:hf6lq#z16wMSi{FjUf tNpm7o%Jna%RĠ/ P2Kg~Z#<.#%<."`n*JqM@I/ب;w82>wz++xe3/ML Rkp5/@:/˳EbkqGQϢҢ[vKO"Y T%GW S HTW;ssssjwn#vo{k}z (%~5 ^Y+xe${I;;`ɀ3EEވ` z*߮|$gz9S0z"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/encrypted.png000066400000000000000000000036351237252063700267370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoe~ڵ[vݘ8w#DaN@&$ߕA!/44˘ ҭou>ɯq!mssRbp1K?mqeءkAlIv =?f,b|%[UY%=7ZHFdUލ߿OXɣ38p%q ]fK!VW`qy. ss$])b(<ގ&qn||+(bJFG ?y=Dj+ʐJr4?YCa">| vB4݄7ڏw}t7ߐ48qBJ{ڃ㨫% H$7,>۷w!cP^VNxa+?rvtvb``===\>e(9NpH#)++C3E,Ip.\DSS.7@s )i??$Br0<?޾}6e9]tIaqigz.]rC:Qhii=Dn(q=4Hv$ t3:<,X;U9Ž{8Q}j t ?եt85MB?A>µ嗥Ze>PR%FT '8ٶ[5&`PHw]{Q5bW}ccTH;Dyѵk'Q*SYY:w'Ajd,c;- i!h}]=j(MB?*WqÁ{}`V?o9[鱜 ҘсJt<+%̔y%m:6T[TnO尒>7匘^r6p4? ȯ LO$l;∮q?W8jÇ)jKjaUM/9YsIlHVWUFGG߿OӴ[*ܝ0%TY2r `*N/?=zS~ڍ"ds@9㤺ı&1uJ@_K)woIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-bmp.png000066400000000000000000000030321237252063700265670ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-cgm.png000066400000000000000000000030321237252063700265570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-fax-g3.png000066400000000000000000000030321237252063700270760ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-gif.png000066400000000000000000000030321237252063700265560ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-jp2.png000066400000000000000000000030321237252063700265040ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-jpeg.png000066400000000000000000000030321237252063700267360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-png.png000066400000000000000000000030321237252063700265750ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-svg+xml-compressed.png000066400000000000000000000033651237252063700315570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<rIDATxڵ[le3ve)[l)\M(>@Л&M4/&F}%>hb|0'1x kmD (x[vCtw;;lu%(8K?fiz @چp;K*yp@‚D"{ Y2jn1y @T dP305 0 1gbFX&@6V(I^*?]6_y,6z)U)? UwP砃Cj_FqjbK}x pp2?w):NM7I9uP˷pt ^Ug# Rncp n2/&UGT 1xS(j*y< .1d{jˎjjY0"_eY3&bpb[+03 +-@Ym1Ԕ2dB@ITw@7a4%<ĺ7[l`:wNĭf)E!h&)ęlEw{Xhd: a /U̶Lґ`A2WdYo}UU!6HC X_~MAtҾ\|*r!U01{/ޅG[X]AX_WG, j>=WT@.L&(xvv<N Gޫi*P)A<pQA0 ;ذvA ؽњa&f5S$Pdm-} a$Krq&'Τ:S2ӥiXJAa{ /) l*F&,)<MՐJWJw)X(0;?g|cc~ d29-RvZ R:$`*/$A$XtɳFa.Q$n< "gPqLЪ#@_c{ SMQQkY) 0>?qmrAT Qp08xGĥKhZ^gGO%j,-926)lH܄Eub+-j#>S(z΍j_-͈S>a۾fԤvڭ^$.Z*Af݃ŕKW\15^Cwũ)۷o/!ư·8јfnOeU 32";p~:z-~ хJH4l{Dv'1@o% ,ge}4[D'*|VbEk K¸>4Q`>:6:IoA x*t6tҘ̢d vlڎ@؎logftvu`t%X?$Rg&OO*0i\_œߤ'A},IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-svg+xml.png000066400000000000000000000024251237252063700274110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkUMd7IS$MIV*Q0DDՊՋ" *^^"XA EV`mmvn23;,'CFox93}K)E(+`&TpoL @Z`q$VhW' eLlCÃY`- W8n%E1 nUuD`ik 1V1%qZ&\t-ׄm*1%-(ݨ02k5l{mYe 7 ?prq!ㇳxkx+A>Y䇙[tibc 6 pQ_>8=G>( FGQeNg|ze9}ُm7{!Am|tZ.~>6R6҉mK:r] /@+V=%T0xtK'Y&'mKs%[k)*_ !Q8oPR1HO&fO^wo=MFE7Wʮ~6#_h?'m$[^.?Wꏚ' \;-$6{ n-;haS2f.ҝ !r[jY}0]-4ܨ='m׻7Pq=ikbpT5sIP R*t `Ξ4F/Knšry^Z@tx+KRຮ8b0$, lct)?,c1q hZpȵࣨag,υ OskHb0kQsi%‚>>R[[Q /wHeŕn1eIC.1<Lp'K-ڻݯtѻY8 e˫ߡT;zKBA/AKK KGy.r&/4:H.ӵ=[,/a kݫ OPJ0@%cAF ^*L S)s@l`3RH "sO p<mSOIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-tiff.png000066400000000000000000000030321237252063700267410ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-applix-graphics.png000066400000000000000000000030321237252063700313510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-dcraw.png000066400000000000000000000030321237252063700273560ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-dds.png000066400000000000000000000030321237252063700270300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-eps.png000066400000000000000000000024251237252063700270520ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkUMd7IS$MIV*Q0DDՊՋ" *^^"XA EV`mmvn23;,'CFox93}K)E(+`&TpoL @Z`q$VhW' eLlCÃY`- W8n%E1 nUuD`ik 1V1%qZ&\t-ׄm*1%-(ݨ02k5l{mYe 7 ?prq!ㇳxkx+A>Y䇙[tibc 6 pQ_>8=G>( FGQeNg|ze9}ُm7{!Am|tZ.~>6R6҉mK:r] /@+V=%T0xtK'Y&'mKs%[k)*_ !Q8oPR1HO&fO^wo=MFE7Wʮ~6#_h?'m$[^.?Wꏚ' \;-$6{ n-;haS2f.ҝ !r[jY}0]-4ܨ='m׻7Pq=ikbpT5sIP R*t `Ξ4F/Knšry^Z@tx+KRຮ8b0$, lct)?,c1q hZpȵࣨag,υ OskHb0kQsi%‚>>R[[Q /wHeŕn1eIC.1<Lp'K-ڻݯtѻY8 e˫ߡT;zKBA/AKK KGy.r&/4:H.ӵ=[,/a kݫ OPJ0@%cAF ^*L S)s@l`3RH "sO p<mSOIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-exr.png000066400000000000000000000030321237252063700270540ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-fits.png000066400000000000000000000030321237252063700272230ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-generic.png000066400000000000000000000030321237252063700276720ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-hdr.png000066400000000000000000000030321237252063700270330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-ico.png000066400000000000000000000030321237252063700270300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-jng.png000066400000000000000000000030321237252063700270340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-msod.png000066400000000000000000000030321237252063700272200ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-pcx.png000066400000000000000000000030321237252063700270500ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-photo-cd.png000066400000000000000000000030321237252063700277730ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-png.png000066400000000000000000000030321237252063700270420ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-portable-bitmap.png000066400000000000000000000030321237252063700313400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-portable-graymap.png000066400000000000000000000030321237252063700315240ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-portable-pixmap.png000066400000000000000000000030321237252063700313620ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-psd.png000066400000000000000000000030321237252063700270440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-rgb.png000066400000000000000000000030321237252063700270300ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-tga.png000066400000000000000000000030321237252063700270310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-vnd.trolltech.qpicture.png000066400000000000000000000020511237252063700326770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-xbitmap.png000066400000000000000000000030321237252063700277220ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-xcf.png000066400000000000000000000030321237252063700270360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-xfig.png000066400000000000000000000020511237252063700272130ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxŗku_$d2\du[-P[Vu0t꓂QMEd >2AG7HSذ?Ykf7$MuMsK$ws!w[u}?w. KpT] kCDD`DapUXsg<4@$tЙ~?<}7żZ'<ݻ2e_VTBC> -mnlJ{R%")5֬ܙQ%!H6-ɬlGA\o5bdY$d}k_,;&xԇ^A45s-:χO?7]*aB)^nfp{{|G f݊{({[F)t͂? sMDo,0~PixR|i _L}s $fy?WyRI3`q[{{Aq>a5MÜ>555 $) \+D/ݻ{&!NW^8sf?R"7,PܹsdHSjN"```\.G2$.B× ~uVΆ9\;VM*bqq1DD$oDrb12== ^r c\oEQXXXXdٛ τr۵1MDx\Y^O@?jnԮSpv? m`))v&@Ѽ0׶IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/image-x-xpixmap.png000066400000000000000000000030321237252063700277440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/inode-directory.png000066400000000000000000000012471237252063700300370ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<$IDATX;OTQڏsy@E+576Xmlvv,lV6Z[NbAabHhh@` s>BDp(tU'ُÈEJ.; ^JPt*}~yQ>^^&O%5 Տj͉3zekf<3=!ߗ^VU .XQ|ڏ G1L*6 ̿|xcOSMޯ[2m>te2Ud1fT5e2V5;yޅPdJV[2L;`":*Kn#6!FLU14P%mL|B&%RLN4M. LJd)f"O6´/ #<}scOt(g.@I 2"Ǯin̴tpiڠ+n),;@Y?=/ABWgBoDETfIQN,]NO:}SVV*cW1S[=\ X\m~]V^4n_FCbObd>EgvEkWl('myo5o|p=ht4|zZ/:gSNߛrߝޟࡷޡ ᢹ⣺⤹ߤॻᦻ়⧼᧼㨽㨾᫿㭡sr#V1 'tRNS $'(+/189::;<>?F67IDATxmKOQ\N\h j .&$]w.L.L(D(Phvfzj[Bg8sw( %b8'8 k*`0@_e@Y@S켥5t*Xy;SJbhZ95?:ȹRoz?-e}_*  X2SiP`̠`t]j "n!>HJʫa[D_0gNƕC#3.L ̓ad L3:qzH `F7"3Ii5P#~KT.4͞r );nIA )DHńO3o+^˸ɓ( 7,PDlYEIzWt I'zVz &ZH)p!e;Y P.CR89@SE\UIJ3m[ɘ0* V" 8M5qHИaR5rہȪOͨ X TwJQiۖͧǥ%T>o,UpX~t=w)hU|$kpHpgW|xngl"&j4 }ѫ t<#G҉( IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/message-rfc822.png000066400000000000000000000025771237252063700273760ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[OcU(--V.R:*L)d$18Nݿ$dˋјh(a LePti-\keX;!}ioΠp-6jF?Qz%eAuMMM}5222 QSS^=Vwvv}J߀u:/kIItuuuU|rp+W$̫%=\*VM Z5) 2{ k(W$J'eΤNailthxa28mb#"B ߎ@{hS|烞+ܡJG5$1vFd*`aMFf7?b7Gww^|Wrpv/oXNn$pr9= L8 Վ&\cv,.a*cjV`N~D9vy`2Cvqzz*-F@ss s` |Mq(q-m#k?*J|*q4=2V&ĊHf]EjǴ]'''dچWF# l!DpZ:E6Ϫ&*(|N~l4d"x(kK1Ykl\<צ@):QR;)%&<`<&UBff^d2<*8ߖ9UD{: 6^dBň{K%y "U?|w? JDMp ]EXTפvUd2u_p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO p&g xYEDDWÏm=!zX D)LLL|kOPV~Sv])0W>!@TRw$,(`pW.I07.` 䎦?gj"uuu˺M&C!$jL&&SdO 98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/odf.png000066400000000000000000000125121237252063700255040ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATxڵytTնvU%bhToVDDPzA #H'G H!#8$jޮ /Q5֯kxF}Md[2He]Ĕ]BYtgX{{gֶ-ݤecZY8v U ȷ,";+C!ߋjl_}дSǜx}wgs7M?4ü̠2-LĜg)cڪ)vZaOՓv]GLyo[xLaFkr~U_t{/$}ͼMo.';N7{\ʾ=}i^]\ŕ}z$837ͨ%LLuPBBXaGc)i7ƦMv L L Z3~!,^)(̑R)pޢF[ߝ:YյH $z/|bn[X}'t__8k-)j7'Yf%7ּ@y [2H*e$iTq][vI+,3-ᰪ!%^f[کt$isU ={,_RL,i!ij곏@لV_\^#@:$\,H9V?T{عwjl.U_P{/W('BKSj?mׁƠCIE^ N(xN&4SUC1gBN>[46ol_p@m?ufDA^Β%|j3p|#GrB;O]cYқ*^Jl[`wsܽbQˎp6Zdz?"#:n' :i&t\?$ff56Xl%sYeRLolRhF-M:IL jP\7d e9@֨n]PQn@H!,GK1f9Є@K z6-ܟ6Z*49gYi`=yoO.e/CϽ|b`J ({ w:;z4L#;WA%`R]ؼBs9|.:@mVk%R3# L'T^-/m6|Zֱ/f*9rU 11W(p:rk(uhu;GϾǔӏ4߈aN)gN_}禍Vո'r{M|詽V.'C:H,xt%@a(+e'З $["GUXryV<R5()$jQ]I3w!~g8d}P7FHZ3\ԗ嬈{1jWQU2畬Z &1fA{H[ڃ) 9/& TUP- TK22D ꉁ= lb+;@zțRmҌvmTO;먴ыDer}\oKYd`p6)9|6@\po1IfYsR[fef[h wĹ^RYXp.L[2Bf:DKǛ> Qr%Ts7\AKY J ,;gV rP&?o3x9Y9}[a,y\W3=SDxgQ[DzX =f?K!×e; o?# zgCTBl+pMMwb$$e(lg7@^x8o@doU$, Ua!,[Ar5 p/ȿ_k(YL³?$(OFNwgLo  >zY NM{dEK;t'SG 4u]HK=`:s\M|DopyG K)2X#ջVRR(K<@QJл _+Y hz\0=C }OGf MR) zN+ <l!TJZ&j8 գB?f$D,tCz)%A `p룦8D;bm{w{艡z9r)N7?s8#\q]@I)`KhHKi.M.edNG41q۟;V{ǺŝgE3/@U 3 y-CHyth (CX Hwg3@<w \p4fDhd='KSr>]G%t =*Q3]ww \PA@_ ^P9mR9\ =AVaa q]'?"FPDJV&\H0bN?gLUS´]Fq~ AL;s>H)O@ZK7\rc[ C1!I#>^I._FC+ O[e.}qA/4r;M]>P/'4Tgl*yxz#0G= E]^yu0It҄@,ECP^w{@&ӚzgB`STrBvAx_gUTQWλD9w`m)$TYϹPtnfmjn wyNˇN;Y2eҀtepC4 =]Yz[ lJhmڸh~f8#o*HM6NtS=zЌ:p8{`;؝\gv:gρǝ{<}4rMȻk33ޝ”)w&y'~>Z1RBFA`ڄC@-GH.M l.5XcTV"| XjH\gЇ >evܢMg|:^n}n]5֏hO3f]B{xz[<|~QEQӇM)YꏩS?.f3Rf.x[i|։`':zZIȯ Twt* IKpoSzR zX$P|R6 UOrK=u [/+dZjOMΙ ]{ujf뚯}ܬ;.}~F׊)NNHLx) ?{ $S VPY>dLPU-hIG9rYv8Aih~r@e& _:Rg.#\W :^/>S1= ;AYmEvLvX]_U7æˋ0n-N6iwM%PC7Mt#?kЮ*sp`!_3ۄZ@&H P l&7l zf9j.˚Nd}=xv{wnPW^_e}%[n1شauD @\QX YRnfhּD ƛ[fBd5a>1C0r?8T )CY2. A.c\w)Ko?gWfEk2ꋳo& K4zʿuz:Ajy/׳&ҥg {{xzց2OH2;e-! & &H+\R:E/e9sz.eWz{s^#玟oY1k\3xۿK*\عY|ˇv393ί;e|f4͟! k!{r_t WrzwZ3g)3g_0v b.T*#6n`ܠO }g<52k ǝnA8h5"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/package-x-generic.png000066400000000000000000000023611237252063700302070ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<nIDATxڵWnE= ƶbG X$6H,K,6^|_G@I@3c33dv.St ѭ.9unj;R„GAχBHC<'^F`n0 iFpp K\<\|sAzGBbgi4ĉ_ܻcX4%ʎ;< ᒻ(˜}GTz#@$CG]9;yQNs|wo8xhrgOFthltJۯ‡VXYwe%xE.fg-ӧHCHTE`8?by H0j6߼tJX+ϲY^S$DOOk D+ Ǹ,$A}̲;+r:?Ͽ4p:Eip,qY*n;7qֻ>rQmTF%HDHd6NB{0P#c ,T"\!%d\PÊj5.- #!WBg! 8=B0@П1E0K"(A%p]^:R^.q3 R%()tGɥMʙ`ZC mWA#y&9a0 6*yLVDjnp !.jΪ 9 Ǐh޴9PrG%^+>!LDR2n(| geNBz]B3nCh4~ zێN ="P Bk5Vp/+LySEIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-calendar.png000066400000000000000000000026461237252063700274760ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-csv.png000066400000000000000000000023561237252063700265160ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |||}}}~~~Gʢ'tRNS $'(+/189::;<>?F0P,IDATxmӿo@%iJ*J%@RRta,L쌝X!D0tEC$Q"J؎Ϲ#g;Dd?> !6RH4CCr9>1B$% }x @4 C\@]n$DR$r(Z9UEX#>s0u dC-k{Ij_ A.,ymހ)W q&?/Pp d˅05zGC-~> (4GNn}ăI pVlJUlvw4JwOTB{|* k^]gg1 #]n^J.ƩrB9}@yʥ-, wG^t̏[2| J* Tb:b /FkhTLˍV1kJYu,Gb{) 繳ze[0RBM5D% ݌,`hg09p5) 70E ~IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-directory.png000066400000000000000000000017661237252063700277330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sIDATxڵWMkQ=4_%RbJ؅.B.EmEJ诐R".QZK6LީFF饇7o&}3M&1u!U,&)MYJŖ#&J"*rW&'' ~Ća DIMMM]E@HBd-@?񠏞`Br=P@@xjw0m5_w庀 XFmdAAEuN-Qnj 9x\Nj_:yڽf;0K29w;4LSljײn4ޝK։x ٔ|V#! FS׹M.$"ׁmrвluNŇNrA h9x}.<Lk/py:W81Z.QxlbtAe&-ܸr. C!t=j!O'&Ay;~k;cm(d=D`[EPZ.lB%*9[񰤋N[0r!m;H@=`[!G_¡%|0(Bv8+"BK_V*}&F˲nvTā݋!a&n6h4"jZ 0Nzi"H #˱#|J"@~Bs0;;aaͅ^o+Q "w)dars~~gDUT~{9P#09]^^`ț_F+s a2DZ`Z+> 7"Flic-..2#"Gz)wD}ts Bl@䏉8[U.gff> QgHҮST /$_IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-enriched.png000066400000000000000000000027431237252063700275040ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-html.png000066400000000000000000000031311237252063700266570ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵkh\e:sf2IӤmbozAQA]ĭ(ayaaYve?A ^H\ɌML&g̜{|9=$xxρw{="PET~RS$/z!U:6$BIֽǯ#O di,n<P|Kχ[V["Xg๳!GvxSQB` 8-pRl*Wy\k䳂]RxW)'7)Mʖ`bq"^c{"ʖ9$5LSpzm}*}~wqqVx؄ڼMt N0(^rhHPq\0XF4r\-{ # w.oxF!)蚆ihdPA_ gꊅ-TmO'nWL9!1ضB@kD.kCKq jԠ+\DNDQ>U:RͶZPg s5Ci9& JD c|ri֗143ߘ ^ǵpZʔ &JCdi9^[=Ϣ\}&ե5i*&-7C ÀO) @E03LYp O@罯gtS5JJW)j:cslc8g[cn  oOaejr nk.O>pbͣVD[ph֨^s(| FնazVVf!(>L}۷Šs H>0O:KdiwQi8UU;2>Až'" ǰE|&[`a%`ZϓfFLmPoyv?KV+@Ғ/~~ OTxrC-fm1!EܮR5'N%_ @OfI^-x`e?,Ѫ'Oqҭy)0xjAP+A$qAgfvv6^k333KLHF0R@rR_ ^ť˧O~ܶ -`wzt+ԩS]o&i-G0p+q%iӂ>9qGSSS_?~i`$y4ax`S=B`-Fb|75IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-mathml.png000066400000000000000000000015751237252063700272070ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-plain.png000066400000000000000000000021621237252063700270210ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񨨨S&tRNS  &(),/2:<<=@G,,IDATxmkA{&V(=TPXm*XՃ/k3bԋ`h!b$3lReyہuN/Su]yD yڎʫЉ$pA,࢝ cAk9v3zgs^2%? Znr^7D¿qɈy"Ϲ ֏CI5O~s#z+dcu S/gh.$p~ Pt{1QxKqSn=Ds~܌0'#7ح陁FWOD,@;H8..n v u5導G~`N(>TJ`۪_s*atp$5iA~#` o*n?t#`g6tQKQuz<JJ}Ջ$cw (Yj(G|&' =4^&_ ,gHuQ>!l" PIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-rdf.png000066400000000000000000000030571237252063700264750ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE /j2Zl2x79x;Pg@Y?=/ABWgBoDETfIQN,]NO:}SVV*cW1S[=\ X\m~]V^4n_FCbObd>EgvEkWl('myo5o|p=ht4|zZ/:gSNߛrߝޟࡷޡ ᢹ⣺⤹ߤॻᦻ়⧼᧼㨽㨾᫿㭡sr#V1 'tRNS $'(+/189::;<>?F67IDATxmKOQ\N\h j .&$]w.L.L(D(Phvfzj[Bg8sw( %b8'8 k*`0@_e@Y@S켥5t*Xy;SJbhZ95?:ȹRoz?-e}_*  X2SiP`̠`t]j "n!>HJʫa[D_0gNƕC#3.L ̓ad L3:qzH `F7"3Ii5P#~KT.4͞r );nIA )DHńO3o+^˸ɓ( 7,PDlYEIzWt I'zVz &ZH)p!e;Y P.CR89@SE\UIJ3m[ɘ0* V" 8M5qHИaR5rہȪOͨ X TwJQiۖͧǥ%T>o,UpX~t=w)hU|$kpHpgW|xngl"&j4 }ѫ t<#G҉( IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-rtf.png000066400000000000000000000027431237252063700265160ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񑕙¸¹¹ùĺĺĻĻŻƼżƼƽǽǽȾǾȾɿ<́&tRNS  &(),/2:<<=@Ge'IDATxmSKQ?3 V~XY/oADEKDEEEdH%631wn3\Dع\#AbG\IKpbrR"@OA+t\- .h(@ѕA/-PVlAHD԰.O |ח%sHЇ ؇ ]z . pKwú%kpSf "alPܱFm0"ygJP"lD?w'"`|VWw7,0Rj= 4[() b~L#X/W9PsZ#hrr]2~2A犥Bيf_C{+Ff*uW1'/it}s]R$\oc vbWܶe0q4ol&o-M[V==$F nMYQ)2rtuێ: HY2[j+ވLey&AɘqjZU)8'h-b;ReTwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-sgml.png000066400000000000000000000120511237252063700266560ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-troff.png000066400000000000000000000022161237252063700270360ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org< IDATxڵWMkF=Hm^^RPmV!t -$RJVǦPڟMdh.J_ea*  ιgxd( Q,Ϙ5HLD;~N,#96?IM&pǶY)ҵVi1("X?GQiQʜjR}p%0,CRh0djQXxq` PPm5ڠ<` 4 1  " z@]h"d_t^I$`dB%+x>Vx' K*dUSڊ 8B>Hha hǞ(`)"X"Pل.Q@ Cw -7B` lL¹eD zbLhs ,yxԌ@i1H d*7z ;'BSibR.!Qbh4nN8C\vn瀐d6QpKzP>?)azfc{{xa ],s>( |" NȒWx>c4o6xxxȫxH))JHW&3~NGd+B=yY{u||| ]ل3a$,2L!ߜ.$5; dk& A2 ! }QJ)熀*oLp_{xA{qY҄?uhyqIw+ּ9Z>e?3+Yzzz_ *Q\^^KT7v{#xIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-vcalendar.png000066400000000000000000000026461237252063700276640ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&,?%@AAB'E5E3G(LAM:NO@O.P,QXBY:[[b(ffgBqQ|\}}}sȌש٫̮ܪ"P6n&tRNS  &(),/2:<<=@G,^IDATxmMkQǝivjqfn\TTޅ.uOƭp ؕbKVƴII'3̽k{8 R xe A1#2" L( 0!"@0+BVX'd&f"dDw1!v@&.vۏmR+1dL4{zxwSL|%מDiBߤKOHH'o')ߘͱq"d$%03t@h} ]B:@pr` Qo?$" pr㜿i}\í7V/HV.v~) xF$ʬ G?gZm?x*rI&X:uCHuX 7j*kςӊ X(}j\T*~AO|J6L,sDFuXKjӝb0=Zz/ "V$ya vA 4d4 aL~Q(;D:MC Y%0љ_-ӏ[A9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-vnd.wap.wml.png000066400000000000000000000015751237252063700301000ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-adasrc.png000066400000000000000000000027231237252063700274230ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE L M QUVVVWW]#_%`'`'c)d,e,e,f.f-g/g/h0i1i1j2m6q?F0PIDATxmOHQƿs=c=J^@yOt]~ b=$,(%2xB^.;ѲezF5(j&f.rҵڎ>)`Aqq"s8'0{>۱lQ!J#_6ӧnT;VyL | Kg^:% `;@W_/.rMwÍ P X\zv0&- DМ#]Ճ)&Mt dce$3*г &Q:Z~!x_Q`9O2KT m#+!,CMK-<QIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-authors.png000066400000000000000000000120511237252063700276460ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-bibtex.png000066400000000000000000000026611237252063700274440ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  !!!'''(((***222555888<<<@@@AAADDDOOORRRUUUVVVXXX]]]````aaaaadeeeeegggkkkmmmnnnrrrssstttuuuwwwzzzz{{}}}Ɋ" (tRNS $'(+/189::;<>?FVY\mIDATxmMHaIF$Bx nBCv .a$!u$%tcUD(xCBu Us?ٙ9< #4 nO}S `"f quV;IAP@^!!# l[( !JSVv4Cy)JN:3舦V; ;V tn! J\Z*ۻ~d7&z%3V\1#`s? ݹewy>Z_p*WcË357 ,K=|tgj ݛDVF@?{1 ;HɆp.2zkGu <Ж;ILpul'O'玉w~j 9cG  g\U$O 0 `w{ W BJNer}߶z@]?F0PaIDATje}o&$mBCzXmт EWх!RB\xށ ހ"BAEFDbML&3<͸!ȩu*Χ[ʈBH"|NntZ'g!H"5яN/KNd)ffRZy1JDğ B( TDN{=o||] .Ys&_+*Th ߉,GIFJqs*rPAD,xU% "+)B͞k fflnn\TY/ܙZﳧޚ>5 2#KZ{}O1: /եU]3Z Bs[O~_D[`HBs)!0n$T?'[֭7 rRn]\.÷F`eguݽaw@n phdp5g1 CF6|g*(7:h^B47"z}} *Q@3.Pi;bn"@>@P hw IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-c++src.png000066400000000000000000000026541237252063700272510ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<dPLTE L M PQRSVYY[\!\!^"_#a&a'c)d+h1j6k6l7n8q=rAr>yJyI{L}MY^\]bagr~ބ݇މ̓ޙ֢㞽襾չ'tRNS $'(+/189::;<>?F̑[IDATxeMHa~Z~Aѽ`uSd ][t $>ܾˏtYwٙijw;=bYzW^s YSD $AΉ9M}} @0 YiZ: OM Ct%$IArD/ğTѵ[u?B@G1!7"G2 ^ "Ngz4WYAZ/S;VВMW ߭7 NR gW6ԩ(twikz$T0Zzo\3Q&yuBT`wt$wCxr1$ȁ/iyAD4Ϥ:%1$%N?nŦH),H>6/783l HXxUm* 1+5՚h>_Z-Қ=Y.0mmRe RtTJ;(?ssllv>Jk囿*@8'݇b+}q4Xh\_ʩ֬VЈ$gL?.rE7-&ZIni~L`YiV  ;Z1mO(x{ƛ IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-changelog.png000066400000000000000000000120511237252063700301100ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-chdr.png000066400000000000000000000023561237252063700271100ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE jqqtu xx}m㎹|~W~'t倳VDJua('tRNS $'(+/189::;<>?F0PGIDATKke<;3\jB5m " EWq ;GQ*tSԅRAHh\疙<'59WB4L0[QRI8h=gOtm.BQVgdQ3KUdRZz!PB;yѺBP!%3dyz-BTК|Y2O[wSDHp.+nID@V$T(33p Y_<\znA@33]w: sznɣ: Xڀ-^u< Qvo1 76F6^1BK|i m B7+wofFBO~)&xztuJP![k~d~ԗTv} ɿӣppN\' ?XD;Ψ20m~i ʃX[ʠΕavNމfzwtHfӳ>PiƳP1i7Bv`Թƃ9@-F$o ZMIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-cmake.png000066400000000000000000000120511237252063700272410ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-copying.png000066400000000000000000000120511237252063700276310ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-csharp.png000066400000000000000000000030241237252063700274410ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE k2l4m5o8n7p9p8q:q;r?F0PIDATxmMHTQ8~%TV (((,!$6.[FTJ@#ڕY %.*+$S#s>}Λ{7KތY~JZK+f+!#iDd"f(SfB}9dv *R@ DSMg@0D`@!%AKMqÖQXau 2ya %TlhZBcA>&#PȊx5,mMC }S[}<|qIʠ2҄ jsKf}d#SJ ҁ8".=Ӻ~f̨0m~HW΂^kA(~'8bf[W-7v}j5=ѦeKݓ-ecAyrY=L G}Ϣ4b&meM=֓7LGp%ԣ#z=nZvLy2n?\7!$BZ1+oxj >_~\ܢ-׷\90 !psaᎠE-g.ʻs1d-19P'i1j$,c'#4!K Av s-IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-csrc.png000066400000000000000000000027231237252063700271200ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE ""#%./1227>?ABCEFJKNOPSSU^chkmx|𷷷k'tRNS $'(+/189::;<>?F0P~IDATxmKHTq4 -РUIM2hZXe!Zئ"h,+aA>J'4Ǚ;;z< w_@LJv#@[%+@ Y bFpPUV،󥫕 $D? GNYEwKWZjm3*zmWhM tۘg )0}e59Koq%p VGZ @i M}bmʒY\wljEcyp@s+l''v5$E3`ǐ`I,8GA9 k@<ۗ@͟Tb1Z>i'>#S I gRldn7НAlTpo<3߽8=PPdbוk T !ۮ`~?3u ƒ^C)d`n% ~j2MU1@7_f|}<6{hQ-{ XFaej>{(:z5&znV wP`I+=-/̊R>*RAFpֺjJ~!+&9>/ KWT>5_QڤbhIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-dtd.png000066400000000000000000000015751237252063700267450ustar00rootroot00000000000000PNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڍMkTgddII51bAt!*tS7/l7 ݸڍ`C?11I9gNoE<57933p2~< cAk'^9>tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-generic.png000066400000000000000000000120511237252063700275750ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-hex.png000066400000000000000000000026621237252063700267540ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<FPLTEpppkkkvwwwwwz2.tRNS  $'*./1389:>?IMrIDATxuKHTa;Gq2-˨{ڢjAJB7JL6ZV2(+iB SJ8s\d{x?hĿ͗9À8#!Bo=@,K@4P G0 5]jR%2Dc2 4rD4sȗm=B6[0 PO_K+?i4qu{}&I R+7SϣWl-qUe 3 tBx\()BIGjwYĿ)f/O(][^=]c{ _wFI{H唻 K e~W4z"7sB._(˽GΘU(@ bWHi x/Be֜ U6?X'*;y!?HmS{Vt]ZВ5]< \xoQqMoY>-d_܏Ji"5]!7?M cЅΝ^~j<{z@ۿ0}4{ *J:)13YSi^6uFD-yW50C 8NZKh4q( ޟH#u1 Io3n88፲=_RLWIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-install.png000066400000000000000000000120511237252063700276270ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-java.png000066400000000000000000000033071237252063700271060ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<DIDATxڵWKOW0+ A"*YFJvMD".hWhi7IH+,W*V0]f\f|^-/dYV-6\.&'h4888!g^x`&< >Bڵt:nKKK/,h\DHq h#FGGQ0==jt] q(!Dz166W?A3cytAcXJpfzx?d)ׯ_Fj''Q.P=>FU&S%z I^/D$9,èI,˺8QG1LjDm6X1ɘssst@REF@%Rxszz p!%@-7nP+ 4H0jr@@튡Vi8.091cA~v b$4&xQ*fLn ryVObh jO! '@XFU*/ _(J=xΧwv $R ,TlK ggg h3vI_~{ m X %Y$~RE?=N'#JIjTs2JlK@#Ԕh|J[ 5W0"PJil.?*ʷ;̢Z.I9P-UZL"$b"S7j8m6`TL o;hZ*Xѩ7"ey淥rA A'6"z0wu iEBtk⒖:Nj8<Хi6zN\H=;o^"E$#ygV{b1bmm ׯ_u=EE@F牙 d O98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-ldif.png000066400000000000000000000017661237252063700271120ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<sIDATxڵWMkQ=4_%RbJ؅.B.EmEJ诐R".QZK6LީFF饇7o&}3M&1u!U,&)MYJŖ#&J"*rW&'' ~Ća DIMMM]E@HBd-@?񠏞`Br=P@@xjw0m5_w庀 XFmdAAEuN-Qnj 9x\Nj_:yڽf;0K29w;4LSljײn4ޝK։x ٔ|V#! FS׹M.$"ׁmrвluNŇNrA h9x}.<Lk/py:W81Z.QxlbtAe&-ܸr. C!t=j!O'&Ay;~k;cm(d=D`[EPZ.lB%*9[񰤋N[0r!m;H@=`[!G_¡%|0(Bv8+"BK_V*}&F˲nvTā݋!a&n6h4"jZ 0Nzi"H #˱#|J"@~Bs0;;aaͅ^o+Q "w)dars~~gDUT~{9P#09]^^`ț_F+s a2DZ`Z+> 7"Flic-..2#"Gz)wD}ts Bl@䏉8[U.gff> QgHҮST /$_IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-log.png000066400000000000000000000120511237252063700267420ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-makefile.png000066400000000000000000000024531237252063700277430ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE j['tRNS $'(+/189::;<>?F llIDATxm=OAvn' /+ cޘX'`Z; BLL,+Bz޺;337 LvO2dh'}1*m61DƠ-zN"0 "e\[# !Œ'  626h++r&1TD@5ߧ9c l0 LOoz1VNE ʕjǽmUv `_ |(a:wE2(0y9o9D1;M? 6[Z _-~ @gDĆ]{"N,hF/FP ֲߤӻ0Y{ *<G` XctzhVD`ݳ1Zk75첌?~D1dR2`GDrX@x`odH`0,1F:h_IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-nfo.png000066400000000000000000000120511237252063700267430ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-objchdr.png000066400000000000000000000023561237252063700276030ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE jqqtu xx}m㎹|~W~'t倳VDJua('tRNS $'(+/189::;<>?F0PGIDATKke<;3\jB5m " EWq ;GQ*tSԅRAHh\疙<'59WB4L0[QRI8h=gOtm.BQVgdQ3KUdRZz!PB;yѺBP!%3dyz-BTК|Y2O[wSDHp.+nID@V$T(33p Y_<\znA@33]w: sznɣ: Xڀ-^u< Qvo1 76F6^1BK|i m B7+wofFBO~)&xztuJP![k~d~ԗTv} ɿӣppN\' ?XD;Ψ20m~i ʃX[ʠΕavNމfzwtHfӳ>PiƳP1i7Bv`Թƃ9@-F$o ZMIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-objcsrc.png000066400000000000000000000027231237252063700276130ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE ""#%./1227>?ABCEFJKNOPSSU^chkmx|𷷷k'tRNS $'(+/189::;<>?F0P~IDATxmKHTq4 -РUIM2hZXe!Zئ"h,+aA>J'4Ǚ;;z< w_@LJv#@[%+@ Y bFpPUV،󥫕 $D? GNYEwKWZjm3*zmWhM tۘg )0}e59Koq%p VGZ @i M}bmʒY\wljEcyp@s+l''v5$E3`ǐ`I,8GA9 k@<ۗ@͟Tb1Z>i'>#S I gRldn7НAlTpo<3߽8=PPdbוk T !ۮ`~?3u ƒ^C)d`n% ~j2MU1@7_f|}<6{hQ-{ XFaej>{(:z5&znV wP`I+=-/̊R>*RAFpֺjJ~!+&9>/ KWT>5_QڤbhIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-pascal.png000066400000000000000000000031741237252063700274320ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵW[O\U]̅aJiSZS XS륱iҾ*j7h&&5i4hME(DJ "rœ˸wd xۓ}f9{o}}Ea%A0X.'p *[UX Qֱv@F0 5Qu4rBHTQN#jlly9$!@&-ZY&#gbrM64 ڻ2+A4?fQLu]D"hll5jl>VOЃrcGGx%Xe'EW&P* ĔlQeTe$- >SnJQ<8B"3 x/ 66$DT2jz?"-8kXK\5si{|tdD+|> lg7 j^,Q@pJ^vuu$]][#)\/-ra=X&Umμ# eF)܋X^^FOOfgfH zP[[ KNܼy{E]]d࠼VUU%׫M&bJRHBBU]]M<{!^#}x]EjF+d*:8ri"yCŝyQ#h sa syu477jzƜ J۔ˏ? h;Nfܸ+bߑv-755 sdJFȀ5Q{Cc;0CR^ *TB{`]|!`;6{>C37)U }:98MLzE]3wg]´ $-`R)WVVXT4` |094jrڟ~ 'Yv#QX#s ]Y` K:DC[,"^4҇Ȧ#Ӹ2,/x6Tܵ\qmG0 Bj8S@ 2z1&'C%IgϾ`\=TJ^UXA"m+Bzݻwow9 V'}qbbp_m# 59Yg>lQK%@ ot_lKDJ(@TIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-patch.png000066400000000000000000000032101237252063700272550ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWIo[eeŪ"@ .b uifjuڍIkgp<;nS|nAι{? / GG'!n >l'y69ȵcO+*4MV. a0+}jVS/P'ask AԴ26ry,O$ GfD"=FL/RX]]EvcbQ-Io8HqWZYGP@$0" #5><.Sam}]D!"~rXuˢ*!l:P-g%R Cׅ s~SjAg$!9L$H./cumMBUYi Ȉ+҂;0GFшF|}EV7X!$gi1 h?_c߅CeѮ4n4) D1vgUYN_h"nm.t BiQ#Hnht崗`NSH07q l 0jązl\x1/ `? eT&!){.FjqB0F`NܹYmnݲlJ<0<ȡ?2POdG5Gn# eHFr.r2~"^mO賗ؽhQB~ Ϟ=,S9r'м8={*y:N?Y%5=BV劼<cgQp}Gh}y.de`8jL:Wl6k mgT.r v W }ID9zO<="7Q 9Q  )O'~FI9 ]DVeNNT ɫN299 ;!a`f%p"`UYr"x2k핫 ?~1G Q ;q^Pp듽^Ņ UCW ߾䴜<+\NUNgdp8h3 նDSv{Yr%E ܐ%o6 ֚08 bX%_rc*VO>kI|9` LD8[7 3qr,,*"PP윭jb-/3>3&{MډłĪ(Egw> G$eȎfTDd:xBRaHzV YM&Rne ʛ E|_}3.1], lu%|Q~! M(R8Jd)&wxtSf|޾Af,"mʕTP4~+ȷ3@\B _ JA4N7Q2Z\o`\YqהƈԗwG4͈,Xm҇hjiA#K*),ttxA;hiAd+spz+̎ ]W7m^0Fey fju(h߼gptˇj%[8#1E)35}*1H[ERJ 0e "H(8/Yފ9%N|n8>t?_}sixK$I6t: Jc& C4 a:YE˘_KׯѸzfiJK4>y۶)8MU%K-!D$=O,LJvP;6 k}߳ 큻J]/]x+J9tvs'rkQ0[VEv"E |_?կIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-python.png000066400000000000000000000031141237252063700275020ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWoUw}R-EP!, 4v磔$Ɲ17ƍpGԅ.X_ljB"Eyә-$|3Ιs5!D i cAxxP@^g=;p? UUFOXs uu44MEWW7ЂZ[[ 0ppp >S<3hO!BQq}͈|M47 w~Rc˹9X&9T:mds3I WU\x 1p v]3ܸ?YJ@i"0p >8$a_oxcǼ͘Z/2MT, |(xW?k 7݉ #:tH$V~ gca2q U,6$6=wv\}Ҕy ~ۏn#lP؟kzc J [ LPZ /JHMDBRzPqT*ULNN^#M"ro4yLyΈMӀ!;KRp<+UJq3٬#GRP$jh؄ChTdDKH mhi@8g{(B#|ml߀Yhjb&aE!0\$A+(N=Eۀﲺ9BL&eB@,+  #Yk . J~7" aЍU+2 *ZF.Yq% yoE*b} Unԗn#pa9.l46^lVJ[6v7ZBZ}#{LbR\32c:3(RMa4'V-ܪƑ=F9mEk(&"t.Q0Q۰x k:g `>7AR; ÐӲTx@?Zѕ8;A:8ޞceD³B-ik{ 35#o"a\F_4422rBQXKT*H>_>`īV|p:;;FS]Ĥ=FIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-readme.png000066400000000000000000000120511237252063700274160ustar00rootroot00000000000000PNG  IHDR #ꦷ pHYs7\7\Ǥ vpAg bKGD XIDATx͙ pTնuNw'Q&2#"2PÂ2*A "sApA A$9d褻ow+U꭯Zw?k>!wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-script.png000066400000000000000000000022451237252063700274710ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<"IDATxڵWKoU=~6qLM I4$>찢 ʊ)E}@ *`XPEm6y `(uc'3ԟtgF~c_sƑn ED (41m)BEB8S=?j%`>鳴 E,CjxC¦0ZZ}$q\^^""lЍx{rCCax&a F0==Ŭ\$~58;Gqrrd2151-%q∎ߺc*enĐTnAd2T҄߀ڋ Ju7i4H[ wϞaB2fdf- q7u:҉KKK!ř}<1H)fY(X[~҇7+dnߞf"̘fm0QVQ.Ci~wfAB$ 9mB[~NCof:jPZ-4M[b jP+Q߾k};3,YV׸EuX4Y{T7px,,Ϊgdue?|oŻI}Gz;md-B+x[ g}ßǏr2ve_(|/!>r y t=MX~^A߈\yHd`g;6, כK1n=˃T*ї/_ `_h C]fLPLgiNzR)C}#4fy֛U{~r~888_" $PS0??//T)}@Tr.C{Awt &FFF(N#ǫ+2%/_#]@lnnr9|5 !wmBZ; !w̻͟BUip[JUT]Tjë5^BgEgsn`5DV*P .1j (X?M9 @&GkK* @"\h"W&> D4I`ja;M|_Y+VXE)KRܪZ::! 72* !!0CZj4|RSF*,Uc1%Enqb9/a@6gd$XH҅;0GI_|rI,0%|2[ސY"JA>J#l*#jOzF{=KcN,k5%iRqVBi5̦ԗn<5<'}ZԪ U\iC[V%0Vb$/UJӺMr , j%Vzp}L{c We*'31ʁb1qQ ?w/;"E,rwBcfGc JF?>]< Ìc ^yAZ~ ÅP8(oHi!P\˼7l>=7FP*"u cd=YN ^KoZGAzIV `zClN̹ؽ6XZ#pvw6uVH5iFwb{ D?*z1TͩY5@Y*/CXKӒy 2bt'c]w? ȣJZk-#r;BGg˰6'G5<69638!qY fKPߨj"2  +7{]`cBj l2ZF7kT{Fi'I >PgE.a8s-m@>!59h߳Ûݾj SGP0pl+`b#91\>mxEK`2g(:\( @!=L9h09vўM$Ȏ ?W2puz 8$d|ˡ֮25.*{./)lI_"0t*E(jB,soIVM>ZCK?ުnp%v8?QYptpc+̚!5AU@X)Y+S=PIЙN$dHDI9:AXumz5u -q`|ZePpĩ{zBR 'U F|{Lޠ#̨a8^oCтiEro]'@׭@_e)TUa|Kw%:G,q0n 8^``n@] @ou.d!㰵2 -ޥގ98bub`D PBLG>dL(ʼ ej|+~Xed@mUsc*>ed#/4wa@5pA<Ћ_Hs6Hm1b N̴Ӡw`s,+LrG5 OCO*$D6dnv@L5j/nPtV%xhn@Dq(R#jPw #-5Ƚ)B΅`/4|b=Fg5c&XP0y QE6Q@C4TeANj$GY(<ꁞCASuM j1 uG|jZ#t+݀U5]M2Yۯoksr1 p`v1;7?3J[q1=1I MA@:Y$c>-Z/8Y΀D jjj@U;q$p#(R#inrKn@]zuoGL Or/!Unxp9]nWGꇹ@x:j| =5 tc7ZV\t"D4pg]Nr3X? t/E8 R]I3*[Xk&ac1x^dPoC| BC]HmZ>C5fmSQ|!匧rXo-k"me iy42Fkt~Q!-5p )2QwRvAsmځ]P$xΛ8s]Pd6ܷ~wuo+oomYF+ #%!W_~ ݻsITg#{#Jl.8%3F 5v6t` X 'vA)ƫ` n,ۥr&AqIq] e5:xJt;}s~N:{ߛT k'\JXTSu.P!4T&Pm28He $Sҡ{]>mA,AXe(R0` O jwA@#UV B(T0$8fHSZBdMwc kXET{Tw;"L8n'ZO7owc}ҼI*̫NO;mmfo=:뺨I,ҼOw,5WG|ʫ|p۾m÷b:2ʷ Z%+!9"4Bs3ό&`?clS[>۱EE g^SPip+v HoHLܷw`T6Rv{ 1Ng;;uקshJ)]LueI,/~6uP4TA_N;ޓfvq9___grf^*^*+Tr\ۧ J•ʝ_E]Tޓ]Q*omz|Rս}Ms *"繼<K(upnR*-cպr1Rk^^3e͔CVXqWOş3;1;/Qs9(R~B|%K׭9@}ۥcެ<5UUza:j~~GFu1;HiY[(u6L/+9zf՛UnV 5|ȗi1&HXVhF\ R7Az.*7钷JRjO=-g9\Ynغb s}\rv ;7h_;ךdͷ>shC [2df2;7ߓomfH})vWN:SJqZ|eӕwv04s=?_>~}QXH;RӼd ;k{]_S34i.?.(GjZ9V.)*s$u)EF猡j'+^|^=S]Bxf? k(m-۶^J+ EtL%}iZi3jx Q34֟dTIDkB*fӃ U wk \[~ yeɉ:k׬=@'B-G? J! #v+ݯ''W{Va9lkjV*C)RRP'KR)H~DpPYH<_l-vmK-m>6ml5,d*A@?iw*mCZoq %A3Qݾ xࡪ͂Prt.h)\p̅"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-tcl.png000066400000000000000000000026131237252063700267460ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<LPLTE ᄒIJKOOPb3d6g;g:j=nDk?sJtK݆cރ_ކboz|}䠅壈壉框²ó鰙ŵ겜ƶ뽫쾬°ȹʻ̿ƶ˻\gt'tRNS $'(+/189::;<>?F0P~IDATKe?}.X:]V!.Ej2hӦMhoAjA(AZ it1͜q<̜3yQ!hەHҬ~d6"T2`D ~L\^ќy*GӾԼQBAXdMdFR !Uln3??pӝ !?/;ٔ(P!a‘W[|3s92yh* ԚM "ZU  p 8:ӟܻԗP]9̮Ϳ|>I $4k燻G)($\i<ԦRmP$DDƭB % ?M9l+M)T_Oo|;k D9Eس{4jBBA҆;Nl ?^_mIX _"A ]c͛4wd7 q@(XYY2ZH3(ʧ'HPvڶcn4n FnwqSK׺ w>awW׻@Ҷ5./Er'=@bYEA[rzKJ {d] F@1IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-tex.png000066400000000000000000000026611237252063700267670ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE  !!!'''(((***222555888<<<@@@AAADDDOOORRRUUUVVVXXX]]]````aaaaadeeeeegggkkkmmmnnnrrrssstttuuuwwwzzzz{{}}}Ɋ" (tRNS $'(+/189::;<>?FVY\mIDATxmMHaIF$Bx nBCv .a$!u$%tcUD(xCBu Us?ٙ9< #4 nO}S `"f quV;IAP@^!!# l[( !JSVv4Cy)JN:3舦V; ;V tn! J\Z*ۻ~d7&z%3V\1#`s? ݹewy>Z_p*WcË357 ,K=|tgj ݛDVF@?{1 ;HɆp.2zkGu <Ж;ILpul'O'玉w~j 9cG  g\U$O 0 `w{ W BJNer}߶z@]˺R)&O|y{ -Apg[;`L]ap`Lݸuߔ[n˰#:_9"G__MlV!1 SKZF>-m4: d=x|/u8!}PjεX`-EЗ*I!,AՎ[BQı@9~_DPOpSqTU㡏= _KP~<%d}ǼwOuwkf Q$ K{\Ɗxq/=X 9iO>GLLL.ޝI [syO>`ƫMXH+ւ!_eG$؏$}#"?Nٍޙ֢N@L^ZDD_n}^2~8%IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-x-vcard.png000066400000000000000000000027151237252063700272660ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<JIDATxڵWKoU=3?NjP %E( TlBRȊس= V,X@B ڠ@B^<_>{):3s|s_DB%` TH 9uaD1OW4 pu_~v| @4 -@*i"Mw2sV@etr؎"iko`G԰N2 #HyRC!m_k"B٦:*[MhQ. `V PB B!H\1<$q]𻺏sp0y2dtNhS!ܸ7kBV^ QʽJ? PWx155y {&2V_˕)t]u]RpHH>߷x0v*g&Qۘ4)޹^3}8CiU6w7e&M|.4ڞH_^ݗz] 1hi5^![lv1p{󊔷O`eJOؽC BɡV@<*a6f\.FVbj7k=a0^p2Jo# \!=,>TfT*>|;L4 5 , `L슔4RItNDAv*nܾ0yZMO|5i|K2;@WeL& յӥޚȥOKˇ/f8 ^eI( @A74loL.JL@.yONNpk27'uIMCYivJ;w>Gm rB9!dqT*DannWY[[{L 6܉NLLHB-ͅǜǘ}BakkhqqԶg(cwV"!Ha O.bDBGP!h+tRڅx 5q̔ N9}3٬L^a61{Mm.@ P=7 Q:ٛ%X%ZlKcxfo^ WMGƲl yf-sL5*QX5+PTkL<+z[@IUz݅uY52%`UF! ;MNY3tʳ`&1CRX Tp% #T Lp %G&Qd!d8J,Qd9ZZkZe"!&(ڊ=Il&4!di}$ͫs2h@ 09|j% 1a"q0Mbee["9Ju>:d8 lq<V꼦Yi{~ %)r#T?^_`=MUA5w~z2;CXEyK;]hW: Z7m"@f?U-܀W}R$OUo,~^%~קŚk?bu@IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-xmcd.png000066400000000000000000000025511237252063700266530ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWmL[U~huP>:YʜY2513K?c(1 ?l3dS1&lDa )0nBim{q{OI-9.K R"e`zz: 0Nڂ>CCCg#0oh [.w nu9;ʷ<8OWO-hGp lLz̮Z@X,/$p/<bː&)dT!8xyEZTWW0HG6ki >ćHI,=. al~M"A88Nǃd2}M =rg:DKۉzc\WXLB$l.O2U"@݌4 ȥ%oL N׋L&#W92%? !`Ɉ}}}2u(Uuf $yHŞőȏNuAydnWNpcJIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/text-xml.png000066400000000000000000000030211237252063700265110ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE 񮮯ֵߜᒳ᥾☷z[_aeeih녯mnpu|쌴v|}터{4(tRNS $'(+/189::;<>?FvLIDATxmKTqu:8c|vQ-\*VQm6EP@[XEh(e䌚C33\'s|@(|tռUdN$ IрPm3@Z\({R˻_(MlZBrJ !4JH` o L 1pV]d?hId@$_$U3]pSqB^!/W%W[ F cgTU@TbfInYzYnjgGzY:ǹ0cZ<`@TG|؂g&sW; #ԫK`N%$lr$CpzTwWLu/mhpOsmg@}&&4,] 98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/uri-mms.png000066400000000000000000000031471237252063700263310ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/uri-mmst.png000066400000000000000000000031471237252063700265150ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/uri-mmsu.png000066400000000000000000000031471237252063700265160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/uri-pnm.png000066400000000000000000000031471237252063700263270ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/uri-rtspt.png000066400000000000000000000031471237252063700267110ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/uri-rtspu.png000066400000000000000000000031471237252063700267120ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵih\Uͼ7k֭TZ m.*EU UAjA" .E%ҦQڤkI2i}&%i'A{9u] T@1p\C51 q+ЀGM@(B)TVxc ?|4L Ӓz WPX\1EBy=cy) "F^2 H$n:p/E|J P`:rUyZosYvz ΦMxɋR.a&''Ln:8v$#h%pתɆrm A :aK/qY\Wm{kDtAedRV^-< P<ǰo>ZZs~"{eϞfsr#txMJE\J%K[ š%aFGT|@JDx"#yƆJNc,2 Tf=JE0Ʃ, Qi=ʧw0w&$i p%O'8P'\lXyrB|BŒg A4V͟S-86axUVNL2Ù?'F)Rq;TT-}H(Ȝ 3{˶HB+EttYR@۶r:r8 u8òiBϘ_?FXQ4]+qA!)P: ew?vnzso$qh%=mX$pd2,ȷ]bcFGG!fr'@Vi5rnpp[> \ks݄E )PTbE*He[%jjj$yWWHss3T]Mrk;'DI!pX}˖-O ST9+Qd $zzz._Ix&|*7)*EXy3|m_vf}AnR=X"~`P)L EwIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-mp4.png000066400000000000000000000027751237252063700265520ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-mpeg.png000066400000000000000000000027751237252063700270020ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-quicktime.png000066400000000000000000000027751237252063700300450ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-flic.png000066400000000000000000000027751237252063700272340ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-generic.png000066400000000000000000000027751237252063700277330ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-matroska.png000066400000000000000000000027751237252063700301400ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-mng.png000066400000000000000000000030321237252063700270630ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx[lWg^]o:%qPG&*R! MSP} /P!T!x@B$xCp*M;έNv׻ޝ+R_6ЗFjf~wΜq"OϺq: l=w=~rg1@o}s}>K|31}EUjJ%G/[_f%IjqLiSW^Ww^pwJw}M9PgZrkM+ECLq4zUOu⵩oӐڍM0?6+Md| wvd٫e_iX@@Uxe;ttt1~xc+}LH҆$b%އL>bQϧExv=0W}iα{3hik 6PUSߤܰ cukUsx^M6e 0",..rd2Jl_GPB"xNmp~*ju&5M/ƛ# T.7w RPZk+С8/=4gggR-&=OFױ4~#\[ uxGW8OٚAuKse?{m3#6d+y/A`‘._s˄M іT>KW1>qĦMM&KEo.Gk=88xfhhhy]j5\1OP4\3ϝ;70??_d`rAT|Ps88N ˲mJ]~}OgVB DV`O0h0O:Up?}s| !$#[y|uo;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-ms-asf.png000066400000000000000000000027751237252063700275050ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-ms-wmv.png000066400000000000000000000027751237252063700275450ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-msvideo.png000066400000000000000000000027751237252063700277650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-ogm+ogg.png000066400000000000000000000027751237252063700276510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/video-x-theora+ogg.png000066400000000000000000000027751237252063700303510ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<zIDATxڵW]le=3;mw vVK(Բ A#4U#@$ICğ$4UIJ>IlQ®t[ZKٶv睛ґ 79ooULӄIdqCqD%QA(Ѕ~Bll|M,E8?yb!χ`Q&Ps*rfC}'k_qd2&uu︺8ҽݥ ,cdd?׮&͈FK /@l9yAٹ9%DؿV,_5HĻ^|y MW@UU\ qe`43ǟX̡a3{tK 0 H1rt2|>;Nv3_:kGߵ#WÙ_Pl{ eyܮxrD>k[O fN}{ |Mfff!." Ys@,d^n@7tLt\ \@Of+L:CI2(=F0jUS191ڵ&W\GUU%n}I f-v;_݆ÇcҞ7Pg64䴞z/-0 R{EA~Pyy96nzL*f1>>)TZ $'ꢎ;;;4 UQPTU'qztb &50*dFG1=5ɽko<,òeK`ydIAWMn'\R5j+e5'x~%FjH~`ͺud0:6MU 7pIa_u.fа@!+Ƚ)j wx?a rt{H]s1~9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/x-kde-nsplugin-generated.png000066400000000000000000000034701237252063700315400ustar00rootroot00000000000000PNG  IHDR szz pHYs7\7\ǤbKGDIDATxWmTU~νwfvctm2H%~"Q?~ _[l0q!hˈXGX!Xd~`ۺ+̝羽m4:3{9>{Μk6E ܹs޸qD"AGࡖNW{ <.ZR7$8"5ك`y?Ջ`/K sd3:f/v e܀qbkL) Ru*=%?eEyZe-m*$eLH|5i01fe*0CK@L qTXuRZ(of@͸pG9+3X!0*6sat[ЌAKL> Ф3@e1<^yqwJ Ay"`C &˅ȤTR3 )¢24%_` g2AEmD.`Z&E3`ؼ9-ќNWD[0{,Y dSˎHFK"Yd4@@F TfB(ڛaU qI]( Zri[^9 Vnocs85h3OBhx7ghkJ x, Rvm<*I _^=Ջ zrlD\^]K,aH?J ) F#cС0J%FR>/LP񪉕HjxfX86G>}_(:t%Uxief#Rc'WE@ %߅|ۇ e&<^)2_JrNJx-ˊ_JHr>UumBwix&D{ҥ+D$ئ9MIHLkXnO?y̱U%V4M1s.:2e[c~}]vQ*jxY ,|t_TmAxVŶm.WuKoO=rYyE?$yw>UC/}RȐP|<=JP* BR~mֳf͚@c;!m:JkY6li͛7bŊk'Ot^]֭ѣG%@l(Sjmjs|_> ]'N|u7:uJyZ ܿjvMׅajBM}~/JCA я?ǎlٲ~7|``?~x\.k[V]CQ^pG:thΝ;?o ]^~X~=QoF̈́e˖V'wp#˙=gϞ\ԘNdنF6ʻ(,28є̡޽ 1y"zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/x-media-podcast.png000066400000000000000000000025311237252063700277130ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڽKPup e}1B#@BB«"(i]@^.mSzrFy! vyb"6uVǕc3rW(! G7@uM=̆gOs!AVH PS[-b07I{m<>G.tGJ|0 0okpNX`,'S&QO{=[𦓼\ֹӔ0}j]wk\U[Qϲsbf]y$vY1|UXkP@ P墳.qe ]xOk |  HRxo ‹u6uT(uFk|7DΙ @;|"?5@I6:dv|{.N.Rx} uV3g=A8 [|~og<0R "-t||fGX%bSq|:F3@W^Y,u_zO\| -`!oC4wxwϝ;yT_|YxF/Nbw>Do`ipsǸ1|Q>^4Yv^ tvr;spKlN[x(`2g-p"胉f27(s90gXF{ ;?pMe :a\c#f c[~lz-{ ,z{oh 4;K`:u^o]ݏu΅i@e Y܂ &1@yy]\. >Yc߇@='7AGGaSˠqFB ȺV "Y" v`1 XOO,I VʟZԆR+J<4" ɫ)iBh5blD2^rеXxA 5 [P?#=΅+0Pru'*cq tKzL}|L Z^T{2%( %bO F`H$}3]R5F$!Æ}K|MJEY3 , k*9U #')Jlhe:^dThtNӋ([5xHY>AJGf=j(WA@B6q 4n'k SoTTJ`)N /֦Ϸ/[Z r]{vXUTSx,0A<0ωm/!P`"^ij݋:Do{&+_+Wn b!|0^7 p&F%d:=C5|ɯ2͖ҥKo3ہi~awIJ9ab?#clߌJ)2\`i?_~h$ҔciY!F2,&]ĬC2g.R "zTXtSoftwarex+//.NN,H/J6XS\IENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/x-office-calendar.png000066400000000000000000000026461237252063700302120ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE |~           !!!!#"##$%%'((((()$)*+)+,',/+//0-2$2!23,3345*5#5$9:=4= = > ?!@+@"A+E$E%J'K(M)N4O4O*V.W.Z0[?F0PKIDATxeNAvK `A701{}eLkc@% -Dm)@;v99lf aH#}>P]6X |Zxja",Nz:5aYN mK7z.H+K_7k2(tx0Tĭà <\?Dz$XTF9!Q{Y);ʨ$Kl{PJwڑ. &B \y;P(CWФk_:-ݏd)|R%jDDL$ D7e&|"@hbDH(l \teڹϹm̙N O ]={{o[L5!ɞl#d!br忾)1, W@]y ԏ3n2ɟxO twmTύHiܲLM6G/-Dt$KMZ4F|*G8Ŧk$#% j#fer%,JF'Zf;1 b1tm4S}O@C NK h7)p! X8:n7pAEA'i_߷rCA;,?2Ut:]VQPknWZ(eL\ZE>"bͣj-)ȥ,]z Hea 3j ), AX@@C哵 ^Ⱦ.yz@*K Z |љuty_ՂՖ -D EI/]>ݟrCR90-Ĵ՗ܹ eBz>@\Mψ${kmxWDll#I#A,{?NͤC3tz&I|ti$B-fO?, 3RaflxqfHpY8">SN-*ј^W?t0'z;}mMcuܩVVFGKZ'|=NUX|;$J5&/Ɓwf͓MW;6a@f=pZ]*훏e걽kN:rU>vcIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/x-office-document.png000066400000000000000000000014011237252063700302430ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<~IDATxڵWn@%R k?6$'J 6k1XtrSV띣 }"ޟ4XN"KSr`8яK#D!ȗľ:`B>{MauyIENDB`Collabtive-2.0/templates/standard/theme/winter/images/files/x-office-spreadsheet.png000066400000000000000000000023321237252063700307400ustar00rootroot00000000000000PNG  IHDR DsBITO pHYsvv}ՂtEXtSoftwarewww.inkscape.org<PLTE װබݸ߸ǿ̿@(tRNS $'(+/189::;<>?F;IDATxmjQg۴VbŢdЛR R}ק|;K[?\%Ij4Ls&$3H7X q$qh@J5I(>R)_|@(`i)?w]-<ZSK+1X`Vc?eJ{/ی3`]Y*$/+d *և eFonSC+6d^6Y-`?$y*QT 8'.9æX*XTH} TqK, b9&3`flRI x E!u"m * 2wum( %@ I<2*(0~f{c7ƀ:$^MFQpc 8lqRL PcPXA:iCc)Q8[NCedEpYhnji@.Cegg/kohhyEچ/&~$4~itOjz*ިrΒuR[@*vk*T(sX:?/)u9Oe ptkwIiJM|6O&4ÝJq/( *)?^3LmI]R(".XSmT*֛MsRs\R֜TtrpnuHt?#O3@A_ Bzc7۽I)jn'S#ڮpe^}(ݏcO ˿?6wItGf6eIENDB`Collabtive-2.0/templates/standard/theme/winter/images/input-bg-a.jpg000066400000000000000000000010231237252063700255640ustar00rootroot00000000000000JFIFddDucky<&Adobed        yaq L ????!MA?!?! ?:??)Collabtive-2.0/templates/standard/theme/winter/images/input-bg-a.png000066400000000000000000000002361237252063700255750ustar00rootroot00000000000000PNG  IHDRʚ%tEXtSoftwareAdobe ImageReadyqe<@IDATxL @ XZ\h6줵JXϹ3gfˋ(8ـk٩8v"?:UU}.>\q{?|) —^Zy<*===?D"!zx-,LO7wwwVa -?B|6t4)#f 4:8VUUܜԩ| `Z'෶BeX=~}Ι 1H]`MDŽ5e/˫ @tii)H$yϞ.I,v>@m2'*1{BI_]]><<K`iWǵ'xz"섀&sTqs@8v@333oGFF8W3"[W*]JJVlEӽ<*bͶS=@)n}vv6W*VXx9+9ug/@hv 0*\qoŚٝ*ǹp{F Yg"v0 W>7if9QqhVtWwO)毯W.|ŹZf\ Q1ͱ= _`"捝FgM4ڭRX?>*/ϊ/Dv5@$;!,*;@iQ?PlY  qKqLgk&\@~ qx2ifÁFuP` ᄐ |1]#~iΙ4 'CK:#'''3ft_EE&LB,! h*x!j/bsQӽrv -77ɭht !X_\\@I^OJ ,D. I"vcjT}p EDjvI4D\I;l nTW1_4Qhd! n"yC?>>Yupsaa;Ut@K K\}<{>>,//ot{k d5cVg|+N>TObЄ546r,x5~l D½EաhO^r6==i$ .DU<`屩̧IENDB`Collabtive-2.0/templates/standard/theme/winter/images/login-keeplogged.png000066400000000000000000000011161237252063700270440ustar00rootroot00000000000000PNG  IHDRЊtEXtSoftwareAdobe ImageReadyqe<IDATxYMK@6UAA/b'=Wx " ~xb mI&,tξ&& c(JwJB Q 7b!,xMEX~dMwbX i Kf<ݢv`)gȲpf*q ^I OI9'|DFN%A&яXNH~j0 Cֶ~RcڶA0, ?C4?Ftٜ8eb(͔I rÏiV>ׯďX %O8>쌸,G?@IA)J 8JcscVe(k3`HHɠ#`͆_FE[S e\jC`psG3"*{2 ,N?"`,.ugEГHƸSpR[GK;k9 ƅ|feGY[s (lQkıFAُ<iq5D}@fU8z&y?zA<a|{u}?.t!10|c .gP렦"mb< F(epZ0p_ؓG߀Ry7P3͟ 4|бyo5KxbJ{n {MSAG>ooOV٦;e.g!sBmݍ -ܧN y`~< &䩡r5}Z?3<LIqjYoV8Vo mӜ641BSNgg̑F\E.sӬS|@)=iӆ6͇]P cJi3Un[?ܖ>3 RODylrSL/&W@>|XRMk/*m[eZgzX{g~)sҕX]+%\⺹"LKQhζ2,NF)ѐW?&{Z5=Nbx#1:yܴpzƚS5 |E>>ߔYkisYhcqs,iVl!J3+7C?r U&hA!+BEv1Hm{ |)Dl"1#-gyOs_dd 6ṯX^js!]#ݮJ_7& (&B;|dmj9N2֨mvיLW3ʦ(tl`<ײLhOy MBͨS1'7EƑ`R|S9ՆSy5 !h'j>E669*B}umBZOL)CQxT7"_8RQ&IQ[7UL8lad1{Jֵ\Bd.{->m߷:#>LhbdzF+}XWk1ܿMm< |w#kVED2fQW`NBDdqNE֝m)xmP͍u+qaBUG?B/3<ǻۤƯSYEe;@I+ҋW=bʭi/ȡ1,(ӘDO{kT_N;Hbto{@Q|^1Ճ—A%j~cCK4{nQ)8Ҭ<a>7ju+Skoߵg(yЗB8__]tz}Ձ`Dy*B2VZރR :#*I{lwv幏+B̋Ҟ :.O8CKcgmmK؈%\xO,h5G^]/~mXDbF#V7$9)wϞsw\1ϛ-N.5 qGԺ>('"::bR6@̄&`4"bץ;MX%\h8){?ŋ't <H.]`Ql޾T*׮,ܸ8\"fnAs( }G' 7PB!ly9&2idY$Ir9Tp4zhh=wMS ';;$zL@A8ABR9kgo@25;zimL5Ӿ]аSUɩ)(˘dK*Tn.h9R ヹqD[O`u`GD[@fhpDj쥖6 01Q^IENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-admin-b.png000066400000000000000000000026401237252063700260640ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<BIDATxXKLGv~6`p D!A_JD{ȡRKHMK(jm.9BҨj$D!IH%m)T `cX{׀vMHoZofVPUIʮŔiH uGDiDKh(4{.(H:g)K )0Dmρ: w*i4YL}gtT.FL9U+LyB1y hYy9%R,LV6c$"EӌFhTj׍02-u[CZڹv>CHn@ev޲v-P2am@:#Wڐx=!*[z'cf[*>I ?Dv`J!XBL̺=Jt[>t8û3׋}ߛD9)l||3zuRyz~mQT,?^F4t5fGmu-74@Vd,|!.]T,$8twvx<~4h֭b !'akBiڨsץ#,>߶evVUA01=EQPJD)I&z8ұ 37 9wFWBs* `DA3'b߿cW䳣G;ᰕ聼Bf2%irUc9F4C,F,gډ4{! *UILsOz*xi *%]ybB(jW&)NjD80E"[rGTLn֩S,YA,s[+Hoi`2dLfl"P SJC$X%JX E2NRT-Hv үQ%eF$(lPR [R`wL^kCF>\3Zk0wrV;HVǁ罏q~?" F~ 'OD-/bAH;Z/njs{hڍ\+~]^KwP91 h2L6>uޯ0*fɌCD"k^hFfOb}wbBqZ ̨G&]{ǎ:x_(ȿhmn7_|y<)ᘴ45r7 |ibVsgm91 F{@ --G أOʰs3}@.}~8,fs?'0IENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-admin-c.png000066400000000000000000000031741237252063700260700ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<IDATxX]lVIAPV(4 MC4D>bLB{`HѾwW!M-iRЦӤayR ]$IC'N5n4mw9A0JvxQË ܃̈́x&mU껥+ffފIWZBG^BsB3J'EDP{*Kz֚l+p*cAY_\O I4pZoX9@R Rv+hh9Hp0ϊZ+f*F=X,ęf IV*:,|.$LO/8X9@I |9q Gzζiw(/I咆) dˊ-#Np]F{+r u;3 ȁLp%Rߚo=HJn 1NJjm$c$-+ds g VE(9''u+RƸE:QYۋv.(`pEpV.֌NtnWCG>pHGUŋ. 0gnB]ό״wxbg{glE x%|盛w~;)^04:~/rf MV:uOHp`?}toJ,v.I ,vjj- C/#}y}@1{&C喙Ґl|)4x`n坂 (F!M0W lyj$N:"Ka/Y>66֠ہ kiF: @PXJfr F/i ݺ8, ܛ ^Y/oc9=qOeP0 iBp7n4]p799}ҹ#\3) :F3lwC]?}V$DLFyڵ3wWym24 JG^'r<5Nx"a<p477/\`1#㸮ˁrŇoBS$k31I1 HӀ\AWA 0kooJ<+/ߣjP[[ |>e2|P.L`WW׈n!?o2XF'nݢ "osU3ɷ|9K1T9,T2"$ՠ|Xsr*\u+!k_X{V鋙U jfcte0Ⱦ+H*P.~`zk3O,g~ݮ>-3ƽj?0'\t;~C慈̴{SthF,#y(.ه^vāKu Ӏ&z+*ߣq|Qz*]%סP y?؃ΰ\8Ք BgG糿|pt{[s*ZTϡZ[[/J< ˳WVP.%Y֊([?lsV8_< 9๹DeIENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-admin-d.png000066400000000000000000000033251237252063700260670ustar00rootroot00000000000000PNG  IHDR @{usRGBbKGD pHYs  tIME /UIDAThXml[g~{mǎ:N&qta]!l&:N*HhHlR5>Mt_4b EH+e:?cdkŤѬS*4mǍݴ}?r#UYcl_sD^sC:cJt9N:V:|gZi&W $"3 A1 BD7F"ŘFA46oef5\.FP'T{ Fۊ-V@<[YE(tfцrU;p)ڛEn2Bt[H-s"28"#ܼ7"*7 mIbm`HDDj4>6wȈ\.3WH XDMU7dc^Lz6[qIc: c5v: kDs ,^Z:o\)nTguvi–/r#"OKU[lLb+M0Ot97&'O'biքB%qoKmwU ]@JS7Oxg-DO=m}t FL }Lm۶2ݞE ¶q\8 X)⥞m kD"ADaT`:Jf]g|vç*Mp{]4N!4 c>G>GTaKYٲqt B m*!XU:=r'wޭץzALwiC 2\9No>X#gE mA)% =EJ` 0 ^U uqP>t ͷ!|{m7QH"M!Ce/DG?shÞ'|EK峐J"tt6I?'OM0*(B&hj\M[/篨릊Jwjy^o_}=k׫jQDRiΗx/4brt+|魉~lݫ$qyT/}㉃G>633_ouK~x\~]Z xS=? K_o_v]xǙٹ-y;v~C67&־rЋ 딒]A ,UXhÆ\6""èl9B̙:WO{ zl|6.b@*J!m;KdhJ)MTTTz?vϣuuC+ @J ^JI03 }}$#,M\6 A)fRJA*IBӢx][pHZ}#x % ᰆٹ9.\)0hb x0XJ?T.ue`~ٟdT`VPD05uF6ˮm[)s9EJ(xҲdR]Ǐ~4qV]7-˾K*sB_'0V.K ,J)%HW$ ='veHE.FD|X(FA\7$u] nwp͚ȈNV2TM$^{@C <hb8٩_fIENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-bg.jpg000066400000000000000000000214651237252063700251470ustar00rootroot00000000000000JFIFHHExifMM*bj(1r2iHHAdobe Photoshop 7.02010:09:27 21:56:49W(&gHHJFIFHH Adobe_CMAdobed            "?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?c$cD%*JEI<$ki䔒NE?I:H4,Photoshop 3.08BIM%8BIMHH8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM@@8BIM8BIMCWmain-bgWnullboundsObjcRct1Top longLeftlongBtomlongWRghtlongslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongWRghtlongurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM8BIM8BIM gJFIFHH Adobe_CMAdobed            "?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?c$cD%*JEI<$ki䔒NE?I:H48BIM!UAdobe PhotoshopAdobe Photoshop 7.08BIMHhttp://ns.adobe.com/xap/1.0/ adobe:docid:photoshop:2456eb72-ca71-11df-be2f-e1c20a469ab5 &Adobed@ W ```!Qa q0@1AP eeM"eQTaTdUa(aʆTr-#1PTQJC + RC4 ©PKH-KZ+6"Q*(!ZXkLWWW?W?W?W?!cHS-&iƄ?)h?- [5nM|źtitV;4P?!hki ??K…~W_x?!n=` ~> ƁS "Tz{_~V6?u~Lp6\ _. 2Ywmne(2wq/;@]ﷲ_, .6wdi YgHv}gQ;zn 42l2S;{)N X|3:>9qbYlKl n%Ӂɰdػ4~PdnGK AJNRUS*2N-h 5 t- tV5nKFKnj K|]?t06JG[ aQj:CSNAu-[+r)إ)h2KaQ:߂[Nì)u+ APq,VӴ.KÊcA gatfKíPoh<LuA:wC?5Ka?Te%% lV e lhӠ/;A|5rA6J# G[1dLQ5+.2K A%J\u*9Tql2R>`a$MJOdB')qR?Collabtive-2.0/templates/standard/theme/winter/images/main-desk.png000066400000000000000000000016141237252063700255030ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<.IDATxjAOULpbB1,&`0\E D | .&A>m)QD"!2)ϩ1LjPU]uBk]I23xdGQBB6ed!AvL~f v9@: jd5ÎdnLٕ@l$>RwF Ҭ$_SIfe -51k)sh۔(d4PC!_g=jglDyjfS?aeҲɬlQܟ'AѼ MA.h+ l@JndԉhPcBc0MUͳՅ40D:ӏ#LyUv z&#n\!DJI 6Žhi2 +#,U1GIe 2> ED< ^u R>(LOTmG v Li rN K5Lk@T*!pG*^PP\mKiz-v=FSxv(fw wN:Զ@Y )̒+f9 TU$ e_ʛ1bvӦӺ;K!VOCǕ許=;;K(HY8.f2d2hS([v&nmm N~ޟt]廵Zm_%Q { `m~ttwIK \UZ]h4쯿@ೞ#ʪҚC(!өs'O EQ^"1 X]RFodX,2đkq(ρ?" ƹYMX95b#j'n$rll,Ht4P|OD` KR6s>lmbbbs}}&|Hq=n76UU]Cp"&@EH$Zϧ[>x'mtuu٢'y ۥA()ռ<8~F !GXܛ*Jn%\ <8~%\D!2!D"E>x#G'R)?NOo m\c 7~rr E`"}a6lo.r5Ԁ"KxEE Ⱦ!oSb<>>ƒL3s~z}?>>^w܎wvv`WCn5XxS ՍØ'|3hb~ffW[*v5"X=Ө~]4;X$9\I|lʷj*߸s+pGG2!v'| dяb jЪp S###6s (k/H fO)IENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-prof-female.png000066400000000000000000000027001237252063700267470ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<bIDATx{lU̾n%KʂƖ *@ $Z!BƠb4+?j(H[@BMFSWAY;ywi)l;tcI~9{ιs/H$$GHQ 2c"At.9ݮCq̂d-l& 1\H|hyFHVю2mRCۘFAm0rU(aXExE/"-V^m)N Y)v*{̬aIחS5SQr\HO#J&0*! EvGlQc"S-8:9:֛X:L:VQ =fK\y% "w'/,4 _KV&4S493\nEPe H/#%s`oaɪayH\é;@ˮ]98(n=r5%//Az#}j1BrǹhZ!|w-`&+ -;`8l{ <ylEA|9z;HNPjx"Et; Mh RZRVLfp8]-}hFN@EH HqDɁỲpWSy.-tZ'|x s& gh!H 3-_L]8n16uG G^"wa?7i{i[?Qu/u:,-ʳg)`8:x}sgO(|~nyb,v9X๰ȡ ꎵzF+J}.979 h 8/͙R6wv.W{=8x#IK rANeok΂斖q2c?jm[Kѡ[SD W 5P/$ זMCy< HK_؈~6]LË.0%-8\HΥw^Ұ=9AGH^t 7x:%s\{/TSWzp//NgBy?w+[IENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-prof-male.png000066400000000000000000000023771237252063700264460ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<IDATxX[lUwҙ-[CMbR#a#R /1PMJKA iVbm6l-nw2sf<;X {NL_v9r$v {9-aژHiH.%y K1%@& b{B6@`=@~"Qbl!- ^ ! 1Ak,s4Ia UZh9y*ϒK112/FW\xКa~CT4 P-iȏ(%RAp(4HY*Rj4!lfXm OqeC۞@1>ФfcW~B0hK49:d}o54ebj:$p}Hj͚bJoLSPF&  ׹y}K-x}mjtQOQ]GbNXl "DG$ CLSmDIVk!&zsQHc$HB(DSǐqTrx9!>:2+"g/ \ AHF0̀LU8 [يJ_BK0 =]ۭ^Ukc5VK?:.2˲{} I'`wNcΝ?j(h;fÃ'O>@(| m -C3={6S?vNLf%;ly@M>>>G wsFl2.ِwk$d'Ï?Q-?;PFFש v}rjr_T hjl|d4ĢehwOOǛnL{c5Ȇb6AnZӹord}}%kȟz9H9JNHIENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-settings.png000066400000000000000000000016301237252063700264130ustar00rootroot00000000000000PNG  IHDR @{utEXtSoftwareAdobe ImageReadyqe<:IDATxMOAm@E5ME1i{܋Gc@PWI4lbR,%-@DFX]v ]-qН&u'Luqqqc#v &g8'q[(Mnl>:8"@礪v@\RCMRC vZ 0]y"CE`ܕ3N#Fp}:<pgE D [ TQO_>*~*xߛM#@Ku[fD;f;f]ོ8h9q/'(FT'nƄ= vnCkl^{ 6}[:$I,|8niozc<~4F}5["@BU6[E9B t:oZiMRm$ X鹭|glVVSDS eaTGU"">^jKP.;3(JȾDGy&ZUUAN:^/||86%>C8cx<( #d2nuu5g=|vv8677TV@PP(>P g- r${2(|ooMI; h6gpuV닋67 B6yשj;;ӌC"3KQ̓;;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/main-submen.png000066400000000000000000000002611237252063700260430ustar00rootroot00000000000000PNG  IHDR ڛg`tEXtSoftwareAdobe ImageReadyqe<SIDATxb<n H<8ğ82A9@Ƣ[g`BD7πP>"/`@ ڨ6HIENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-files.png000066400000000000000000000004011237252063700266240ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbOc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@#xiIENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-miles.png000066400000000000000000000004011237252063700266330ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxblc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;If9@?bә W@ AlfJ6ɧ@Ļэ dc]#IENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-msgs.png000066400000000000000000000004011237252063700264730ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbLMc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@I#ήf<IENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-neutral.png000066400000000000000000000004011237252063700271740ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbͳc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@$_8IENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-projects.png000066400000000000000000000004011237252063700273530ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb/,c``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;I9@?bә W@ AlfJ6ɧ@Ļэ dc]Em#|ZIENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-tasks.png000066400000000000000000000004011237252063700266470ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb4*c``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@R#hxIENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-timetrack.png000066400000000000000000000004011237252063700275050ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxbwc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@#9IENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side-user.png000066400000000000000000000004011237252063700265000ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<IDATxb ύc``8Ŀkq(`n b)l0b &rW >O%o ]5JtȀ 0*I;IF`Ҝ#6@|]q+ Ļd ?.;QL`t`| ĉ@ع@ @6ݵ(@##Q;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/next-side.png000066400000000000000000000003331237252063700255300ustar00rootroot00000000000000PNG  IHDR b]tEXtSoftwareAdobe ImageReadyqe<}IDATxb<31:f b@0IxO/6IdSI tbk IP1(K 4$ >ĿI2 M.X]ןΒ'EIENDB`Collabtive-2.0/templates/standard/theme/winter/images/no-avatar-female.jpg000066400000000000000000000060021237252063700267420ustar00rootroot00000000000000JFIFddDucky<&Adobed j        0` @!P" !1Aq"0Qa2BRr3`# S4!10AQq a@` q! S#[S[esBJS#׫T6ئv'b@2>U;7F]q#o~~S^A ]^AZHQUP_# ~d^S2!`~i( w_t5_50Tp*RAG[ %?4?4?L6~ZlJzk9#-Z򄜍ePN,4lMg|)Ȉ-(j :)$_fZ;K2+ݡ:MiXm'I }V43hv)͔BZOvkp[`hp)v" ]C =d<"EGt1fݏ; G1"CJ3w9L*scte+p X#k--AAAF<;I2@1uuZ壬^R*8w11TV/o'%{Ԫk5ޥr,Gq 6lx$Y9b8;t\;yxԸt,{GS-c]N$4gkOs+ P?2l+nhuS?_B";ܹyF;72:V={-˗._\a?!Rt\t5~yǨ*%:x砣W,CùrYr?!NRt~Q>Cgn1^+JҠ KKБo,E w ݖi͎o > d]>~./kM#Oɸ^@mk [e@$% ?WpJ*T\3@*TRJ @Ԩ"h%܁\]y-gEL1M$HBt7jr!PPYxIuX˾T;o̎\ODHH*ڏUUW(U@űTfp2su3KE/AA4HRxb:JܷE _%hi2&>i$c! /S{z̤"ňvfuo,0Zڥ nm}$!I ~y Svd9۰e2r{_& h 3PK!u'GY^HjGj~|Xs ò <^c!RC;|n͊;D g"CKnc9<=UXU&*19<} VLcA";eJW(yYU?~'6.:Bx5 }<@3>噛 X;ӬX:`Xc /.,X˗.\r^.\rffffff}?Mj)o2"EˌA a,i$\e%PAa:/]; G9$)?g1h.2u 8քұj:|MW꼢},DPڑI@ZLҪƔ겤D2r Vz3+<2\޳iŒ#/Dmj̅XtewlF7==VU&6 sB}BuۣȠtyk7>KT⤥x+PҔ+I&ixdžTa]Su/?!DO _b&G{ ;h}4=XAʓ]㓴GR"C:.\Gr/󎛜Rѥlqo|<!i ũuxvꓘ9>IbYEn~n/߿UBj\Œ\*c Ad˗/\?! 5aSGg|!쐗:3}+ ] ^3.\z\r%?!{ 5H)- `q ZE2a̪^;auqu|cGS/ Ilg %, ?@_` g`?[]M fH lodO1ӎ&ik!]ɼm{ [d}@$$ ?ֵ*V4RJ+Gh J*$H @)W.ΑǐbbUnw$tx3TO.•rAcԉ7~vǀ@9BKFAL U:&bQлx+| 0 a, BKςK` xP@AYA#:A2+·VF1QbR=e`MKrB }$!`į(64Bb,cԧ!q+_::;ce:"sgcNnAJFn m}%%׿V ww'#S##CB]0ۧtW֊U*fB5*; ;n%[[&GKMl.1! qdY䠽cEAKyD&oxP;;6Ӎ]pyI`VR] :ȱu4 @0bGA_\Xc.\r˗.\ r˗33333?+lµT> 0xߤA{ 4d> e*R^Dse`DD\M=45N"eO?/n#6<{Ƿ2 Dz[euePv!Dcg *Thrʕ*kEyU7TzNҧj:/Collabtive-2.0/templates/standard/theme/winter/images/onlinelist-hover.png000066400000000000000000000001561237252063700271340ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb@ %|IENDB`Collabtive-2.0/templates/standard/theme/winter/images/paging_last.png000066400000000000000000000002661237252063700261250ustar00rootroot00000000000000PNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTELKKyZtRNS A$IDATxb`bbb`b &ÙL &*Y ^ P :IENDB`Collabtive-2.0/templates/standard/theme/winter/images/paging_next.png000066400000000000000000000002661237252063700261400ustar00rootroot00000000000000PNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTELKKyZtRNS A$IDATxb`db`b@hqHj" `pIENDB`Collabtive-2.0/templates/standard/theme/winter/images/root-arrow.png000066400000000000000000000015771237252063700257560ustar00rootroot00000000000000PNG  IHDR+fltEXtSoftwareAdobe ImageReadyqe<!IDATxXMkQ&$$MSZԝ ;qZĺWJ]UDETDDE)ꢥh4z^|5R7fpfy}&'bc#eppwjy6%0ȁk~o겦MWGXH `0,T8YV_P;%TB$D'y*FyCCK!o\BpISkF @ C'S<0P"&FGxCwъ_h3] ReÃE1/zwd@ERMks7l:RZB!0t]3dπq#ΒB؝5%ť/=e$բSf $() XoiL^#cN^ (wvjmGV*բ_y'fPn皽oӾqJJQc`RGG_/ Bnie 8O\P&^l;]Fǫ<,#W=mR<"fD[xJ%^*sYmŊ-DnSt-e )ZՌ4`$imٶ8p.lK/'NbjԐm m)8-.lKY-Ao٪],C %aA"A? m murHnmƖ,nw DaYJlńmDz%k4-Yؖ,lKeE~44pkM&eW2Ԇ"`jN6IENDB`Collabtive-2.0/templates/standard/theme/winter/images/scroll_left_miles.png000066400000000000000000000004061237252063700273320ustar00rootroot00000000000000PNG  IHDR,9&tEXtSoftwareAdobe ImageReadyqe<IDATxblsc8؍21 j 6 F6$6,f=@?a@< a@ &,VMa?.ĀJJEI6wl@܋-ۻ| fBS=w$=\5ڑUKVBKx..~dSk{IENDB`Collabtive-2.0/templates/standard/theme/winter/images/scroll_right_miles.png000066400000000000000000000004021237252063700275110ustar00rootroot00000000000000PNG  IHDR,9&tEXtSoftwareAdobe ImageReadyqe<IDATxblsc``?q+c> b)0b &r' w%!]5JtȀ 0*9*9%Yb Mg2_bW\JC3~\v-gL&x7sX$l,\5kQT##LIENDB`Collabtive-2.0/templates/standard/theme/winter/images/search-butn-side.png000066400000000000000000000023741237252063700267740ustar00rootroot00000000000000PNG  IHDR".M˹tEXtSoftwareAdobe ImageReadyqe<IDATx]U3/L\Lm b?HExWR,4{'HUtY,(Ue!+MB^%̌9O;&$ҽ9o908MN$ԛ{9CpmC f_IÎSWg\,gV8@`f9L(gF(@`9^YIENDB`Collabtive-2.0/templates/standard/theme/winter/images/statusbar_complete.jpg000066400000000000000000000010331237252063700275220ustar00rootroot00000000000000JFIFddDucky<&Adobed         $1!1 8`i?????T??!?!O?!0 ?/G???Collabtive-2.0/templates/standard/theme/winter/images/statusbar_complete_b.jpg000066400000000000000000000005211237252063700300240ustar00rootroot00000000000000JFIFddDucky<Adobed        ] S&!" ?099}l޸&ɃCollabtive-2.0/templates/standard/theme/winter/images/statusbar_incomplete.jpg000066400000000000000000000010171237252063700300530ustar00rootroot00000000000000JFIFddDucky<&Adobed          z"a  __???????!'?!??! ?F??Collabtive-2.0/templates/standard/theme/winter/images/statusbar_incomplete_b.jpg000066400000000000000000000005061237252063700303560ustar00rootroot00000000000000JFIFddDucky<Adobed        XR$! ?xJ[)Collabtive-2.0/templates/standard/theme/winter/images/symbols/000077500000000000000000000000001237252063700246135ustar00rootroot00000000000000Collabtive-2.0/templates/standard/theme/winter/images/symbols/activity.png000066400000000000000000000025561237252063700271650ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxsUdz?ݤI时VJ*RhZ$L[|_/ʣ'htJ8cb;eH2Hhj+_l~'q>w{=`$/ { `9R/ `0kL3IŹV_3 5ʽR-*tSz{7(̱5[-0nZɧӜ(KQP+JQT (mEOs\!5V.[x=Z,h4f.;TBx$ŲlEAj5{<'BCFЗUF޵p$)hɕG@wouuO5mnh2ix> 4$-qL(!w[71Nϟg`9GS8qэ͍ĝt|S.f }}} C`$Ym!\4񰧧jlhS$iMO)X,|\&\糙L| rR",[W6 L/_Ȼ*N-lYZyC`,dy*5REJ0E#0* s&A8V\hR')0x\Tj`PAM[ z  K$;ṙ0&̖W(vE vc1(!ٚvmmMuz#XդNvp{K陙HN"z7bX9MBo|~Xxbiwv úľ˵ι©ոÿp ! , "^1YIL[j[&u︞ŠmFNcT5imv_&e[= )z-~}ffyiwrunpv­IJ͢ȷƹӴџ߻{^!3A!EVd ! , ='j XWLYxzޯ bXH#6LS ϫtEqSpj=pBeM۳x૿iuyrwz~~kpdqʵ̷μɽĦƨO^AzA *Xb`0d^>b>! , =t" Wj7YI;ݽ69O4B n"iz%eX%bwfolotuxSy|zcfAYpeijlnI7 µ׹H]Ywo~E$(513tGĚx%7_{WS E^t{Tzvgn}rDjxaƿ·־֣׎;_9xb 惸O._3miB'M*~/iD o^IK~ ,! , =ɤ|7 $ '33URL+#(t+);HMJk9po~^Wْ9]-vAyNzQVpm%q)}rvk\~Dh%̼ӺлѾ8`s۷P! (1ٟtw_fqiyk{~dfEpz|&Ŷʺ̼ΨҴmM[|%a|#8`a?*Ȑ]D%cNw&ݕpJ!i! , =ɤ|7(j%amɦ3wF,cHC( Kb^%5Mw-f7.\LM᷹{_u'WmQ~rv@jyYZg?²ĴƸʬ׼սߺ][!z :h7 a w BƏ5^8! , =ɤ|7ٚuqpc 79[^Lp%LFͫ/Bۯ;NtX]lg^G<gqZxVzd|S}btôȾb޾ ilṆ*pb+<! , =ɤ|7YIk˹@N#6ZvdtE'yVJ49W5]oY ^j,gϻ>~Xxbiwv úľ˵ι©ոÿp ;Collabtive-2.0/templates/standard/theme/winter/images/symbols/basecamp.png000066400000000000000000000030031237252063700270700ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxXK$WUvk/Y\G@( #(2@"%$7=)B%#xPA\pq[^guu$ ~^+ar]Qޛjaz6wXfd_X6w/be< DDknn-..|_:|.K9G---'x%`28-774!!{]_-.$$D @隦 Jw@ammmePXwyyb2UUaʛZ[[ o @!-)ixx8# z,a?999Cߛ7tec6C=iooůPt; i憒o7B[02+HvvvhNNKHQDDI! eQQQljjqSmllp`J7sĸ(V  [\\d,::183g,3330Uj\\\iyyy.X}E+++ *sMfgg[__@,,>>P}I K}^UUɌ&鸓 *++`\^^櫍+a]\\ v||WrVIrrrymmm@IϤ~gU1=hg !2K^^g!'!!0'v3нcF"en?0~fO4!#r%&$G8#oG_ sn+49)11I[2+| kMcЬUZ Hz҂ D`U?h§pZ "{`gB ɔg} e ̷}}}PKRRvJJAʀX0zvQ(b/--mvGb)צB]ʾɯ%pܯ1$pj4MA $ǧ kkkMMMH T@/ f}BJe DDPSS (ӥ@[NIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/blank.gif000066400000000000000000000000531237252063700263670ustar00rootroot00000000000000GIF89a!,D;Collabtive-2.0/templates/standard/theme/winter/images/symbols/closelabel.gif000066400000000000000000000012111237252063700274020ustar00rootroot00000000000000GIF89azzzYYY҃䌌PPPTTTVVVRRRXXXQQQSSSUUU{{{```WWWOOOLLLfff___KKKޡlllxxxyyydddZZZﳳ㇇iiiNNNsssMMMggg|||ccc߹pppeeevvvmmmnnnooo,/2X]$(Y';8*'G?,T!'M&HO*DS0 4+8FB( WN1I"\0V#>[+EfiņPZиjH *806ܐAARTAP8Z0ń%0Ƙ$h"XD 'P2ȀPT Z$ = ꔫWJ;Collabtive-2.0/templates/standard/theme/winter/images/symbols/customers.png000066400000000000000000000031321237252063700273440ustar00rootroot00000000000000PNG  IHDR szzsRGBbKGD pHYs B(xtIME6.)!IDATX]l\Wsνw׻ήc'QDI!HiqJU  J҇R B^RWZ7uWJh&|ٻw93y觙93]܄X3l6Ud IbN8?wn.=ݻWDx@[DB! ybpr ܾ}Wu'$IJ0乩y~+NZWuƘCm~,XkATfAXkFP *w`rr硯*8F@~C8fkdժUnZ9$ẒwJMv5vi;" " bQ""޲=03O{DyªH]8&fglyeݏ-pfe(( ! !Pڕk魞@D@BVgMe_; uM6Q6# d3(NEL }tV_%Ӝl&$P&ٌl-[;z K/ )aQl1޾47{> _-xW[Cq]S K9ԈS{|G}Yn¾={..2ͮ[Bۻ*َ|?ћ7> e$~ꕺZr$Żf~[ނo|pexx#s;$n-T֢\{PWv N>=_G{d}gt3ZOWk5<3r&7.Z+S*2>ܯO/,,Ȳ##X`~4f ^Ҋ,Xc7J {{|S}(1c203@)(yV˸K$N7 k- B-[Mg M3Fҵe4@lj3zkh[{" z/5:G \"dBPIB3VyFZ 0D(J""`=8sk 7@ ]]łWxHiEf ꍀ_!k a*^FXdy**AdYf4}!˲yv?9"z]N*k PÁ߃gvHN`+bz[kf{Z;e锰˲dJU+:Zۭyrɵaj H3y9֡y y+Œ}/Yk6IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/files.png000066400000000000000000000022001237252063700264150ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<"IDATxXk1Ɍ~ڃ -D*( AOxB$zVP63M N!f"cDű 54`r2#;sc8yFV I CDſYo옻0`M( \2g)@*\5TkOi)P EM3N̸b{ *S_&ݻ;sl9sDzTUnq#bqVq--a?] ++\aC8^:03*'WVw!s j_T?x*Fª|҂9~LLOXV8vdCO>|R)t e!L#v<)騹 jjPo,S؆ T[n%-‚$%6 .?_(@ M077'Aʒv#t;f\j./} hfP/l0 e\H>wWf%A&RBPusɌJR/PHhP.Κy:gE(D@DGQa(lT_8)W&JJr7Q8\!޼N;A fK;5m5Ojj!v[Iz7̴f0[:jݽg3cc&SE٥ѡq(L,ۀK}+wOg2uIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/folder-root.png000066400000000000000000000021111237252063700275500ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxXIo1~L2ҽtAe ~!! Ul*4M[d~NO!/=;dDWEvF<1۶12JPoEhEXQ[AFIk|jgS;Haj[\L)J~5FY|Dli)|X먑"XHEy\--xTꓧ&[WȞ.fL3Vg3~r\?hM]bz(X& e1M 3q(6,,aޖ? {{dRr#lB: ih,|asB"aA%}/Qf"lMݻa<`YA|/u\VA$ϝb9 p tvA|eI“ojؓgp!ر#Y gOR DŽg܂3܆Qu4|\U2qi*RJ^-(BA?G"DRS6U\)NNj J(B⽫+˟@Gj%CO(i'!1$rZZ Ҏ!GP:TJ^"H%V2 &:o,.qA܍@#4jPkoqv=IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/folder-sub.png000066400000000000000000000006261237252063700273670ustar00rootroot00000000000000PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<8IDATxb?@&pFFF@J=2z\\933s?6񇏟2|򍁓Ov/_1>~p=>^nG:|VżIaC3 b@Ѯ٨WTImIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/indicator_arrows.gif000066400000000000000000000034711237252063700306600ustar00rootroot00000000000000GIF89a_\'Gm7$+!! ,w Ie9*, (*(B5[1 ZIah!GexzJ0e6@V|U4Dm%$͛p \Gx }@+| =+ 1- Ea5l)+!! ,y )䨞'AKڍ,E\(l&;5 5D03a0--ÃpH4V % i p[R"| #  6iZwcw*!! ,y )䨞,K*0 a;׋аY8b`4n ¨Bbbx,( Ƚ  % >  2*i* /:+$v*!! ,u )䨞l[$ Jq[q 3`Q[5:IX!0rAD8 CvHPfiiQAP@pC %D PQ46  iciNj0w )#!! ,y ). q ,G Jr(J8 C*B,&< h W~-`, ,>; 8RN<, <1T] c' qk$ @)#!;Collabtive-2.0/templates/standard/theme/winter/images/symbols/loader-cal.gif000066400000000000000000000034711237252063700273120ustar00rootroot00000000000000GIF89aNHWRb]©䪆zuﱑ˵! NETSCAPE2.0!Created with ajaxload.info! ,w  !DBAH¬aD@ ^AXP@"UQ# B\; 1 o:2$v@ $|,3 _# d53" s5 e!! ,v i@e9DAA/`ph$Ca%@ pHxFuSx# .݄YfL_" p 3BW ]|L \6{|z87[7!! ,x  e9DE"2r,qPj`8@8bH, *0- mFW9LPE3+ (B"  f{*BW_/ @_$~Kr7Ar7!! ,v 4e9!H"* Q/@-4ép4R+-pȧ`P(6᠝U/  *,)(+/]"lO/*Ak K]A~666!! ,l ie9"* -80H=N; TEqe UoK2_WZ݌V1jgWe@tuH//w`?f~#6#!! ,~ ,e9"* ; pR%#0` 'c(J@@/1i4`VBV u}"caNi/ ] ))-Lel  mi} me[+!! ,y Ie9"M6*¨"7E͖@G((L&pqj@Z %@wZ) pl( ԭqu*R&c `))( s_J>_\'Gm7$+!! ,w Ie9*, (*(B5[1 ZIah!GexzJ0e6@V|U4Dm%$͛p \Gx }@+| =+ 1- Ea5l)+!! ,y )䨞'AKڍ,E\(l&;5 5D03a0--ÃpH4V % i p[R"| #  6iZwcw*!! ,y )䨞,K*0 a;׋аY8b`4n ¨Bbbx,( Ƚ  % >  2*i* /:+$v*!! ,u )䨞l[$ Jq[q 3`Q[5:IX!0rAD8 CvHPfiiQAP@pC %D PQ46  iciNj0w )#!! ,y ). q ,G Jr(J8 C*B,&< h W~-`, ,>; 8RN<, <1T] c' qk$ @)#!;Collabtive-2.0/templates/standard/theme/winter/images/symbols/loading.gif000066400000000000000000000023771237252063700267300ustar00rootroot00000000000000GIF89a&&&似̪ظppphhhFFFHHH222PPP666VVV! ! NETSCAPE2.0,@pHL<á ĨtW`4S退-k\J%<f4c`𸜛 GyXg{wQoX  hDd aeTyvkyBVe vC pyC yFpQpGpPCpHpͫpIp pJe֝Xϧe p X%ia6Ž'_SjtEYB!  B !BvGur GA! !,XpH,(q9XP2TDK%fPGC P~@D@XĆ۩S~ S  S!u~! A;Collabtive-2.0/templates/standard/theme/winter/images/symbols/miles.png000066400000000000000000000032141237252063700264320ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<.IDATxڤXolSU?ڮؠus`aP B_ DB ~"L4bhI B8`0Ǻu]o֕ۜ9wN9W"sKaўohd#?^!R[ut'i[ ۇa;8N=I9{څydTtY!f^U}Sa`SCCq\N>ñ]w&@=+/UTWɬ]b_ˆ1ڷW`c4j}xgǶP!x,SdݾuvzDR$DJE0LHD0Xj_ʊVH?bd~JẺi` K&8Pwh1JƤ8Lœlr84SǿDî1 ~?R48v- Htt^ ަȅԔgc*(/gW˝[ аr'Ri`2[xk{& xkjPԄ&"b+6669>T2 rɹz dg3`5dotEV"0a1:4z(^MZ 34cr6` ˫iՅeH d9>*}6/7[rιqboxkJ V+4<5 3HFXHLM2?}Ͻ^&7eΜt@ٕ7l;w` 9oZ'{c/_da}6ĢQw]E3B; ?Q0RzBNe>ִ' e3n&˴R$14~?Hpl<5.E6##*A$DH;H&8ٌvW&kׯY[W?/Klny=rsWd<zvb8IMĈճJ $˹7GƫqZ }E 0N^wo\'x붴p(рeIbgvť#$apuiI$練wWѧ[sJ6`*ܘlF"CVHblִOEBlTӖD)PFy##Jgc F,9јfl.]]{q9\p jk+) s%IFZP'HP_=1иV_'_ ¼ԤE_ LdC ѶFgjjs1Ħ%8YKeazI<ŀgshR#>ëk$`O GZۈI^]W  ( q|f BμST%*Ύgȳw1Vj2$YB+sd$@`&D =KUO.b|$cF)գ,%Yu&Ȱt*dδ@!?ڔڢtbERS:̓JV`P:k6Qeu: *3f|#m+E!\.?MBݻw mt``ff=A*55 A.G>FT(ZI?L` gAFMbzO^9+سw?6Ds.jg#3H&&SIttt L"E;"Q(FFF|صkD m"*rmjI&I!њ6г)I@EDVJ 7v |?SGx ˔*W (hʔPk4ȷށ.^Dn\@:8}χɛ7B>Gy]98 NlCf p֗ͦ;c 0D1۱*ϭ[-|s ZWd$Ʀ`Hi.-5⠖AbQRuZ% ʺ?س%dy'蜄Qbnn21Ι]!ϗض=@)"h znA}&gGdr Etw' WD@nֶ@_ZPޣVJ_i{{{n=ʟSv1gz<ɅbG鳪 IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/prev.gif000066400000000000000000000005631237252063700262620ustar00rootroot00000000000000GIF89a? bbbmmmǺyyy廻WWW333!,? `&dihprmx|pH,ibpdӦ@i@0CS +&vOR =Dak# ~Xb%| BLbs# i&`LQ}eg|X""Nhr#\C&d"&x \j$j&~ȄrXtu`YJ"+*$H0 TPaÄ#JHS;Collabtive-2.0/templates/standard/theme/winter/images/symbols/projects.png000066400000000000000000000026171237252063700271600ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<1IDATxWMoE~fv$N\'$*R  *T =rF Hpp)D@PUHJ>4M4;gzgg?…_zvgsc ?k˹ Y SBy R <1"XJlu jm(L[  {{{L~  踌7~eX6%:T*|/7;?|K\oSCXaCD|G5Ɔ%lVԬ=ӓO%ɤΖ\4S m6-+cp>=yZ+ s[!d)0fbNOL:y̲9~Hh`L?dsL^^< 1??qLs ~'yUh[6-W Hxu $Clnn~0ͽYVclEDŚH#^91N*dqsaOMN"4vb!Q>6Yn]Y× Nc⋨jL; QF40U`Ƹ\{u2pxx(Ad2q>f403yӀ拏9, q6(J3r~i5OSfXG anתUk/\x"ba畉3"ZX41zj){{իs[<ۉjwX+сOKdrclomT( =24O~}Y|偏RXo՜ufFU;sh騀DO~+k+IR>~WȊQ==g\O~xzz5U"Y7k*J7##}^$la.=L]^>_T.6vccӓP;VcۉRU \y!-P"cCoNON&#T*)g|$z `ag31kx-s0[nGxJ5EWI_Işi^ ۺugʪXBP9lH(f8Yp}le[t&`j3Jʼ5NUF1 <4Un1b&O6yw-PͰDq<ğ|lZ;s=\z1atQJg!X+qc]]k}("r 8JW# HS[)%v#t@ dXs 4nj9qT4!'cM0;IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/search.png000066400000000000000000000025551237252063700265750ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx_L[UZI\ EHfHH@`6=%7.|@gmIA#5Bs^ϽMl=?$ˇ?CD^k|G?2s2|?0 @"rOYPTaIjŨŭP(~왻Yj(Ww$m򄍍 PZZJ~ \=SFPIQ{矺Az  > T3CF[[[Exe3t> mooQ@c' h  V0~cLn7k+.U魷yMUMS%GyEE9,W0vf7ȁFou2<=M=BӴ|A-X s=+_! ʂ(X҂!pqEQ `>8hssI(Bopx[vFT^ٓp@ nll,z>ޕJvaN*SI~V,y}QU'pxJS45h 6t;_f;VG4 Օw= RʼnW$2RBzt>vYOUh斛 S~,$ 4=g{<ޑٺ:C`zzc^2 S*;us{WV&''_XX0ԃ0Ef::;?dYN$芍z C!h z`P eD{ #^~@"AO8 @2ud0@ah*c Dok\ LοEzp0 093tpIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/system-settings.png000066400000000000000000000035661237252063700305150ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘p WKT$K1Eog4a 5=E QRQA38EDB ITR0)I]rroEtf{`Y+ ޡx7yxYq W@M0JBlt}j%k6?-5so\\@e/!*zRAS({hkzRo (dslCC ;j7nݹdF&|˺rvvC\]ۻN0Qb2rؓ6wnDevXс()z:0 MTorO2`༥[(fPoFchawRS&$$`1| &v jTP 00pJ'd@Z֢~d-fQ)*'&B+:mYݿs"ۥ)Cʩ;Ŕ\ISŸAZ]Yu.%xdt\GtP0J0` 'w<3<1 FuG_MԔOf%$^gw,gO-;˺~V Os߰477Attomm]ǏX,Ks 0LOUa x0%k!H1#[nR*Up}%(**ј!̏ mY:n@@U8k|nx\SƏKy榾 88'OaaƑ>ƍt)/Ct7Ð Zyi4]Eөܼ ].' zwUuu5ߙ}0##rKiʂ;t S𽊿D0\˿R`=بbd$eee(&YP+SOĠU,Wn5t:`̘1D^tXN0m.1iyݾ}ݻӛ6mJ>^˹Tۿr^NUmZα]Kg{ewE N5L 33Ssp9+w\Mu)jgFz@$܄*FZ^a#VYPR7Nj[ERL [S{͚q Nc=+.dDXC :ɍy77FI κ%Ό&[7J,`pkD{m6ͬ5۞??D;ʳo'?!ޠxt;/JP-A:I] U4NunJ""Mqn@o5bS uY"8^O]72Ar HmĐ$K#HCDM6W Nn' 9<ar {Fm(:Æ\?^.,S;Iu֏+!Ig,Z }{"rȊpim )]XMvz;lW(FeLP(H)¥9Ml؊U]axm̸ F~h+/ A@ /"ԁԢ&WjuJ7p#7uq$zs*HH Pc▣Rd3.mcA?N.:]P ^k]5BvO*7ݭUPyfnaXo<_ya"T z>H1>901{+ o7Z," R"RVUPtAͦS*fdhƆ6}-yRK}{7)l&>^OwdhJY&)*3ہMϰ|3R.R~Oў%dR!=f6Fwl}?]Ow\4o<47[l/&"b" |_Oh7.-9& CB8bޏ8ff"F)gJ{Vt>Fۊ!\Q͎jv_/'IH b!_*/.5ts7Ju0kx>Sf2d s!;u::sO~6^MåwxUA@`? bnB{^<Jb S!1LY :B77Z d+~/)֑TaZaE EqL3_<5ٙ} I;081a(U,^Z.|[;>DVځ4N[Xf]0J8┒Աŕzj 9qaO6S C{$is^mc$i¦Iqi5qFkdZ0  "&B/V DI*Dْ雓9WFT4"C=Y`z3usiBY[@B;m&]x&"gky9bnd}s9Nr)gi3z$")I@$꤂@ R(@PLDJLp"I@p'VHaXR_ s}'UF1JT] _A(NIcC. a.I ΁Bʲy`02ixibKu%ٚumu2NR399ՎSwv}jZj 8D( NI}:HVBzj9* S)sG,F8$umd'𨂜<ϣmS\XYY^[kmNWU4xyH!qx 'PavĜB<844+`u^Z8aN@. %焜_F+H2fZISq{ij=k-)Q#Wc1F|abs}ρ ũq#$&ML[d%ABU!d03 \p"s<1rY{a()HSgR+e8ƉwkAjW/EDu﵀3^DʜAI vCGy2g>VZ7Z d6p*&TDe 1%л/]W de6Juõgm J*lczhfDk'-[ꑪ VͤbtݛI[]{gQu[7se'-ϵrSxwŭqkƭ.yä\l Y1`@@ZTbMu!v288|\v]VrΥQWW]+E-fDthtt|3Af.qYkpT8l]rW`jz?ht:HDs9XkamʾZfW|wE?]dê8׏_YXZ ,tWgw-V+pQ",4Dn.'8*Q\.VkVZbeejzj ^û!ô&L0ayٺ4>w\liA&G 'RØ^<\5]NxN 2`c=įO~?Pp%5ݰ/~.4ȝIXh=G r^qb e=q`G(>Oڽ_vE\Uug0~30W_}5?X?uI @9Jݷ|ā] n]s/?Ea\pѲ3MNNҫNVo([:!q fw3I\ i'Tw>[JGnʪ?HX,Nr05Ƙ>HObHS?<ٮmCk4IʛԱP($x@l {Ÿ}t"gcUXpi :::jg3w/ )ff.aFrP ͸BvdAIҹX5 SU/" jvTc2n!"Z\\Sx2`\Fed^!pzzZJB݈]"[k(ܹss={l~! > 70_©SjI9'7{#t!c4 Z\\N'<>| nqE$|| 삹?*SSSZTX,nuۦΡnZbaa^~v45jh4PULL{箇w~}sCnHWQO^:i]za<17rKwNKKK8iG/`f 0Dŋ/BD>K_‘+q+Gavn6kl'B$ ^~zLJ?v \n6}݇Zz/7&'&0::Rq`=-d C}kkk.oIH,C֚*nO\]w-gK%TB7`0XZ^tN\lvu韡j9 {x6&IҍZ+>AW^E2@ss]1 FsyyNdA:X{-靥4/fw'3avvV?*lB7볾*t:m$"r980VkIdDtuŋЉb4ν O#\]Zr41eJwƺJ>0y8ws3`f8k9 38vlE\) @T@ 8qYfF?z Je I(= nQpE9sI\00FK ؏?pO?AG@뮻u7o T\.@Xľ=8vgw dvQn# CZ-Z-" C$I4M\fyh |?yJ% b``R R B\n={F=t/6&lf'Z;vۑwΓ统ۋIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-desk.png000066400000000000000000000070521237252063700270170ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe< IDATx[KodGۏ3!RD~bM#~@$xX;:DH#ÞĎcV;Uu}$J}ޮ;;ꖥsN|y  /@N [?؛~W>(43 cնZ]mG|/UM(;iwXQ/J[:TXg n+,ߍfuug7o ]yՕo|?Pi @N3ι|O c V T{l=y.g:WpwwlCПL,v' Ks@SƃcPƟ5`#`r)#KɁ%0!PTq`Df]Ο?y۩0 ^fy} PXg Ö,ʜ| d4tT@:e8 Qk*NX {a/ q$,TSVQGa|MW퀯8˨8*Ƙ,Kr ++3isGm;=,ٳgG{Sd,;?eBT^Onnn굵EϤ7WT:͟m6T3E\Ă)z۷ƍtnnnTSy_SY( Lf,6fS! 1(x֐+- QUB?FKT^Eg7CQ:$+b,Λ'E]glT^ڟG7I%7ft/Apa'zH\e~yl0Ub䤯 Tܪۯ/Bg BR8,1v O话d2!5~J@^x-8njD73V낙RRLRlP]u|L0"Z=͊'`^9i3 Bꈹbݤ/Jm"=n{IPsY8YWݝ$&YٛuggGs n]Ѱˢl/*HOھ D#IPW*7FL Gc~W߽;wijϮj̕NꓥL!Da?<4{{{b&x ϊ%`j51;;$m#`(`~kkKλ.rY@Ph u9j׌X9Ue.)ٜ-=quȀNSNUA9$uave>&ƹߝS}+C @nln}og⯨V˹+j[ArcAn%xn"&~~֓ĮڿxX8$AI|2T֭\a#s.OwΪ%F `J!ݣJ̷r/e@ d-YbeA0SE_\N1@x ٌC^qeLrs$7\ZF7|z:x YQFcsIQK1M&S_>AyDA ځ@mpnղ X`n3MOXl,x[70pĢ(O*pǃHkwfo -MLm:.*j 0AI, muJYĦ(؈c+hρ$'aqli&b<qC^s-!w@hoh Z$gk{|2SD }4߸fYl}l_nc!THFEד%CDP%B,?N` t7OM&j'pL!!s^֨5M= r) @0s11w@jU\vGWV8:?NEFTNu Dݴ_ z86F )eKAicxS=;2U#zs}Ey,x4?ܵhA#q]SF)!@OxL$2/_RƏ#\|4;ɓ@s EhEI.ܲi)j\c^d;o)>+.| O,Ztq(=O&% 4#*#q@P$& 9>#C8ds.hZ|an6HVta E6)й$9Kz{ d*-lZ}ؾ]oE @X%?gَg\HOȏzH"xd%EA1%ykQi=} sgR~ wo?=(V!ZǁDMdl^Ԉ&gsd ՋO(嚪}btVkJteù6{?xZPA2Q(L3IJ FMsH{tG~k{Yx76VaRr$ Ќc= #*|L'8s92<3cg- i`.dȚ ]mgd3WϤe GtQ)+l'{]ueC]QdA,sڤZʹ8ǢGw:_Ə2j'BƆ鸛lPc#qi۳;_u׳-ЭC~}Yl; c,QS4_IcVO7Vh} Os'@OgYL<ܼ ]' [ڿ#oͽx-K0*PE z׀0ʢpKi1Ye !sǏ"zU͜}y }yhe$O@VDdltnr Ki+H%6iAdY`@ȩl6 H6% ¶P`{=MceJ 7AcFve[Y q>=𚝁% a/@4EU F7l9N `< .TV~gwՕ"]j-c2 djy<~ȯpC1!鄘Kl퐖 ܐ1/FvG;j"vCe}%K5TIPE@O敕,X 2䆆*%d-36hF1$Iv|"WՎqA UeIі%&R?*x]umM~z*e % Q"C!Gnn.Fahp q$.{z P[?05>x5fCh B\ 0p'X2̕]Lkg.&BN. J°˳®]HᆆsrY[nR0pF͂`ւQMW Se ] ;X*ز.ɕ$כͻ b1MSDEHt wMڽ{wNaQ mPmVj04s !3±acm)w]e!>E䖾YwM-|jvC7nd@o&Xntttֳ#Y_aQgƛz-%-Andd4ğ4Ot Wf=vZ01Р`QQyQ^WQ!mիWC[[\N> }}}i@jkF۳-HG]qHt\۳Q@qN6ˍc+A C|eq15kְvЗ/_* ]qLπ^{; wn8t}4Ȏĭ@w{[ WnڼTQa9Z`Ds9Lu&j xS#pךq HDمOY(WKAN&?)Py!L)qYYQ{h # ChO|?C S."& 6 vF 13'4g:ocd ᕽR}eğ?@wiXkldʵ $ ܌AZuѣ)q*7~ɗ;u>[ P:5"Ơf "֒p|ƾƑ3&pwxŘ%γ|j75[CQz؉A?Ȩ? 79 @Μ*|&99duVLvqmx 7v`iaNͼ2VX>xu<@؝5la-ʏOR q8&ɓ= (+ᮯ. `U}TA8m :dCyQ14zXV_999MC;r#LA׫ Dt~Pڱ:&>!7VY +g:}]u5FM1kB82W1t`b-b؟]b1gEK u 3W XevI`>e>l5U {8'D1v.5H 03 YSzpd]+i{s_ }WPu*l4{>.ʶNhwy\} [(Bi(DSrQY~Kx],z DSC@S@I $xPi~@?6 Q*ݺQ0=m ;o]" d6)m_qȒ6Y*?3$@dJOh/䌲K1 J0n`󎃾RWcl%nk+wlr(8na9œ DbI{7 WF3f3cr%߰sֺTiUј',Ibr FV>#-ftEΊUyI,MI60:nLC3АK(3Bw ~694=s{d~XS`ΖZUywދ][/6(ԄK&0ZYaeƓB4 }vy\<6|5/j0"=mh 0|SNm)}%tc^b"ڝP0;czur2 ф?ECMϣ 3 Kw:.$(o J?n pz3t( U!PPU;uwd,ώ,@T }wwKH8H-Hw+j54)N޵<8f&F!2.S@ichBBI8xR]qb:>PtDPU oQ2گwxbv_EIvN k,8HZd$mHhd"q,Ah7;²KIb՞m5QT(:(`w3b2 "%ek ;FUkKg@EIFr LNjjFvN77 tmxlCE7l>y$0Ľs?~UwL'PNb/wDi孮=X#F`n6#23LAwioF HO=_mwUw0CWv^v#8 T>s[j{4nS6Kej@rչY<%׺{? h{7[G'[$7&-%ԫ?yh{Tܿ. J 3h~YUujF'VŅĘM=cc0e~U3{}~C}uBL(3CfL>~aQ& /ډs}%Ȑ^W7ȦQt$)$.x.lyGcH uFWr}'g#ܦH@tkj&9#5m30/=JifCEmRWCd1%\+TsTg߿=&n  U-C&8 1 tUK?b$A"+fL͸!/2J[)zδvC~cD"#Qr^0"1JR)"tPB۰#(ʼn?,-Qb` }r޶n_:.}XďK_mFĜYj+@$ԆƧT^ . mUO^;+鰡Y eDd(XɄ^BϘ+ )( WGSؗo^[{s5coPdUP4ʨA:OcFk@%.$X+&J'#OM%ljJq榁8 /q0u@V$=g]_㣆HStI r+ le' Qt$1J{ VXR1&%Q`F"ai$"5SwbbFM+Kd` /K'tkfD)I gQ1903": UQU E%`88d1;d*/c٦Qb3ȲEʞ3!9"^=r^0[<_Rd^/cM683sǏXr钞&p*|O`s B^Egi9Xy19l1"--͘&8@]?˔)e ]jGEs\ue 0[Zxebţ52Rk#: |W}k^[w<mxr1Ikyؽe;kXZj>3A &8M&ͽZ%H9F_uxw׻vG*+06kFX.k!lзup>w`K[>Jz/]/ / 7,J ?L{G>w.mXe~=ggo*#(+]fw4~]g/ .jn*FcqvE|wqx/$ V9N_|ʪW'ކ_k8R 4|S=dm6B=zp7*~'~mjˍs$t~oPͲɏZAD~h|\$;Z:}Xٽx@]n7E(XFviǴoܴJJ=7P>ɋ9^!R /hx}#eP6^s{&p艧~Ux8PwtP-mۣuYJ>߿\ BrdD;ڧ&;yb' g!13W\~@NV[y_iYL&Y FRTDuU0hʈTTXM )x*ԅʝk,slcYa/ xElDۋ ׬f(I`I]tfzRgJ"555EW_-ٲߙ$`d "|̅m2IV@6~`)b<+1켵Ξ=ksr"`N)PT$$[N(g.߻ZvDC)3@`R4@udGޯ5.:JKN˰lh4}Qرc蠠QF~ckb|4n,PАpuTO* nI]B:\ H}[ZuA 0IYI& 0³>+Kȧjj,։kQKt  X0_O_fGF%:%U Š -}Lx+"^%ƾ>DaffիWQȑ#[2qu)RWb#7N~x$.<$?>5e%:i .`XWok+NN`bbn޼is3JJJdL) [?s>/vӏ=g|&e3:z[*Oj7n@[[$FΉ'×\kbqxt^<~S3e>墑(f;DA7TV—>SS_7aoGl޼"V#, "w!L0|vEs`u5ѓO:&@.lZU%OzʕUь-?y)}8s`jfa6jfs@P{V:^ g׬VUXms3~Db&wzn~~` 6r<+B=x:ʫ_r_>`qeli61dF&` 2{awܝstWէO>gE35]OwU}Ror #zc]05H`:9g?g:c(| +?raٶ׽dT疝g:~$7kx:*P b\~]6U*$3Au'5|>zr=A,xXt@>=Ȏ¤.^Yf(Cf[f d?c"ʣ`OX!r]U'$6Z;l@YűkE][\2:@'l _tXcX"φu 93 g˳% ( èObXYW^9"#jkǗV8NVS:$-.;l.|g>B\'9| ^'clZM!9[K/m,y9 R%n ku' 6')*[΋w421qG I+cp}nO ӛ[g'(D1odd~Zʧ-59Oby.8fE@n* *Tȱ٩ 㡉P4y'8E2(b9%xd8@i @S^]aR4ԧ,CB-kIt5gf1>qłmq1H E|ìXbvR(sdl6 C|皆HQ #E#rbgvZFȠYm1hfc:jiDI.LY#aFԅtߺlX0jҲ bF;]lKw.nNNAPgr\~MrO&q%M@ HIMEIȡ̛$ng#}֕D1 2e+P&. q0:7Ad%VoU  {zbE־Og'z; ; h[Ӥ> 㒁S.#0ZNB<0`mh!"W#I 0o/.c??{٥(`Rm@ӬQ]k7 lLg0lw\)$UdѶ:ƅK$قi2@oߦf5ZP'eԽ~Xְ?m2|dhsES&Ó$`IA 6$_W7nŗaj'Ų7Y4̤5XI8dAU&2kg#1b,˄s~a0B?0d 1ԛݫ"",>q?FyZT&ِkRPQi1ҵ.+|T^ym쪫? >EAʄgAgڨVVԳɯ8S>8AmfE]2;/aw_ʓ q_P<N=N8[lةH;9kf:g Jhw Ͷƻ^=d89\Դ-90V-Dh/lN>ʂ\/ˀAo*w^2p~,2 6;37~AzjWXƘ-OCrm`0D[] + Π$s  '~QFu;{ϧO&1ma_ő}3ʢ./Wd,PX&o:~͊ tR fuIl]ʵ~=O{QON:Bh xYMɻu۶mf$WuI *SYbW$oA-=)[P2\} {>sGvSHuXzb6졲 X=$6g7/~B){N(KYt3-y`#1[[&庆qБm3$[0a|>MgR^r!~ mkIa@NavнEsY/Jf! Zuh"A'[H1)99N^'08cBL6/|J^wf aXMWe_ qԩwOY WAAEYEnˈ?ޡA"ttydj[oT7MSB_^._y?#Te$=WwGV1g`m'L仏!?oP, 1)6,S 2^s=uNR$N`K"TgBog\" erwYuy;wap8rZIh1EѬaBP7 1(C&{Yme8H mgo}TU`UVVV8}֓vX dXd|>JVt ,௸駩c3PG[Zl`%Ê+a?Mc /|hBJ,SSS,.d吒aA"eI[z_XD7u:p zֵ%=cK&נɱu\d1>z!5QPR@#7T8HU\/} P}1/ٷUIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-miles.png000066400000000000000000000111701237252063700271760ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\ylyؓ. > '/,:4V ;895v*rZmKo<^R+6G[9UsϾq9hZ*$̊QSd_PX|+"0B7Tomgj PRY= 낶//G[`[_`z/9v*kIuHxT#S015s!S " ar# pGsv | ΟHGՑek&% 2$Q]Rano;wu@e;w?[&d"YG2U)dTC]u*4Xnh|g[WBa8\쳔U;=׵$V-e %c` UebI$m)0:zW`R#@ڝn(mNd/@7 v_ b޾JȹdDH%n2nj5van}':~9FQH#T5TzM%AZl׊{?$ e[F*pn 00:M>g{_;f _A;}UUQ&V+mj2ZWU!%$iKt/\+a8_;v ĶA `R{=Pq4G!}t2G̔!B.ՐXt<VJH]ހadP}ѴH&! ]<=C6GŔ$RCI)O8RTQDbBJYg'>FfaCxQ1)mл~O2g#H_A>+{S6LɤhI G9.sa`cS6.mu9gJGϞڷ\t IQU3xLII$$r9K3m̑ l#bJK$ۈ."Tb*L'%SeU ,Jyث}pk?0gi]vBCUAIHW&D[QH])I"\,.80<2$eвS-@7PuJdv{C*.t<TQ4@Iq Ia ގF3;Mi֐نDJC;C`6S̆)&ѬQA"W#aX$zK9]*"s6rdltK#d '0W.Ì lJ>G!{&Ӻ)I*l\RvI\΋Vs ܘ]g.Tv$*YI8MD MBZ% !% Z \VT2(J fdH=^1iX,$|!P=bQcPªcW2D"H+EGcc@L;KcE͂`ٽ׾΃frJBUQqPUsdմI&vm0cJgUmJie8vm))Za5{KUsŚۓ[2/B]h;'ZӬn(I[vMw˕\X&de`Mٵ,PtwA(+ Sx>酇OAT?F_򈙛F`Qt]YxRBaCI5C_26}9*+3J{`Zgŏw>WQi$ >ʫgv~/x{ƣYSrDpiNKL@yy=͒1xPS 4g:GHuEz_z;ZxgM@;ޯD:ٳg!Y\\Rډ8S=6 A 0;pAWmskPX\ #ס'an2 ;,ɶ nNJ@J[:x>(ls0-hi?)ntv]<9ohjZ1<zd}w4X_cd<y0뚙ROɉLe[bha.h3!P~VggWV~l~u ±#Ʒ4I H:@[8RיqO Ox^CuUovXpG`]龙Mj <@zk)iEm远>J 6>"pFqB0 _gm6loQHad0?6|/<dۤizkw!V N}&˝O< 3 CN8𕯂tC͇ wkW.{ v|>`PxJMtے`xDJ. u۶|ov, v]&ؾyn C ?غMH}X],q.I37Zr3s(}ܱCƼ7?7w>'b>S 5C4/P~pꍣ0Ixb! Z+O9>?g/}yɻDG糫'͠%*L]{:C}K+gwdϩP{u5d4g0󓗡htNfzw91*%>oӮ-nymg.Zv[擫]!IC )R |eQiTo~^IW/I9x T .كqq%h{t?Jo?Kx\ OO:ikͤIB:+ ^EG@U kg|0 3b%u`'`eh%L@Syz,v^H]u$IFRsak)ibZ+Z͘~lȮ uan>i$1GL޼.#75ö rv YL,>Ǘ0TJZ,dF0uk b$I@AW%[%r`٘ժ}Zi47Kz?#LhA~˧ 09̆8IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-msgs.png000066400000000000000000000101221237252063700270320ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\klfvvsc;qEx*6$*Rh6IQ+?*_ZAD! $Ďޝ~ۙfc';k JW3{=qqe"E A.\9;=޻{vqDccf#^֒2 เPm urnEʯxW:WH$rf48[3)CiLTգ1%,@r03KQi? |ɕh955HT-QY9g(5s95*SQA4[7&09M GwN ,Ɔn ]6uѲ%>j帝nq =gi5tקRυIc6 =ec= LÿnoZ+:oXJ=A޼ E$kh*8NZ:ɵ& E%x lGꉖ떖Kߐ*J @&8_<Ƈhl`5WW&cf+NJ?!/;2:x}vnٴCC up_V ˎQlk2++`{JG`>yPK4k2!bhmE7}ƘZGf3U<,;wS&N*Ǚ1ff2B.c{OJb^vV,i,hNO3C-V ۩z ˱,S)"OxI|-~pMٰZG')"ӚJx&6|%fb%@vb < (7hPrs`HPSTkggHygf-UW @sqN1S{w0c<˶ HvJD(@r**=0@(Nfe4$ ^MTdJkW,1Il9Ч8c3 b+7*Ϫvi]IȵoU*hx,H%E^x$`hhtp:5$8O ᕯb ho_1|Eb0Zx| lۺYlj)%84s{pN2@Ss~ xvAZ6Iiq@bg/X[6 A&ɤ}J=9m1in[M›b̎04dt'j 1M[%nڦFp@3 *Lr83ٞ1Gv ̨xVY-l6MPHGR(Egڳ 0i.>!N,+9i]m7Xv &ql,0epha.u["NM $~h&Va9in @Q9Lo<abb.d2xz*`I\8Oddb5gKl$X<*10 3qoŰɉc),n߱Mn oNNq/2maDao eE;NG@F"a/`)eK3Eܰ4!yH) l=E@[±}옼XjddHeNL:i%Sz[QbC Dt v*e"E d齻GNELXѣQvF6Fk|~k7|1)#ҊϹ̆'K}=TĀOS]]=_J<$ZGh[k Dk׮] U i ʕ 7^`8{,(@UU(SS\X 5|E!OLÏVU-ϥ !nEve%LTVVFKy#̞G=]r-]|C|/R,3qҜnڵ{MNN&=pz;fkoFeK P;::+ًzfڒT#ORoo  2=.#+4:|,F3亜3\ X.=uuu,=\͖3M6%mHv[S]Ko.utQ08! Sܳ{Jq;+Kz 񃙲7C"wks @icM2-PawO6:Wt{/yy0+38EkUե*XJtَ SIIwvv94 #e;m`یm`"A@Br>&KKK Z/r$$v|MMۗ8Y6uu͛o5ȴYFtIՂB<Nk1vbYPCv/[ O @fRvv:Dgϝ?O~V_-JEuKsrղ͵!l~,BG\SYEz(Tݽ}.2<<,7Y+ionndF W&|,D#JJ(C#OizzZu,?~ Fi`TZf Zǎ ,^r={㔗祁^ +WɪOXC40mKhMb%Hא|%$PWw'g9518_I9܅rc:]Nh;If>\SŹ: =$<-_ﰿ UGϞ[pQPWr}C^Ko$IQm4dP N,2AGFOJ۬T\/_z0s rg'$k>>ArO!b3nP$!`1{!qOZ$ X] `3| /W\"4XcJbrOސ<Жn8h. lS6XX\rЁe`r4`1*9uA}Օ, QPTҘ<+ &''! mOIo:֝:e(.aưlRc.=ɑE((nl3 :d$1* Մ(rUZurRPL9LЖl=+J),,/-"2 3c%?>끷EdF]HT6Yv\RW25kעm0K:S߭' 6e|N 4TּeL6IYw/fR$&>k"TWr K := MC5w:Ob&@b+Ke5T٪pD/2fNqړ'Fu@e2EG9_[r%1&IW7\SQ3spWi3tt$H Vb&&N E_])AGFMdN,O Co+ ـD=hO0F,2iGC{'[ϊrPHMH]9.rj~HUK RbǣY/,*k~(%B(fq' NAVwJC ?P%%5"V/l}<(H iU>@hω{ 2Q3}NG& hrA0@tf3kЦOK4a50 ?E[Sg/AY_B婶GzM8K,VYr91I5qמ@n0ӠleR'N֟?&Q ǹWh5̀Q]R/ H,V*:0 ,)HRe g(T +o5[{h<7:6ǎi*/%&a/rja{|* {ش. w0s4\76 =}}s"KexW3 3T oe 0I۲4dРS>t~{7 %q#?GBg$oyW9 8 4Q;eT%s?1kTXw%>L,/Νб^a5ʐR|UVa\miFKhL8ܩ*$ oD;fSJ;rv\>2Nl%j em:.-0MJ 4RĀ.]DSIT0\>ǢʄEL0RQ۶=(І6OT[>7 J Ä4V 'Ϝ;;:޾0l1^H&/a Ecr(8ZOO7d(wQ"tvu'˶3 {peH$j~"gQlWh5?826t54F$S26Ro!S|)w>}>ieKYw,Wm5X=X]cE:t Q g䪓UWV]+ZbKfQ;i"~@V򕪖VEP33 Sx:YєL'&sUY\eMEIeMjj%UYOe#;հȡwp޸M%T` ;ئ|llӆ捰XPv1b 2fyY:дCFov]WζQW(Rah0؆/5 )rPOuzsZjdQl e峲OP˜ IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-settings.png000066400000000000000000000064601237252063700277330ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe< IDATxilǟyw׷1C ID*jDhVUJmoij!FCP%6j8& I8X|zPۻ^$c\;#J_MZ\\\\\\\C>˿,~.-˹9UA5xJ&gP)wʃn< ‘}v/~ԇ*2 (}[?ԺsUg`30F7{sC%L'd}z}|mKgމ VTd'ܬP8U9 wp|1!i:&x6` WkɤZdFd=q\SP"]x༦Twa"8aX+m\YKg.׺(7}WI>`uiu=`FcȉaUdē/C X]YF+6:fvgLPS}{]ծs H-P0U{Y UHaM :yzϊ& qZPddQF) "P $YE]T OޒfRc<-M J]{`֯.|&'(ZbArM %SV@6A\O¬B(ʀaE8 U=PD,0V:( $inUZ`B$gJrpa seXe'*,BJo4CaifbLߋ7%5H=/!1*2 z>ʀ-xj@a0n-hPZy<:L XM6[GQdON<@_=/4tl-0=(Sk¦jP Ik|ʠ$,fWy@TkkGplha)mK2fdR Ƞ0QNmSSV̦ɁFkQ4DLC*qH \L0qq-Aժ!sn!Մ[;6A)*iI\L?ތOFĤtXL.f|O" P2Gۀ_ނnĜ2F,I;z;%(*{BT&pfbc%:=Ӫ$cM_ȅ~3p?n222ڒ~ٓ/zlLUfw%<xVd4ZHTE4`N4{ٱs7SDo:$o 淯xd˖<^)dw 0>91q$ANI+۷3.^/ÇwOk! tf@E_@Gѱc>5S:92Y\++K\. Ú^r%y桺qs8,ܥ!YVw: {zzl,R" CTт̑HY&USH7 m!; W ׭[7TUU*"l6hӝn^6nFtU(O`2@^qiӦIF&I`oo`,bNOOS\<|00l(]bBArgz/ h?bQ](^jPH+pl555ڱ{ 2$re¥$l@Lp#)A2 W% C߶֥$&d6.m-K0%H^A=Jc,iڵ~zmF) y͔o 'Nf Z.3}}}H(yKtIڲex4TkόAAZp8GbG{졊 m!2v0qrrRk$[STo^#-$ (-C.CG K/#c>IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-system-settings.png000066400000000000000000000132621237252063700312530ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<TIDATx[ pՙ~}̭gt[d$\NL YԮͱ@ڬ8Bva%$. pc[aIHfFH3{[<%"i~};ɲ / Է>}q~/I r ȝU{wq(0*^y  hp> o_򁶫~W|[l*35>WZ7~7QqJ ]Vw+ؾ/+eԕ$}x_}ٛ_n6#L =g_K4*s󡭸Z&\`4{4=gC=ξۼc=ګ*ۓϽ~6./@#nl GbQj=UH;m9C__U_Qh==bdMD/8AsQ0 v +>fԅ3=o1oeMRդ Ac\4foc6K]e FR R3v`68hOv@Ɏg )f1OE89ؙIaCyd*S©)XS .>t4SaG#B(M.3Q{+1d E>DL %R\<[<U,EHH•: ̏?F 4Ga9)&˫JT/.+FB8=0Il=NIDQbE"!T9J4+ZFLeh*NKfNc;:6q5c RF^X3 -AD}yjmls?//MRLg88E/iMwdjмZ+i$a _=0Z&ճ7 AK0EhPٜ֜ I5&P\:QB?4%w$ --]HG!6.S@$h嗣XҘ&13a?IhW!@ [L#m){} ϊI^j&Aa~!w0K賟׀N iz˹!_":8.Lu/!J^Ae:X]cuHӺ }$\VE⟾?v pYC㳖")>C4$$g76iƀLpH3]`$=VUe,{ uАOR]Fsl~ (ɦ~քB+zT֐#3G; Cr`%4U4 4ҍ$G΂d|~!XQe XL)?jB^,yԀw%-ӑ#c T4(iYVf]ͶT`ٰb"xL m@aA0G AI@f`&UKYY%R>szdisJ{-wpA$R, %I)OdW 9 ԵGߠ PVC btwrZYTMɤt3 N"S]ѩyIһ@@;i5!Olwy5YbH[Vz%4W5y~a˔ <*ZeYNkDX* /ŕ _.בuD{n8 9ݳfzK}"KP2`i+-Nb,sR@\bS|G>dF$O}O*PZ,%U:pKݥW>j/W6!~jsORZn_ :M˪`:ʿ'ЀQ贕SGQx`N,fZ&ҏp뿺iͺ63N(jquU;s뗷Tvȯ~e*u&9'#C}ǢHd2xq 7ɻrZv&cڸq*[_ގWKk0Mk>~䓟DEkEuV!QV0sQh-HDy ]vyC?|_cSMcadxm-1-M{lOlڱ n~v~]]DEqeڴi]?j0hylN|&a픕juجsJpӟsUt0{Ȱt"}=NZSA6]xZ4ǣyRĤ9G'I#tt`>4 V^}Cqa!e̺:OϿtv\sڲe۶m.-]9 77.Ysu K3l|"2i$ [i5ʖg8(rav'j!}7o޼n͚5?yU[LvӦoZy/zj57S/+;Ҭf:Dq7޽ZjkjL"EAAc$U >WzV[$ )UqyVܴb͹DK[KO>: O8ԆmK%8Z ]{Vybh[o{|LfF x<׹J*V-9γS}R-R5Ygۂ8tvvbQZ\nPt:w=Jht{YwW';cέNIf!Z8um[mmŖkUı۷M Ȟ[%X++-% )W^===M 3!v&XOwW;T( gâQ@D}ιvNX,tw"~OY[?VL/`0А ~_qG[e]t`v]#am l޽boƁ4-M냎 aT\uȵs_`I.91yFFǐ <T}`>Ki F˱Wu(!Ϧ\K$\<S`630P8cQk#r`PF\ǫDd koogGQd6 Zoذa $3QJ ׫gK(7l'Ҧ3ݕd6ƪA> 9KpٲeO#5J?nDr ''A(2zQBG4@~H\6RFM2y<ƬtZN>"m0ʴ.OTvŐH`r ;w#MMMY4Ea 7L(*`ת8( SN1*Y S Z# H*@.˖ ]dlhhHMFu$ p*Nqn ҬadlvOf@7r ϓ^7s"l,ɘq0)|'hP |APN ;J\AHdޏkL;Ŷ D->O8RϝlVTTrرQ ScJaVHeHӤ'$ ajJ B tJY;1h(D'١b547ȪRȿ⍠hXQ㊪4's -CD 4H 0 'ͬj$-֎Ȩe&@yΩ_cE݀ʛQP@SŒ|]NpJ b!9=>%$rcwtGb'lBI%2UR`(aqv¥Ů89@6@z&ͣ&fZL#yv?b(QLgx($ Ƨk0 &&ŬtN$ZF,&hEHZ2&ZZ)x#.)~we$0UqYrdʼNfaRdT4KNa/a iyL2s\<`^( 3,R:G>&ƱI=c~^G\ قa]jeHrQf+3ٳG>y }i1V6B ؙDYԴI;yZQsoz UVz6!#L^o=slYz+-r3u6 "NNFʕ+%Ʋ) VaY,2˞\nCsƻn7$?%Ns?ZZZ؎; 7ܠ'I 㱛Yx\7-j|OmfZ91yH9xI-iСC 8ꪫvH+~Rk 2"Ֆ2ZI:KuAjq0ʀB6E4OGɁQr2KRӨS4>HI]<h x/ 0BPA]IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-task.png000066400000000000000000000122741237252063700270350ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<^IDATx\ t\ym/h,nج&RL9(9,M!,%p4pڦҔ 6^wKFϛ^{㑬6=3}ܲ,ا g ?~)_?>͍Sޤcn4 'PL) 4W[r/yZS(^_5w>X.~>tw~#a*E|g/|#(1 23#\Q]`ْԡ-]jӥMJSEGИOSVnnSHUE5گeɚ@_n&*>~d.Ma*{~%:6tIGe׸֜9eE% ;-Zyn=U&C25 ڛNs YlVm͑Y.CN*g57zuu/h^hޯǹo'JB$̕8eǭ3u!42́0)?xd0|w~hmVdfKcM:xk]F ~uwG.>nBۻv;h$Tx@$A4yζ%5Ar6gOo~\!T"ЕW^*4wĝWa3˴WRҡ:2p^'3Za|O9/8< {v KgK.UJGkWw$]R]KQ5Kh.zsY˦ywׇd'Е7Lcݗ򘷶hm5gͨ5gϬ3a ʄ +60O%BBzi$ rpD:Ζ}ݾ=C!Z晜NR$$xh#Y\%z#A|"HKVmʙ#).M ݕ(9JAHnb O:9dO0$A+pd1<Zi ڃuP=KP' ii8dY &H?*ۥZ| *iqhK|f 4yj-1#*3O' 8 ZW,, P2-L bqB]78D:vu~#}c+Y ܂07]JaN!Aed5>)% f%gnB4 (/ Y4-,}uE}SU|h*o'@sȤMQDŽtN(iEhE')Qdu>Ahd(3QjY%ʨ*@D$3"\◃ PvR;޲0iR1x,oj&',H ZxSmHDŽO?aݚhifRU4W$@R6#3ҤB&MCi"ˍGIo4 ԣ,IE8(e#Ax>2F)g_bWIJA3x@&FUQ= 0Cnw+"|l M ܀4ԟޑcL^qiәp|G|V\#RQB")4I~ 3jpQr&,νI&*XqRh#J(-?wHȷځbdEe] [tQA"^c%P=خ«-C}M#+",{($G$WCo'F6ABL=i,Mb@@46@Oab[* G]: ɴ({?ZȪD%~>0 MXKƞՀ$$r4Y i 10A4vQ,)T` a Dvb@QSor2[(.+'z&"w!wNt.4@1Yn^K͡+r:7ɔ$r`(j  #(@L؍ /}.`&FS t xz)h,`)9KpL,, U0An [edv86 X=t6U ƥPD@$ :v\MrC{@b^QOLk~$dx2$'aGР0UҺlU4Kfݶ_mdNTo ڋ`X1MJV''צA,9!O$wJD)̈XQR9JKw&$7 p$ʅE3{ 48aJ$3r2V21X#j0,4 쳙z0&1'D[4'xWᓺk",8ZH) Pܲc+ ]'1d*&[DYmɖ"ZeVe56K9 ES.jPY-OO@̈́P6~7+o?1EG%|&{}~C5s=mĺJIl z/_뾋gM(^NdLtU:zgӴo< W6?WmV Xf߰iG]ހve7\ұH]ifF۾tuR%{IêhƵya=lo٫l]ڳmS+NG&N^{]yN- ,]l.r^xϦ4 Tmqu닱^Ixݚœ <^>ͦ~_k}ML2;gwr"ۯBRS`&X貳/]E>[~٤6!2R&`4S.f_{W@o6=}!= ݏy߻m]M3g?k^}O`" D|p~3N\wuN nYv|wa C͍ͭ^o,) .C]we+$_;CBUt^gm?S~g߶-JzQ;af{/-\K c Mk.<5!DϫQ-԰3Բ `)T6zW=uMz)JR9:vO{ O28h-oʨ2δi( 䭬}${cI-l+ +N-U kOl* R}M,z=Ob .U,lt,d ȳ>&T*%8 $M DȰUF p`8;n[ָLKe&Lj=yȦNHM0rTX8."aRY=8 T g_(.23XqYabcrN/2ض(~)]iVUoynXOCĪWI~"Wb|z(Pöd25I"b`m'1yRoQ!RcB x e #2k;RWTU+٩-*g0;bjȷ폎OZ5W@drx{+ MR-lZ(U>C`j)7,a 9 ,t9+,IRGd4_lVW!)S-Y@̃Y1p{P?N6|.+;e~ab!AJfY8`˳lp%%s F% Au ln5n6w_Ϲf {odܙnv_ι;sϽYy 7@N;~wj[Itb/̺~&Zrү(p!`Ld`ikʦ(z <@;tB]Slz ̔m~m;R[2b a2afLłBӥ\ӁsbLz>_{LfhhM!h8>vT2~Uarklkol1Kå/΁ev9_ws PZ䗙 #I ÂVE`9c=/9`&)ЉO`~#׭ 8 0<9Llw&ClXdTCJ-q ׌䮹#C@u#aJ!ܾ. A*)̖5aS˂s;RuLdȩNJڎEpG~^FMWXC2b̔, W{`u3/ή>E _FtEA)eB(-Of΂LTm .5֜ڊB.8273Y,+|$Q)My\4\9 o]'}q )Xu(Yլy|vMTUqK$2lX(hhhLkC#qW@>80Ρ2ZuJ8C [ǙeX3\ϨHY! >{i`D"|#HvC2{ >h=04e,hhhIToɬ$o7 Cp iޘNQ>SAI3&S90AFid\׾^y}ߏZ •!l9_|lDV+p Y*{$hJrgJ)v((9]v>텄<݇V@B1@Մih;*]X&2Xb0znM[n0 ϖ3c×u~?#M'Hblɽ۞\rST͵0Ae8tlaC?jh4 LbJ/ -O3M1L"crL88©Jv*H|]9$ne=F}͚},榹P74e9p v?Rm= 2.O4 ܩ^|vwɉZB6HO׳{X 1qr}耤:a b%Թ6)*6^zf,S%Jm{@N}N*Y 2 \Vc+?[TKg(t;LZ3id&_ayкmzq7ښJ8Zny8+OZPlI-]8 ߂#ܺy5TF#ug_t|uar'wlduuuYO$ g o~{?ܾ~╯{Auiu!fCWGԙwUU b"sA(Č=+#Lg6۾=446CpA> 3<ᄏ"f[ڐ< s?mOLۚbL,^160Ƈ|nؔ(} PxvpM4kƙshi(Rb n';zðY,ale$Ig/)ݳ8D(*,@֘t̚0*7)Fw}7S3V;6Xh2|Zܻ09=jKmmT@:z}:{ L-)G%gLJ ǡbT㙟܅j*b|qI@}ϧMPqEpatX|U5b7?6]Y`M䌾!VX+ʺ&@3rQQșM>~u#li $G/k.. 2xXY()C,,;"Π?{h#:dv=|OgE|0 4 hZ%JQ}Đ 1ʅ%5rLdL%Ce7V'Lɔ>wzF&ɾ&RàI`ιrdJ=|l2Tdu55*BG^q~0$˒DM!P.~B;NU⾅Dzyo☑"?NIÚ-GJ4S|k.̞8Q!"68]T  &%l9$Ne5j)Af2Oҟʟ\Xjhj?'v]*%r_6HZi4)9:H"$U7Jn:(zF(žChȫ [ˤҹ$r]l!4$=.b4ؽRA~>&M3̛6lê/}xň 1/0dĵqqa];)ћ:,{~wj5~I mUT8XۈO!5> m"JnϷ`lV&#gp8G)wOW^82RTVWyj*kqg^uk{f +]p1J(ʟG5S2@n'ǥF(JTW>4,rChSd|[x^Ca0q9NIvUvH:q@w0Hj\9>ҡ`a[WTcէ;p0HXBY4::}`LXq$Z6UGU&.KVeI7]n7Z:(0UTMn="{揿DPxWQ0?p#98VPPXVJ!v"*' )9Tf@u$DŽfgr9Lt-T)cq4/7|5R7[{;r&;;O ,A&ڙM u$? I1i 4U$:*1L"b+&&!>(;krN\8vjR:spS,a$’4/fW&D%{(qǛᶙŶ3t)#hwPɕ +5(DÄE;|r!0p^^XE I谲 {o}T#vUfYv]".)I&΢L wb<ݷKoo65IUURrȥsPeHGX`AڻTm4:WHB[ +}N J3pL&rcقoeI uNZl6l#ŒN*D:@?1w EP~0״զolNO4J@rNH+sӢ{Z-;畼j*(8V5+kORʹPU;'1RJg ’]#%`}HI*w ;\q jXh|y[h,K/+r;,7z˱qĠJAteE`Ao& K7 B Ε4Saⶊ 9F d7dE+2XQwV\^dtZ+Q+ Lʅv'sչZ釲qB:!ƀٲN~Ԥjm-9 >n^j&̑;7t4htU8xp@JVG !ta[춬NR r0Un{5Tru'l.*mm$t.۴N6z"ы8t2IC.]?%Qǜ6r+|; b7띲?9s0bPSmtiquC۪eۻ*u H"c#2T"9.%U\HCZSSw / T9v}߳.kntA/+KvbA{7@$mWo~s= lվ   D|M Y`Kjpƥ;\Ň}UhR[t~U+&.W9y =bw+{Q/&cPKM3YYwX=?T{˧ZѩsF<[\e/yw]Dz'{t34//ۗ,+4 T=kb MEV\z,**@}aWr80"c죊r`Äzix<=0-2h9â=X-l“u*:_|#6%Uoٟ}k Կ²z{nXp;}3 %` =g›ncaꨌ A1J$YT$n-^ 59nx7ؔjH5@O++7]Uٺݿ篤,s̫ko5k,˜8- (9s 5tvFҕitzYS̚/7fǡdDw7_XU1W+H@/ypج6<5@me9!@j4Z 90~KFִq#R^K¼Fwԕsl<%w.Z(`/6Wow,FEQʋ XY9(^+vT!gnOg0#qÏO^בv:EpD ~EEs%؆ +E}zWM6'Qt8*!650a`4yNjy堢 )c ":ePv ښ0"k2nZ06dL샎czͼAlE. d=y1+\ @wü@K>_f&£8z9|< ՊT&-ESfaKƯ?;K߯gUX2b@5zMFs =)Qn喧XEgk Jc|#vRC#&M%ACjELѧF!PO5Bq1ʅ1) (8~Ly-fmJ긨+QOX6~::Zx ^&ٗeq,xtT[OwtP=8݈R+L9>DF7CM9$eNĢsz{/S^>+lEqǟM=mX焰]g̔ F7Tq,rZ N+ǯiY1uhKk+>2ݡrH?O*hn-+[V!s,eˌ0 w_f#~~ h C<8sFg!v(.;>ǟAPte5O[r/^k8hH_ /De' T n:rRaDWSU/ŹR5-FO͜?IMCV$̹ MbF\jBa1"' 25ŧs=Yݮ!  WhV1$񨪤& Xy dMıc.A,1Kʼn_JK˧"DDĤIazBbζf&H݈C`Yx(6 Hbѵ6ԹyՁڪrx~[7HJJ MM-2)}?~I0sﯤNF|J5Űl]y}o2e%h)iԈԤgRl_Ii'}NRɒaftSq]Iss!QzX"#z*D=x?uNVCȋ@sto5ekJiTZ@1LZ>wG{1!MS%ފ]vxɽz'ښnvvUUzz:A"6 ?n_QDMkյ~WȢq(͂2MPߗcZ+-[k^ASjٹYm0ȒZr!HJsC/J$),r,5*aS١3$N߯ے|f)~ysZ[ZJ 5US+ j(Q DKdr и.߳S|#%!7wTSQ,ù'Mop~ٶɷEV Iu%dIaJCG[ /woSه8yּ˻JGT"wjpte WGVr O 88Xpwwt:K4`'V2n^MT}_m@xL|ypyy'GDiISBSm5܈ae$HY۩wz;zjҜ*,>Y>o{mDك:SL<(+p)r6wIg9L& HWUWcĘų^CXX&ރZ/ס(?c`E/p=\_=$SK`:<}H*F_w *C^;w6hTZG Aw/>o,n=|up,y[ńEw#<*ZP ;tR4͵غf%-"GdXN, P_[&?ZO=|4%hliC֬)ܔ^3ǿ݃}hLG}x<@6Q5UYEXLQcD80r^-kL͔Of!Y;@)1BnE=i]e9j-<HtP`q5] m[eySYQTgbs}Y_^)4.f_a5*8~Wd_lYWΩɓ`W e+1Z k9됳2{?u-}o ^0U> l:IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-userlist.png000066400000000000000000000101421237252063700277350ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\y^3.͹.5 *6FU4䟔ZJD+U0&@D "ž}3}ggvfvg2֣gz^ޱ29_< σ<rAȳ+'E&IY}WM| Bml:OYfx_'ףGU].S68"n:/t\c<8t%΍$&]O[}ڊRq*aL&cs̨&wMTJ*BZX7>< ۞ ̮'p}/eIuifM F^ӾKҍ$B%> (B#P(.[#uR:jHCB=l;qC:#n:yT9:MPTZ z7ёS?,SnNawy3הȺQ?˜S9c(%5 ,Ɉp )dèBτxY4#O=j/z[ZT4W6A&^Zzų$lCz(W~p6IąϩBc>J PP**ȓe l/x}-*IL YD°+ }aa2ʁ|\!.y=3)cQ*MDc"Vt=YEp d䁘M̨}c<,\2WqFhpUU&`̟\GZIbJP33!N9*nP}jvj<'*`VF5c?(XB5w;kX{A#H(rƘdX2Āo`qr$VV1dŰ`_ep$/y#OE,u~\lN:6.=UK&y7>Ҹd#X]% ,%"s[I$"poW@u>p6_fȡvl>2o&\R\Sq`"@36R]W'SBx,T֭k7CaińS;RWcA1d@ 3P[S z,|Gv .$mۅB:-@攠sHVWC6G 1x@̑!82j)ɔ`R5A;flf */@SX$cbpg[]i rUqP(^$’zKl˶3F#ݭD&1IsO('ҹ#Xrc)rrka? xa<:/Pϛ9ёϮz,wȇf󜪞k6ȶL7\נaDbߥ]i'a@+%"բ6ĞeV/^lh #VQ.kj -&݂ 930MZҤ S] kiQu+sУȱ0qa{`(E@/imف,IMe'B]A!qO+O !f=!U2zL&E!4+%TVfgoDMA! P{جd1ɳdx!"'t*9vA(Ccr -#P5*ӱL&!q5p]l14mK)/zZS0 30(O3L2ɬPo]2k9h6Yd5G 9_aXٰ6%cT6nY֫uY%rf:V\^~vݓTCk!O!`y[ `7 ΛHan4b?$atڿvv ׉{(JzpF'˥o:UviiR@Lu^Z- ŦMNTLꦖ&/&ǿ:n&`'[O[Uܿ>urz!)2:qSUUG1[ Adk'us+`uj^Ȃi]ҊNde† @vvwcGiҟj=wj*(U!@&ǨQל@!IUSY-E+/JyoA|a\&uFQD֎? }Qrd6wri/\_/Q8NQEr)I^jj`*>$Ic^׽y a9>'=WPP{-Ь@8QD'}w1eTQs6*?=g)tKNIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-userprofil-female.png000066400000000000000000000111741237252063700315120ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATx\ lyߛcO)\DQ$KEbYaǮبuIE(6c@)NF ,NR)4)Rk{3C-)J]2j_3;_Obi¯vw@y7VM?3Ksy_α+/AP-ח=p+0sPȹUr>0!~k[8g+=};lPJ])&SU>4t CK/}{g%WQl[wid~24$QHĦx R M춰y꽪B|GÛ>su9Ny@aVb5ljO?Ek: k^J" PU5qC'<7 Oڭ׃OY 62U5`]("CQ~엁iU$>&%I)AfD(zUPt@܋U6ٴÓѮeTcH'oJz Ǧ` Udb0LIOO^{|0x|Az|Ö[fBaˬ $!xvW0}k/P@8Zd^d=5K( LKüwpJ]g4Ȋ,CgOsĠHP!AlH^YZ`U"kLWmr`c˶жףqW=cCd8q__dt=N R %dt?= yA8(PRǂ~ICD 71da˼iKm O_.SyLl/2% pRV,9 PyT\XS~G !}SeU|[kMtj .4CxZ|C`_&)/I p'-:1Zٌ;8#[gy3nəh")52t"[ݙh3PuC:0f&_0#BFM+2W׎Gq {2{,=zvz|6w'Tgzg8yY ouuvmX>LȤAΉl +&)ߴX4ENr -j;GgfH&b.|!&TYVf6Cl̥h 7-I?mRr`PLg|&pXYP= 5& d)2epm;fbǨeJ+mp>dڵqlEYi^pax75Z$ [3DJԹuxֽwMn3Xp@9-w9A\4g;Q~=ȦiUM a_ʤYiu8ƜY9 Yͤ9GklV=n sZӀ@jIҜc{--: 7vc. 7e2B8\9xRYcU&۷{\[0;k s:}\A,y: Kں_-+Ǔ;gr֩gN R{3[ukF+Q^LcN}d$p [R`?>&H&WuՖH7S5Nܥad¦mjc5ȧq/Y %&{ UݶVY(csGas6HѴ% iiEVI^-PQɑٗmYWK-;I'}ScY;g!-.+ UR9'vu6 F[]ea~y d#d_f3fv\j܇{>(Qz}hU&ZvKܶQWZ-Z y7D_@o@o%<zԝT-81Ƨ iE$(x͚T(2r otL QE(W}^>ućC>HbP.*\.0:0$*_Rx<2j,e3bE%"UY󉺴6=$S(5}M_@dTA?]]p|^E8myi'"4@>`y.AQVZUw'Z㟋\EQU"@bp7@U!w\, L,[YeA?GSL:x8 3h4JВQr;dHƓN9%U5~zI c\m{Śkco L Z" :e˵ukz/ C ++-{**tt6W/OBK*9KzZFdzz]v*qHJ  \ZzwOu댒#:sӼBȒ62C+0FYB^Y+i>&|M<5 d@r]Z^hH?PI;!_ՆT+N+<^~zW~6;kyyy&$K&yQ/1NS9#SSSΙ7>1ݣxvz˧paߐ0R 5ƧmזKblR ˃ǻ{dx]d:p:掎ق׊tFee9<֋Rpޜ/+.㊆z9 [6ɶ6S!>xpϽиu+ ed x(#inoQ>1N #%k ꪫ1za3+ $;{'qG%\Dl58SHH-3$Nr>`Gαa3ٽsiÈxϗ\@-;l;"ӾgW=2߿- ?#)IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tab-userprofil-male.png000066400000000000000000000077651237252063700312120ustar00rootroot00000000000000PNG  IHDR9ZxqtEXtSoftwareAdobe ImageReadyqe<IDATxil}Ξ]H\HuR۲#Wv@I@jFIhuP a#Q#"[LZ$ݙvvERy7\q_Yma\3%yN19EOWBu]sdPM6[LaV ]sPȮ"Y$tAyuN((QB",O϶lOz(J\d<g;&V}Ć@ yVkoZG!L41T0&f oh0\]8t߾K &:#ECUAdV,Ȩd<EvnTpC.\Ϛf=qҏ] j.Ar:$EC9l0cOԎQy&/Ļtu Eӡ*z`c)q^Qjs8:+ˢRhX7ݦMޔ:Tu-}-=bՒ$XAC8ϗ3!ΥMm{.BXg.w?o<"GD*[H+>2*`oo!{-m62Z wsb.1^OfkDma4e:^ʣUg;"uM[Al6H5ki&@ s; =WHG.olf%Xm]mpoFiYLPn[eZ1EX݂$ls;s{$O'bm|Yв]/*aH&eIՕ$j.sBMM@ueEnotH5 ;DXaZm!j}eVzFk1ivӓG8Mxӕksl8@8=_EĞ(w%@Vr:\eꘔ17_Lbr Eud"PA/)H *pb_m:6YPkeuqL ^dtՊKR( uTQ,uU yGLcZTy"9,oloo!7ay͒Б8_uuB+@׀tfpkG<1$k,תrvIn2U E{:&וMֶkO3?Tk#$mAlu<#}$ kj`[fuCV(XE> GCit! [IҔ hFKouHH\}@X;l~tNO[Ē]&-xF7{ھ|wjpOWFT>w}OPV6j p?*ߡ`gǺ:C/Z*m zׅĜM+ M(|+ *vp8'G7ӐH a@4/,s=Xjη*n5}ǓƏ~@Bt`E8˟Q̀)P4/;C{ pYm!?Dڅʚz\EH̍b54#ґc/F{LG"911k;9U$@ET]S/OC!ӳ}`2NyCJ6cug?f̮1|~ldӸ^ȉPbiEBQKA{^Mлr˳׍Jo5,vS.5L1:VյMb<}; #KL?!4 X"4TQx=Nn.2(#E 2qlPȚ loEhpEuTZrR G-I:6yPW-hWrŖ̅Uq5k'ϝGmX#l~aAzo I\ RUCz H%UKg+h[kW'߂'5܈Ffg˵1w-wށKeyEU{WF`y-GU(PS=q ][ YV(ԅ,24%P#5!Ld+okyN= DdCSO!B%;z{O?é)X<ɚz }5C;v@G GYO=!uH]8!z>HX|g\:&:rvbhD:B[nȵH||[(/zסk;)ϭU 0iM憥IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tags.png000066400000000000000000000027411237252063700262630ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATxڼ[H\Gǿj/޵ [#UMJ}MADlUh^|(y'AX)-AxkŪD&sx4&g\7o)c\z`SczQyU0K@0o+2H2J2xή<{liiiejjꮸ @P'n}}\\\>s^cb+xYJKK׊D̔gdd R>?o3AN͛^iiiߚLP:Ƙrpp@E(++[c3E ;;&`3쪱Mqqq8_Q-@O xzzBPPݏ=uVFkkkт8ll6~9n~$醯/> 4 bZ}$Cdd$ihh `ޢYampp{zxV1: =#7/(5!cDDZ@˂< pFAff&s:.84.v@@`` ;RRRNat@@t bAȬbaH xbbx0θs@NXp7+vA bx9$ttt۷osɞ-LgG^e^OppO<5EEE|x1ΛyJpq' hGFFVNt"C0ިN+uXXXS,՗%''cJE d/gB5 T. y'Epi^U )jۘB-Tt. AA]]UW3CKBmm-pD9¦vѰ,7Q^q-+//ghX&fXXii)C/~ C~!0uGECPP1F F=@Tj:djrVWWܪ GGyPEg0.OԻ0To:F '@< -3'`7D8"P.q%;zE7GX_f ݻ|Yt:8ϼ*3YĨu_\mRKv~LtB%=F_TȁK轀Z(E\DDgAtwcg6iti0I#dH~"7DH_󎢧0<"j !C`*{4c[C~@1z.IE|KkrzMBƓ:v (յ#Fw35{1mon80 g8lE~' $Ԅ3"1)wwS/$Eϭ/.o,CT&(@\'sDeER@E@xf=> gfOwFǶ6MӴf /5 /IU@Qf@wb ?)xZi\Qjk6{DޟmOֺ^-i8NhcoڬL wWSJޕ~)YkAwYX[H(;HPڥ n$$pZ/Qו,Y q׾ЖZ3`QzJN&U9$IxA|CIL6d{{)kӟF]UrT3Ўbu͔K+]x]Ex[xNb!rIT=htփG@!T TJ ThNbŹlQ+=-0 ˾z`XS0R (+ ,%x=:7 *@ΐ"u*IOP9YFtJu6|ޞ_  !7WL 2F_IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tasklist-done.png000066400000000000000000000023721237252063700301060ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘]h\E̝lm>M7MkEPJ?,`RJcTDACA'%>X*VS-mEЦ56dΌ3nfo}:93g/0ݪ{8AQ@x5pa0ƃQ&.&1iwak` 8>满umoI>sgO? f@A0:ef7l{ CqP_7oH`v  %6_Ks?q %9H@*iֶ ޞ9of`j6" ǺLѕ!)Z`h.BXW' ӽ>rfS/XL]? mzqu a`)fYsc0͙H$mTQ@$`{j1`xFm+*;j)IՕ1SV1=eeROSe I#FǮ2qL3'!@{ajf!r0ƫP@A̅yuc?•PhKF4JäbF3kĸ0wx@Y=Wq&R&2۫ ;2[}qf&0Lէfo{ۓprȽPkK3+L* F:9z"|5~ oa7> ܚJ ;=MeuRF̱Gv¿ֶtZ 7aǟ/6<ۑ1xKp~ P&^j,fb9mA-Q$s +- /mE9tnV'8H\~n-Hu$!%3(TFn}!859[O~;2Hf[$rKkXcUޕL{Gc:bpqrbۙLGSu-<Í1ab%UϿ5 BzaWRI}@W?b{/Ja/0-}k .{ķm4:V,lŵu׋8U1y V ?Հ ]9TQz@D$J utCV yfG4 " l(DIT1;  0S+V^IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/tasklist.png000066400000000000000000000023471237252063700271650ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<IDATx̘k\En66MZ&6ѬZ VBh-AZ"YD_ED|DZ+*R@jM&Xڴv,ޙq77}pp={f)%_ABH]ѷj`Hg% Y \m{  5 vLF|?cQwWЅ*0${m?;x%TUF㐁m=3SsWoFPy* kr5듋>S]xP-`!As;אָRZ:džd  7&(0@Lew eP.ҟ ׽-Uf>H&sO0$D&G0VH$M/^it:R@"b! *ar9m5eG#eQ܉zcpS3:Bp) Qf>'glHTD2ٿtGZˋKVuz6TT vx)8==T yn,cR $ $ R!…ؐu80-2Qlnj6ʃgݡ&/n"TftgUe.^jRX}6B+ʤ: ӿąYTwjok2_0lɹKW`zvv3*nU|8У74 TV,g#{Mjq R* BN €w ފ*R#e 9k_L+;ڣsO2ae3'Lj  F=/uLfȨ B*Jcz}E`dF}s5 +:g:/Sz3@u ׮'6BkUxR˫Ciӥ3_k15)KiWQXI? ʒoM|/ށ-1]߱Vk `alMYѵw&iqԨ @u*Vv+DXE1Ò8U1r ,5zQG 8\U GR )Y']D#IENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/timetracker.png000066400000000000000000000043051237252063700276350ustar00rootroot00000000000000PNG  IHDR##ٳYtEXtSoftwareAdobe ImageReadyqe<gIDATxX{PSW$W@+X[]+;řnngmήmwǶ>jk3]XQVv|2<0 $$@&Эyf~sroN;0xZ"f 6A`,xλCaxd!ĵ②N[s}IXhcP/> 5yF'. D^ueR6f}^͛yӢs߱w)GY/:z wCIrn ŋUO52ơAFc8t6dתNo"-k[^yk y'+9N"1zBwPbڲ5&6B U#7Ѧ+ΕUG.P#&!D3<8p,+9~w~+qnGNBxa~D$>6wJdZ &y71n3Cx]fQm['hoCq"B"+C2aL,$xŐ@%ƍ{R3sLT|eyN_+=v( >($ - ΋;wC탈|/=Er01FHh'ci\>O_ /^gGLYtQRB0LX ZM(X"2; %D+D3Y,F*54]mCth!u&MPu Sl ]-cOj/w cc1[ Cɓ)([ y*|oP?m_BhTsHADT4:v п~w ~]>xIoc_& ahrb{PB`CI CH'1$#"ѷJ͊C:;|%⢩1]jh^!ث2 l2فVGC< 4b4!G;"+8:Z\_m\Qq_Оӈ2e_ӟ&]jOZ'ca늋8ˆs\:Pa6Ѩ;^LK]Ŏ Sc:vj!'N~SzlMV~!@Q]Wwz汫=JC[Mõ*K*mMā-3Z-HNO]+_ۭU54ڛtc55T#$x-Ņ/>rqv`"mjB8 IJ;|AD/!ї(^ 2"dMψSq6n$FאTZ_EB@U(BHnz͝0E㮮Ow&X>"93 )ex4chR(rVn,:Fw:~p9$$ :) *o@MJ V#J>mBBV>̣F9SRL.2."vw~ChbdXdJh5K>D__?qaGbӽNV\QhDGſ`BWe J( i ]8wGN]!5S=ֆPn oV'*"dgXNP%Rخ<Ǩ~VGh;b凍95Փxs~ԄHujW{mf<.P`r}e^[ y3s 񃜻;gk*Ń;2\Ij9ff03|!E:O8huPbIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/user-icon-female.png000066400000000000000000000027011237252063700304540ustar00rootroot00000000000000PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<cIDATxWklURB (P( [aJb`$1FmL ш@b ЄC!1V( t1> a)ᵯyy '{v^;8?}#''^ ( Ľ-w+mcN,PpHIu֦ؼ쥠miL]2 Y(Q k ܓ1@ư`,@$h*!^@ceeFS)i` =Cg/Re|dE ݋U>{$ u錅tMXyvּ?>ݴg @&J5=4K*M$ $ȗ›[G%'m* 3XA,#1 -8,,eAmFAV!EXbh԰441B҃CMgf>1cnQQ۰T%|6]ouNY` IS1C>@e j=Hbby9Brq ^GRڨ9!24&2Z(&EȢ#Eg"8o˴ADy^ \d>b⹋t/̘[B8L& W.L-9|gS&T6&R>* "Ot2pPPH I;O?'I(vZ^ZQ8"#._$F9UKN Y͎>Ȩtu_}>%6}ڸPO 0yi"N6&VHX0![wJ4WCfl2{q^D~ݹCՎh[t_O;_[)ٶߕ~Lg v]qO7Q,J iŢL}s4vmZݾK} IG"2\΢gr;xf21kG^*[zmJFD}$was{~e74@9d |IlUU5ܹi#. خ'd.GP-,;,aNop)l8`; ŕo>՝ @oHnN=L%ǪЉ`PUU@QAo{%OK!ұ"m&dO4piimIQAV44kк^G{@zz!=D´h% W{ 45O 8Q].,CRG׌1=8P?lT(ATP06ƞ]=g`O2Fa!?**o`EI_c2ib0@H<;&0v 6P2l Y@:No GwNP:&:7Y= qj jÊs\U Y4Ѻa4p"8jct UnOj`Kﻂ`MP+v\DKPr9so[z[kGm%3c ^#ka-(u<: ܷiÒk:sLn{+_UedϿB05A 4* j?%S0HsG9Ow­OKJ}]*T|JIDF` J!4T~DBDCPPhx.iSvcfgΌN/2.[nLvYu]8(w[\hS{<{a,o#NfBx{?am;+=£ dB׮{Tg!VԶIJz("" _G!"H1RT -!ݡ& $lS(l^y}5"K62H/X@B[ao77[E-WY}BQLʲ&޹t'>{Olh&rokRc^a Tby=eO>bC <*|7+OKaCcs/K8o\``&8ȃc$#rF(̄;0?pR}|Vn$s96$G9 9ȥFVbT1T^<im_Iz`@PP4؈ |ޞ@Lʾ?=z@UD/]520s#q&{XxK$Sc{{ #sciSl:DOVְ,?!GTO_j:^Q 'Vm3ey "\ɔ6n=9-1A <rD%--ͳV_S"eh&"?x+Rj-"Û`5 ݽ#\}}W#QKt#эTf`ޢ Dc۲J9^-I'nb1 I\DKC5KH$**JXT /XQ42FzOXF&F `(hz*5d)s & t j5IL"k' 09(^m:ЯӗPdDT?C,F,3S #14w '#E`P@|=Sm1#xߞ9Sp7Ŷ5)x>hIENDB`Collabtive-2.0/templates/standard/theme/winter/images/symbols/user-marker-male.png000066400000000000000000000023771237252063700305030ustar00rootroot00000000000000PNG  IHDRr ߔtEXtSoftwareAdobe ImageReadyqe<IDATxڬVkhU>wfvg1; YjS["4i,T`J_ Ђ H1"+DPhQ[iZkMyfw=㹓$n6ޙs7;u^(sw Y:F`۶Ӵώe].8 RqABcq%RyokbFZ!U胮&m5BnP޹y;tHd "j0 BAcoAh-0ܸ^(U s/rM 醟~q3#L#2O8*'PA!|`[ JԬMhO%뮎wښk qh ;60Jugx`xw[҉7rlo72#+v]ʜqsmb9xoؚ|s̃}+Cqm\K(1Ual2N}'Nky9ȃV!G{JOL`S^RB 1|vJ3 3`= гixOqĨЭԇty2g 7>>9h8p,h.;?81ctԊ3 z3{r) ZC/ }S:l=3NޛSĨl^U_"V d]u]SGDF Q0:|(`h|,TXI{oIYᳶa_8~QAsD$`Ԉ/`bFTw2PH/"+"#_(`$Lȑ&Fd@)IG}}:Ya/x{mU@T1%"{G GV!7V_E [QĢ3*zŭ2a{v'p)}h xq'v04++(3m^uiw `FN<3 +7"WY<%xviHhC$Ȅ<8 A2|5R̃0g6eV|Jd0ܜ]<nc+UqZ2͜ mT N~?q\*[=xdk$Μg1nL#q/#ЦAݍ'GJURһ89O>#s08<'NųKW.΁xzdأsf@\zTIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-projects-bg-b.png000066400000000000000000000001561237252063700275410ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb|U@w 9 IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-projects-bg-c.png000066400000000000000000000001551237252063700275410ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb/,0V?IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-projects-head.png000066400000000000000000000001541237252063700276310ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb/,0% IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-projects-sechead.png000066400000000000000000000001551237252063700303250ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb/,q0fGIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-projects-secthead.png000066400000000000000000000001551237252063700305110ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb+ 0{scIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-projects-thead.png000066400000000000000000000002661237252063700300210ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<XIDATxD 0T&#GAA8x- 1//MJL [[٧t=`fJ}yU(6^TIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-tasks-bg-a.png000066400000000000000000000001561237252063700270340ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb:{n@妙IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-tasks-bg-b.png000066400000000000000000000001561237252063700270350ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbzU@k tPoIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-tasks-bg-c.png000066400000000000000000000001551237252063700270350ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb0*0!:eIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-tasks-head.png000066400000000000000000000001541237252063700271250ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb0*0+!,IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-tasks-sechead.png000066400000000000000000000001551237252063700276210ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb6*s0&JGIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-tasks-thead.png000066400000000000000000000002651237252063700273140ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<WIDATxT 0 B0t!q A 60O/.M-Gn Y@am{ϺLg޴Sjs W?y TQIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-user-bg-a.png000066400000000000000000000001561237252063700266650ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxb8~x:@Ϥ=IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-user-bg-b.png000066400000000000000000000001561237252063700266660ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbxE@dIENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-user-bg-c.png000066400000000000000000000001561237252063700266670ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbxLE <IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-user-head.png000066400000000000000000000001541237252063700267560ustar00rootroot00000000000000PNG  IHDRwStEXtSoftwareAdobe ImageReadyqe<IDATxb ύ0E!S*IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-user-sechead.png000066400000000000000000000001551237252063700274520ustar00rootroot00000000000000PNG  IHDRĉtEXtSoftwareAdobe ImageReadyqe<IDATxbLf `lͨ IENDB`Collabtive-2.0/templates/standard/theme/winter/images/tables-user-thead.png000066400000000000000000000002621237252063700271420ustar00rootroot00000000000000PNG  IHDR%(tEXtSoftwareAdobe ImageReadyqe<TIDATxt 0S$#e(~Ng0ϼ D9Fsi}`šQJr_y^x hIENDB`Collabtive-2.0/templates/standard/theme/winter/images/win-down-side.png000066400000000000000000000003741237252063700263210ustar00rootroot00000000000000PNG  IHDR MetEXtSoftwareAdobe ImageReadyqe<IDATx1 PD#OH] vepYeI$,b* s|^mFL@iB%qaÁn?H&RHC, M/`dva&b!b' ֛23,Z6i3`_")kXc6m4CH~ndcw]8ɴpji:tgiaB^b@O^M \ \ 6=za-S!6y{%DzyM5 䱄WEzT.+y<)* [ EA-Hp,V n;tvpmV`Ko$+Z IEpoq'pՎK%Q|xCa3gk `YV(u]ϩ)Jgn+X}KSeZ6{_k|/[Bl5~x:f5j樬BÕnyV.jVȈ'2 gx?I}n{WSqԊŽSKH8\y|g_l~[$(njLbΝ+jܒ]6bL;>%f*VZYLS_ r2;eb#MÍyŽ+DPQ31pfckfI/7V~(JKA6?\tb! JKAuzEvIF pűru#1W BÆ8saɵLH@AVi\A1BCϬvv$ǀcCp83&pJ]Iɉd=9A@)k/&z,)&ۣms;f@!筩0qUC:eY%d\em)94瑮*q#X{xD38 Zvq5p2 *;ۃAn7Tx2`]ΠGV_I7oiM7:/;jˋfXL@ą'o*G'n%Bp2oA[r׀(BE 1zs3,NZNJrl.\Y!f "%g oo-1@8.f'wp,Den(\'u3Ƙ`E _8HD}5}kV&ZLYZF!gz{8̓Fn@jʎvu+\Q;&a:gZU ֦HW>4$cP穮v 'IENDB`Collabtive-2.0/templates/standard/theme/winter/images/win-up-side.png000066400000000000000000000003501237252063700257700ustar00rootroot00000000000000PNG  IHDR MetEXtSoftwareAdobe ImageReadyqe<IDATx1 06EʔVb*^*f#x'C&` gxyBb hv;H=]Z! 'i4mk!? 5(~0k=fyAxGjwi4p`"(#IENDB`Collabtive-2.0/templates/standard/theme/winter/images/win-up.png000066400000000000000000000010201237252063700250410ustar00rootroot00000000000000PNG  IHDRp0K8tEXtSoftwareAdobe ImageReadyqe<IDATx옽JA7WHHa!D0O` b3؞`" 猌.{[a۽%do{u]+}.щ@V Ö`k}CT. {7Cuo =;5m\87d6XY/7e=;b y[D \F#^R^!tmRyJh rE(j-{ f =;87dêD aSȖJ`JN7wś>m1dgɨyʏ=c`:0Sש24PgCY09',T*vq }{ȁm@l#ȉmBAlL:8L]f:BjB٭, X7O~~w!IENDB`Collabtive-2.0/templates/standard/tracker_project.tpl000066400000000000000000000150611237252063700231510ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax" } {include file="tabsmenue-project.tpl" timetab = "active"} {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/templates/standard/update.tpl000066400000000000000000000116211237252063700212500ustar00rootroot00000000000000{config_load file='lng.conf' section = "strings" scope="global" } {$title} @ {$settings.name} {if $stage != "project" and $loggedin|default} {elseif $stage == "project" and $loggedin} {/if} {if $loggedin} {/if} {if $jsload|default == "ajax"} {literal} {/literal} {/if} {if $jsload2 == "chat"} {literal} {/literal} {/if} {if $jsload3 == "lightbox"} {/if} {if $jsload1 == "tinymce"} {literal} {/literal} {/if} {if $showheader != "no"} {include file="header_main.tpl"} {/if}

    Update Status

    Update successfully completed

    Congratulations! The latest version of Collabtive is now running on your server.

    As a next step, you could extend the functionality of your installation with plugins.
    They enable you to easily adapt Collabtive to your workflow.
    Collabtive-2.0/templates/standard/updateNotify.tpl000066400000000000000000000015621237252063700224440ustar00rootroot00000000000000

    Update available

    Collabtive {$updateNotify->currentVersion} was released on {$updateNotify->pubDateStr}.




    Collabtive-2.0/templates/standard/userprofile.tpl000066400000000000000000000411441237252063700223300ustar00rootroot00000000000000{include file="header.tpl" jsload = "ajax"} {include file="tabsmenue-user.tpl" usertab = "active"}

    {#userprofile#}/ {$user.name}

    {#export#}
    {*at vcard items*} {if $user.gender == "f"} {#vcardexport#} {else} {#vcardexport#} {/if}
    {if $user.avatar != ""}
    {else} {if $user.gender == "f"}
    {else}
    {/if} {/if}
    {if $user.state == ""} {elseif $user.country == ""} {else} {/if}
    {#company#}: {if $user.company}{$user.company}{/if}
    {#email#}: {$user.email}
    {#url#}: {$user.url}
    {#phone#}: {$user.tel1}
    {#cellphone#}: {$user.tel2}
    {#address#}: {$user.adress}
    {#zip#} / {#city#}: {$user.zip}{if $user.zip && $user.adress2} {/if}{$user.adress2}
    {#country#}: {$user.country}{#state#}: {$user.state}{#country#} ({#state#}): {$user.country} ({$user.state})
    {#tags#}: {section name = tag loop=$user.tagsarr} {$user.tagsarr[tag]} {/section}
    {*Block End*}
    {*Message End*}
    {*UserWrapper End*}
    {*User END*}
    {if $userpermissions.admin.add}{if $opros|default}{*Projects*}
    {section name=opro loop=$opros} {*Color-Mix*} {if $smarty.section.opro.index % 2 == 0} {else} {/if} {/section}
    {#project#} {#daysleft#}  
    {if $adminstate|default > 4} {/if} {$opros[opro].daysleft}  
    {$opros[opro].desc}

    {#user#}:

    {*inwrapper End*}
    {*block END*}
    {*projects END*}
    {*Projects End*} {literal} {/literal} {/if}{/if} {*if admin end*} {if $userpermissions.admin.add or $userid == $user.ID}{if $tracker} {*timetracker start*}
    {*Filter Report*}
    {section name = track loop=$tracker} {*Color-Mix*} {if $smarty.section.track.index % 2 == 0} {else} {/if} {/section}
    {#project#} {#day#} {#started#} {#ended#} {#hours#}  
    {$tracker[track].daystring|truncate:12:"...":true} {$tracker[track].startstring|truncate:12:"...":true} {$tracker[track].endstring|truncate:12:"...":true} {$tracker[track].hours|truncate:12:"...":true}   {if $userpermissions.timetracker.edit} {/if} {if $userpermissions.timetracker.del} {/if}
    {if $tracker[track].comment != ""} {#comment#}:
    {$tracker[track].comment} {/if} {if $tracker[track].task > 0}

    {#task#}:
    {$tracker[track].tname}

    {/if}
    {#totalhours#}: {$totaltime}  
    {paginate_prev} {paginate_middle} {paginate_next}
    {*smooth End*}
    {*block END*}
    {*timetrack END*} {/if}{/if}
    {literal} {/literal}
    {*content-left-in END*}
    {*content-left END*} {include file="sidebar-a.tpl"} {include file="footer.tpl"}Collabtive-2.0/thumb.php000066400000000000000000000025511237252063700153010ustar00rootroot00000000000000') !== false ? explode('>', str_replace('<', '', $tags)) : array($tags)); if(end($tags) == '') array_pop($tags); } foreach($tags as $tag) { if ($stripContent) $content = '(.+|\s[^>]*>)|)'; $str = preg_replace('#|\s[^>]*>)'.$content.'#is', '', $str); } return $str; } function getArrayVal(array $array, $name) { if (array_key_exists($name, $array)) { return strip_only_tags($array[$name], "script"); } } error_reporting(0); $pic = getArrayVal($_GET,"pic"); $height = getArrayVal($_GET,"height"); $width = getArrayVal($_GET,"width"); include(CL_ROOT . "/include/class.hft_image.php"); $imagehw = GetImageSize($pic); $imagewidth = $imagehw[0]; $imageheight = $imagehw[1]; $myThumb = new hft_image(CL_ROOT . "/" . $pic); $myThumb->jpeg_quality = 80; if (!isset($height)) { $ratio = $imageheight / $imagewidth; $height = $width * $ratio; $height = round($height); } if (!isset($width)) { $ratio = $imagewidth / $imageheight; $width = $height * $ratio; } $myThumb->resize($width, $height, 0); HEADER("Content-Type: image/jpeg"); $myThumb->output_resized(""); ?>Collabtive-2.0/update.php000066400000000000000000000052021237252063700154400ustar00rootroot00000000000000query("CREATE TABLE IF NOT EXISTS `customers_assigned` ( `ID` int(10) NOT NULL AUTO_INCREMENT, `customer` int(10) NOT NULL, `project` int(10) NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `ID` (`ID`) )"); $oldTemplate = $settings["template"]; $template->assign("theme",$oldTemplate); $conn->query("INSERT INTO `settings` (`ID` ,`settingsKey` ,`settingsValue`) VALUES (NULL , 'theme', '$oldTemplate')"); $conn->query("UPDATE `settings` SET `template`='standard'"); $conn->query("INSERT INTO `settings` (`ID`, `settingsKey`, `settingsValue`) VALUES (NULL, 'filePass', '$filePass')"); $filesList = $conn->query("SELECT * FROM `files`")->fetchAll(); $fileObj = new datei(); foreach($filesList as $file) { $tmpFile = CL_ROOT . "/" . $file["datei"]; $fileObj->encryptFile($tmpFile,$filePass); } //drop tags field from files $conn->query("ALTER TABLE `files` DROP `tags`"); // VERSION-INDEPENDENT // Clear templates cache $handle = opendir($template->compile_dir); while (false !== ($file = readdir($handle))) { if ($file != "." and $file != "..") { unlink(CL_ROOT . "/" . $template->compile_dir . "/" . $file); } } // Optimize tables $opt1 = $conn->query("OPTIMIZE TABLE `files`"); $opt2 = $conn->query("OPTIMIZE TABLE `files_attached`"); $opt3 = $conn->query("OPTIMIZE TABLE `log`"); $opt4 = $conn->query("OPTIMIZE TABLE `messages`"); $opt5 = $conn->query("OPTIMIZE TABLE `milestones`"); $opt6 = $conn->query("OPTIMIZE TABLE `milestones_assigned`"); $opt7 = $conn->query("OPTIMIZE TABLE `projectfolders`"); $opt8 = $conn->query("OPTIMIZE TABLE `projekte`"); $opt9 = $conn->query("OPTIMIZE TABLE `projekte_assigned`"); $opt10 = $conn->query("OPTIMIZE TABLE `roles`"); $opt11 = $conn->query("OPTIMIZE TABLE `roles_assigned`"); $opt12 = $conn->query("OPTIMIZE TABLE `settings`"); $opt13 = $conn->query("OPTIMIZE TABLE `tasklist`"); $opt14 = $conn->query("OPTIMIZE TABLE `tasks`"); $opt15 = $conn->query("OPTIMIZE TABLE `tasks_assigned`"); $opt16 = $conn->query("OPTIMIZE TABLE `timetracker`"); $opt17 = $conn->query("OPTIMIZE TABLE `user`"); $template->display("update.tpl"); ?>
    {literal} {/literal}

    {$projectname|truncate:45:"...":true}/ {#timetracker#}

    {*Filter End*}
    {section name = track loop=$tracker} {*Color-Mix*} {if $smarty.section.track.index % 2 == 0} {else} {/if} {/section}
    {#user#} {#day#} {#started#} {#ended#} {#hours#}  
    {$tracker[track].daystring|truncate:12:"...":true} {$tracker[track].startstring|truncate:12:"...":true} {$tracker[track].endstring|truncate:12:"...":true} {$tracker[track].hours|truncate:12:"...":true}   {if $userpermissions.timetracker.edit} {/if} {if $userpermissions.timetracker.del} {/if}
    {if $tracker[track].comment != ""} {#comment#}:
    {$tracker[track].comment} {/if} {if $tracker[track].task > 0}

    {#task#}:
    {$tracker[track].tname}

    {/if}
    {#totalhours#}: {$totaltime|default}  
    {paginate_prev} {paginate_middle} {paginate_next}
    {*smooth End*}
    {*block END*}
    {*timetrack END*}
    {literal} {/literal}
    {*Timetracking END*}
    {*content-left-in END*}