You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oodt.apache.org by ga...@apache.org on 2012/03/02 03:09:05 UTC

svn commit: r1296032 [2/4] - in /oodt/trunk/balance/modules: ./ cas-browser/ cas-browser/classes/ cas-browser/scripts/ cas-browser/scripts/widgets/ cas-browser/static/ cas-browser/static/css/ cas-browser/static/img/ cas-browser/static/js/ cas-browser/v...

Added: oodt/trunk/balance/modules/cas-browser/scripts/widgets/CustomSearchWidget.php
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/scripts/widgets/CustomSearchWidget.php?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/scripts/widgets/CustomSearchWidget.php (added)
+++ oodt/trunk/balance/modules/cas-browser/scripts/widgets/CustomSearchWidget.php Fri Mar  2 02:09:04 2012
@@ -0,0 +1,178 @@
+<?php
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * 
+ * This widget is configured by the customSearchConfig array in the config file.  The
+ * widget expects the specifications for the criteria to search in sequence.  Each
+ * criteria should start with either 'term' or 'range' as an element in the config
+ * array, followed by the name of the metadata element that will be searched with the
+ * value given in the field corresponding to that criteria.  Finally the next element
+ * or two elements in the config array will be occupied by labels for the inout fields,
+ * depending upon the criteria type (term or range).
+ * Here is an exmaple of a config array for a term criterion and a range criterion in order:
+ * 
+ * customSearchConfig[]=term
+ * customSearchConfig[]=EUFile
+ * customSearchConfig[]=EUFile
+ * customSearchConfig[]=range
+ * customSearchConfig[]=VideoLength
+ * customSearchConfig[]=Min. Video Length
+ * customSearchConfig[]=Max. Video Length
+ * 
+ */
+class CustomSearchWidget 
+	implements Org_Apache_Oodt_Balance_Interfaces_IApplicationWidget {
+	
+	// This array will specify what criteria we use in our search, what types they are
+	// and how they should be labeled.
+	public $criteria;
+	
+	// The ProductType that the widget is filtering.  This must be set before calling
+	// render() or renderScript().
+	public $productType;
+	
+	// The id of the HTMLElement that will be modified by filter results.  This must be set before
+	// calling renderScript().
+	public $htmlID;
+	
+	// The url of the site base
+	public $siteUrl;
+	
+	// Will results be returned in html or json
+	public $resultFormat;
+	
+	public function __construct($options = array()){
+		
+		if(isset($options['productType'])){
+			$this->productType = $options['productType'];
+		}
+		if(isset($options['htmlID'])){
+			$this->htmlID = $options['htmlID'];
+		}
+		if(isset($options['siteUrl'])){
+			$this->siteUrl = $options['siteUrl'];
+		}
+		if(isset($options['resultFormat'])){
+			$this->resultFormat = $options['resultFormat'];
+		}
+		
+		if(!isset(App::Get()->settings['customSearchConfig'])){
+			echo '<div class="error">No criteria config was found for the CustomSearchWidget.</div>';
+			return;
+		}
+		$criteriaConfig = App::Get()->settings['customSearchConfig'];
+		
+		// Build a representation of the criteria to be searched by the widget.
+		// If, during this process, we encounter config values that don't make
+		// sense or an incomplete config for a criterion, we'll simply skip to
+		// the next index in the config array.
+		$this->criteria = array();
+		$configIndex = 0;
+		while(isset($criteriaConfig[$configIndex])){
+			
+			$newCriterion = array();
+			
+			// Look for a criteria type
+			$newType = strtolower($criteriaConfig[$configIndex]);
+			if($newType == 'term' or $newType == 'range'){
+				$newCriterion['type'] = $newType;
+				$configIndex++;
+			}else{
+				continue;	// Let's skip this one and hope that we
+							// find one that makes more sense later.
+			}
+			
+			// Extract the metadata element associated with the criterion
+			$newElement = $criteriaConfig[$configIndex];
+			if(isset($newElement)){
+				$newCriterion['element'] = $newElement;
+				$configIndex++;
+			}else{
+				continue;	// This criterion wasn't finished.
+			}
+			
+			// Extract the labels for the input field(s)
+			$newLabel = $criteriaConfig[$configIndex];
+			if(isset($newLabel)){
+				if($newType == 'term'){
+					$newCriterion['termLabel'] = $newLabel;
+				}else{
+					$newCriterion['minLabel'] = $newLabel;
+					$configIndex++;
+					$newLabel = $criteriaConfig[$configIndex];
+					if(isset($newLabel)){
+						$newCriterion['maxLabel'] = $newLabel;
+					}else{
+						continue;	// This criterion wasn't finished.
+					}
+				}
+			}else{
+				continue;	// This criterion wasn't finished.
+			}
+			
+			array_push($this->criteria, $newCriterion);
+			$configIndex++;
+			
+		}
+	}
+	
+	// Using the criteria representation at this->criteria, we create the fields for
+	// specifying the criteria values.  We put a hidden input tag with an id of the
+	// form termX or rangeX before the specification fields.  The JS will find these
+	// hidden tags and use them to understand whether the fields specify term or
+	// range criteria.  The number following the criterion type is only so that they
+	// have unique IDs.
+	public function render($bEcho = true){
+		$str = '';
+		for($i = 0; $i < count($this->criteria); $i++){
+			if($this->criteria[$i]['type'] == 'term'){
+				$str .= '<input id="term' . $i . '" type="hidden" value="' . $this->criteria[$i]['element'] . '">';
+				$str .= $this->criteria[$i]['termLabel'] . ':&nbsp;<input type="text" size="18" id="inputTerm' . $i . '"><br/>';
+			}else{
+				$str .= '<input id="range' . $i . '" type="hidden" value="' . $this->criteria[$i]['element'] . '">';
+				$str .= $this->criteria[$i]['minLabel'] . ':&nbsp;<input type="text" size="18" id="inputRangeMin' . $i . '">';
+				$str .= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+				$str .= $this->criteria[$i]['maxLabel'] . ':&nbsp;<input type="text" size="18" id="inputRangeMax' . $i . '"><br/>';
+			}
+		}
+		$str .= '<input type="button" value="Search" onclick="customQuery()" />';
+		
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+	
+	public function renderScript($bEcho = true){
+		$module = App::Get()->loadModule();
+		$str = '';
+		$str .= '<script type="text/javascript">var htmlID = "' . $this->htmlID . '";</script>';
+		$str .= '<script type="text/javascript">var ptName = "' . $this->productType->getName() . '";</script>';
+		$str .= '<script type="text/javascript">var siteUrl = "' . $this->siteUrl . '";</script>';
+		$str .= '<script type="text/javascript">var resultFormat = "' . $this->resultFormat . '";</script>';
+		$str .= '<script type="text/javascript" src="' . $module->moduleStatic . '/js/querywidget.js"></script>';
+		$str .= '<script type="text/javascript" src="' . $module->moduleStatic . '/js/customsearchwidget.js"></script>';
+		
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+}
+?>

Added: oodt/trunk/balance/modules/cas-browser/scripts/widgets/FilterWidget.php
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/scripts/widgets/FilterWidget.php?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/scripts/widgets/FilterWidget.php (added)
+++ oodt/trunk/balance/modules/cas-browser/scripts/widgets/FilterWidget.php Fri Mar  2 02:09:04 2012
@@ -0,0 +1,136 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class FilterWidget 
+	implements Org_Apache_Oodt_Balance_Interfaces_IApplicationWidget {
+
+	// The ProductType that the widget is filtering.  This must be set before calling
+	// render() or renderScript().
+	public $productType;
+	
+	// The ID of the HTMLElement that will be modified by filter results.  This must be set before
+	// calling renderScript().
+	public $htmlID;
+	
+	// The ID of the HTMLElement that contains the loading icon that will be
+	// displayed while getting results
+	public $loadingID;
+	
+	// The url of the site base
+	public $siteUrl;
+	
+	// Whether filtered results will be displayed all at once or in a paged format
+	public $pagedResults;
+	
+	// Will results be returned in html or json
+	public $resultFormat;
+
+	public function __construct($options = array()){
+		if(isset($options['productType'])){
+			$this->productType = $options['productType'];
+		}
+		if(isset($options['htmlID'])){
+			$this->htmlID = $options['htmlID'];
+		}
+		if(isset($options['loadingID'])){
+			$this->loadingID = $options['loadingID'];
+		}
+		if(isset($options['siteUrl'])){
+			$this->siteUrl = $options['siteUrl'];
+		}
+		if(isset($options['pagedResults'])){
+			$this->pagedResults = $options['pagedResults'];
+		}
+		if(isset($options['resultFormat'])){
+			$this->resultFormat = $options['resultFormat'];
+		}
+		
+	}
+	
+	public function setProductType($productType){
+		$this->productType = $productType;
+	}
+	
+	public function setHtmlId($htmlID){
+		$this->htmlID = $htmlID;
+	}
+	
+	public function setSiteUrl($siteUrl){
+		$this->siteUrl = $siteUrl;
+	}
+	
+	public function setPagedResults($pagedResults){
+		$this->pagedResults = $pagedResults;
+	}
+	
+	public function setResultFormat($resultFormat){
+		$this->resultFormat = resultFormat;
+	}
+	
+	public function render($bEcho = true){
+		$str = '';
+		$str .= '<select id="filterKey">';
+		$filterKeys = Utils::getMetadataElements(array($this->productType));
+		natcasesort($filterKeys);
+		foreach($filterKeys as $label){
+			$str .= '<option value="' . $label . '">' . $label . '</option>';
+		}
+		$str .= '</select>&nbsp;=&nbsp;';
+		$str .= '<input type="text" id="filterValue" size="18" alt="filterValue">&nbsp;';
+		$str .= '<input type="button" value="Add" onclick="addFilter()" />';
+		$str .= '<table id="filters"></table>';
+		$str .= '<div id="permalink"></div>';
+		
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+	
+	public function renderScript($bEcho = true){
+		$str = '<script type="text/javascript">';
+		$str .= 'var htmlID = "' . $this->htmlID . '";';
+		$str .= 'var loadingID = "' . $this->loadingID . '";';
+		$str .= 'var ptName = "' . $this->productType->getName() . '";';
+		$str .= 'var ptID = "' . $this->productType->getId() . '";';
+		$str .= 'var siteUrl = "'. $this->siteUrl . '";';
+		$str .= 'var resultFormat = "' . $this->resultFormat  . '";';
+		$str .= 'var displayedMetadata = new Array(';
+		if(isset(App::Get()->settings['browser_products_met'])){
+			$metList = '';
+			foreach(App::Get()->settings['browser_products_met'] as $met){
+				if(strlen($metList) > 0){
+					$metList .= ',';
+				}
+				$metList .= '"' . $met . '"';
+			}
+			$str .= $metList;
+		}
+		$str .= ');</script>';
+		$str .= '<script type="text/javascript" src="' . App::Get()->request->moduleStatic . '/js/querywidget.js"></script>';
+		$str .= '<script type="text/javascript" src="' . App::Get()->request->moduleStatic . '/js/filterwidget.js"></script>';
+	
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+}
+?>

Added: oodt/trunk/balance/modules/cas-browser/scripts/widgets/MetadataDisplayWidget.php
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/scripts/widgets/MetadataDisplayWidget.php?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/scripts/widgets/MetadataDisplayWidget.php (added)
+++ oodt/trunk/balance/modules/cas-browser/scripts/widgets/MetadataDisplayWidget.php Fri Mar  2 02:09:04 2012
@@ -0,0 +1,90 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class MetadataDisplayWidget
+	implements Org_Apache_Oodt_Balance_Interfaces_IApplicationWidget {
+	
+	public $metadata;
+	
+	public function __construct($options = array()) {
+		
+	}
+	
+	public function loadMetadata($metadata) {
+		$this->metadata = $metadata;
+	}
+	
+	
+	public function render($bEcho = true) {
+		$str  = "<table class=\"metwidget\"><tbody>";
+		$str .= $this->renderHelper($this->metadata);
+		$str .= "</tbody></table>";
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+	
+	protected function renderHelper($metadata) {
+		foreach ($metadata as $key => $values) {
+			if ( !empty($values) ) {
+				// Build nested metadata tables recursively
+				$r .= "<tr><th>{$key}</th>";
+				// Associative array means met contains subkeys
+				if (is_array($values) && self::is_assoc($values)) {
+					$r .= "<td>";
+					$r .= "<table class=\"metwidget multivalue\"><tbody>";
+					$r .= $this->renderHelper($values);
+					$r .= "</tbody></table>";
+				} 
+				// Numeric array means met has multiple values
+				else if (is_array($values)) {
+					$r .= "<td>";
+					$r .= "<table class=\"metwidget\"><tbody>";
+					foreach ($values as $val) {
+						if (is_array($val) && self::is_assoc($val)) {
+							$r .= "<tr class=\"multivalue\"><td>";
+							$r .= "<table class=\"metwidget\">";
+							$r .= $this->renderHelper($val);
+							$r .= "</table>";
+						} else {
+							$r .= "<tr><td class=\"value\">";
+							$r .= "<div>". wordwrap($val, 80, "<br />", true) . "</div>";
+						}
+						$r .= "</td></tr>";
+					}
+					$r .= "</tbody></table>";
+				} 
+				// Scalar value means met has one value 
+				else {
+					$r .= "<td class=\"value\">";
+					$r .= "<div>{$values}</div>";
+				}
+				$r .= "</td></tr>";
+			}
+		}
+		return $r;
+	}
+	
+	protected static function is_assoc($array) {
+    	return (is_array($array) && 
+    		(count($array)==0 || 
+    			0 !== count(array_diff_key($array, array_keys(array_keys($array))) )));
+	}
+}
\ No newline at end of file

Added: oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductDownloadWidget.php
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductDownloadWidget.php?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductDownloadWidget.php (added)
+++ oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductDownloadWidget.php Fri Mar  2 02:09:04 2012
@@ -0,0 +1,96 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ProductDownloadWidget 
+	implements Org_Apache_Oodt_Balance_Interfaces_IApplicationWidget {
+	
+	public $client;
+	public $product;
+	public $dataDeliveryUrl;
+	
+	public function __construct($options = array()) {
+		$this->dataDeliveryUrl = $options['dataDeliveryUrl'];
+		
+	}
+	
+	public function setClient(&$XmlRpcClient) {
+		$this->client = $XmlRpcClient;
+	}
+	
+	public function load($Product) {
+		$this->product = $Product;
+	}
+	
+	public function render($bEcho = true) {
+		$str = '';
+		$references = $this->client->getProductReferences($this->product);
+		if (isset($references['faultCode'])){
+			$str .=  "<div class=\"error\">";
+			$str .=  "Error encountered while attempting to retrieve product references.<br/>";
+			$str .=  "FAULT CODE: $references[faultCode]<br/>";
+			$str .=  "FAULT STRING: $references[faultString]<br/>";
+			$str .=  "</div>";
+			if ($bEcho) {
+				echo $str;
+			} else {
+				return $str;
+			}
+		}
+		
+		$referenceCounter = 0;
+		$str .=  "<table class=\"pdw_downloadTable\">";
+		foreach ($references as $reference){
+			$fileName = end(explode("/",$reference['dataStoreReference']));
+			$fileSize = $reference['fileSize'];
+			$fileSizeStr = "";
+			($fileSize > (1024*1024)) 
+				? $fileSizeStr = number_format(($fileSize/(1024*1024)),1) . " MB"
+				: (($fileSize > (1024))
+					? $fileSizeStr = number_format(($fileSize / 1024),1) . " KB"
+					: $fileSizeStr = $fileSize . " bytes");
+			$str .=  "<tr>";
+			$str .=  "<td>";
+			if ($reference['mimeType'] == 'image/jpeg') {
+				$str .=  "<img class=\"tn\" src=\"".$this->dataDeliveryUrl."/data?refIndex=$referenceCounter&productID={$this->product->getID()}\">";	
+			} else {
+				$str .=  "<img class=\"tn\" src=\"".App::Get()->request->moduleStatic."/img/download-icon.gif\"/>";
+			}
+			$str .=  "</td>";
+			$str .=  "<td style=\"vertical-align:top;\">".urldecode($fileName)." <br/><span id=\"product_download_span\">$fileSizeStr</span><br/>";
+			$str .=  "Mime Type: $reference[mimeType]<br/>";
+			if($reference['mimeType'] == 'image/jpeg') {
+				$str .=  "&nbsp;<a href=\"".$this->dataDeliveryUrl."/data?refIndex=$referenceCounter&productID={$this->product->getID()}\" target=\"_new\">view</a> &nbsp;";
+				$str .=  "<a href=\"getImage.php?productID={$this->product->getID()}&refNumber=$referenceCounter&fileName=$fileName\">save</a>&nbsp;";	
+			}
+			else{
+				$str .=  "<a href=\"".$this->dataDeliveryUrl."/data?refIndex=$referenceCounter&productID={$this->product->getID()}\">save</a> &nbsp;";		
+			}
+				
+			$str .=  "</td>";
+			$str .=  "</tr>";
+			$referenceCounter++;
+		}
+		$str .=  "</table>";
+		
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}	
+	}
+}

Added: oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductPageWidget.php
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductPageWidget.php?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductPageWidget.php (added)
+++ oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductPageWidget.php Fri Mar  2 02:09:04 2012
@@ -0,0 +1,133 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Display a page of product results.
+ * @author ahart
+ *
+ */
+class ProductPageWidget 
+	implements Org_Apache_Oodt_Balance_Interfaces_IApplicationWidget {
+	
+	public $page;
+	public $pageMetadata;
+	public $productTypeId;
+	public $returnPage;
+	public $urlBase;
+	
+	private $pageNum;
+	private $pageProducts;
+	private $pageSize;
+	private $totalPages;
+	
+	public function __construct($options = array() ) {
+		$this->page = false;
+		$this->productTypeId = $options['productTypeId']; 
+		$this->returnPage    = (isset($options['returnPage']))
+			? $options['returnPage']
+			: 1;
+		$this->urlBase       = $options['urlBase'];
+	}
+	
+	public function load($productPage, $productMetadata = NULL) {
+		$this->page 		= $productPage;
+		$this->pageMetadata = $productMetadata;
+		$this->pageNum 		= $this->page->getPageNum();
+		$this->pageProducts = $this->page->getPageProducts();
+		$this->pageSize 	= $this->page->getPageSize();
+		$this->totalPages 	= $this->page->getTotalPages();
+	}
+	
+	public function render($bEcho = true) {
+		$str = '';
+		if ($this->page) {
+			$str .= "<table><tr><th>Product Name</th>";
+			$displayedElements = App::Get()->settings['browser_products_met'];
+			foreach($displayedElements as $elementName){
+				$str .= "<th>{$elementName}</th>";
+			}
+			$str .= "</tr>";
+			
+			if ( !App::Get()->settings['browser_private_products_visibility'] ) {
+			// Get a CAS-Browser XML/RPC client
+			$browser  = new CasBrowser();
+			$client   = $browser->getClient();
+			foreach ($this->pageMetadata as $key => $value) {
+				if ( $browser->getProductVisibilityLevel($key) == "deny") {
+					unset($this->pageMetadata[$key]);
+					foreach ($this->pageProducts as $product) {
+						if ($product->id == $key) {
+							$productKey = array_search($product, $this->pageProducts);
+							unset($this->pageProducts[$productKey]);
+						}
+					}
+				}
+			}
+			}
+			foreach($this->pageProducts as $product){
+				$str .= "<tr><td><a href=\"".$this->urlBase."/product/{$product->getId()}/{$this->returnPage}\">" 
+				  . urlDecode(basename($product->getName())) . "</a></td>";
+				foreach($displayedElements as $elementName){
+					$str .= "<td>" . $this->pageMetadata[$product->getId()]->getMetadata($elementName) . "</td>";
+				}
+				$str .= "</tr>";
+			}
+			$str .= "</table>";
+		} 
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+	
+	public function renderPageDetails($bEcho = true) {
+		// Variables to determine product range displayed and total count
+		$pageNum    = ($this->pageNum == -1)    ? 0 : $this->pageNum;
+		$totalPages = ($this->totalPages == -1) ? 0 : $this->totalPages;
+		
+		$displayCountStart = ($totalPages == 0) ? 0 : $this->pageSize * ($pageNum - 1) + 1;
+		$displayCountEnd   = ($totalPages == 0) ? 0 : $displayCountStart + count($this->pageProducts) - 1;
+		$displayCountStart = ($totalPages > 0 && $displayCountStart == 0) ? 1 : $displayCountStart;
+		
+
+		// 'Previous' and 'Next' page links
+		$linkBase    = App::Get()->loadModule()->moduleRoot . "/products/{$this->productTypeId}/page";
+		$prevPageNum = $this->pageNum -1;
+		$nextPageNum = $this->pageNum +1;
+		 
+		$prevPageLink = ($prevPageNum >= 1) 
+			? "<a href=\"{$linkBase}/{$prevPageNum}\">&lt;&lt;&nbsp;Previous Page</a>"
+			: '';
+		$nextPageLink = ($nextPageNum <= $this->totalPages)
+			? "<a href=\"{$linkBase}/{$nextPageNum}\">Next Page&nbsp;&gt;&gt;</a>"
+			: '';
+	
+		$rangeInfo = "<span class=\"pp_detail\">Page {$pageNum} of {$totalPages} "
+			."(products {$displayCountStart} - {$displayCountEnd})</span>";
+
+		
+		$str = "<div class=\"pp_pageLinks\">{$rangeInfo}&nbsp;&nbsp;{$prevPageLink}&nbsp;&nbsp;{$nextPageLink}</div>\r\n";	
+	
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+}

Added: oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductTypeListWidget.php
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductTypeListWidget.php?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductTypeListWidget.php (added)
+++ oodt/trunk/balance/modules/cas-browser/scripts/widgets/ProductTypeListWidget.php Fri Mar  2 02:09:04 2012
@@ -0,0 +1,91 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ProductTypeListWidget 
+	implements Org_Apache_Oodt_Balance_Interfaces_IApplicationWidget {
+	
+	public $productTypes;
+	public $urlBase;
+	
+	public function __construct($options = array()) {
+		$this->productTypes = $options['productTypes'];
+		$this->urlBase      = isset($options['urlBase']) 
+			? $options['urlBase']
+			: '';
+	}
+	
+	public function setUrlBase($base) {
+		$this->urlBase = $base;
+	}
+	
+	public function render($bEcho = true) {
+		$str = '';
+		$str.= "<table id=\"productTypeSearch\" class=\"dataTable\">
+			  <thead>
+			    <tr>";
+		// Display the Column Headers
+		foreach (App::Get()->settings['browser_pt_search_met'] as $metKey) {
+			$str .= "<th>".ucwords($metKey)."</th>";
+		}
+		if (isset(App::Get()->settings['browser_pt_hidden_search_met'])) {
+			foreach (App::Get()->settings['browser_pt_hidden_search_met'] as $metKey) {
+				$str .= "<th class=\"hidden\">{$metKey}</th>";
+			}
+		}
+		$str .= "</tr></thead><tbody>";
+
+		// Display the Data
+		foreach ($this->productTypes as $ptKey => $ptMetadata) {
+			if (isset(App::Get()->settings['browser_product_type_ignores']) && 
+				in_array($ptKey,App::Get()->settings['browser_product_type_ignores'])) { continue; }
+			$str .= "<tr>";
+			foreach (App::Get()->settings['browser_pt_search_met'] as $metKey) {
+				if ($metKey == App::Get()->settings['browser_pt_search_linkkey']) {
+					$str .= "<td><a href=\"{$this->urlBase}/products/{$ptKey}\">{$ptMetadata[$metKey][0]}</a>";
+					if(count($ptMetadata[$metKey]) == 2){
+						$str .= "&nbsp({$ptMetadata[$metKey][1]})";
+					}
+					$str .= "</td>";
+				} else {
+					if (count($ptMetadata[$metKey]) > 1) {
+						$str .= "<td>" . implode(", ", $ptMetadata[$metKey]) . "</td>";
+					} else {
+						$str .= "<td>{$ptMetadata[$metKey][0]}</td>";	
+					}
+				}
+			}
+			if (isset(App::Get()->settings['browser_pt_hidden_search_met'])) {
+				foreach (App::Get()->settings['browser_pt_hidden_search_met'] as $metKey) {
+					if (count($ptMetadata[$metKey]) > 1) {
+						$str .= "<td class=\"hidden\">" . implode(", ", $ptMetadata[$metKey]) . "</td>";
+					} else {
+						$str .= "<td class=\"hidden\">{$ptMetadata[$metKey][0]}</td>";	
+					}
+				}
+			}
+			$str .= "</tr>\r\n";
+		}
+		$str .= "</tbody></table>";	
+
+		if ($bEcho) {
+			echo $str;
+		} else {
+			return $str;
+		}
+	}
+}
\ No newline at end of file

Added: oodt/trunk/balance/modules/cas-browser/static/css/cas-browser.css
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/css/cas-browser.css?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/static/css/cas-browser.css (added)
+++ oodt/trunk/balance/modules/cas-browser/static/css/cas-browser.css Fri Mar  2 02:09:04 2012
@@ -0,0 +1,289 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@CHARSET "UTF-8";
+
+a {
+	color:#236;
+}
+
+br.fiftyPx{
+	margin-bottom:50px;
+}
+
+table#productTypeSearch {
+		
+}
+table#productTypeSearch th.hidden,
+	table#productTypeSearch td.hidden {
+	display:none;	
+}
+
+div#productTypeSearch_length {
+	float:right;
+	text-align:right;
+	margin-bottom:20px;	
+	margin-top:25px;	
+}
+div#productTypeSearch_filter {
+	float:none;
+	margin-top:-20px;	
+	right:0px;	
+	text-align:left;
+	width:450px;
+}
+
+table.dataTable tr {
+	
+}
+table.dataTable tr td {
+	padding:6px;
+	vertical-align:top
+}
+
+table.dataTable  {
+	margin-top:15px;	
+}
+.dataTables_filter input[type=text] {
+	padding:5px;
+	margin-left:0px;	
+	width:97%;
+}
+table.dataTable thead tr th {
+	border-bottom:solid 1px #888;
+}
+
+table.dataTable tbody tr.odd {
+	background-color:#eee;	
+}
+table.dataTable tbody tr.even {
+	background-color:#fff;
+}
+table.dataTable tbody tr.odd td {
+	background-color:transparent;	
+}
+table.dataTable tbody tr.even td {
+	background-color:transparent;	
+}
+table.dataTable tbody tr td.sorting_1,
+	table.dataTable thead tr th.sorting_asc,
+	table.dataTable thead tr th.sorting_desc {
+	background-color:#f3fff3;	
+}
+table.dataTable tbody tr.odd td.sorting_1 {
+	background-color:#e3f3e3;
+}
+table.dataTable tbody tr td a {
+	color:#222;
+}
+
+/**
+ * DATASET
+ */
+ul.tabs {
+	border-bottom:solid 1px #ccc;
+	margin:0px;
+	padding:0px;
+	padding-bottom:6px;
+}
+ul.tabs li {
+	display:inline;
+	margin:0px;
+	padding:0px;
+}
+ul.tabs li a {
+	border:solid 1px #ccc;
+	padding:8px 12px;
+	margin-right:5px;
+	margin-bottom:0px;
+	background-color:#ccc;
+}
+ul.tabs li a.selected {
+	background-color:#fff;
+	border-bottom:solid 1px #fff;
+}
+
+/**
+ * MET VIEWER
+ */
+h4.toggler {
+	padding:5px 0px;
+	text-decoration:underline;
+	cursor:pointer;
+	_cursor:hand;
+	margin-bottom:0px;
+}
+table.metwidget {
+	
+}
+
+
+table.metwidget tr {
+	
+}
+
+table.metwidget th {
+	background-color:#e3f3e3;
+	border-bottom:solid 1px #b3c3b3;	
+	vertical-align:top;
+	padding-top:15px;
+	width:110px;
+}
+table.metwidget td {
+	vertical-align:top;
+	border-bottom:solid 1px #b3c3b3;
+}
+table.metwidget table td {
+	border-bottom:none;
+}
+
+table.metwidget td.value div {
+	background-color:transparent;
+	border:solid 4px #fff;
+	padding:5px;
+}
+table.metwidget.multivalue td {
+	border:none;	
+}
+table.metwidget table {
+	margin:0px;
+	padding:0px;
+}
+
+div#section_products {
+	position:relative;
+}
+div#cas_browser_dataset_download {
+
+}
+
+ul.pp_productList {
+	margin-top:10px;
+	list-style:none;
+	padding-left:0px;
+}
+ul.pp_productList li {
+	line-height:28px;
+	padding-left:0px;
+	margin-left:0px;
+}
+ul.pp_productList li a {
+	text-decoration:none;
+	display:block;
+	background-color:#fff;
+	padding:0px 8px;
+	width:100%;
+}
+ul.pp_productList li a:hover {
+	text-decoration:underline;
+	background-color:#e3f3e3;
+}
+
+input[type=text] {
+	padding:5px;	
+}
+select {
+ 	padding:3px;
+}
+
+div.breadcrumbs {
+	border-bottom:dotted 1px #ccc;
+	padding-bottom:4px;
+	margin-top:-5px;
+}
+
+
+
+table.metwidget {
+	border-top:dotted 1px #bbb;	
+}
+table.metwidget table {
+	border-top:none;	
+}
+
+table.metwidget tr th {
+	vertical-align:top;
+	padding-top:8px;	
+	background-color:#eee;
+	border-bottom:solid 2px #fff;
+}
+table.metwidget tr td {
+	background-color:#f8f8f8;	
+}
+
+ul.tabmenu {
+	margin:0px;
+	padding:0px;
+	margin-bottom:15px;
+	padding-bottom:7px;
+	border-bottom:solid 1px #ccc;	
+}
+ul.tabmenu li {
+	display:inline;
+	border:solid 1px #ccc;
+	background-color:#eee;
+	padding:10px 15px;
+	font-size:1.6em;
+	margin-right:5px;
+	cursor:pointer;
+	_cursor:hand;
+}
+ul.tabmenu li.selected {
+	border-bottom:solid 1px #fff;
+	background-color:#fff;
+}
+
+div#filter_widget {
+	display:none;
+	border:solid 1px #ccc;
+	background-color:#f8f8f8;
+	padding:5px;	
+}
+
+div#section_filter_tools_container {
+	position:relative;	
+}
+div#section_filter_tools_buttons {
+	text-align:right;
+	position:absolute;
+	top:0px;
+	right:0px;
+}
+div#section_filter_tools {
+	margin-bottom:15px;	
+}
+div#filter_widget_exclusive_container {
+	position:absolute;
+	top:25px;
+	right:0px;
+}
+
+
+
+span#product_download_span {
+	color:#555;
+	font-size:0.9em;
+}
+
+div#loading_icon_container {
+	margin-bottom:50px;
+}
+
+img#zip_icon{
+	float:left;
+	margin-right:15px;
+}

Added: oodt/trunk/balance/modules/cas-browser/static/css/dataTables.css
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/css/dataTables.css?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/static/css/dataTables.css (added)
+++ oodt/trunk/balance/modules/cas-browser/static/css/dataTables.css Fri Mar  2 02:09:04 2012
@@ -0,0 +1,469 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * General page setup
+ */
+#dt_example {
+	font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
+	margin: 0;
+	padding: 0;
+	color: #333;
+	background-color: #fff;
+}
+
+
+#dt_example #container {
+	width: 800px;
+	margin: 30px auto;
+	padding: 0;
+}
+
+
+#dt_example #footer {
+	margin: 50px auto 0 auto;
+	padding: 0;
+}
+
+#dt_example #demo {
+	margin: 30px auto 0 auto;
+}
+
+#dt_example .big {
+	font-size: 1.3em;
+	font-weight: bold;
+	line-height: 1.6em;
+	color: #4E6CA3;
+}
+
+#dt_example .spacer {
+	height: 20px;
+	clear: both;
+}
+
+#dt_example .clear {
+	clear: both;
+}
+
+#dt_example pre {
+	padding: 15px;
+	background-color: #F5F5F5;
+	border: 1px solid #CCCCCC;
+}
+
+#dt_example h1 {
+	margin-top: 2em;
+	font-size: 1.3em;
+	font-weight: normal;
+	line-height: 1.6em;
+	color: #4E6CA3;
+	border-bottom: 1px solid #B0BED9;
+	clear: both;
+}
+
+#dt_example h2 {
+	font-size: 1.2em;
+	font-weight: normal;
+	line-height: 1.6em;
+	color: #4E6CA3;
+	clear: both;
+}
+
+#dt_example a {
+	color: #0063DC;
+	text-decoration: none;
+}
+
+#dt_example a:hover {
+	text-decoration: underline;
+}
+
+#dt_example ul {
+	color: #B0BED9;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables features
+ */
+
+.dataTables_wrapper {
+	position: relative;
+	min-height: 302px;
+	_height: 302px;
+	clear: both;
+}
+
+.dataTables_processing {
+	position: absolute;
+	top: 0px;
+	left: 50%;
+	width: 250px;
+	margin-left: -125px;
+	border: 1px solid #ddd;
+	text-align: center;
+	color: #999;
+	font-size: 11px;
+	padding: 2px 0;
+}
+
+.dataTables_length {
+	width: 40%;
+	float: left;
+}
+
+.dataTables_filter {
+	width: 50%;
+	float: right;
+	text-align: right;
+}
+
+.dataTables_info {
+	width: 60%;
+	float: left;
+}
+
+.dataTables_paginate {
+	width: 44px;
+	* width: 50px;
+	float: right;
+	text-align: right;
+}
+
+/* Pagination nested */
+.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
+	height: 19px;
+	width: 19px;
+	margin-left: 3px;
+	float: left;
+}
+
+.paginate_disabled_previous {
+	background-image: url('../css-images/dataTables/back_disabled.jpg');
+}
+
+.paginate_enabled_previous {
+	background-image: url('../css-images/dataTables/back_enabled.jpg');
+}
+
+.paginate_disabled_next {
+	background-image: url('../css-images/dataTables/forward_disabled.jpg');
+}
+
+.paginate_enabled_next {
+	background-image: url('../css-images/dataTables/forward_enabled.jpg');
+}
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables display
+ */
+table.display {
+	margin: 0 auto;
+	width: 100%;
+	clear: both;
+}
+
+table.display thead th {
+	padding: 3px 10px;
+	border-bottom: 1px solid black;
+	font-weight: bold;
+	cursor: pointer;
+	* cursor: hand;
+}
+
+table.display tfoot th {
+	padding: 3px 10px;
+	border-top: 1px solid black;
+	font-weight: bold;
+}
+
+table.display tr.heading2 td {
+	border-bottom: 1px solid #aaa;
+}
+
+table.display td {
+	padding: 3px 10px;
+}
+
+table.display td.center {
+	text-align: center;
+}
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables sorting
+ */
+
+.sorting_asc {
+	background: url('../css-images/dataTables/sort_asc.jpg') no-repeat center right;
+}
+
+.sorting_desc {
+	background: url('../css-images/dataTables/sort_desc.jpg') no-repeat center right;
+}
+
+.sorting {
+	background: url('../css-images/dataTables/sort_both.jpg') no-repeat center right;
+}
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables row classes
+ */
+table.display tr.odd.gradeA {
+	background-color: #ddffdd;
+}
+
+table.display tr.even.gradeA {
+	background-color: #eeffee;
+}
+
+
+
+
+table.display tr.odd.gradeA {
+	background-color: #ddffdd;
+}
+
+table.display tr.even.gradeA {
+	background-color: #eeffee;
+}
+
+table.display tr.odd.gradeC {
+	background-color: #ddddff;
+}
+
+table.display tr.even.gradeC {
+	background-color: #eeeeff;
+}
+
+table.display tr.odd.gradeX {
+	background-color: #ffdddd;
+}
+
+table.display tr.even.gradeX {
+	background-color: #ffeeee;
+}
+
+table.display tr.odd.gradeU {
+	background-color: #ddd;
+}
+
+table.display tr.even.gradeU {
+	background-color: #eee;
+}
+
+
+tr.odd {
+	background-color: #E2E4FF;
+}
+
+tr.even {
+	background-color: white;
+}
+
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Misc
+ */
+.top, .bottom {
+	padding: 15px;
+	background-color: #F5F5F5;
+	border: 1px solid #CCCCCC;
+}
+
+.top .dataTables_info {
+	float: none;
+}
+
+.clear {
+	clear: both;
+}
+
+tfoot input {
+	margin: 0.5em 0;
+	width: 100%;
+	color: #444;
+}
+
+tfoot input.search_init {
+	color: #999;
+}
+
+
+.example_alt_pagination div.dataTables_info {
+	width: 40%;
+}
+
+.example_alt_pagination .dataTables_paginate {
+	width: 400px;
+}
+
+.example_alt_pagination div.dataTables_paginate span.paginate_button,
+ 	.example_alt_pagination div.dataTables_paginate span.paginate_active {
+	border: 1px solid #aaa;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	padding: 2px 5px;
+	margin: 0 3px;
+	cursor: pointer;
+	*cursor: hand;
+}
+
+.example_alt_pagination div.dataTables_paginate span.paginate_button {
+	background-color: #ddd;
+}
+
+.example_alt_pagination div.dataTables_paginate span.paginate_button:hover {
+	background-color: #ccc;
+}
+
+.example_alt_pagination div.dataTables_paginate span.paginate_active {
+	background-color: #99B3FF;
+}
+
+
+table.display tr.row_selected.odd td {
+	background-color: #B0BED9;
+}
+
+table.display tr.row_selected.even td {
+	background-color: #9FAFD1;
+}
+
+
+/*
+ * Sorting classes for columns
+ */
+/* For the standard odd/even */
+tr.odd td.sorting_1 {
+	background-color: #D3D6FF;
+}
+
+tr.odd td.sorting_2 {
+	background-color: #DADCFF;
+}
+
+tr.odd td.sorting_3 {
+	background-color: #E0E2FF;
+}
+
+tr.even td.sorting_1 {
+	background-color: #EAEBFF;
+}
+
+tr.even td.sorting_2 {
+	background-color: #F2F3FF;
+}
+
+tr.even td.sorting_3 {
+	background-color: #F9F9FF;
+}
+
+
+/* For the Conditional-CSS grading rows */
+/*
+ 	Colour calculations (based off the main row colours)
+  Level 1:
+		dd > c4
+		ee > d5
+	Level 2:
+	  dd > d1
+	  ee > e2
+ */
+tr.odd.gradeA td.sorting_1 {
+	background-color: #c4ffc4;
+}
+
+tr.odd.gradeA td.sorting_2 {
+	background-color: #d1ffd1;
+}
+
+tr.even.gradeA td.sorting_1 {
+	background-color: #d5ffd5;
+}
+
+tr.even.gradeA td.sorting_2 {
+	background-color: #e2ffe2;
+}
+
+tr.odd.gradeC td.sorting_1 {
+	background-color: #c4c4ff;
+}
+
+tr.odd.gradeC td.sorting_2 {
+	background-color: #d1d1ff;
+}
+
+tr.even.gradeC td.sorting_1 {
+	background-color: #d5d5ff;
+}
+
+tr.even.gradeC td.sorting_2 {
+	background-color: #e2e2ff;
+}
+
+tr.odd.gradeX td.sorting_1 {
+	background-color: #ffc4c4;
+}
+
+tr.odd.gradeX td.sorting_2 {
+	background-color: #ffd1d1;
+}
+
+tr.even.gradeX td.sorting_1 {
+	background-color: #ffd5d5;
+}
+
+tr.even.gradeX td.sorting_2 {
+	background-color: #ffe2e2;
+}
+
+tr.odd.gradeU td.sorting_1 {
+	background-color: #c4c4c4;
+}
+
+tr.odd.gradeU td.sorting_2 {
+	background-color: #d1d1d1;
+}
+
+tr.even.gradeU td.sorting_1 {
+	background-color: #d5d5d5;
+}
+
+tr.even.gradeU td.sorting_2 {
+	background-color: #e2e2e2;
+}
+
+
+/*
+ * Row highlighting example
+ */
+.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
+	background-color: #ECFFB3;
+}
+
+.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
+	background-color: #E6FF99;
+}
\ No newline at end of file

Added: oodt/trunk/balance/modules/cas-browser/static/img/download-icon.gif
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/img/download-icon.gif?rev=1296032&view=auto
==============================================================================
Binary file - no diff available.

Propchange: oodt/trunk/balance/modules/cas-browser/static/img/download-icon.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: oodt/trunk/balance/modules/cas-browser/static/img/loading.gif
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/img/loading.gif?rev=1296032&view=auto
==============================================================================
Binary file - no diff available.

Propchange: oodt/trunk/balance/modules/cas-browser/static/img/loading.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: oodt/trunk/balance/modules/cas-browser/static/img/zip-icon-smaller.gif
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/img/zip-icon-smaller.gif?rev=1296032&view=auto
==============================================================================
Binary file - no diff available.

Propchange: oodt/trunk/balance/modules/cas-browser/static/img/zip-icon-smaller.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: oodt/trunk/balance/modules/cas-browser/static/img/zip-icon.gif
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/img/zip-icon.gif?rev=1296032&view=auto
==============================================================================
Binary file - no diff available.

Propchange: oodt/trunk/balance/modules/cas-browser/static/img/zip-icon.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: oodt/trunk/balance/modules/cas-browser/static/js/crosstypesearchwidget.js
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/js/crosstypesearchwidget.js?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/static/js/crosstypesearchwidget.js (added)
+++ oodt/trunk/balance/modules/cas-browser/static/js/crosstypesearchwidget.js Fri Mar  2 02:09:04 2012
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function renderJsonOutput(data){
+	output = '<table id="crossPTSearchTable" class="dataTable"><thead><tr><th>Product Name</th><th>ProductType</th>';
+	for(i = 0; i < displayedMetadata.length; i++){
+		output += '<th>' + displayedMetadata[i] + '</th>';
+	}
+	output += '</tr></thead><tbody>';
+	for(i = 0; i < data['results'].length; i++){
+		output += '<tr><td><a href="' + siteUrl + '/product/' + data['results'][i]['id'] + '">';
+		output += data['results'][i]['name'] + '</a></td>';
+		output += '<td>' + data['results'][i]['type'] + '</td>';
+		for(k = 0; k < displayedMetadata.length; k++){
+			output += '<td>' + data['results'][i]['metadata'][displayedMetadata[k]] + '</td>';
+		}
+		output += '</tr>';
+	}
+	output += '</tbody></table><br />';
+	$("#" + htmlID).html(output);
+}
+
+function displayPermalink(){
+	output = 'To see these filters again, go to:<br />' + siteUrl + '/typesearch/';
+	if($("#exclusive").attr("checked")){
+		output += '0/';
+	}else{
+		output += '1/';
+	}
+	for(i = 0; i < allCriteria[criteriaRoot].criteria.length; i++){
+		termIndex = allCriteria[criteriaRoot].criteria[i];
+		termKey = allCriteria[termIndex].element;
+		termValue = allCriteria[termIndex].value;
+		output += termKey + '/' + termValue + '/';
+	}
+	$("#permalink").html(output);
+}
+
+function clearResults(){
+	$("#" + htmlID).html("");
+}
+
+function createFilter(key, value){
+	index = addTermCriteria(key, value, criteriaRoot);
+	var filterText = '<tr id="filter' + index + '">';
+	filterText += '<td>' + key + '</td><td>=</td><td>' + value + '</td>';
+	filterText += '<td align="right">';
+	filterText += '<input type="button" value="Remove" onclick="removeFilter(\'' + index + '\')" />';
+	filterText += '</td></tr>';
+	$("#filters").append(filterText);
+}
+
+function addFilter(){
+	pCurrPage = 1;
+	key = $("#filterKey").val();
+	value = $("#filterValue").val();
+	if(value!=""){
+		$("#permalink").html("");
+		createFilter(key, value);
+		formatCrossTypeQueryRequest();
+		$("#filterValue").val("");
+    }
+}
+
+function removeFilter(filterIndex){
+	pCurrPage = 1;
+	$("#filter" + filterIndex).remove();
+	$("#permalink").html("");
+	removeCriteria(filterIndex);
+	sendCrossTypeRequest();
+}
+
+function getNextPage(){
+	pCurrPage = pCurrPage + 1;
+	sendCrossTypeRequest();
+}
+
+function getPrevPage(){
+	pCurrPage = pCurrPage - 1;
+	sendCrossTypeRequest();
+}
+
+function changeExclusive(){
+	if($("#exclusive").attr("checked")){
+		setExclusiveQuery(true);
+	}else{
+		setExclusiveQuery(false);
+	}
+	if(determineRequest(criteriaRoot)){
+		formatCrossTypeQueryRequest();
+	}
+}

Added: oodt/trunk/balance/modules/cas-browser/static/js/customsearchwidget.js
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/js/customsearchwidget.js?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/static/js/customsearchwidget.js (added)
+++ oodt/trunk/balance/modules/cas-browser/static/js/customsearchwidget.js Fri Mar  2 02:09:04 2012
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// When the document is ready, we need to create a representation of the criteria
+// tree in javascript.  This is done by looking for hidden input tags with ids that
+// start with either 'term' or 'range'.  These precede the text input fields to
+// specify criteria of the corresponding type.  We store the ids of the input fields
+// so we can use thier values when the search button is clicked.  Create criteria
+// that have blank values since they haven't been filled in yet; these values will
+// be updated when the user clicks the search button.
+$(document).ready(function(){
+	var parentIndex = addBooleanCriteria('and', null);
+	$('input[id^="term"]').each(function(){
+		var newTermIndex = addTermCriteria($(this).val(), '', parentIndex);
+		allCriteria[newTermIndex].termInputId = $(this).next().attr("id");
+	})
+	$('input[id^="range"]').each(function(){
+		var newRangeIndex = addRangeCriteria($(this).val(), '', '', parentIndex);
+		allCriteria[newRangeIndex].minInputId = $(this).next().attr("id");
+		allCriteria[newRangeIndex].maxInputId = $(this).next().next().attr("id");
+	})
+});
+
+// Since the criteria in our query tree are originally created with empty values, we
+// must grab the values from the input fields at the stored ids.
+function customUpdateCriteria(index){
+	if(allCriteria[index].type == 'term'){
+		allCriteria[index].value = $('#' + allCriteria[index].termInputId).val();
+		$('#' + allCriteria[index].termInputId).val('');
+	}else if(allCriteria[index].type == 'range'){
+		allCriteria[index].min = $('#' + allCriteria[index].minInputId).val();
+		$('#' + allCriteria[index].minInputId).val('');
+		allCriteria[index].max = $('#' + allCriteria[index].maxInputId).val();
+		$('#' + allCriteria[index].maxInputId).val('');
+	}else if(allCriteria[index].type == 'boolean'){
+		for(i = 0; i < allCriteria[index].criteria.length; i++){
+			customUpdateCriteria(allCriteria[index].criteria[i]);
+		}
+	}
+	return;
+}
+
+// This function is called when the search button is clicked.
+function customQuery(){
+	$("#page_num").val(1);	// Set the value of the desired page to 1 (first in
+							// the set).  The user can fetch later pages by
+							// clicking the links for next and previous pages.
+	customUpdateCriteria(criteriaRoot);	// Update the criteria in the query tree
+										// with the values from the input fields.
+	formatQueryRequest("html");	// Perform the query
+}
+
+function renderJsonOutput(data){
+	output = '<ul class="pp_productList" id="product_list">';
+	for(i = 0; i < data['productList'].length; i++){
+		output += '<li><a href="' + siteUrl + '/product/' + data['productList'][i]['id'] + '">';
+		output += data['productList'][i]['name'] + '</li>';
+	}
+	output += '</ul>';
+	output += '<input type="hidden" id="total_pages" value="' + data['totalPages'] + '">';
+	output += '<input type="hidden" id="page_size" value="' + data['pageSize'] + '">';
+	output += '<input type="hidden" id="total_type_products" value="' + data['totalTypeProducts'] + '">';
+	$("#" + htmlID).html(output);
+}
\ No newline at end of file

Added: oodt/trunk/balance/modules/cas-browser/static/js/filterwidget.js
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/js/filterwidget.js?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/static/js/filterwidget.js (added)
+++ oodt/trunk/balance/modules/cas-browser/static/js/filterwidget.js Fri Mar  2 02:09:04 2012
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function createFilter(key, value){
+	if(!allCriteria[criteriaRoot]){
+		criteriaRoot = addBooleanCriteria('and', null);
+	}
+	index = addTermCriteria(key, value, criteriaRoot);
+	var filterText = '<tr id="filter' + index + '">';
+	filterText += '<td>' + key + '</td><td>=</td><td>' + value + '</td>';
+	filterText += '<td align="right">';
+	filterText += '<input type="button" value="Remove" onclick="removeFilter(\'' + index + '\')" />';
+	filterText += '</td></tr>';
+	$("#filters").append(filterText);
+}
+
+function addFilter(){
+	key = $("#filterKey").val();
+	value = $("#filterValue").val();
+	pCurrPage = 1;
+	if(value!=""){
+		$("#permalink").html("");
+		createFilter(key, value);
+		formatQueryRequest(resultFormat);
+		$("#filterValue").val("");
+    }
+}
+
+function removeFilter(filterIndex){
+	pCurrPage = 1;
+	$("#filter" + filterIndex).remove();
+	$("#permalink").html("");
+	removeCriteria(filterIndex);
+	sendRequest(resultFormat);
+}
+
+function renderJsonOutput(data){
+	output = '';
+	if(displayedMetadata.length > 0){
+		output = '<table><thead><tr><th>Product Name</th>';
+		for(i = 0; i < displayedMetadata.length; i++){
+			output += '<th>' + displayedMetadata[i] + '</th>';
+		}
+		output += '</tr></thead><tbody>';
+		for(i = 0; i < data['results'].length; i++){
+			output += '<tr><td><a href="' + siteUrl + '/product/' + data['results'][i]['id'] + '">';
+			output += data['results'][i]['name'] + '</a></td>';
+			for(j = 0; j < displayedMetadata.length; j++){
+				output += '<td>' + data['results'][i]['metadata'][displayedMetadata[j]] + '</td>';
+			}
+			output += '</tr>';
+		}
+		output += '</tbody></table>';
+	}else{
+		output = '<ul class="pp_productList" id="product_list">';
+		for(i = 0; i < data['results'].length; i++){
+			output += '<li><a href="' + siteUrl + '/product/' + data['results'][i]['id'] + '">';
+			output += data['results'][i]['name'] + '</a></li>';
+		}
+		output += '</ul>';
+	}
+	$("#" + htmlID).html(output);
+}
+
+function displayPermalink(){
+	output = 'To see these filters again, go to:<br />' + siteUrl + '/products/' + ptID + '/';
+	for(i = 0; i < allCriteria[criteriaRoot].criteria.length; i++){
+		termIndex = allCriteria[criteriaRoot].criteria[i];
+		termKey = allCriteria[termIndex].element;
+		termValue = allCriteria[termIndex].value;
+		output += termKey + '/' + termValue + '/';
+	}
+	$("#permalink").html(output);
+}
+
+function getNextPage(){
+	pCurrPage = pCurrPage + 1;
+	sendRequest("json");
+}
+
+function getPrevPage(){
+	pCurrPage = pCurrPage - 1;
+	sendRequest("json");
+}
\ No newline at end of file

Added: oodt/trunk/balance/modules/cas-browser/static/js/jcorner.jquery.js
URL: http://svn.apache.org/viewvc/oodt/trunk/balance/modules/cas-browser/static/js/jcorner.jquery.js?rev=1296032&view=auto
==============================================================================
--- oodt/trunk/balance/modules/cas-browser/static/js/jcorner.jquery.js (added)
+++ oodt/trunk/balance/modules/cas-browser/static/js/jcorner.jquery.js Fri Mar  2 02:09:04 2012
@@ -0,0 +1,247 @@
+/*!
+ * jQuery corner plugin: simple corner rounding
+ * Examples and documentation at: http://jquery.malsup.com/corner/
+ * version 2.11 (15-JUN-2010)
+ * Requires jQuery v1.3.2 or later
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ * Authors: Dave Methvin and Mike Alsup
+ */
+
+/**
+ *  corner() takes a single string argument:  $('#myDiv').corner("effect corners width")
+ *
+ *  effect:  name of the effect to apply, such as round, bevel, notch, bite, etc (default is round). 
+ *  corners: one or more of: top, bottom, tr, tl, br, or bl.  (default is all corners)
+ *  width:   width of the effect; in the case of rounded corners this is the radius. 
+ *           specify this value using the px suffix such as 10px (yes, it must be pixels).
+ */
+;(function($) { 
+
+var style = document.createElement('div').style,
+    moz = style['MozBorderRadius'] !== undefined,
+    webkit = style['WebkitBorderRadius'] !== undefined,
+    radius = style['borderRadius'] !== undefined || style['BorderRadius'] !== undefined,
+    mode = document.documentMode || 0,
+    noBottomFold = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8),
+
+    expr = $.browser.msie && (function() {
+        var div = document.createElement('div');
+        try { div.style.setExpression('width','0+0'); div.style.removeExpression('width'); }
+        catch(e) { return false; }
+        return true;
+    })();
+
+$.support = $.support || {};
+$.support.borderRadius = moz || webkit || radius; // so you can do:  if (!$.support.borderRadius) $('#myDiv').corner();
+
+function sz(el, p) { 
+    return parseInt($.css(el,p))||0; 
+};
+function hex2(s) {
+    var s = parseInt(s).toString(16);
+    return ( s.length < 2 ) ? '0'+s : s;
+};
+function gpc(node) {
+    while(node) {
+        var v = $.css(node,'backgroundColor'), rgb;
+        if (v && v != 'transparent' && v != 'rgba(0, 0, 0, 0)') {
+            if (v.indexOf('rgb') >= 0) { 
+                rgb = v.match(/\d+/g); 
+                return '#'+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
+            }
+            return v;
+        }
+        if (node.nodeName.toLowerCase() == 'html')
+            break;
+        node = node.parentNode; // keep walking if transparent
+    }
+    return '#ffffff';
+};
+
+function getWidth(fx, i, width) {
+    switch(fx) {
+    case 'round':  return Math.round(width*(1-Math.cos(Math.asin(i/width))));
+    case 'cool':   return Math.round(width*(1+Math.cos(Math.asin(i/width))));
+    case 'sharp':  return Math.round(width*(1-Math.cos(Math.acos(i/width))));
+    case 'bite':   return Math.round(width*(Math.cos(Math.asin((width-i-1)/width))));
+    case 'slide':  return Math.round(width*(Math.atan2(i,width/i)));
+    case 'jut':    return Math.round(width*(Math.atan2(width,(width-i-1))));
+    case 'curl':   return Math.round(width*(Math.atan(i)));
+    case 'tear':   return Math.round(width*(Math.cos(i)));
+    case 'wicked': return Math.round(width*(Math.tan(i)));
+    case 'long':   return Math.round(width*(Math.sqrt(i)));
+    case 'sculpt': return Math.round(width*(Math.log((width-i-1),width)));
+    case 'dogfold':
+    case 'dog':    return (i&1) ? (i+1) : width;
+    case 'dog2':   return (i&2) ? (i+1) : width;
+    case 'dog3':   return (i&3) ? (i+1) : width;
+    case 'fray':   return (i%2)*width;
+    case 'notch':  return width; 
+    case 'bevelfold':
+    case 'bevel':  return i+1;
+    }
+};
+
+$.fn.corner = function(options) {
+    // in 1.3+ we can fix mistakes with the ready state
+    if (this.length == 0) {
+        if (!$.isReady && this.selector) {
+            var s = this.selector, c = this.context;
+            $(function() {
+                $(s,c).corner(options);
+            });
+        }
+        return this;
+    }
+
+    return this.each(function(index){
+        var $this = $(this),
+            // meta values override options
+            o = [$this.attr($.fn.corner.defaults.metaAttr) || '', options || ''].join(' ').toLowerCase(),
+            keep = /keep/.test(o),                       // keep borders?
+            cc = ((o.match(/cc:(#[0-9a-f]+)/)||[])[1]),  // corner color
+            sc = ((o.match(/sc:(#[0-9a-f]+)/)||[])[1]),  // strip color
+            width = parseInt((o.match(/(\d+)px/)||[])[1]) || 10, // corner width
+            re = /round|bevelfold|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dogfold|dog/,
+            fx = ((o.match(re)||['round'])[0]),
+            fold = /dogfold|bevelfold/.test(o),
+            edges = { T:0, B:1 },
+            opts = {
+                TL:  /top|tl|left/.test(o),       TR:  /top|tr|right/.test(o),
+                BL:  /bottom|bl|left/.test(o),    BR:  /bottom|br|right/.test(o)
+            },
+            // vars used in func later
+            strip, pad, cssHeight, j, bot, d, ds, bw, i, w, e, c, common, $horz;
+        
+        if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
+            opts = { TL:1, TR:1, BL:1, BR:1 };
+            
+        // support native rounding
+        if ($.fn.corner.defaults.useNative && fx == 'round' && (radius || moz || webkit) && !cc && !sc) {
+            if (opts.TL)
+                $this.css(radius ? 'border-top-left-radius' : moz ? '-moz-border-radius-topleft' : '-webkit-border-top-left-radius', width + 'px');
+            if (opts.TR)
+                $this.css(radius ? 'border-top-right-radius' : moz ? '-moz-border-radius-topright' : '-webkit-border-top-right-radius', width + 'px');
+            if (opts.BL)
+                $this.css(radius ? 'border-bottom-left-radius' : moz ? '-moz-border-radius-bottomleft' : '-webkit-border-bottom-left-radius', width + 'px');
+            if (opts.BR)
+                $this.css(radius ? 'border-bottom-right-radius' : moz ? '-moz-border-radius-bottomright' : '-webkit-border-bottom-right-radius', width + 'px');
+            return;
+        }
+            
+        strip = document.createElement('div');
+        $(strip).css({
+            overflow: 'hidden',
+            height: '1px',
+            minHeight: '1px',
+            fontSize: '1px',
+            backgroundColor: sc || 'transparent',
+            borderStyle: 'solid'
+        });
+    
+        pad = {
+            T: parseInt($.css(this,'paddingTop'))||0,     R: parseInt($.css(this,'paddingRight'))||0,
+            B: parseInt($.css(this,'paddingBottom'))||0,  L: parseInt($.css(this,'paddingLeft'))||0
+        };
+
+        if (typeof this.style.zoom != undefined) this.style.zoom = 1; // force 'hasLayout' in IE
+        if (!keep) this.style.border = 'none';
+        strip.style.borderColor = cc || gpc(this.parentNode);
+        cssHeight = $(this).outerHeight();
+
+        for (j in edges) {
+            bot = edges[j];
+            // only add stips if needed
+            if ((bot && (opts.BL || opts.BR)) || (!bot && (opts.TL || opts.TR))) {
+                strip.style.borderStyle = 'none '+(opts[j+'R']?'solid':'none')+' none '+(opts[j+'L']?'solid':'none');
+                d = document.createElement('div');
+                $(d).addClass('jquery-corner');
+                ds = d.style;
+
+                bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);
+
+                if (bot && cssHeight != 'auto') {
+                    if ($.css(this,'position') == 'static')
+                        this.style.position = 'relative';
+                    ds.position = 'absolute';
+                    ds.bottom = ds.left = ds.padding = ds.margin = '0';
+                    if (expr)
+                        ds.setExpression('width', 'this.parentNode.offsetWidth');
+                    else
+                        ds.width = '100%';
+                }
+                else if (!bot && $.browser.msie) {
+                    if ($.css(this,'position') == 'static')
+                        this.style.position = 'relative';
+                    ds.position = 'absolute';
+                    ds.top = ds.left = ds.right = ds.padding = ds.margin = '0';
+                    
+                    // fix ie6 problem when blocked element has a border width
+                    if (expr) {
+                        bw = sz(this,'borderLeftWidth') + sz(this,'borderRightWidth');
+                        ds.setExpression('width', 'this.parentNode.offsetWidth - '+bw+'+ "px"');
+                    }
+                    else
+                        ds.width = '100%';
+                }
+                else {
+                    ds.position = 'relative';
+                    ds.margin = !bot ? '-'+pad.T+'px -'+pad.R+'px '+(pad.T-width)+'px -'+pad.L+'px' : 
+                                        (pad.B-width)+'px -'+pad.R+'px -'+pad.B+'px -'+pad.L+'px';                
+                }
+
+                for (i=0; i < width; i++) {
+                    w = Math.max(0,getWidth(fx,i, width));
+                    e = strip.cloneNode(false);
+                    e.style.borderWidth = '0 '+(opts[j+'R']?w:0)+'px 0 '+(opts[j+'L']?w:0)+'px';
+                    bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
+                }
+                
+                if (fold && $.support.boxModel) {
+                    if (bot && noBottomFold) continue;
+                    for (c in opts) {
+                        if (!opts[c]) continue;
+                        if (bot && (c == 'TL' || c == 'TR')) continue;
+                        if (!bot && (c == 'BL' || c == 'BR')) continue;
+                        
+                        common = { position: 'absolute', border: 'none', margin: 0, padding: 0, overflow: 'hidden', backgroundColor: strip.style.borderColor };
+                        $horz = $('<div/>').css(common).css({ width: width + 'px', height: '1px' });
+                        switch(c) {
+                        case 'TL': $horz.css({ bottom: 0, left: 0 }); break;
+                        case 'TR': $horz.css({ bottom: 0, right: 0 }); break;
+                        case 'BL': $horz.css({ top: 0, left: 0 }); break;
+                        case 'BR': $horz.css({ top: 0, right: 0 }); break;
+                        }
+                        d.appendChild($horz[0]);
+                        
+                        var $vert = $('<div/>').css(common).css({ top: 0, bottom: 0, width: '1px', height: width + 'px' });
+                        switch(c) {
+                        case 'TL': $vert.css({ left: width }); break;
+                        case 'TR': $vert.css({ right: width }); break;
+                        case 'BL': $vert.css({ left: width }); break;
+                        case 'BR': $vert.css({ right: width }); break;
+                        }
+                        d.appendChild($vert[0]);
+                    }
+                }
+            }
+        }
+    });
+};
+
+$.fn.uncorner = function() { 
+    if (radius || moz || webkit)
+        this.css(radius ? 'border-radius' : moz ? '-moz-border-radius' : '-webkit-border-radius', 0);
+    $('div.jquery-corner', this).remove();
+    return this;
+};
+
+// expose options
+$.fn.corner.defaults = {
+    useNative: true, // true if plugin should attempt to use native browser support for border radius rounding
+    metaAttr:  'data-corner' // name of meta attribute to use for options
+};
+    
+})(jQuery);