Index: /extensions/rv_gmaps/tags/2.0.b/admin/admin.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/admin/admin.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/admin/admin.php (revision 3449)
@@ -0,0 +1,31 @@
+set_filename('plugin_admin_content', dirname(__FILE__).'/admin.tpl');
+
+if (!isset($_GET['tab']))
+ $page['tab'] = 'config';
+else
+ $page['tab'] = $_GET['tab'];
+
+$my_base_url = get_admin_plugin_menu_link(__FILE__);
+
+$tabsheet = new tabsheet();
+$tabsheet->add( 'config', 'Configuration', add_url_params( $my_base_url, array('tab'=>'config') ) );
+$tabsheet->add( 'edit', 'Edit', add_url_params( $my_base_url, array('tab'=>'edit') ) );
+$tabsheet->add( 'sync', 'Synchronize', add_url_params( $my_base_url, array('tab'=>'sync') ) );
+$tabsheet->select($page['tab']);
+
+$tabsheet->assign();
+
+$my_base_url = $tabsheet->sheets[ $page['tab'] ]['url'];
+$template->set_filename( 'tab_data', dirname(__FILE__).'/admin_'.$page['tab'].'.tpl' );
+include_once( dirname(__FILE__).'/admin_'.$page['tab'].'.php');
+$template->assign_var_from_handle( 'TAB_DATA', 'tab_data');
+$template->assign_var_from_handle( 'ADMIN_CONTENT', 'plugin_admin_content');
+
+if ( empty($conf['gmaps_api_key']) )
+ $page['infos'][] = 'Please define the Google maps api key';
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/admin/admin.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/admin/admin.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/admin/admin.tpl (revision 3449)
@@ -0,0 +1,5 @@
+
Synchronization of EXIF gps metadata information with the database.
+
+{if isset($metadata_result)}
+_image_ranks) )
+ $this->_image_ranks = array_flip( array_keys($this->_image_map) );
+ usort( $clusters[$i]['items'], array($this, '_image_rank_compare') );
+ $clusters[$i]['bounds'] = bounds_union($clusters[$i]['bounds'], $clusters[$j]['bounds'] );
+ array_splice( $clusters, $j, 1);
+ $j--;
+ $ci = bounds_center( $clusters[$i]['bounds'] );
+ $ret++;
+ }
+ }
+ }
+ return $ret;
+ }
+
+ function _image_rank_compare($a, $b)
+ {
+ return $this->_image_ranks[$a] - $this->_image_ranks[$b];
+ }
+
+ function _split_cluster($cluster, $maxLatPrecision, $maxLonPrecision)
+ {
+ $latRange = bounds_lat_range($cluster['bounds']);
+ $lonRange = bounds_lon_range($cluster['bounds']);
+
+ $lat_nb_tiles = max( 1, $latRange/$maxLatPrecision );
+ $lon_nb_tiles = max( 1, $lonRange/$maxLonPrecision );
+ //echo('lat_nb '.$lat_nb_tiles.' lon_nb '.$lon_nb_tiles."\n");
+ if ($lat_nb_tiles<2 and $lon_nb_tiles<2)
+ return array();
+
+ $ll_tile_factor = $lat_nb_tiles/$lon_nb_tiles;
+
+ if ($ll_tile_factor > 3)
+ { // 1x3
+ $lat_step = $latRange/3;
+ $lon_step = $lonRange;
+ }
+ elseif ($ll_tile_factor < 1/3)
+ { // 3x1
+ $lat_step = $latRange;
+ $lon_step = $lonRange/3;
+ }
+ elseif ($ll_tile_factor > 2)
+ { // 2x3
+ $lat_step = max( $latRange/3, $maxLatPrecision );
+ $lon_step = max( $lonRange/2, $maxLonPrecision );
+ }
+ elseif ($ll_tile_factor < 1/2)
+ { // 3x2
+ $lat_step = max( $latRange/2, $maxLatPrecision );
+ $lon_step = max( $lonRange/3, $maxLonPrecision );
+ }
+ else
+ { // 3x3
+ $lat_step = max( $latRange/3, $maxLatPrecision );
+ $lon_step = max( $lonRange/3, $maxLonPrecision );
+ }
+
+ if ( $cluster['bounds']['count'] > 200 )
+ {
+ if ($lat_step>4*$maxLatPrecision) $lat_step = $lat_step/2;
+ if ($lon_step>4*$maxLonPrecision) $lon_step = $lon_step/2;
+ }
+
+ $lat_step += 1e-7;
+ $lon_step += 1e-7;
+ //echo ( "$lat_step $latRange x $lon_step $lonRange tiles $lat_nb_tiles x $lon_nb_tiles\n" );
+
+ $lon_nb_tiles = ceil( $lonRange / $lon_step );
+
+ $clusters = array();
+ foreach ( $cluster['items'] as $id )
+ {
+ $lon = $this->_image_map[$id]['lon'];
+ $lat = $this->_image_map[$id]['lat'];
+
+ $idx_lon = floor ( ( $lon - $cluster['bounds']['w'] ) / $lon_step );
+ $idx_lat = floor ( ( $lat - $cluster['bounds']['s'] ) / $lat_step );
+
+ $idx = $lon_nb_tiles * $idx_lat + $idx_lon;
+
+ if ( !isset($clusters[$idx]) )
+ {
+ $clusters[$idx] = array(
+ 'bounds' => array(),
+ 'items' => array(),
+ );
+ }
+ array_push( $clusters[$idx]['items'], $id );
+ $clusters[$idx]['bounds'] = bounds_add( $clusters[$idx]['bounds'] , $lat, $lon );
+ }
+ return $clusters;
+ }
+}
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/include/functions.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/include/functions.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/include/functions.php (revision 3449)
@@ -0,0 +1,106 @@
+ 0)
+ return true;
+ return false;
+}
+
+function rvm_make_map_picture_url($params)
+{
+ global $conf;
+ if ( empty($conf['gmaps_api_key']) and $_SERVER['SERVER_ADDR']!='127.0.0.1' )
+ return "";
+ $map_url = make_picture_url($params);
+ return add_url_params($map_url, array('map'=>null) );
+}
+
+function rvm_duplicate_map_picture_url()
+{
+ global $conf;
+ if ( empty($conf['gmaps_api_key']) and $_SERVER['SERVER_ADDR']!='127.0.0.1' )
+ return "";
+ $map_url = duplicate_picture_url();
+ return add_url_params($map_url, array('map'=>null) );
+}
+
+function rvm_make_map_index_url($params=array())
+{
+ global $conf, $rvm_dir;
+ if ( empty($conf['gmaps_api_key']) and $_SERVER['SERVER_ADDR']!='127.0.0.1' )
+ return "";
+ $url = get_root_url().'map';
+ if ($conf['php_extension_in_urls'])
+ $url .= '.php';
+ if ($conf['question_mark_in_urls'])
+ $url .= '?';
+ $url .= make_section_in_url($params);
+ $url = add_well_known_params_in_url($url, array_intersect_key($params, array('flat'=>1) ) );
+ return $url;
+}
+
+function rvm_duplicate_map_index_url($redefined=array(), $removed=array())
+{
+ return rvm_make_map_index_url(
+ params_for_duplication($redefined, $removed)
+ );
+}
+
+function rvm_duplicate_kml_index_url($redefined=array(), $removed=array())
+{
+ return rvm_make_kml_index_url(
+ params_for_duplication($redefined, $removed)
+ );
+}
+
+function rvm_make_kml_index_url($params)
+{
+ global $conf, $rvm_dir;
+ $url = get_root_url().'plugins/'.$rvm_dir.'/kml.php';
+ if ($conf['question_mark_in_urls'])
+ $url .= '?';
+
+ $url .= make_section_in_url($params);
+ unset( $params['start'] );
+ if ( 'categories'!=$params['section']) unset( $params['flat'] );
+ $url = add_well_known_params_in_url($url, $params);
+ $get_params = array();
+ if ( isset($params['box']) and !empty($params['box']) )
+ {
+ include_once( dirname(__FILE__).'/functions_map.php' );
+ if ( ! bounds_is_world($params['box']) )
+ $get_params['box'] = bounds_to_url($params['box']);
+ }
+ if ( isset($params['ll']) and !empty($params['ll']) )
+ $get_params['ll'] = $params['ll']['lat'].','.$params['ll']['lon'];
+ $url = add_url_params($url, $get_params );
+ return $url;
+}
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/include/functions_map.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/include/functions_map.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/include/functions_map.php (revision 3449)
@@ -0,0 +1,566 @@
+1) ) );
+
+ $get_params = array();
+ if ( isset($params['box']) and !empty($params['box']) and !bounds_is_world($params['box']) )
+ $get_params['box'] = bounds_to_url($params['box']);
+ elseif ( isset($params['ll']) and !empty($params['ll']) )
+ $get_params['ll'] = $params['ll']['lat'].','.$params['ll']['lon'];
+ if ( isset($params['start']) and $params['start']>0 )
+ $get_params['start'] = $params['start'];
+ $url = add_url_params($url, $get_params );
+ return $url;
+}
+
+function rvm_parse_blowup_url($tokens, &$next_token)
+{
+ $page=array();
+ $page = array_merge($page, parse_section_url($tokens, $next_token) );
+ if ( !isset($page['section']) )
+ $page['section'] = 'categories';
+ $page = array_merge( $page, parse_well_known_params_url( $tokens, $next_token) );
+ $page['start']=0;
+ if ( isset($_GET['start']) )
+ $page['start']=$_GET['start'];
+ $page['box'] = rvm_bounds_from_url( @$_GET['box'] );
+ if ( isset($_GET['ll']) )
+ $page['ll'] = rvm_ll_from_url( $_GET['ll'] );
+ return $page;
+}
+
+function rvm_bounds_from_url($str)
+{
+ if ( !isset($str) or strlen($str)==0 )
+ return null;
+ $r = explode(',', $str );
+ if ( count($r) != 4)
+ bad_request( $str.' is not a valid geographical bound' );
+ $b = array(
+ 's' => $r[0],
+ 'w' => $r[1],
+ 'n' => $r[2],
+ 'e' => $r[3],
+ );
+ return $b;
+}
+
+function rvm_bounds_to_sql( $b )
+{
+ if ( !isset($b) or empty($b) )
+ return null;
+ $sql_where = 'i.lat BETWEEN '.$b['s'].' AND '.($b['n']);
+ $sql_where .= ' AND ';
+ if ($b['e'] >= $b['w'])
+ $sql_where .= 'i.lon BETWEEN '.$b['w'].' AND '.($b['e']);
+ else
+ $sql_where .= 'i.lon NOT BETWEEN '.($b['e']+1e-7).' AND '.($b['w']-1e-7);
+ return $sql_where;
+}
+
+function bounds_to_url($b, $p = 6 )
+{
+ if ( empty($b) )
+ return '';
+ return round($b['s'],$p).','.round($b['w'],$p).','.round($b['n'],$p).','.round($b['e'],$p);
+}
+
+function rvm_ll_from_url($str)
+{
+ if ( !isset($str) or strlen($str)==0 )
+ return null;
+ $r = explode(',', $str );
+ if ( count($r) != 2)
+ bad_request( $str.' is not a valid geographical position' );
+ $b = array('lat'=>$r[0],'lon'=>$r[1]);
+ return $b;
+}
+
+function rvm_ll_to_sql( $ll, &$order_by )
+{
+ $cos_lat = max( 1e-2, cos($ll['lat']*M_PI/180) );
+ $dlat = 3; // 1 degree is approx between 111 and 116 km
+ $dlon = min( 3/$cos_lat, 180 );
+ $bounds = array(
+ 's' => $ll['lat'] - $dlat,
+ 'w' => $ll['lon'] - $dlon,
+ 'n' => $ll['lat'] + $dlat,
+ 'e' => $ll['lon'] + $dlon,
+ );
+ if ($bounds['s']<-90) $bounds['s']=-90;
+ if ($bounds['w']<-180) $bounds['w']+=360;
+ if ($bounds['n']>90) $bounds['n']=90;
+ if ($bounds['e']>180) $bounds['e']-=360;
+ $where_sql = rvm_bounds_to_sql( $bounds );
+ $order_by = 'ORDER BY POW('.$ll['lat'].'-i.lat,2)+POW('.$cos_lat.'*('.$ll['lon'].'-i.lon),2)';
+ return $where_sql;
+}
+
+
+function bounds_is_world( $b )
+{
+ if (empty($b)) return false;
+ return $b['n']>=90 and $b['s']<=-90 and $b['w']<=-180 and $b['e']>=180;
+}
+
+function bounds_add($bounds, $lat, $lon)
+{
+ if ( empty($bounds) )
+ {
+ $bounds = array(
+ 's' => $lat,
+ 'n' => $lat,
+ 'w' => $lon,
+ 'e' => $lon,
+ 'count' => 1
+ );
+ }
+ else
+ {
+ if ( $lat>$bounds['n'] )
+ $bounds['n']=$lat;
+ elseif ( $lat<$bounds['s'] )
+ $bounds['s']=$lat;
+ if ( $lon>$bounds['e'] )
+ $bounds['e']=$lon;
+ elseif ( $lon<$bounds['w'] )
+ $bounds['w']=$lon;
+ $bounds['count']=$bounds['count']+1;
+ }
+
+ return $bounds;
+}
+
+function bounds_union($b1, $b2)
+{
+ $total_count = $b1['count'] + $b2['count'];
+ $res =
+ array_merge(
+ $b1,
+ array(
+ 's' => min( $b1['s'], $b2['s'] ),
+ 'n' => max( $b1['n'], $b2['n'] ),
+ 'w' => min( $b1['w'], $b2['w'] ),
+ 'e' => max( $b1['e'], $b2['e'] ),
+ 'count' => $total_count,
+ )
+ );
+ if ( isset($b2['min_date']) )
+ $res = array_merge(
+ $res,
+ array(
+ 'min_date' => min( $b1['min_date'], $b2['max_date'] ),
+ 'max_date' => max( $b1['max_date'], $b2['max_date'] ),
+ )
+ );
+ return $res;
+}
+
+function bounds_center($b)
+{
+ if (empty($b))
+ return array();
+ return array(
+ 'lat' => ($b['s']+$b['n'])/2,
+ 'lon' => ($b['w']+$b['e'])/2,
+ );
+}
+
+function bounds_sw($b)
+{
+ if (empty($b))
+ return array();
+ return array(
+ 'lat' => $b['s'],
+ 'lon' => $b['w'],
+ );
+}
+
+function bounds_ne($b)
+{
+ if (empty($b))
+ return array();
+ return array(
+ 'lat' => $b['n'],
+ 'lon' => $b['e'],
+ );
+}
+
+
+function bounds_lat_range($b)
+{
+ if (empty($b))
+ return 0;
+ return $b['n'] - $b['s'];
+}
+
+function bounds_lon_range($b)
+{
+ if (empty($b))
+ return 0;
+ return $b['e'] - $b['w'];
+}
+
+
+function rvm_get_cat_bounds()
+{
+ $cache_file_name = rvm_get_cache_file_name();
+ if ( file_exists($cache_file_name) )
+ {
+ return unserialize( file_get_contents($cache_file_name) );
+ }
+ $forbidden = get_sql_condition_FandF(
+ array
+ (
+ 'forbidden_categories' => 'category_id',
+ 'visible_categories' => 'category_id',
+ 'visible_images' => 'i.id'
+ ),
+ 'AND'
+ );
+
+ $query = '
+SELECT category_id cat_id, uppercats, MAX(lat) AS n, MIN(lat) AS s, MAX(lon) AS e, MIN(lon) AS w, COUNT(i.id) count, MIN(i.date_creation) min_date, MAX(i.date_creation) max_date
+ FROM
+ '.CATEGORIES_TABLE.' as c
+ INNER JOIN
+ '.IMAGE_CATEGORY_TABLE.' ON category_id = c.id
+ INNER JOIN
+ '.IMAGES_TABLE.' i ON image_id=i.id
+ WHERE lat IS NOT NULL '.$forbidden.'
+ GROUP BY category_id
+;';
+
+ $result = pwg_query($query);
+ $uppercats_list = array();
+ $cat_bounds = array();
+ while ($row = mysql_fetch_assoc($result))
+ {
+ array_push($uppercats_list, $row['uppercats']);
+ $cat_id = $row['cat_id'];
+ unset( $row['cat_id'], $row['uppercats'] );
+ $cat_bounds[ $cat_id ] = $row;
+ $cat_bounds[ $cat_id ]['self'] = $row;
+ }
+ natsort($uppercats_list);
+ //echo "" . var_export($uppercats_list,true);
+
+ foreach ( array_reverse($uppercats_list) as $uppercats)
+ {
+ $cat_ids = explode(',', $uppercats);
+ $bounds = $cat_bounds[ $cat_ids[count($cat_ids)-1] ];
+ for ($i=count($cat_ids)-2; $i>=0; $i--)
+ {
+ $this_bounds = @$cat_bounds[ $cat_ids[$i] ];
+ if ( !isset($this_bounds) )
+ {
+ $this_bounds = $bounds;
+ unset($this_bounds['self']);
+ }
+ else
+ {
+// if ($cat_ids[$i]==43) echo "Before\n" . var_export($this_bounds,true);
+// if ($cat_ids[$i]==43) echo "Union\n" . var_export($bounds,true);
+ $this_bounds = bounds_union($this_bounds, $bounds);
+ }
+ $this_bounds['nb_cats'] = 1 + @$this_bounds['nb_cats'];
+// if ($cat_ids[$i]==43) echo "" . var_export($this_bounds,true);
+ $cat_bounds[ $cat_ids[$i] ] = $this_bounds;
+ }
+ }
+ //echo "" . var_export($cat_bounds,true);
+ mkgetdir( dirname($cache_file_name) );
+ $file = fopen($cache_file_name , 'w' );
+ fwrite($file, serialize($cat_bounds) );
+ fclose( $file );
+
+ return $cat_bounds;
+}
+
+
+function marray_from_query($query)
+{
+ $ret = array();
+ $result = pwg_query($query);
+ while ($row = mysql_fetch_assoc($result))
+ $ret[] = $row;
+ return $ret;
+}
+
+define('RVM_BUILD_ARRAY', 0);
+define('RVM_BUILD_HASH', 1);
+define('RVM_BUILD_AGGREGATE', 2);
+
+function rvm_build_section_items($img_fields, $where_sql, $mode, $order_by=null)
+{
+ global $page, $conf, $user;
+
+ $page['items'] = array();
+
+ if (empty($where_sql))
+ $where_sql .= 'i.lat IS NOT NULL';
+ $where_sql_images_only = $where_sql;
+ $where_sql .= get_sql_condition_FandF(
+ array
+ (
+ 'forbidden_categories' => 'category_id',
+ 'visible_categories' => 'category_id',
+ 'visible_images' => 'i.id'
+ ),
+ "\n AND"
+ );
+
+ switch ($mode)
+ {
+ case RVM_BUILD_ARRAY:
+ $func = 'marray_from_query';
+ $group_by = '
+ GROUP BY i.id';
+ break;
+ case RVM_BUILD_HASH:
+ $func = create_function( '$q', 'return hash_from_query($q, "id");' );
+ $group_by = '
+ GROUP BY i.id';
+ break;
+ case RVM_BUILD_AGGREGATE:
+ $func = 'marray_from_query';
+ $group_by = '';
+ break;
+ }
+
+ if ($mode != RVM_BUILD_AGGREGATE )
+ {
+ if ($order_by==null and pwg_get_session_var('image_order',0) > 0)
+ {
+ $orders = get_category_preferred_image_orders();
+
+ $conf['order_by'] = str_replace(
+ 'ORDER BY ',
+ 'ORDER BY '.$orders[ pwg_get_session_var('image_order',0) ][1].',',
+ $conf['order_by']
+ );
+ $page['super_order_by'] = true;
+ }
+ elseif ($order_by!=null)
+ {
+ $conf['order_by']=$order_by;
+ $page['super_order_by'] = true;
+ }
+ elseif ( 'categories' == $page['section'] and isset($page['category']['image_order']) )
+ {
+ $conf['order_by'] = 'ORDER BY '.$page['category']['image_order'];
+ }
+ }
+ else
+ {
+ $conf['order_by'] = 'ORDER BY NULL';
+ $page['super_order_by'] = true;
+ }
+
+ if ('categories' == $page['section'])
+ {
+ if ( isset($page['flat']) or isset($page['category']) )
+ {
+ if (isset($page['flat']))
+ {
+ if ( isset($page['category']) )
+ {
+ $subcat_ids = get_subcat_ids( array($page['category']['id']) );
+ $where_sql .= ' AND category_id IN ('.implode(',',$subcat_ids).')';
+ }
+ }
+ else
+ {
+ $where_sql .= ' AND category_id='.$page['category']['id'];
+ }
+
+ $query='
+SELECT '.$img_fields.'
+ FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
+ WHERE '.$where_sql.$group_by.'
+ '.$conf['order_by'];
+
+ $page['items'] = $func($query);
+ }
+ if ( isset($page['category']) )
+ {
+ $page['title'] = $page['category']['name'];
+ $page['comment'] = $page['category']['comment'];
+ }
+ else
+ $page['title'] = $conf['gallery_title'];
+ }
+ else if ('tags' == $page['section'])
+ {
+ $items = get_image_ids_for_tags( array($page['tags'][0]['id']) );
+ if ( !empty($items) )
+ {
+ $query = '
+SELECT '.$img_fields.'
+ FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.IMAGES_TABLE.' i ON i.id=image_id
+ WHERE '.$where_sql.'
+ AND image_id IN ('.implode(',', $items).')'
+ .$group_by.'
+ '.$conf['order_by'];
+
+ $page['items'] = $func($query);
+ }
+ $page['title'] = strip_tags( get_tags_content_title() );
+ }
+ elseif ('search' == $page['section'])
+ {
+ include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
+ $search_result = get_search_results($page['search'], @$page['super_order_by'], $where_sql_images_only);
+ if ( !empty($search_result['items']) )
+ {
+ $query = '
+SELECT '.$img_fields.'
+ FROM '.IMAGES_TABLE.' i
+ WHERE id IN ('.implode(',', $search_result['items']).')'
+ .$group_by.'
+ '.$conf['order_by'].'
+;';
+
+ if ($mode != RVM_BUILD_AGGREGATE )
+ {
+ $page['items'] = hash_from_query($query, 'id' );
+
+ global $item_ranks;
+ $item_ranks = array_flip($search_result['items']);
+ function cmp_item_hash($a, $b)
+ {
+ global $item_ranks;
+ return $item_ranks [ $a['id'] ] - $item_ranks [ $b['id'] ];
+ }
+ uasort( $page['items'], 'cmp_item_hash' );
+ unset( $item_ranks );
+ }
+ else
+ $page['items'] = $func($query);
+ }
+
+ $page['title'] = l10n('search_result');
+ }
+ elseif ('recent_pics' == $page['section'])
+ {
+ $conf['order_by'] = ' ORDER BY hit DESC, file ASC';
+
+ $query ='
+SELECT '.$img_fields.'
+ FROM '.IMAGES_TABLE.' i
+ INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+ WHERE date_available >= SUBDATE(
+ CURRENT_DATE,INTERVAL '.$user['recent_period'].' DAY)
+ AND '.$where_sql
+ .$group_by.'
+ '.$conf['order_by'].'
+ LIMIT 0, '.$conf['top_number'].'
+;';
+
+ $page['items'] = $func($query);
+ $page['title'] = l10n('recent_pics_cat');
+ }
+ else if ('list'==$page['section'])
+ {
+ $query ='
+SELECT '.$img_fields.'
+ FROM '.IMAGES_TABLE.' i
+ INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+ WHERE image_id IN ('.implode(',', $page['list']).')
+ AND '.$where_sql
+ .$group_by.'
+ '.$conf['order_by'].'
+;';
+
+ $page['items'] = $func($query);
+ $page['title'] = l10n('random_cat');
+ }
+ else
+ fatal_error( 'section '.$page['section']. ' not handled '. __FILE__);
+}
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/include/picture_map.inc.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/include/picture_map.inc.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/include/picture_map.inc.php (revision 3449)
@@ -0,0 +1,63 @@
+concat('PLUGIN_PICTURE_ACTIONS', '
+
+ ');
+
+$template->assign(
+ array(
+ 'RVM_PLUGIN_VERSION' => RVM_PLUGIN_VERSION,
+ 'GMAPS_API_KEY' => $conf['gmaps_api_key'],
+ 'PLUGIN_ROOT_URL' => get_absolute_root_url().'plugins/'.$rvm_dir,
+ )
+ );
+
+$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+
+
+add_event_handler(
+ 'render_element_content',
+ 'rvm_picture_map_content',
+ EVENT_HANDLER_PRIORITY_NEUTRAL-5,
+ 2
+ );
+
+add_event_handler( 'loc_end_picture', 'rvm_end_picture' );
+
+
+function rvm_picture_map_content($content, $picture)
+{
+ include_once( dirname(__FILE__) .'/functions_map.php');
+ global $template;
+ $template->set_filename( 'map_content', dirname(__FILE__).'/../template/picture_map_content.tpl' );
+ $template->assign(
+ array(
+ 'TN_SRC' => $picture['thumbnail'],
+ 'U_NO_MAP' => duplicate_picture_url(),
+ 'U_BLOWUP' => rvm_make_blowup_url( array('ll'=>$picture), array('start','box') ),
+ 'COMMENT_IMG' => nl2br($picture['comment'])
+ )
+ );
+ if ( isset($picture['lat']) )
+ {
+ $template->assign( 'coordinates',
+ array(
+ 'LAT' => $picture['lat'],
+ 'LON' => $picture['lon'],
+ )
+ );
+ }
+ return $template->parse( 'map_content', true);
+}
+
+function rvm_end_picture()
+{
+ global $template;
+ $template->assign( 'COMMENT_IMG', null); // no legend below picture (we put it left)
+ $rating = & $template->get_template_vars('rating');
+ if (isset($rating))
+ $rating['F_ACTION'] = add_url_params( $rating['F_ACTION'], array('map'=>null) );
+}
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/kml.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/kml.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/kml.php (revision 3449)
@@ -0,0 +1,182 @@
+$value)
+ {
+ if (!strlen($value)) $section=$key;
+ break;
+ }
+}
+// deleting first "/" if displayed
+$tokens = explode(
+ '/',
+ preg_replace('#^/#', '', $section)
+ );
+$next_token = 0;
+$result = rvm_parse_kml_url($tokens, $next_token);
+$page = array_merge( $page, $result );
+
+$order_by=null;
+if ( isset($page['ll']) )
+ $where_sql = rvm_ll_to_sql($page['ll'], $order_by);
+else
+ $where_sql = rvm_bounds_to_sql( $page['box'] );
+
+
+$img_fields = ' i.id,i.tn_ext,i.name,i.comment,i.file,i.path,i.lat,i.lon,i.date_creation';
+
+rvm_build_section_items($img_fields, $where_sql, RVM_BUILD_ARRAY, $order_by);
+
+
+$dataTpl = new Template( PHPWG_ROOT_PATH );
+$dataTpl->set_filename('main', dirname(__FILE__).'/template/earth_kml.tpl' );
+
+$dataTpl->assign(
+ array(
+ 'PAGE_TITLE' => strip_tags(@$page['title']),
+ 'CONTENT_ENCODING' => get_pwg_charset(),
+ 'PAGE_COMMENT' => strip_tags( @$page['comment'], ''),
+ 'U_INDEX' => duplicate_index_url( array('start'=>0) ),
+ )
+);
+
+if ( !empty($page['items']) )
+ $dataTpl->assign( 'NB_ITEMS_DESC', sprintf( l10n('%d elements'), count($page['items']) ).' ' );
+
+
+// +-----------------------------------------------------------------------+
+// | sub categories network links |
+// +-----------------------------------------------------------------------+
+if ( 'categories'==$page['section'] and !isset($page['flat']) )
+{
+ $query = '
+SELECT id, name, permalink, comment, uppercats, representative_picture_id
+ FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+ ON id = cat_id and user_id = '.$user['id'].'
+ WHERE id_uppercat '.
+ (!isset($page['category']) ? 'is NULL' : '= '.$page['category']['id']).'
+ ORDER BY rank
+;';
+// echo "" . var_export($query,true);
+ $result = pwg_query($query);
+ $categories = array();
+ $thumbnail_ids=array();
+ while ($row = mysql_fetch_assoc($result))
+ {
+ array_push($categories, $row);
+ if (isset($row['representative_picture_id']) and is_numeric($row['representative_picture_id']))
+ array_push($thumbnail_ids, $row['representative_picture_id'] );
+ }
+ $thumbnail_src_of = array();
+ if ( count($thumbnail_ids) )
+ {
+ $query = '
+SELECT id, path, tn_ext
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(',', $thumbnail_ids).')';
+ $result = pwg_query($query);
+ while ($row = mysql_fetch_assoc($result))
+ $thumbnail_src_of[$row['id']] = get_thumbnail_url($row);
+ unset($thumbnail_ids);
+ }
+
+ $cat_bounds = rvm_get_cat_bounds();
+
+ foreach ($categories as $category)
+ {
+ if ( !isset( $cat_bounds[ $category['id'] ] ) )
+ continue; // without geo tagged images
+
+ $bounds = $cat_bounds[ $category['id'] ];
+
+ if ( isset($bounds['self']) )
+ {
+ $count_desc = l10n_dec('%d element', '%d elements', $bounds['self']['count']);
+ if ( $bounds['self']['count'] == $bounds['count'] )
+ $count_desc .= ' '.l10n('images_available_cpl');
+ else
+ $count_desc .= '/'.l10n_dec('%d element', '%d elements', $bounds['count']).' '.l10n_dec('images_available_cat','images_available_cats', $bounds['nb_cats'] );
+ }
+ else
+ $count_desc = l10n_dec('%d element', '%d elements', $bounds['count'])
+ .' '.l10n_dec('images_available_cat','images_available_cats', $bounds['nb_cats'] );
+
+ $tpl_var = array(
+ 'NAME' => $category['name'],
+ 'COMMENT' => trigger_event('render_category_literal_description', trigger_event('render_category_description', @$category['comment']) ),
+ 'U_CATEGORY' => make_index_url( array('category'=>$category) ),
+ 'U_KML' => rvm_make_kml_index_url( array('section'=>'categories', 'category'=>$category) ),
+ 'U_MAP' => rvm_make_map_index_url( array('section'=>'categories', 'category'=>$category) ),
+ 'COUNT_DESC' => $count_desc,
+ 'region' => $bounds,
+ );
+ if ( isset( $thumbnail_src_of[$category['representative_picture_id']] ) )
+ $tpl_var['TN_SRC'] = $thumbnail_src_of[$category['representative_picture_id']];
+
+ $dataTpl->append( 'categories', $tpl_var );
+ }
+}
+
+
+
+// +-----------------------------------------------------------------------+
+// | generate content for items |
+// +-----------------------------------------------------------------------+
+$bounds = array();
+foreach( $page['items'] as $img )
+{
+ $bounds = bounds_add($bounds, $img['lat'], $img['lon']);
+ $page_url = duplicate_picture_url(array('image_id' => $img['id'],'image_file' => $img['file']), array('start') );
+
+ if (!empty( $img['name'] ) )
+ $title = $img['name'];
+ else
+ $title = str_replace('_', ' ', get_filename_wo_extension($img['file']));
+
+ $tpl_var = array(
+ 'U_PAGE'=> $page_url,
+ 'TN_SRC' => get_thumbnail_url($img),
+ 'TITLE' => $title,
+ 'DESCRIPTION' => $img['comment'],
+ 'LAT' => $img['lat'],
+ 'LON' => $img['lon'],
+ 'DATE_CREATION' => $img['date_creation'],
+ );
+ $dataTpl->append('images', $tpl_var);
+}
+
+if ( !empty($bounds) )
+ $dataTpl->assign( 'region', $bounds );
+
+/*header('Cache-Control: public' );
+header('Expires: '.gmdate('D, d M Y H:i:s', time()+600).' GMT');
+header('Pragma:');*/
+header('Content-Disposition: inline; filename="'.str2url($page['title']).'.kml";' );
+header('Content-Type: application/vnd.google-earth.kml+xml; charset='.get_pwg_charset());
+if (isset($_GET['debug']))
+ header('Content-Type: text/xml; charset='.get_pwg_charset());
+
+
+$dataTpl->pparse('main');
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/language/cz_CZ/lang.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/language/cz_CZ/lang.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/language/cz_CZ/lang.php (revision 3449)
@@ -0,0 +1,25 @@
+
Index: /extensions/rv_gmaps/tags/2.0.b/language/en_UK/lang.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/language/en_UK/lang.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/language/en_UK/lang.php (revision 3449)
@@ -0,0 +1,25 @@
+
Index: /extensions/rv_gmaps/tags/2.0.b/language/fr_FR/lang.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/language/fr_FR/lang.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/language/fr_FR/lang.php (revision 3449)
@@ -0,0 +1,25 @@
+
Index: /extensions/rv_gmaps/tags/2.0.b/main.inc.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/main.inc.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/main.inc.php (revision 3449)
@@ -0,0 +1,136 @@
+concat( 'PLUGIN_INDEX_ACTIONS' ,'
+
+');
+ }
+
+// if ( empty($map_url) )
+ {
+ $kml_url = rvm_duplicate_kml_index_url( array(), array('start') );
+ $link_title = sprintf( l10n('opens %s in Google Earth'), strip_tags($page['title']) );
+ $template->concat( 'PLUGIN_INDEX_ACTIONS' ,'
+
+');
+ }
+}
+
+function rvm_picture_pictures_data($pictures)
+{
+ if ( isset($pictures['current']['lat']) and isset($pictures['current']['lon']) )
+ {
+ global $template;
+ $template->append('head_elements', ' ' );
+ include_once( dirname(__FILE__) .'/include/functions.php');
+ rvm_load_language();
+ if ( isset($_GET['map']) )
+ include_once( dirname(__FILE__) .'/include/picture_map.inc.php');
+ else
+ {
+ global $rvm_dir;
+ $map_url = rvm_duplicate_map_picture_url();
+ if (!empty($map_url))
+ {
+ $link_title = sprintf( l10n('displays %s on a map'), strip_tags($pictures['current']['name']) );
+ $template->concat('PLUGIN_PICTURE_ACTIONS', '
+
+');
+ }
+ }
+ }
+ else
+ if ( isset($_GET['map']) )
+ redirect( duplicate_picture_url() );
+ return $pictures;
+}
+
+function rvm_plugin_admin_menu($menu)
+{
+ include_once( dirname(__FILE__) .'/include/functions.php');
+ add_event_handler('invalidate_user_cache', 'rvm_invalidate_cache' );
+
+ array_push($menu,
+ array(
+ 'NAME' => 'Maps & Earth',
+ 'URL' => get_admin_plugin_menu_link(dirname(__FILE__).'/admin/admin.php')
+ )
+ );
+ return $menu;
+}
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/maintain.inc.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/maintain.inc.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/maintain.inc.php (revision 3449)
@@ -0,0 +1,76 @@
+
+EOD;
+ $fp = fopen( PHPWG_ROOT_PATH.'map.php', 'w' );
+ fwrite( $fp, $c);
+ fclose( $fp );
+
+ $old = dirname(__FILE__).'/_rvgm_config.dat';
+ if ( is_file($old) )
+ {
+ global $conf;
+ $dest = $conf['local_data_dir'].'/plugins/'.basename(dirname(__FILE__)).'.dat';
+ if (!file_exists($dest) )
+ {
+ mkgetdir( dirname($dest) );
+ copy( $old, $dest );
+ }
+ unlink( $old );
+ }
+}
+
+function plugin_deactivate()
+{
+ @unlink( PHPWG_ROOT_PATH.'map.php' );
+ rvm_invalidate_cache();
+}
+
+function plugin_uninstall()
+{
+ $q = '
+ALTER TABLE '.IMAGES_TABLE.' DROP COLUMN `lat`';
+ pwg_query( $q );
+
+ $q = '
+ALTER TABLE '.IMAGES_TABLE.' DROP COLUMN `lon`';
+ pwg_query( $q );
+
+ $q = '
+DELETE FROM '.CONFIG_TABLE.' WHERE param="gmaps_api_key" LIMIT 1';
+ pwg_query( $q );
+
+ global $conf;
+ $dest = $conf['local_data_dir'].'/plugins/'.basename(dirname(__FILE__)).'.dat';
+ @unlink( $dest );
+}
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/map.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/map.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/map.php (revision 3449)
@@ -0,0 +1,89 @@
+$value)
+ {
+ if (!strlen($value)) $section=$key;
+ break;
+ }
+}
+
+// deleting first "/" if displayed
+$tokens = explode(
+ '/',
+ preg_replace('#^/#', '', $section)
+ );
+$next_token = 0;
+$result = rvm_parse_map_data_url($tokens, $next_token);
+$page = array_merge( $page, $result );
+
+
+if (isset($page['category']))
+ check_restrictions($page['category']['id']);
+
+if ( !isset($_GET['ll']) and ($page['section']!='categories' or isset($page['category']) ) )
+{
+ $img_fields = 'MIN(i.lat) s, MIN(i.lon) w, MAX(i.lat) n, MAX(i.lon) e';
+ $page['flat']=true;
+ rvm_build_section_items($img_fields, null, RVM_BUILD_AGGREGATE);
+ //var_export( $page['items'] );
+ if ( count($page['items']) )
+ $template->assign('initial_bounds', $page['items'][0] );
+ unset( $page['items'] );
+}
+
+
+$map_data_url = get_absolute_root_url().'plugins/'.$rvm_dir.'/map_data.php?';
+$map_data_url .= $section;
+
+$template->set_filename( 'map', dirname(__FILE__).'/template/map.tpl' );
+
+$template->assign(
+ array(
+ 'CONTENT_ENCODING' => get_pwg_charset(),
+ 'RVM_PLUGIN_VERSION' => RVM_PLUGIN_VERSION,
+ 'GMAPS_API_KEY' => $conf['gmaps_api_key'],
+ 'PLUGIN_ROOT_URL' => get_absolute_root_url().'plugins/'.$rvm_dir,
+ 'U_MAP_DATA' => $map_data_url,
+ 'GALLERY_TITLE' => $conf['gallery_title'],
+ 'U_HOME' => make_index_url(),
+ 'U_HOME_MAP' => rvm_make_map_index_url(),
+ )
+ );
+
+$marker_js_file = rvm_get_config_var('marker_icon', '');
+if ( !empty($marker_js_file) )
+ $marker_js_file = dirname(__FILE__).'/template/markers/'.$marker_js_file.'.tpl';
+if ( !empty($marker_js_file) and file_exists($marker_js_file) )
+{
+ $template->set_filename( 'map_marker_icon', $marker_js_file );
+ $template->assign_var_from_handle('MAP_MARKER_ICON_JS', 'map_marker_icon');
+}
+else
+ $template->assign('MAP_MARKER_ICON_JS', 'return G_DEFAULT_ICON;');
+
+$template->pparse('map');
+$template->p();
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/map_data.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/map_data.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/map_data.php (revision 3449)
@@ -0,0 +1,184 @@
+make_clusters(
+ $page['items'],
+ isset($_GET['lap']) ? $_GET['lap'] : 0.01,
+ isset($_GET['lop']) ? $_GET['lop'] : 0.01,
+ isset($_GET['n']) ? $_GET['n'] : rvm_get_config_var('nb_markers',40)
+ );
+ $cluster_debug .= ' cluster: '. $cm->debug_str. ';';
+}
+
+function jsgm_position( $position )
+{
+ return 'new GLatLng(' . $position['lat'] . ',' . $position['lon'] . ')';
+}
+
+function jsgm_bounds( $bounds )
+{
+ return 'new GLatLngBounds(' . jsgm_position(bounds_sw($bounds)) . ',' . jsgm_position(bounds_ne($bounds)) . ')';
+}
+
+function jsgm_str( $str )
+{
+ return '"'. str_replace(array("\\",'"',"\n","\r","\t"), array("\\\\",'\"',"\\n","\\r","\\t"), $str) .'"';
+}
+
+$out='';
+function rvo($s) {
+ global $out; $out.=$s;
+}
+
+function rvf() {
+ global $out; echo $out; $out='';
+ ob_flush();
+}
+
+$start_output = get_moment();
+
+rvo( '{' );
+
+rvo( "\ntitle: ".jsgm_str( strip_tags($page['title']) ) );
+rvo( ",\n" );
+
+rvo( "page_url: ".jsgm_str( duplicate_index_url( array('start'=>0) ) ) );
+rvo( ",\n" );
+
+rvo( "blowup_url: ".jsgm_str( rvm_duplicate_blowup_url( array('start'=>0) ) ) );
+rvo( ",\n" );
+
+rvo( "kml_url: ".jsgm_str( rvm_duplicate_kml_index_url( array('start'=>0, 'flat'=>1) ) ) );
+rvo( ",\n" );
+
+rvo( "nb_items: ".count($page['items']) );
+rvo( ",\n" );
+
+rvo( "bounds: " );
+if ( isset($cm) )
+ rvo( jsgm_bounds( $cm->bounds ) );
+else
+ rvo( "null" );
+rvo( ",\n" );
+
+
+rvo( "\nnb_clusters: ".count($clusters) );
+rvo( "," );
+
+rvo( "\nimage_clusters: [\n" );
+$i=0;
+foreach( $clusters as $c )
+{
+ if ($i) rvo( ",\n\n" );
+ rvo( "{" );
+ rvo( 'position: '. jsgm_position( bounds_center($c['bounds']) ) );
+ rvo( ",\n" );
+ rvo( 'bounds: '. jsgm_bounds( $c['bounds'] ) );
+ rvo( ",\n" );
+ rvo( 'nb_items: '.count($c['items']) );
+ rvo( ",\n" );
+
+ rvo( 'blowup_url: "'.rvm_duplicate_blowup_url(array('box'=>$c['bounds']), array('start') ). '"' );
+ rvo( ",\n" );
+
+ rvo( 'kml_url: "'.rvm_duplicate_kml_index_url(array('box'=>$c['bounds'], 'flat'=>1), array('start') ). '"' );
+ rvo( ",\n" );
+
+ $max_per_cluster = rvm_get_config_var('nb_images_per_marker',20);
+ if ( count($c['items']) > $max_per_cluster )
+ {
+ $c['items'] = array_slice($c['items'], 0, $max_per_cluster);
+ }
+ rvo( 'items: [' );
+ for ($j=0; $j $img['id'],
+ 'image_file' => $img['file'],
+ 'flat' => 1,
+ );
+ $page_url = duplicate_picture_url($params, array('start') );
+
+ if ($j) rvo( "," );
+ rvo( "{" );
+ rvo( "tn: ".jsgm_str( get_thumbnail_url( $img ) ) );
+ rvo( "," );
+ rvo( "name: ".jsgm_str( $title ) );
+ rvo( "," );
+ rvo( "comment: ".jsgm_str( $img['comment'] ) );
+ rvo( "," );
+ rvo( "page_url: ".jsgm_str( $page_url ) );
+ rvo( "}" );
+ }
+ rvo( ']' );
+ rvo( "\n" );
+ rvo( "}" );
+ rvf();
+ $i++;
+}
+rvo( "] /*clusters*/\n" );
+
+$time = get_elapsed_time($t2, get_moment());
+$page['queries_time'] = number_format($page['queries_time'],3,'.',' ');
+rvo( "\n,debug:'$time; out:".get_elapsed_time($start_output,get_moment()).";$cluster_debug queries:".$page['count_queries']." in ".$page['queries_time']."s'\n" );
+
+rvo( '}' );
+rvf();
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/mapl.php
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/mapl.php (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/mapl.php (revision 3449)
@@ -0,0 +1,182 @@
+$value)
+ {
+ if (!strlen($value)) $section=$key;
+ break;
+ }
+}
+
+// deleting first "/" if displayed
+$tokens = explode(
+ '/',
+ preg_replace('#^/#', '', $section)
+ );
+$next_token = 0;
+$result = rvm_parse_blowup_url($tokens, $next_token);
+$page = array_merge( $page, $result );
+
+$order_by=null;
+if ( isset($page['ll']) )
+ $where_sql = rvm_ll_to_sql($page['ll'], $order_by);
+else
+ $where_sql = rvm_bounds_to_sql( $page['box'] );
+
+$img_fields = ' i.id,i.tn_ext,i.name,i.path,i.lat,i.lon';
+
+$was_flat = @$page['flat'];
+$page['flat']=true;
+rvm_build_section_items($img_fields, $where_sql, RVM_BUILD_HASH, $order_by);
+if (!$was_flat) unset($page['flat']);
+
+$template->set_filename( 'map', dirname(__FILE__).'/template/mapl.tpl');
+
+if (!empty($page['items']))
+{
+/* GENERATE THE CATEGORY LIST *************************************************/
+$where_sql = 'i.id IN ('.implode(',', array_keys($page['items']) ).')';
+$where_sql .= get_sql_condition_FandF(
+ array( 'forbidden_categories' => 'category_id' ),
+ ' AND'
+ );
+$query = '
+SELECT DISTINCT c.id, c.name, c.permalink, COUNT(DISTINCT i.id) counter
+ FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON i.id=image_id
+ INNER JOIN '.CATEGORIES_TABLE.' c ON c.id=category_id
+ WHERE '.$where_sql.'
+ GROUP BY category_id
+ ORDER BY counter DESC
+ LIMIT 0,5
+;';
+$result = pwg_query($query);
+$categories=array();
+while ($row=mysql_fetch_assoc($result))
+ array_push($categories, $row);
+$categories = add_level_to_tags($categories);
+
+foreach( $categories as $category)
+{
+ $template->append(
+ 'related_categories', array(
+ 'U_MAP' => rvm_make_map_index_url( array( 'category' => $category ) ),
+ 'URL' => make_index_url( array( 'category' => $category ) ),
+ 'NAME' => $category['name'],
+ 'TITLE' => l10n_dec( '%d element', '%d elements', $category['counter'] ),
+ 'CLASS' => 'tagLevel'.$category['level']
+ )
+ );
+}
+
+/* GENERATE THE TAG LIST ******************************************************/
+$tags = get_common_tags( array_keys($page['items']), $conf['content_tag_cloud_items_number'], null);
+$tags = add_level_to_tags($tags);
+function counter_compare($a, $b)
+{
+ $d = $a['counter'] - $b['counter'];
+ if ($d==0)
+ return strcmp($a['name'], $b['name']);
+ return -$d;
+}
+usort($tags, 'counter_compare');
+foreach ($tags as $tag)
+{
+ $template->append(
+ 'related_tags',
+ array_merge( $tag,
+ array(
+ 'U_MAP' => rvm_make_map_index_url( array( 'tags' => array($tag) ) ),
+ 'URL' => make_index_url( array( 'tags' => array($tag) ) ),
+ 'TITLE' => l10n_dec( '%d element', '%d elements', $tag['counter'] ),
+ )
+ )
+ );
+}
+} // end !empty items
+
+
+$title = ''.$page['title'].' ';
+if ( count($page['items']) > 0)
+ $title.=' ['.count($page['items']).']';
+
+$template->assign(
+ array(
+ 'PLUGIN_ROOT_URL' => get_absolute_root_url().'plugins/'.$rvm_dir,
+ 'TITLE' => $title,
+ 'U_HOME' => make_index_url(),
+ 'U_KML' => rvm_duplicate_kml_index_url( array('flat'=>1), array('start') ),
+ 'KML_LINK_TITLE' => sprintf( l10n('opens %s in Google Earth'), strip_tags($page['title']) ),
+ )
+ );
+
+$url = rvm_duplicate_blowup_url(array('start'=>0));
+$navbar = create_navigation_bar($url, count( $page['items'] ), $page['start'], 48);
+$template->assign('NAVBAR', $navbar);
+
+$page['items'] = array_slice(
+ $page['items'],
+ $page['start'],
+ 48
+ );
+
+foreach ($page['items'] as $img)
+{
+ $img['file'] = basename( $img['path'] );
+ $thumbnail_url = get_thumbnail_url($img);
+ $page_url = duplicate_picture_url(
+ array(
+ 'image_id' => $img['id'],
+ 'image_file' => $img['file'],
+ 'flat' => 1,
+ ),
+ array('start')
+ );
+ if (!empty( $img['name'] ) )
+ $title = $img['name'];
+ else
+ $title = str_replace('_', ' ', get_filename_wo_extension($img['file']));
+
+ $template->append(
+ 'thumbnails',
+ array(
+ 'TN_SRC' => $thumbnail_url,
+ 'URL' => $page_url,
+ 'TN_ALT' => $img['file'],
+ 'TN_TITLE' => $title,
+ )
+ );
+}
+
+$title = $page['title'];
+$page['body_id'] = 'theMapListPage';
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->parse('map');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+
+?>
Index: /extensions/rv_gmaps/tags/2.0.b/template/data_handler.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/data_handler.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/data_handler.js (revision 3449)
@@ -0,0 +1,297 @@
+
+function PwgDataHandler( map, opts )
+{
+ this._map = map;
+ this.options = Object.extend(
+ {
+ icon: G_DEFAULT_ICON,
+ show_all_img_src: null
+ }
+ , opts || {} );
+
+ GEvent.addListener( map, "infowindowclose", function() {map.getInfoWindow().pwgMarker=null;} );
+}
+
+PwgDataHandler.prototype = {
+
+_map: null,
+options: {},
+_markers: [],
+_navHtmlIds: ["gotoPrevImage", "gotoNextImage"],
+_timerBindPictureNavigation: null,
+_prevResult: { nb_items:0 },
+
+
+terminate: function()
+{
+ this._map = null;
+ try {
+ for (i=0; i0 && !this._markers[0].getLatLng().equals( data.image_clusters[0].position ) )
+ changed=true;
+ }
+
+ if (changed)
+ {
+ var newMarkers = [];
+ var infoWindowMarker = this._map.getInfoWindow().pwgMarker;
+
+ for (i=0; i1)
+ theTitle = Localization.fmt1("%d elements", cluster.nb_items);
+ else
+ theTitle = cluster.items[0].name;
+
+ var marker;
+ marker = this._markers.pop();
+ if (marker && marker==infoWindowMarker)
+ {
+ this._map.removeOverlay( marker );
+ GEvent.clearListeners(marker, "click" );
+ GEvent.clearListeners(marker, "dblclick" );
+ this._map.getInfoWindow().pwgMarker = infoWindowMarker = null;
+ if (document.is_debug) GLog.write('removed marker with infoWindow');
+ marker = this._markers.pop();
+ }
+
+ if (!marker)
+ {
+ marker = new GMarker( cluster.position, {title: theTitle, icon: this.options.icon } );
+ GEvent.addListener( marker, "click", this._onMarkerClick.bind(this, marker) );
+ GEvent.addListener( marker, "dblclick", this._onMarkerDblClick.bind(this, marker) );
+ this._map.addOverlay( marker );
+ }
+ else
+ {
+ marker.currentImageIndex=0;
+ marker.setLatLng( cluster.position );
+ // changing the marker title is undocumented so we hack it
+ if (!this.hack)
+ {
+ this.hack = {};
+ for (var prop in marker)
+ {
+ if ( typeof(marker[prop])!='object') continue;
+ if (!this.hack.markerHtmlElemWithTitle )
+ {
+ try {
+ if (eval("typeof marker." + prop + "[0].src") == "string" && eval("typeof marker." + prop + "[0].title") == "string" )
+ this.hack.markerHtmlElemWithTitle = prop;
+ }
+ catch (e) {}
+ }
+ if (!this.hack.markerOptions)
+ try {
+ if ( eval("typeof marker."+prop+".title")=="string" && eval("typeof marker."+prop+".src")=="undefined")
+ this.hack.markerOptions = prop;
+ }
+ catch (e) {}
+ }
+ }
+ //undocumented marker.K , marker.ch and marker.jb and marker.l
+ if (this.hack.markerOptions)
+ eval( 'marker.'+this.hack.markerOptions+'.title=theTitle');
+ if (this.hack.markerHtmlElemWithTitle)
+ eval( 'marker.'+this.hack.markerHtmlElemWithTitle+'[0].title=theTitle');
+ }
+
+ newMarkers.push(marker);
+
+ marker.pwg = {
+ nb_items: cluster.nb_items,
+ images: cluster.items,
+ bounds: cluster.bounds,
+ blowup_url: cluster.blowup_url
+ };
+ }
+
+ for (i=0; i
{$PAGE_COMMENT}
+]]>
+{if not empty($region)}
+
+
+ {$region.n}
+ {$region.s}
+ {$region.e}
+ {$region.w}
+
+
+{/if}
+
+{if not empty($categories)}
+{foreach from=$categories item=category}
+
+ 0
+
+
+ {/if}
+]]>
+
+ {$category.U_KML}
+
+{if not empty($category.region)}
+
+
+ {$category.region.n}
+ {$category.region.s}
+ {$category.region.e}
+ {$category.region.w}
+
+
+
+ {$category.region.min_date}
+ {$category.region.max_date}
+
+{/if}
+
+{/foreach}
+{/if}
+
+{if not empty($images)}
+{foreach from=$images item=img}
+
+ 1
+ 1
+
+ {$img.DESCRIPTION|@strip_tags:false|@truncate:80}
+
+
+]]>
+ #img
+
+ {$img.LON},{$img.LAT},0
+
+ {if not empty($img.date_creation)}
+
+ {$img.date_creation}
+
+ {/if}
+
+{/foreach}
+{/if}
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/map.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/map.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/map.tpl (revision 3449)
@@ -0,0 +1,225 @@
+
+
+
+
+
+{$GALLERY_TITLE}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/mapl.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/mapl.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/mapl.tpl (revision 3449)
@@ -0,0 +1,63 @@
+{html_head}
+
+{/html_head}
+
+
+
+
+
+
+
+
{$TITLE}
+
+
+{assign var='displays_x_on_a_map' value='displays %s on a map'|@translate }
+{if not empty($related_categories)}
+
+ {'Categories'|@translate}:
+ {foreach from=$related_categories item=cat}
+ {strip}
+ {$cat.NAME}
+
+ {/strip}
+ {/foreach}
+
+{/if}
+
+{if not empty($related_tags)}
+
+ {'Tags'|@translate}:
+ {foreach from=$related_tags item=tag}
+ {strip}
+ {$tag.name}
+
+ {/strip}
+ {/foreach}
+
+{/if}
+
+{if not empty($NAVBAR)}
{$NAVBAR}
{/if}
+
+{if not empty($thumbnails)}
+
+ {foreach from=$thumbnails item=thumbnail}
+
+
+
+
+
+
+ {/foreach}
+
+{/if}
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_orange.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_orange.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_orange.tpl (revision 3449)
@@ -0,0 +1,6 @@
+var icon = new GIcon();
+icon.image = "{$PLUGIN_ROOT_URL}/template/markers/small_bullet_orange.png";
+icon.iconSize = new GSize(11, 11);
+icon.iconAnchor = new GPoint(5, 5);
+icon.infoWindowAnchor = new GPoint(5, 0);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_red.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_red.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_red.tpl (revision 3449)
@@ -0,0 +1,6 @@
+var icon = new GIcon();
+icon.image = "{$PLUGIN_ROOT_URL}/template/markers/small_bullet_red.png";
+icon.iconSize = new GSize(11, 11);
+icon.iconAnchor = new GPoint(5, 5);
+icon.infoWindowAnchor = new GPoint(5, 0);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_yellow.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_yellow.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_bullet_yellow.tpl (revision 3449)
@@ -0,0 +1,6 @@
+var icon = new GIcon();
+icon.image = "{$PLUGIN_ROOT_URL}/template/markers/small_bullet_yellow.png";
+icon.iconSize = new GSize(11, 11);
+icon.iconAnchor = new GPoint(5, 5);
+icon.infoWindowAnchor = new GPoint(5, 0);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_blue.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_blue.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_blue.tpl (revision 3449)
@@ -0,0 +1,8 @@
+var icon = new GIcon();
+icon.image = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
+icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
+icon.iconSize = new GSize(12, 20);
+icon.shadowSize = new GSize(22, 20);
+icon.iconAnchor = new GPoint(6, 20);
+icon.infoWindowAnchor = new GPoint(5, 1);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_green.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_green.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_green.tpl (revision 3449)
@@ -0,0 +1,8 @@
+var icon = new GIcon();
+icon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
+icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
+icon.iconSize = new GSize(12, 20);
+icon.shadowSize = new GSize(22, 20);
+icon.iconAnchor = new GPoint(6, 20);
+icon.infoWindowAnchor = new GPoint(5, 1);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_purple.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_purple.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_purple.tpl (revision 3449)
@@ -0,0 +1,8 @@
+var icon = new GIcon();
+icon.image = "http://labs.google.com/ridefinder/images/mm_20_purple.png";
+icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
+icon.iconSize = new GSize(12, 20);
+icon.shadowSize = new GSize(22, 20);
+icon.iconAnchor = new GPoint(6, 20);
+icon.infoWindowAnchor = new GPoint(5, 1);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_red.tpl
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_red.tpl (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/markers/small_dot_red.tpl (revision 3449)
@@ -0,0 +1,8 @@
+var icon = new GIcon();
+icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
+icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
+icon.iconSize = new GSize(12, 20);
+icon.shadowSize = new GSize(22, 20);
+icon.iconAnchor = new GPoint(6, 20);
+icon.infoWindowAnchor = new GPoint(5, 1);
+return icon;
Index: /extensions/rv_gmaps/tags/2.0.b/template/page_linker.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/page_linker.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/page_linker.js (revision 3449)
@@ -0,0 +1,88 @@
+function PageLinker(map, aElementId)
+{
+ this._map = map;
+ this._elementId = aElementId;
+
+ PageLinker.url2Map( map );
+
+ GEvent.bind( this._map, "maptypechanged", this, this._regenerateUrl );
+ GEvent.bind( this._map, "moveend", this, this._regenerateUrl );
+ if ( this._map.isLoaded() )
+ this._regenerateUrl();
+}
+
+PageLinker.getQueryVars = function()
+{
+ var vars = {};
+ var qString = unescape( top.location.search.substring(1) );
+ if (qString.length==0)
+ return vars;
+ var pairs = qString.split(/\&/);
+ for (var i=0; i
+
+
+
+
+
+
+{/html_head}
+
+
+
+
+
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/style.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/style.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/style.css (revision 3449)
@@ -0,0 +1,147 @@
+
+HTML, BODY {
+ height: 100%;
+ max-height: 100%;
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+
+HTML {
+/* hide overflow:hidden from IE5/Mac */
+ overflow: hidden; /*get rid of scroll bars in IE */
+ /* */
+}
+
+BODY {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+}
+
+
+#titlebar {
+ width: 100%;
+ height: 18px;
+ overflow: hidden;
+}
+
+
+#map {
+ overflow: auto;
+ position: absolute;
+ left: 0; width: 100%;
+ top: 18px; bottom: 0;
+}
+
+
+
+
+#titlebar .titlebar_links { float:right; }
+
+#titlebar .titlebar_title {
+ margin-left: 5px;
+ margin-right: 5px;
+}
+
+#titlebar .titlebar_title A {
+ font-size: 14px;
+ font-weight: bold;
+}
+
+#titlebar FORM {
+ display:inline;
+ margin:0;
+}
+
+#titlebar FORM INPUT {
+ border: 1px solid gray;
+ font-size:80%;
+}
+
+#titlebar FORM INPUT {
+ color: #404040;
+ background-color: #dddddd;
+}
+
+#titlebar FORM INPUT:focus {
+ color: black;
+ background-color: #ffffff;
+}
+
+#titlebar .titlebar_links A {
+ border: none;
+ text-decoration: none;
+}
+
+#titlebar .titlebar_links A SPAN {
+ text-decoration: underline;
+}
+
+#titlebar IMG {
+ border: none;
+ vertical-align: bottom;
+}
+
+
+#titlebar #dataLoadStatus {
+ min-width: 150px;
+ width: 150px;
+ margin-right: 10px;
+ margin-left: 5px;
+ font-weight: bold;
+}
+
+
+/* Info Window Structure is
+DIV.gmiw_header
+ SPAN#pwgImageCounters
+ A#gotoPrevImage
+ A#gotoNextImage
+ A#pwgImageBlowup
+DIV#pwgImageDetail
+ DIV.gmiw_imageTitle
+ DIV.gmiw_imageContent
+ DIV.gmiw_imageWrap
+ A IMG
+ DIV.gmiw_imageComment
+*/
+
+.gmiw_header A {
+ margin-left: 5px;
+ border: none;
+ text-decoration: none;
+}
+
+.gmiw_header IMG { vertical-align: bottom; }
+
+.gmiw_header A SPAN { text-decoration: underline; }
+
+.gmiw_header A#pwgImageBlowup {
+ margin-left: 15px;
+ font-weight: bold;
+}
+
+.gmiw_imageTitle {
+ font-size: 14px;
+ font-weight: bold;
+}
+
+.gmiw_imageContent {
+ min-width: 325px;
+ width: 325px;
+ min-height: 168px;
+ height: 168px;
+ overflow-y: auto;
+}
+
+.gmiw_imageWrap {
+ margin: 0 5px -3px 0; /* - for bottom something wrong with Geko and Opera ignored by IE6*/
+ float:left;
+ display:inline;
+}
+
+.gmiw_imageWrap A IMG { border-width: 1px; }
+
+.gmiw_imageComment { display:inline; }
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/MIT-LICENSE
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/MIT-LICENSE (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/MIT-LICENSE (revision 3449)
@@ -0,0 +1,19 @@
+Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/index.html
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/index.html (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/index.html (revision 3449)
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PWC OS
+
+
+
+
+
+
+ Theme:
+
+ Mac OS X
+ Blue lighting
+ Green lighting
+
+
+
+
+
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/pwc-os.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/pwc-os.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/pwc-os.css (revision 3449)
@@ -0,0 +1,36 @@
+body {
+ margin:0;
+ padding:0;
+ overflow: hidden;
+ background: #FFF8DD url(body-bg.png) no-repeat fixed center 10px;
+}
+
+#dock {
+ position:absolute;
+ bottom:0;
+ left:0;
+ width:100%;
+ height:26px;
+ background:transparent url(dock-bg.gif) repeat-x 0 0;
+ z-index: 100000;
+}
+
+.dock_icon {
+ float:left;
+ width:102px;
+ height:21px;
+ margin-top:3px;
+ background: url(button-bg.gif);
+ text-align:center;
+ font-size: 14px;
+ color: #000;
+ line-height: 22px;
+ margin-right:10px;
+ margin-left:10px;
+}
+
+#theme {
+ float:right;
+ margin-top:3px;
+ margin-right:15px;
+}
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/pwc-os.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/pwc-os.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/PWC-OS/pwc-os.js (revision 3449)
@@ -0,0 +1,103 @@
+// Overide WindowUtilities getPageSize to remove dock height (for maximized windows)
+WindowUtilities._oldGetPageSize = WindowUtilities.getPageSize;
+WindowUtilities.getPageSize = function() {
+ var size = WindowUtilities._oldGetPageSize();
+ var dockHeight = $('dock').getHeight();
+
+ size.pageHeight -= dockHeight;
+ size.windowHeight -= dockHeight;
+ return size;
+};
+
+
+// Overide Windows minimize to move window inside dock
+Object.extend(Windows, {
+ // Overide minimize function
+ minimize: function(id, event) {
+ var win = this.getWindow(id)
+ if (win && win.visible) {
+ // Hide current window
+ win.hide();
+
+ // Create a dock element
+ var element = document.createElement("span");
+ element.className = "dock_icon";
+ element.style.display = "none";
+ element.win = win;
+ $('dock').appendChild(element);
+ Event.observe(element, "mouseup", Windows.restore);
+ $(element).update(win.getTitle());
+
+ new Effect.Appear(element)
+ }
+ Event.stop(event);
+ },
+
+ // Restore function
+ restore: function(event) {
+ var element = Event.element(event);
+ // Show window
+ element.win.show();
+ //Windows.focus(element.win.getId());
+ element.win.toFront();
+ // Fade and destroy icon
+ new Effect.Fade(element, {afterFinish: function() {element.remove()}})
+ }
+})
+
+// blur focused window if click on document
+Event.observe(document, "click", function(event) {
+ var e = Event.element(event);
+ var win = e.up(".dialog");
+ var dock = e == $('dock') || e.up("#dock");
+ if (!win && !dock && Windows.focusedWindow) {
+ Windows.blur(Windows.focusedWindow.getId());
+ }
+})
+
+// Chnage theme callback
+var currentTheme = 0;
+function changeTheme(event) {
+ var index = Event.element(event).selectedIndex;
+ if (index == currentTheme)
+ return;
+
+ var theme, blurTheme;
+ switch (index) {
+ case 0:
+ theme = "mac_os_x";
+ blurTheme = "blur_os_x";
+ break;
+ case 1:
+ theme = "bluelighting";
+ blurTheme = "greylighting";
+ break;
+ case 2:
+ theme = "greenlighting";
+ blurTheme = "greylighting";
+ break;
+ }
+ Windows.windows.each(function(win) {
+ win.options.focusClassName = theme;
+ win.options.blurClassName = blurTheme;
+ win.changeClassName(blurTheme)
+ });
+ Windows.focusedWindow.changeClassName(theme);
+ currentTheme = index;
+}
+
+// Init webOS, create 3 windows
+function initWebOS() {
+ // Create 3 windows
+ $R(1,3).each(function(index) {
+ var win = new Window({className: "mac_os_x", blurClassName: "blur_os_x", title: "window #"+index, width:250, height:150, top: 100 + index*50, left:100 + index*50});
+ win.getContent().update("Window #" + index + " ");
+ win.show();
+ })
+ //
+ $$("#theme select").first().selectedIndex = currentTheme;
+ Event.observe($$("#theme select").first(), "change", changeTheme);
+}
+Event.observe(window, "load", initWebOS)
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/README
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/README (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/README (revision 3449)
@@ -0,0 +1,182 @@
+== Installation/Usage
+
+Just copy windows.js in your javascript directory, and default.css + default directory in your stylesheets directory
+See samples/index.html for more details and go on my web page : http://prototype-window.xilinus.com
+
+== Change log
+- 04/23/07 V 1.3
+ - Added: getTitle
+ - Added: blur/focus function on Windows module
+ - Added: onBlur event
+ - Fixed: WindowCloseKey works with URL content (iframe)
+ - Fixed: Modal window with a parent != document.body
+ - Updated: prototype 1.5RC3
+ - Updated: Dialog handle resizable,minimizable, maximizable, draggable and closable options
+- 02/27/07 V 1.2
+ - Added: gridX and gridY constructor's options to snap move and resize
+ - Added: Effect on modal overlay (fade/appear) only if effects.js in included.
+ You can change effect options (Windows.overlayShowEffectOptions and Windows.overlayHideEffectOptions).
+
+ - Fixed: Multimodal mode.
+ - Fixed: Works on WebKit.
+
+ - Beta: effects on minimize and maximize. You need to include window_effects.js to have them.
+
+- 02/17/07 V 1.1
+ - Constructor has been simplified, now you can just do win = new Window(). By default id is automatically generated and can be passed as options
+ win = new Window({id: "my_id", width: 100, height: 100})
+ Backward compatibility with old constructor win = new Window("my_id", {width: 100, height: 100})
+ - Observer event can be passed as window option: win = new Window({onClose: function() {alert('close')}})
+ - parent option can be id or element
+ - delegate has been removed (not really usefull) and0 setCloseCallback has been addedinstead. (It could be also passed as a constructor's option closeCallback: your_callcabck)
+ your_callcabck must return true to be able to close the window
+ - add onMove event
+ - fix constraint for minimized window
+ - destroyOnClose could be passed as constructor's option: win = new Window({destroyOnClose: true})
+ - constraint works for maximized windows
+ - Dialog ok and cancel parameters has been renamed to onOk and onCancel for coherence (ok and cancel still works)
+ - Update to Prototype 1.5 and script.aculo.us 1.7
+
+- 01/14/07 V 1.00
+ - add changeClassName to change look and feel dynamically.
+ - add constraint move. Constraint can be on a div or document.
+ - full top and bottom bar are use to move window.
+ - fixed computation of window width or height.
+ - add setURL/getURL/refresh and setHTMLContent. Content can be change dynamically.
+ - add tooltip.js add on. It's an add-on to add dynamically tooltips on a webpage (see samples/tooltips/tooltip.html)
+ Thanks to Jonathan Modell of 2moromedia.com.
+
+- 12/06/06 V 0.99
+ - remove addClass that automatically tries to include default.css
+ - add wired move/resize
+ - fix recenterAuto
+ - add show to WindowStore to be able to open a window the first time, wihtout any cookie (check samples/window_store/html)
+
+- 11/06/06 V 0.98
+ - new optional behavior for multi-level modal window.
+ - Two new add-ons (in window_ext.js file)
+ + WindowStore to save open/close window status.
+ + WindowCloseKey to handle escape key (or any keys) to close windows/dialogs
+
+- 10/26/06 V 0.97
+ - add recenterModal to constructor
+ - setAjaxContent eval response request
+ - modal window multi level
+ - fix close/closeAll issues
+ - add addCss (auto add default.css)
+
+- 09/26/06 V 0.96.3
+ - Fixed onClose, no more memory leak and nore issues with sound on IE (even on dialogs)
+ - add getLocation
+ - Debug select problem on Firefox
+ - change mouseup event to onclick event
+ - Fixed event propagation on mininize/maximize/close
+ - Add frameborder=0
+ - Add prototype_window_class_helper.rb by Jorge Díaz (http://xurde.info)
+
+- 07/22/06 V 0.96.2
+ - Fixed select issue in modal window
+
+- 07/15/06 V 0.96.1
+ - Bugs fixed
+ - Add isVisible()
+ - Update debug.js
+
+- 07/11/06 V 0.96
+ - New events onShow, onHide, onFocus
+ - isVisible()
+ - Autofit width or height if width or (NOT AND) height is set to null in the constructor
+ - updateWidth / updateHeight if you need to update width or height (useful after changing window content if you do not want scrollbars)
+ - Add top, left to showCenter(modal, top, left) optional arguments if you need to center only left or top value.
+
+- 06/30/06 V 0.95
+ - Now you can set windows or dialogs content with an Ajax request!!
+ - Fixed IE issue when you destroy window with an url that embeds mp3.
+ - Fixed buttonClass issue for Dialog.
+ - Update samples
+
+- 06/24/06 V 0.90
+ - Valid XHTML 1.0 Strict!
+ - Fixed minimize function
+ - Fixed destroy on window without hide effects
+ - No more text selection while dragging
+ - Add onMinimize/onMaximize event
+
+- 06/19/06 V 0.85.2
+ - Remove undeclared vars
+ - Set top/left to 0 if not specify
+ - Destroy objet after hide effect instead of before effect instead
+ - getSize
+ - add extended_debug.js (from Jason Pollard)
+
+- 06/13/06 V 0.85.1
+ - IE bug fixed
+
+- 06/12/06 V 0.85
+ - Autofit width or height for Dialog
+ - Better Move/Resize over
+ - Allow select in modal window (even on IE)
+ - WARNING, ok callback for Dialog should returns true to close the dialog
+ - better window HTML code (no more div inside the td)
+ - Add themes
+
+- 05/23/06 V 0.80
+ - Add setTitle
+ - Add setStatusBar
+ - Store minimize/maximize in the cookie (Thanks to Ifran)
+ - Add onload constructor parameter (Thanks to Ifran)
+ - Add button class for dialog (Thanks to Felix Shnir)
+
+- 05/09/06 V 0.75
+ - Update with Script.aculo.us 1.6.1 and Prototype 1.5.0_rc1
+ - Remove PNG for dialog overlay, use opacity as done in lightbox V2
+ - Add Windows.focusedWindow and Windows.closeAll
+ - Add name to iframe in case of url window
+ - Clean up code, use _ for private function (just name convention)
+ - Add Dialog.info function, usefull for for submit or notice info (in Rails)
+ - Add minimize and maximize buttons
+ - Add alert_lite.css without any images
+ - Debug
+
+- 04/15/06 V 0.70
+ - Add autoposition in setContent. The window will at the element location
+ - Add draggable/closable parameter if you need to specify is the window is draggable/closable or not
+ - Add parent parameter if you need a specific parent instead of body
+ - Better resize
+ - Add setCookie to store window location/size in a cookie
+ - Add parent.html sample
+
+- 04/05/06 V 0.65
+ - Update to Prototype 1.5.0_pre1, script.aculo.us 1.6.0
+ - Add setDestoyOnClose
+ - Add Windows Observer with onStartResize(), onEndResize(), onStartMove(), onEndMove(), onClose(), onDestroy() events
+ - Add setContent(id, autoresize)
+
+- 03/29/06 V 0.6
+ - Add Window delegate to manage close action
+ - Add modal mode and Dialog class with common panels: alert, confirm
+ - Clean HTML code and change caracters to lowercase to be XHTML compliant (thanks to nuxygen and Joseph)
+ - Add showEffectOptions, hideEffectOptions, effectOptions to Window constructor (thanks to Jon)
+ - Fix checkbox IE bug (big thanks to JCA)
+ - Fix other little bugs (thanks to nuxygen, Dennis, and all who sent me emails)
+ - Update samples/index.html
+ - Add new sample usng frame (samples/inset.html and samples/inframe.html but use only samples/inset.html)
+
+- 03/27/06 V 0.51
+ - New CSS theme structure
+ - Add url: constructor parameter to have a window with an URL content
+ - Add bottom/right constructor parameters
+ - Update sample files.
+
+- 03/24/06 V 0.50 Initial revision
+
+
+== License
+
+it is licensed under the terms of the MIT License, see the included MIT-LICENSE file.
+
+== Thanks
+To all of you who sent me bugs, patches and feature requests
+
+http://www.ciudadmovil.com.co/q/mod/mapa/conexion.php
+http://www.desyr.net/
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/helper/prototype_window_class_helper.rb
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/helper/prototype_window_class_helper.rb (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/helper/prototype_window_class_helper.rb (revision 3449)
@@ -0,0 +1,58 @@
+# Prototype Window Class Helper (http://pwc-helper.xurdeonrails.com)
+# by Jorge Díaz (http://xurde.info)
+# thanks to Sebastien Gruhier for his Prototype Window Class (http://prototype-window.xilinus.com/)
+
+#Quick use:
+#Reference this helper in your rails applicaction adding -> helper :prototype_window_class in your application.rb
+#You must include in the template header the prototype window class javascripts and the .css theme you want to use.
+#This code in your template might be enough:
+
+ # <%= stylesheet_link_tag 'default' %> (or theme you wanna use)
+ # <%= stylesheet_link_tag 'alert' %>
+ # <%= javascript_include_tag :defaults %>
+ # <%= javascript_include_tag 'window'%>
+
+
+module PrototypeWindowClassHelper
+
+ def params_for_javascript(params) #options_for_javascript doesn't works fine
+
+ '{' + params.map {|k, v| "#{k}: #{
+ case v
+ when Hash then params_for_javascript( v )
+ when String then "'#{v}'"
+ else v #Isn't neither Hash or String
+ end }"}.sort.join(', ') + '}'
+ end
+
+
+
+ def link_to_prototype_dialog( name, content, dialog_kind = 'alert', options = { :windowParameters => {} } , html_options = {} )
+
+ #dialog_kind: 'alert' (default), 'confirm' or 'info' (info dialogs should be destroyed with a javascript function call 'win.destroy')
+ #options for this helper depending the dialog_kind: http://prototype-window.xilinus.com/documentation.html#alert (#confirm or #info)
+
+ js_code ="Dialog.#{dialog_kind}( '#{content}', #{params_for_javascript(options) } ); "
+ content_tag(
+ "a", name,
+ html_options.merge({
+ :href => html_options[:href] || "#",
+ :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + js_code }))
+ end
+
+
+
+ def link_to_prototype_window( name, window_id, options = { :windowParameters => {} } , html_options = {} )
+
+ #window_id must be unique and it's destroyed on window close.
+ #options for this helper: http://prototype-window.xilinus.com/documentation.html#initialize
+
+ js_code ="var win = new Window( '#{window_id}', #{params_for_javascript(options) } ); win.show(); win.setDestroyOnClose();"
+ content_tag(
+ "a", name,
+ html_options.merge({
+ :href => html_options[:href] || "#",
+ :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + js_code }))
+ end
+
+end
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/debug.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/debug.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/debug.js (revision 3449)
@@ -0,0 +1,137 @@
+var debugWindow = null;
+function debug(text, reverse) {
+ if (debugWindow == null)
+ return;
+
+ time = "-"; //new Date();
+ if (reverse) {
+ $('debug').innerHTML = time + " " + text + " "+ $('debug').innerHTML;
+ debugWindow.getContent().scrollTop=0;
+ }
+ else {
+ $('debug').innerHTML += time + " " + text + " ";
+ debugWindow.getContent().scrollTop=10000; // Far away
+ }
+}
+
+function hideDebug() {
+ if (debugWindow) {
+ debugWindow.destroy();
+ debugWindow = null;
+ }
+}
+
+function showDebug(bShow) {
+ if (debugWindow == null) {
+ debugWindow = new Window('debug_window', {className: 'dialog',width:250, height:100, right:4, bottom:42, zIndex:1000, opacity:1, showEffect: Element.show, resizable: true, title: "Debug"})
+ debugWindow.getContent().innerHTML = "
";
+ date=new Date;
+ date.setMonth(date.getMonth()+3);
+
+ //debugWindow.setCookie(null, date);
+ }
+ if( typeof bShow == 'undefined' || bShow)debugWindow.show()
+}
+
+
+function clearDebug() {
+ if (debugWindow == null)
+ return;
+ $('debug').innerHTML = "";
+}
+
+/**
+ * document.createElement convenience wrapper
+ *
+ * The data parameter is an object that must have the "tag" key, containing
+ * a string with the tagname of the element to create. It can optionally have
+ * a "children" key which can be: a string, "data" object, or an array of "data"
+ * objects to append to this element as children. Any other key is taken as an
+ * attribute to be applied to this tag.
+ *
+ * Available under an MIT license:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * @param {Object} data The data representing the element to create
+ * @return {Element} The element created.
+ */
+function $E(data) {
+ var el;
+ if ('string'==typeof data) {
+ el=document.createTextNode(data);
+ } else {
+ //create the element
+ el=document.createElement(data.tag);
+ delete(data.tag);
+
+ //append the children
+ if ('undefined'!=typeof data.children) {
+ if ('string'==typeof data.children ||'undefined'==typeof data.children.length) {
+ //strings and single elements
+ el.appendChild($E(data.children));
+ } else {
+ //arrays of elements
+ for (var i=0, child=null; 'undefined'!=typeof (child=data.children[i]); i++) {
+ el.appendChild($E(child));
+ }
+ }
+ delete(data.children);
+ }
+
+ //any other data is attributes
+ for (attr in data) {
+ el[attr]=data[attr];
+ }
+ }
+
+ return el;
+}
+
+// FROM Nick Hemsley
+var Debug = {
+ inspectOutput: function (container, within) {
+ within = within || debugWindow.getContent()
+
+ if (debugWindow == null)
+ return;
+
+ within.appendChild(container)
+ },
+
+ inspect: function(object) {
+ var cont = $E({tag: "div", className: "inspector"})
+ Debug.inspectObj(object, cont)
+ debugWindow.getContent().appendChild(cont)
+ },
+
+ inspectObj: function (object, container) {
+ for (prop in object) {
+ Debug.inspectOutput(Debug.inspectable(object, prop), container)
+ }
+ },
+
+ inspectable: function(object, prop) {
+ cont = $E({tag: 'div', className: 'inspectable', children: [prop + " value: " + object[prop] ]})
+ cont.toInspect = object[prop]
+ Event.observe(cont, 'click', Debug.inspectClicked, false)
+ return cont
+ },
+
+ inspectClicked: function(e) {
+ Debug.inspectContained(Event.element(e))
+ Event.stop(e)
+ },
+
+ inspectContained: function(container) {
+ if (container.opened) {
+ container.parentNode.removeChild(container.opened)
+ delete(container.opened)
+ } else {
+ sibling = container.parentNode.insertBefore($E({tag: "div", className: "child"}), container.nextSibling)
+ if (container.toInspect)
+ Debug.inspectObj(container.toInspect, sibling)
+ container.opened = sibling
+ }
+ }
+}
+var inspect = Debug.inspect;
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/effects.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/effects.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/effects.js (revision 3449)
@@ -0,0 +1,1094 @@
+// script.aculo.us effects.js v1.7.1_beta1, Mon Mar 12 14:40:50 +0100 2007
+
+// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+// Justin Palmer (http://encytemedia.com/)
+// Mark Pilgrim (http://diveintomark.org/)
+// Martin Bialasinki
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+ var color = '#';
+ if(this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if(this.slice(0,1) == '#') {
+ if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if(this.length==7) color = this.toLowerCase();
+ }
+ }
+ return(color.length==7 ? color : (arguments[0] || this));
+}
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+ }).flatten().join('');
+}
+
+Element.collectTextNodesIgnoreClass = function(element, className) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ Element.collectTextNodesIgnoreClass(node, className) : ''));
+ }).flatten().join('');
+}
+
+Element.setContentZoom = function(element, percent) {
+ element = $(element);
+ element.setStyle({fontSize: (percent/100) + 'em'});
+ if(Prototype.Browser.WebKit) window.scrollBy(0,0);
+ return element;
+}
+
+Element.getInlineOpacity = function(element){
+ return $(element).style.opacity || '';
+}
+
+Element.forceRerendering = function(element) {
+ try {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Array.prototype.call = function() {
+ var args = arguments;
+ this.each(function(f){ f.apply(this, args) });
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+ _elementDoesNotExistError: {
+ name: 'ElementDoesNotExistError',
+ message: 'The specified DOM element does not exist, but is required for this effect to operate'
+ },
+ tagifyText: function(element) {
+ if(typeof Builder == 'undefined')
+ throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+
+ var tagifyStyle = 'position:relative';
+ if(Prototype.Browser.IE) tagifyStyle += ';zoom:1';
+
+ element = $(element);
+ $A(element.childNodes).each( function(child) {
+ if(child.nodeType==3) {
+ child.nodeValue.toArray().each( function(character) {
+ element.insertBefore(
+ Builder.node('span',{style: tagifyStyle},
+ character == ' ' ? String.fromCharCode(160) : character),
+ child);
+ });
+ Element.remove(child);
+ }
+ });
+ },
+ multiple: function(element, effect) {
+ var elements;
+ if(((typeof element == 'object') ||
+ (typeof element == 'function')) &&
+ (element.length))
+ elements = element;
+ else
+ elements = $(element).childNodes;
+
+ var options = Object.extend({
+ speed: 0.1,
+ delay: 0.0
+ }, arguments[2] || {});
+ var masterDelay = options.delay;
+
+ $A(elements).each( function(element, index) {
+ new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+ });
+ },
+ PAIRS: {
+ 'slide': ['SlideDown','SlideUp'],
+ 'blind': ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+ },
+ toggle: function(element, effect) {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+ }, arguments[2] || {});
+ Effect[element.visible() ?
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }
+};
+
+var Effect2 = Effect; // deprecated
+
+/* ------------- transitions ------------- */
+
+Effect.Transitions = {
+ linear: Prototype.K,
+ sinoidal: function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
+ },
+ reverse: function(pos) {
+ return 1-pos;
+ },
+ flicker: function(pos) {
+ var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+ return (pos > 1 ? 1 : pos);
+ },
+ wobble: function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+ },
+ pulse: function(pos, pulses) {
+ pulses = pulses || 5;
+ return (
+ Math.round((pos % (1/pulses)) * pulses) == 0 ?
+ ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
+ 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
+ );
+ },
+ none: function(pos) {
+ return 0;
+ },
+ full: function(pos) {
+ return 1;
+ }
+};
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create();
+Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+ initialize: function() {
+ this.effects = [];
+ this.interval = null;
+ },
+ _each: function(iterator) {
+ this.effects._each(iterator);
+ },
+ add: function(effect) {
+ var timestamp = new Date().getTime();
+
+ var position = (typeof effect.options.queue == 'string') ?
+ effect.options.queue : effect.options.queue.position;
+
+ switch(position) {
+ case 'front':
+ // move unstarted effects after this effect
+ this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ });
+ break;
+ case 'with-last':
+ timestamp = this.effects.pluck('startOn').max() || timestamp;
+ break;
+ case 'end':
+ // start effect after last queued effect has finished
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+
+ if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+ this.effects.push(effect);
+
+ if(!this.interval)
+ this.interval = setInterval(this.loop.bind(this), 15);
+ },
+ remove: function(effect) {
+ this.effects = this.effects.reject(function(e) { return e==effect });
+ if(this.effects.length == 0) {
+ clearInterval(this.interval);
+ this.interval = null;
+ }
+ },
+ loop: function() {
+ var timePos = new Date().getTime();
+ for(var i=0, len=this.effects.length;i= this.startOn) {
+ if(timePos >= this.finishOn) {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ if(this.finish) this.finish();
+ this.event('afterFinish');
+ return;
+ }
+ var pos = (timePos - this.startOn) / this.totalTime,
+ frame = Math.round(pos * this.totalFrames);
+ if(frame > this.currentFrame) {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+ cancel: function() {
+ if(!this.options.sync)
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
+ 'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+ },
+ event: function(eventName) {
+ if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+ if(this.options[eventName]) this.options[eventName](this);
+ },
+ inspect: function() {
+ var data = $H();
+ for(property in this)
+ if(typeof this[property] != 'function') data[property] = this[property];
+ return '#';
+ }
+}
+
+Effect.Parallel = Class.create();
+Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
+ initialize: function(effects) {
+ this.effects = effects || [];
+ this.start(arguments[1]);
+ },
+ update: function(position) {
+ this.effects.invoke('render', position);
+ },
+ finish: function(position) {
+ this.effects.each( function(effect) {
+ effect.render(1.0);
+ effect.cancel();
+ effect.event('beforeFinish');
+ if(effect.finish) effect.finish(position);
+ effect.event('afterFinish');
+ });
+ }
+});
+
+Effect.Event = Class.create();
+Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+ initialize: function() {
+ var options = Object.extend({
+ duration: 0
+ }, arguments[0] || {});
+ this.start(options);
+ },
+ update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create();
+Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ // make this work on IE on elements without 'layout'
+ if(Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ var options = Object.extend({
+ from: this.element.getOpacity() || 0.0,
+ to: 1.0
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ update: function(position) {
+ this.element.setOpacity(position);
+ }
+});
+
+Effect.Move = Class.create();
+Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ x: 0,
+ y: 0,
+ mode: 'relative'
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function() {
+ // Bug in Opera: Opera returns the "real" position of a static element or
+ // relative element that does not have top/left explicitly set.
+ // ==> Always set top and left for position relative elements in your stylesheets
+ // (to 0 if you do not need them)
+ this.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop = parseFloat(this.element.getStyle('top') || '0');
+ if(this.options.mode == 'absolute') {
+ // absolute movement, so we need to calc deltaX and deltaY
+ this.options.x = this.options.x - this.originalLeft;
+ this.options.y = this.options.y - this.originalTop;
+ }
+ },
+ update: function(position) {
+ this.element.setStyle({
+ left: Math.round(this.options.x * position + this.originalLeft) + 'px',
+ top: Math.round(this.options.y * position + this.originalTop) + 'px'
+ });
+ }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+ return new Effect.Move(element,
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
+};
+
+Effect.Scale = Class.create();
+Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
+ initialize: function(element, percent) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
+ scaleFrom: 100.0,
+ scaleTo: percent
+ }, arguments[2] || {});
+ this.start(options);
+ },
+ setup: function() {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = this.element.getStyle('position');
+
+ this.originalStyle = {};
+ ['top','left','width','height','fontSize'].each( function(k) {
+ this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = this.element.getStyle('font-size') || '100%';
+ ['em','px','%','pt'].each( function(fontSizeType) {
+ if(fontSize.indexOf(fontSizeType)>0) {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }.bind(this));
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+
+ this.dims = null;
+ if(this.options.scaleMode=='box')
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if(/^content/.test(this.options.scaleMode))
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ if(!this.dims)
+ this.dims = [this.options.scaleMode.originalHeight,
+ this.options.scaleMode.originalWidth];
+ },
+ update: function(position) {
+ var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+ if(this.options.scaleContent && this.fontSize)
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+ },
+ finish: function(position) {
+ if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ },
+ setDimensions: function(height, width) {
+ var d = {};
+ if(this.options.scaleX) d.width = Math.round(width) + 'px';
+ if(this.options.scaleY) d.height = Math.round(height) + 'px';
+ if(this.options.scaleFromCenter) {
+ var topd = (height - this.dims[0])/2;
+ var leftd = (width - this.dims[1])/2;
+ if(this.elementPositioning == 'absolute') {
+ if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
+ if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+ } else {
+ if(this.options.scaleY) d.top = -topd + 'px';
+ if(this.options.scaleX) d.left = -leftd + 'px';
+ }
+ }
+ this.element.setStyle(d);
+ }
+});
+
+Effect.Highlight = Class.create();
+Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if(this.element.getStyle('display')=='none') { this.cancel(); return; }
+ // Disable background image during the effect
+ this.oldStyle = {};
+ if (!this.options.keepBackgroundImage) {
+ this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+ this.element.setStyle({backgroundImage: 'none'});
+ }
+ if(!this.options.endcolor)
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+ if(!this.options.restorecolor)
+ this.options.restorecolor = this.element.getStyle('background-color');
+ // init color calculations
+ this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+ this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+ },
+ update: function(position) {
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+ return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
+ },
+ finish: function() {
+ this.element.setStyle(Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
+
+Effect.ScrollTo = Class.create();
+Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ this.start(arguments[1] || {});
+ },
+ setup: function() {
+ Position.prepare();
+ var offsets = Position.cumulativeOffset(this.element);
+ if(this.options.offset) offsets[1] += this.options.offset;
+ var max = window.innerHeight ?
+ window.height - window.innerHeight :
+ document.body.scrollHeight -
+ (document.documentElement.clientHeight ?
+ document.documentElement.clientHeight : document.body.clientHeight);
+ this.scrollStart = Position.deltaY;
+ this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
+ },
+ update: function(position) {
+ Position.prepare();
+ window.scrollTo(Position.deltaX,
+ this.scrollStart + (position*this.delta));
+ }
+});
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ var options = Object.extend({
+ from: element.getOpacity() || 1.0,
+ to: 0.0,
+ afterFinishInternal: function(effect) {
+ if(effect.options.to!=0) return;
+ effect.element.hide().setStyle({opacity: oldOpacity});
+ }}, arguments[1] || {});
+ return new Effect.Opacity(element,options);
+}
+
+Effect.Appear = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+ to: 1.0,
+ // force Safari to render floated elements properly
+ afterFinishInternal: function(effect) {
+ effect.element.forceRerendering();
+ },
+ beforeSetup: function(effect) {
+ effect.element.setOpacity(effect.options.from).show();
+ }}, arguments[1] || {});
+ return new Effect.Opacity(element,options);
+}
+
+Effect.Puff = function(element) {
+ element = $(element);
+ var oldStyle = {
+ opacity: element.getInlineOpacity(),
+ position: element.getStyle('position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
+ return new Effect.Parallel(
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
+ beforeSetupInternal: function(effect) {
+ Position.absolutize(effect.effects[0].element)
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().setStyle(oldStyle); }
+ }, arguments[1] || {})
+ );
+}
+
+Effect.BlindUp = function(element) {
+ element = $(element);
+ element.makeClipping();
+ return new Effect.Scale(element, 0,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ restoreAfterFinish: true,
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
+ }, arguments[1] || {})
+ );
+}
+
+Effect.BlindDown = function(element) {
+ element = $(element);
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.SwitchOff = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ return new Effect.Appear(element, Object.extend({
+ duration: 0.4,
+ from: 0,
+ transition: Effect.Transitions.flicker,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(effect.element, 1, {
+ duration: 0.3, scaleFromCenter: true,
+ scaleX: false, scaleContent: false, restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makePositioned().makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+ }
+ })
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.DropOut = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
+ return new Effect.Parallel(
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+ Object.extend(
+ { duration: 0.5,
+ beforeSetup: function(effect) {
+ effect.effects[0].element.makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.Shake = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ return new Effect.Move(element,
+ { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+ effect.element.undoPositioned().setStyle(oldStyle);
+ }}) }}) }}) }}) }}) }});
+}
+
+Effect.SlideDown = function(element) {
+ element = $(element).cleanWhitespace();
+ // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+ var oldInnerBottom = element.down().getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: window.opera ? 0 : 1,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.down().makePositioned();
+ if(window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().setStyle({height: '0px'}).show();
+ },
+ afterUpdateInternal: function(effect) {
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping().undoPositioned();
+ effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+ }, arguments[1] || {})
+ );
+}
+
+Effect.SlideUp = function(element) {
+ element = $(element).cleanWhitespace();
+ var oldInnerBottom = element.down().getStyle('bottom');
+ return new Effect.Scale(element, window.opera ? 0 : 1,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ scaleMode: 'box',
+ scaleFrom: 100,
+ restoreAfterFinish: true,
+ beforeStartInternal: function(effect) {
+ effect.element.makePositioned();
+ effect.element.down().makePositioned();
+ if(window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping().show();
+ },
+ afterUpdateInternal: function(effect) {
+ effect.element.down().setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
+ effect.element.down().undoPositioned();
+ }
+ }, arguments[1] || {})
+ );
+}
+
+// Bug in opera makes the TD containing this element expand for a instance after finish
+Effect.Squish = function(element) {
+ return new Effect.Scale(element, window.opera ? 1 : 0, {
+ restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping();
+ }
+ });
+}
+
+Effect.Grow = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var initialMoveX, initialMoveY;
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ initialMoveX = initialMoveY = moveX = moveY = 0;
+ break;
+ case 'top-right':
+ initialMoveX = dims.width;
+ initialMoveY = moveY = 0;
+ moveX = -dims.width;
+ break;
+ case 'bottom-left':
+ initialMoveX = moveX = 0;
+ initialMoveY = dims.height;
+ moveY = -dims.height;
+ break;
+ case 'bottom-right':
+ initialMoveX = dims.width;
+ initialMoveY = dims.height;
+ moveX = -dims.width;
+ moveY = -dims.height;
+ break;
+ case 'center':
+ initialMoveX = dims.width / 2;
+ initialMoveY = dims.height / 2;
+ moveX = -dims.width / 2;
+ moveY = -dims.height / 2;
+ break;
+ }
+
+ return new Effect.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetup: function(effect) {
+ effect.element.hide().makeClipping().makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ new Effect.Parallel(
+ [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+ new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+ new Effect.Scale(effect.element, 100, {
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+ ], Object.extend({
+ beforeSetup: function(effect) {
+ effect.effects[0].element.setStyle({height: '0px'}).show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
+ }
+ }, options)
+ )
+ }
+ });
+}
+
+Effect.Shrink = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ moveX = moveY = 0;
+ break;
+ case 'top-right':
+ moveX = dims.width;
+ moveY = 0;
+ break;
+ case 'bottom-left':
+ moveX = 0;
+ moveY = dims.height;
+ break;
+ case 'bottom-right':
+ moveX = dims.width;
+ moveY = dims.height;
+ break;
+ case 'center':
+ moveX = dims.width / 2;
+ moveY = dims.height / 2;
+ break;
+ }
+
+ return new Effect.Parallel(
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+ new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+ new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+ ], Object.extend({
+ beforeStartInternal: function(effect) {
+ effect.effects[0].element.makePositioned().makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+ }, options)
+ );
+}
+
+Effect.Pulsate = function(element) {
+ element = $(element);
+ var options = arguments[1] || {};
+ var oldOpacity = element.getInlineOpacity();
+ var transition = options.transition || Effect.Transitions.sinoidal;
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
+ reverser.bind(transition);
+ return new Effect.Opacity(element,
+ Object.extend(Object.extend({ duration: 2.0, from: 0,
+ afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+ }, options), {transition: reverser}));
+}
+
+Effect.Fold = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
+ element.makeClipping();
+ return new Effect.Scale(element, 5, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
+ scaleY: false,
+ afterFinishInternal: function(effect) {
+ effect.element.hide().undoClipping().setStyle(oldStyle);
+ } });
+ }}, arguments[1] || {}));
+};
+
+Effect.Morph = Class.create();
+Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ if(!this.element) throw(Effect._elementDoesNotExistError);
+ var options = Object.extend({
+ style: {}
+ }, arguments[1] || {});
+ if (typeof options.style == 'string') {
+ if(options.style.indexOf(':') == -1) {
+ var cssText = '', selector = '.' + options.style;
+ $A(document.styleSheets).reverse().each(function(styleSheet) {
+ if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
+ else if (styleSheet.rules) cssRules = styleSheet.rules;
+ $A(cssRules).reverse().each(function(rule) {
+ if (selector == rule.selectorText) {
+ cssText = rule.style.cssText;
+ throw $break;
+ }
+ });
+ if (cssText) throw $break;
+ });
+ this.style = cssText.parseStyle();
+ options.afterFinishInternal = function(effect){
+ effect.element.addClassName(effect.options.style);
+ effect.transforms.each(function(transform) {
+ if(transform.style != 'opacity')
+ effect.element.style[transform.style] = '';
+ });
+ }
+ } else this.style = options.style.parseStyle();
+ } else this.style = $H(options.style)
+ this.start(options);
+ },
+ setup: function(){
+ function parseColor(color){
+ if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+ color = color.parseColor();
+ return $R(0,2).map(function(i){
+ return parseInt( color.slice(i*2+1,i*2+3), 16 )
+ });
+ }
+ this.transforms = this.style.map(function(pair){
+ var property = pair[0], value = pair[1], unit = null;
+
+ if(value.parseColor('#zzzzzz') != '#zzzzzz') {
+ value = value.parseColor();
+ unit = 'color';
+ } else if(property == 'opacity') {
+ value = parseFloat(value);
+ if(Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ } else if(Element.CSS_LENGTH.test(value)) {
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+ value = parseFloat(components[1]);
+ unit = (components.length == 3) ? components[2] : null;
+ }
+
+ var originalValue = this.element.getStyle(property);
+ return {
+ style: property.camelize(),
+ originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
+ targetValue: unit=='color' ? parseColor(value) : value,
+ unit: unit
+ };
+ }.bind(this)).reject(function(transform){
+ return (
+ (transform.originalValue == transform.targetValue) ||
+ (
+ transform.unit != 'color' &&
+ (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+ )
+ )
+ });
+ },
+ update: function(position) {
+ var style = {}, transform, i = this.transforms.length;
+ while(i--)
+ style[(transform = this.transforms[i]).style] =
+ transform.unit=='color' ? '#'+
+ (Math.round(transform.originalValue[0]+
+ (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
+ (Math.round(transform.originalValue[1]+
+ (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
+ (Math.round(transform.originalValue[2]+
+ (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
+ transform.originalValue + Math.round(
+ ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
+ this.element.setStyle(style, true);
+ }
+});
+
+Effect.Transform = Class.create();
+Object.extend(Effect.Transform.prototype, {
+ initialize: function(tracks){
+ this.tracks = [];
+ this.options = arguments[1] || {};
+ this.addTracks(tracks);
+ },
+ addTracks: function(tracks){
+ tracks.each(function(track){
+ var data = $H(track).values().first();
+ this.tracks.push($H({
+ ids: $H(track).keys().first(),
+ effect: Effect.Morph,
+ options: { style: data }
+ }));
+ }.bind(this));
+ return this;
+ },
+ play: function(){
+ return new Effect.Parallel(
+ this.tracks.map(function(track){
+ var elements = [$(track.ids) || $$(track.ids)].flatten();
+ return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
+ }).flatten(),
+ this.options
+ );
+ }
+});
+
+Element.CSS_PROPERTIES = $w(
+ 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
+ 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+ 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+ 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+ 'fontSize fontWeight height left letterSpacing lineHeight ' +
+ 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+ 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+ 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+ 'right textIndent top width wordSpacing zIndex');
+
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.prototype.parseStyle = function(){
+ var element = document.createElement('div');
+ element.innerHTML = '
';
+ var style = element.childNodes[0].style, styleRules = $H();
+
+ Element.CSS_PROPERTIES.each(function(property){
+ if(style[property]) styleRules[property] = style[property];
+ });
+ if(Prototype.Browser.IE && this.indexOf('opacity') > -1) {
+ styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
+ }
+ return styleRules;
+};
+
+Element.morph = function(element, style) {
+ new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
+ return element;
+};
+
+['getInlineOpacity','forceRerendering','setContentZoom',
+ 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
+ function(f) { Element.Methods[f] = Element[f]; }
+);
+
+Element.Methods.visualEffect = function(element, effect, options) {
+ s = effect.dasherize().camelize();
+ effect_class = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[effect_class](element, options);
+ return $(element);
+};
+
+Element.addMethods();
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/extended_debug.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/extended_debug.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/extended_debug.js (revision 3449)
@@ -0,0 +1,113 @@
+var commandHistory;
+var historyIndex;
+
+function showExtendedDebug() {
+ if (debugWindow != null) {
+ hideDebug();
+ }
+
+ if (debugWindow == null) {
+ commandHistory = new Array();
+ historyIndex = 0;
+
+ debugWindow = new Window('debug_window', {className: 'dialog',width:250, height:100, right:4, minWidth:250, bottom:42, zIndex:1000, opacity:1, showEffect: Element.show, resizable: true, title: "Debug"})
+ debugWindow.getContent().innerHTML = "
";
+
+ //create hourglass icon and attach events to it.
+ var cont = "
";
+
+ new Insertion.After('debug_window_maximize', cont);
+ Event.observe('debug_window_inspect', 'click', enterInspectionMode, false);
+
+ //create command text box
+ cont = "Eval: "
+ debugWindow.setStatusBar(cont);
+
+ Event.observe('debug_window_command', 'mousedown', donothing);
+ Event.observe('debug_window_command', 'keypress', evalJS, false);
+ }
+ debugWindow.show();
+}
+
+function donothing(evt){
+ Field.activate('debug_window_command');
+ return false;
+}
+
+function evalJS(evt){
+ if(evt.keyCode == Event.KEY_RETURN){
+ var js = $F('debug_window_command');
+ try{
+ var ret = eval(js);
+ if(ret != null)
+ debug(ret);
+ }catch(e){
+ debug(e);
+ }
+ $('debug_window_command').value = '';
+
+ Field.activate('debug_window_command');
+ commandHistory.push(js);
+ historyIndex = 0;
+ }
+
+ if(evt.keyCode == Event.KEY_UP){
+ if(commandHistory.length > historyIndex){
+ historyIndex++;
+ var js = commandHistory[commandHistory.length-historyIndex];
+ $('debug_window_command').value = js;
+ Event.stop(evt);
+ Field.activate('debug_window_command');
+ }
+ }
+
+ if(evt.keyCode == Event.KEY_DOWN){
+ if(commandHistory.length >= historyIndex && historyIndex > 1){
+ historyIndex--;
+ var js = commandHistory[commandHistory.length-historyIndex];
+ $('debug_window_command').value = js;
+ Event.stop(evt);
+ Field.activate('debug_window_command');
+ }
+ }
+}
+
+function enterInspectionMode(evt){
+ //stop observing magnifying glass
+ Event.stopObserving('debug_window_inspect', 'click', enterInspectionMode, false);
+ //change pointer
+ document.body.style.cursor='help';
+ //start observing mouse clicks
+ Event.observe(window, 'click', inspectItem, false);
+}
+
+function inspectItem(evt){
+ // the element that triggered the event
+ var element = Event.element(evt);
+ if(element.id!="debug_window_inspect"){
+ clearDebug()
+ //change pointer
+ document.body.style.cursor='default';
+ debug(element.id);
+ inspect(element);
+ //stop observing mouse clicks
+ Event.stopObserving(window, 'click', inspectItem, false);
+ //alert('doing something');
+ //start observing mag
+ Event.observe('debug_window_inspect', 'click', enterInspectionMode, false);
+ }
+}
+
+function clearDebug() {
+ var win = $('debug');
+ if (win == null)
+ return;
+
+ win.innerHTML=" ";
+ //clear inspections too
+ var divs = document.getElementsByClassName('inspector');
+ divs.each(function(div){
+ Element.remove(div);
+ });
+}
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/prototype.js
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/prototype.js (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/javascripts/prototype.js (revision 3449)
@@ -0,0 +1,4221 @@
+/* Prototype JavaScript framework, version 1.6.0.2
+ * (c) 2005-2008 Sam Stephenson
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.6.0.2',
+
+ Browser: {
+ IE: !!(window.attachEvent && !window.opera),
+ Opera: !!window.opera,
+ 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,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ document.createElement('div').__proto__ &&
+ document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__
+ },
+
+ ScriptFragment: '
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/darkX.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/darkX.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/darkX.css (revision 3449)
@@ -0,0 +1,121 @@
+.overlay_darkX {
+ background-color: #85BBEF;
+ filter:alpha(opacity=60);
+ -moz-opacity: 0.6;
+ opacity: 0.6;
+}
+
+.darkX_nw {
+ background: transparent url(darkX/titlebar-left-focused.png) no-repeat 0 0;
+ width:6px;
+ height:21px;
+}
+.darkX_n {
+ background: transparent url(darkX/titlebar-mid-focused.png) repeat-x 0 0;
+ height:21px;
+}
+.darkX_ne {
+ background: transparent url(darkX/titlebar-right-focused.png) no-repeat 0 0;
+ width:6px;
+ height:21px;
+}
+.darkX_w {
+ background: transparent url(darkX/frame-left-focused.png) repeat-y top left;
+ width:3px;
+}
+
+.darkX_e {
+ background: transparent url(darkX/frame-right-focused.png) repeat-y top right;
+ width:3px;
+}
+
+.darkX_sw {
+ background: transparent url(darkX/frame-bottom-left-focused.png) no-repeat 0 0;
+ width:5px;
+ height:3px;
+}
+.darkX_s {
+ background: transparent url(darkX/frame-bottom-mid-focused.png) repeat-x 0 0;
+ height:3px;
+}
+.darkX_se, .darkX_sizer {
+ background: transparent url(darkX/frame-bottom-right-focused.png) no-repeat 0 0;
+ width:5px;
+ height:3px;
+}
+
+.darkX_sizer {
+ cursor:se-resize;
+}
+
+.darkX_close {
+ width: 21px;
+ height: 21px;
+ background: transparent url(darkX/button-close-focused.png) no-repeat 0 0;
+ position:absolute;
+ top:0px;
+ right:5px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.darkX_minimize {
+ width: 21px;
+ height: 21px;
+ background: transparent url(darkX/button-minimize-focused.png) no-repeat 0 0;
+ position:absolute;
+ top:0px;
+ right:26px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.darkX_maximize {
+ width: 21px;
+ height: 21px;
+ background: transparent url(darkX/button-maximize-focused.png) no-repeat 0 0;
+ position:absolute;
+ top:0px;
+ right:47px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+
+.darkX_title {
+ float:left;
+ height:14px;
+ font-size:12px;
+ text-align:center;
+ margin-top:2px;
+ width:100%;
+ color:#FFF;
+}
+
+.darkX_content {
+ overflow:auto;
+ color: #E6DF2A;
+ font-family: Tahoma, Arial, sans-serif;
+ font-size: 14px;
+ background:#5E5148;
+}
+
+
+/* FOR IE */
+* html .darkX_minimize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-minimize-focused.png", sizingMethod="crop");
+}
+
+* html .darkX_maximize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-maximize-focused.png", sizingMethod="scale");
+}
+
+* html .darkX_close {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/darkX/button-close-focused.png", sizingMethod="crop");
+}
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/debug.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/debug.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/debug.css (revision 3449)
@@ -0,0 +1,25 @@
+div.inspector div.inspectable {
+ padding: 0.25em 0 0.25em 1em;
+ background-color: Gray;
+ color: white;
+ border: outset 2px white;
+ cursor: pointer;
+}
+
+div.inspector div.child {
+ margin: 0 0 0 1em;
+}
+
+#debug_window_content { /* DIV container for debug sizing*/
+ width:250px;
+ height:100px;
+ background-color:#000;
+}
+
+#debug { /* DIV container for debug contents*/
+ padding:3px;
+ color:#0f0;
+ font-family:monaco, Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size:10px;
+}
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/default.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/default.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/default.css (revision 3449)
@@ -0,0 +1,155 @@
+.overlay_dialog {
+ background-color: #666666;
+ filter:alpha(opacity=60);
+ -moz-opacity: 0.6;
+ opacity: 0.6;
+}
+
+.overlay___invisible__ {
+ background-color: #666666;
+ filter:alpha(opacity=0);
+ -moz-opacity: 0;
+ opacity: 0;
+}
+
+.dialog_nw {
+ width: 9px;
+ height: 23px;
+ background: transparent url(default/top_left.gif) no-repeat 0 0;
+}
+
+.dialog_n {
+ background: transparent url(default/top_mid.gif) repeat-x 0 0;
+ height: 23px;
+}
+
+.dialog_ne {
+ width: 9px;
+ height: 23px;
+ background: transparent url(default/top_right.gif) no-repeat 0 0;
+}
+
+.dialog_e {
+ width: 2px;
+ background: transparent url(default/center_right.gif) repeat-y 0 0;
+}
+
+.dialog_w {
+ width: 2px;
+ background: transparent url(default/center_left.gif) repeat-y 0 0;
+}
+
+.dialog_sw {
+ width: 9px;
+ height: 19px;
+ background: transparent url(default/bottom_left.gif) no-repeat 0 0;
+}
+
+.dialog_s {
+ background: transparent url(default/bottom_mid.gif) repeat-x 0 0;
+ height: 19px;
+}
+
+.dialog_se {
+ width: 9px;
+ height: 19px;
+ background: transparent url(default/bottom_right.gif) no-repeat 0 0;
+}
+
+.dialog_sizer {
+ width: 9px;
+ height: 19px;
+ background: transparent url(default/sizer.gif) no-repeat 0 0;
+ cursor:se-resize;
+}
+
+.dialog_close {
+ width: 14px;
+ height: 14px;
+ background: transparent url(default/close.gif) no-repeat 0 0;
+ position:absolute;
+ top:5px;
+ left:8px;
+ cursor:pointer;
+ z-index:2000;
+}
+
+.dialog_minimize {
+ width: 14px;
+ height: 15px;
+ background: transparent url(default/minimize.gif) no-repeat 0 0;
+ position:absolute;
+ top:5px;
+ left:28px;
+ cursor:pointer;
+ z-index:2000;
+}
+
+.dialog_maximize {
+ width: 14px;
+ height: 15px;
+ background: transparent url(default/maximize.gif) no-repeat 0 0;
+ position:absolute;
+ top:5px;
+ left:49px;
+ cursor:pointer;
+ z-index:2000;
+}
+
+.dialog_title {
+ float:left;
+ height:14px;
+ font-family: Tahoma, Arial, sans-serif;
+ font-size:12px;
+ text-align:center;
+ width:100%;
+ color:#000;
+}
+
+.dialog_content {
+ overflow:auto;
+ color: #DDD;
+ font-family: Tahoma, Arial, sans-serif;
+ font-size: 10px;
+ background-color:#123;
+}
+
+.top_draggable, .bottom_draggable {
+ cursor:move;
+}
+
+.status_bar {
+ font-size:12px;
+}
+.status_bar input{
+ font-size:12px;
+}
+
+.wired_frame {
+ display: block;
+ position: absolute;
+ border: 1px #000 dashed;
+}
+
+/* DO NOT CHANGE THESE VALUES*/
+.dialog {
+ display: block;
+ position: absolute;
+}
+
+.dialog table.table_window {
+ border-collapse: collapse;
+ border-spacing: 0;
+ width: 100%;
+ margin: 0px;
+ padding:0px;
+}
+
+.dialog table.table_window td , .dialog table.table_window th {
+ padding: 0;
+}
+
+.dialog .title_window {
+ -moz-user-select:none;
+}
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/iefix/iepngfix.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/iefix/iepngfix.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/iefix/iepngfix.css (revision 3449)
@@ -0,0 +1,3 @@
+/* PNG fix for all themes that uses PNG images on IE */
+td, div { behavior: url(../themes/iefix/iepngfix.htc) }
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/iefix/iepngfix.htc
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/iefix/iepngfix.htc (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/iefix/iepngfix.htc (revision 3449)
@@ -0,0 +1,54 @@
+
+
+
+
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/lighting.css
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/lighting.css (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/lighting.css (revision 3449)
@@ -0,0 +1,960 @@
+.overlay___invisible__ {
+ background-color: #666;
+ filter:alpha(opacity=0);
+ -moz-opacity: 0;
+ opacity: 0;
+}
+
+.top_draggable, .bottom_draggable {
+ cursor:move;
+}
+
+.status_bar {
+ font-size:12px;
+}
+.status_bar input{
+ font-size:12px;
+}
+
+.wired_frame {
+ display:block;
+ position:absolute;
+ border:1px #000 dashed;
+}
+
+
+
+.overlay_bluelighting {
+ background-color:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.bluelighting_wired_frame {
+ background:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.bluelighting_nw {
+ background:transparent url(lighting/top-left-blue.png) no-repeat 0 0;
+ width:9px;
+ height:28px;
+}
+
+.bluelighting_n {
+ background:transparent url(lighting/top-middle-blue.png) repeat-x 0 0;
+ height:28px;
+}
+
+.bluelighting_ne {
+ background:transparent url(lighting/top-right-blue.png) no-repeat 0 0;
+ width:15px;
+ height:28px;
+}
+
+.bluelighting_w {
+ background:transparent url(lighting/left-blue.png) repeat-y top left;
+ width:9px;
+}
+
+.bluelighting_e {
+ background:transparent url(lighting/right-blue.png) repeat-y top right;
+ width:15px;
+}
+
+.bluelighting_sw {
+ background:transparent url(lighting/bottom-left-blue.png) no-repeat 0 0;
+ width:9px;
+ height:15px;
+}
+
+.bluelighting_s {
+ background:transparent url(lighting/bottom-middle-blue.png) repeat-x 0 0;
+ height:15px;
+}
+
+.bluelighting_se, .bluelighting_sizer {
+ background:transparent url(lighting/bottom-right-blue.png) no-repeat 0 0;
+ width:15px;
+ height:15px;
+}
+
+.bluelighting_sizer {
+ cursor:se-resize;
+}
+
+.bluelighting_close {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-close-blue.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:10px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.bluelighting_maximize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-maximize-blue.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:25px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.bluelighting_minimize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-minimize-blue.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:40px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.bluelighting_title {
+ float:left;
+ height:14px;
+ font-size:14px;
+ font-weight:bold;
+ font-family:Verdana, Arial, sans-serif;
+ text-align:center;
+ margin-top:2px;
+ width:100%;
+ color:#17385B;
+}
+
+.bluelighting_content {
+ overflow:auto;
+ color:#000;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:12px;
+ background:#BFDBFF;
+}
+
+/* For alert/confirm dialog */
+.bluelighting_window {
+ border:1px solid #F00;
+ background:#FFF;
+ padding:20px;
+ margin-left:auto;
+ margin-right:auto;
+ width:400px;
+}
+
+.bluelighting_message {
+ font-size:12px;
+ text-align:center;
+ width:100%;
+ padding-bottom:10px;
+}
+
+.bluelighting_buttons {
+ text-align:center;
+ width:100%;
+}
+
+.bluelighting_buttons input {
+ border:1px solid #999;
+ border-top-color:#CCC;
+ border-left-color:#CCC;
+ padding:2px;
+ background-color:#FFF;
+ color:#333;
+ background-image:url(lighting/background_buttons.gif);
+ background-repeat:repeat-x;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:10px;
+ font-weight:bold;
+ text-align:center;
+}
+
+.bluelighting_progress {
+ float:left;
+ margin:auto;
+ text-align:center;
+ width:100%;
+ height:16px;
+ background:transparent url('lighting/spinner.gif') no-repeat center center
+}
+
+/* FOR IE */
+* html .bluelighting_nw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_n {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-blue.png", sizingMethod="scale");
+}
+
+* html .bluelighting_ne {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_w {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-blue.png", sizingMethod="scale");
+}
+
+* html .bluelighting_e {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-blue.png", sizingMethod="scale");
+}
+
+* html .bluelighting_sw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_s {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-blue.png", sizingMethod="scale");
+}
+
+* html .bluelighting_se, * html .bluelighting_sizer {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_close {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_minimize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_maximize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-blue.png", sizingMethod="crop");
+}
+
+* html .bluelighting_content {
+ background:#B8D7FF;
+}
+
+
+
+.overlay_greylighting {
+ background-color:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.greylighting_wired_frame {
+ background:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.greylighting_nw {
+ background:transparent url(lighting/top-left-grey.png) no-repeat 0 0;
+ width:9px;
+ height:28px;
+}
+
+.greylighting_n {
+ background:transparent url(lighting/top-middle-grey.png) repeat-x 0 0;
+ height:28px;
+}
+
+.greylighting_ne {
+ background:transparent url(lighting/top-right-grey.png) no-repeat 0 0;
+ width:15px;
+ height:28px;
+}
+
+.greylighting_w {
+ background:transparent url(lighting/left-grey.png) repeat-y top left;
+ width:9px;
+}
+
+.greylighting_e {
+ background:transparent url(lighting/right-grey.png) repeat-y top right;
+ width:15px;
+}
+
+.greylighting_sw {
+ background:transparent url(lighting/bottom-left-grey.png) no-repeat 0 0;
+ width:9px;
+ height:15px;
+}
+
+.greylighting_s {
+ background:transparent url(lighting/bottom-middle-grey.png) repeat-x 0 0;
+ height:15px;
+}
+
+.greylighting_se, .greylighting_sizer {
+ background:transparent url(lighting/bottom-right-grey.png) no-repeat 0 0;
+ width:15px;
+ height:15px;
+}
+
+.greylighting_sizer {
+ cursor:se-resize;
+}
+
+.greylighting_close {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-close-grey.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:10px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.greylighting_maximize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-maximize-grey.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:25px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.greylighting_minimize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-minimize-grey.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:40px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.greylighting_title {
+ float:left;
+ height:14px;
+ font-size:14px;
+ font-weight:bold;
+ font-family:Verdana, Arial, sans-serif;
+ text-align:center;
+ margin-top:2px;
+ width:100%;
+ color:#525252;
+}
+
+.greylighting_content {
+ overflow:auto;
+ color:#000;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:12px;
+ background:#CDCDCD;
+}
+
+/* For alert/confirm dialog */
+.greylighting_window {
+ border:1px solid #F00;
+ background:#FFF;
+ padding:20px;
+ margin-left:auto;
+ margin-right:auto;
+ width:400px;
+}
+
+.greylighting_message {
+ font-size:12px;
+ text-align:center;
+ width:100%;
+ padding-bottom:10px;
+}
+
+.greylighting_buttons {
+ text-align:center;
+ width:100%;
+}
+
+.greylighting_buttons input {
+ border:1px solid #999;
+ border-top-color:#CCC;
+ border-left-color:#CCC;
+ padding:2px;
+ background-color:#FFF;
+ color:#333;
+ background-image:url(lighting/background_buttons.gif);
+ background-repeat:repeat-x;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:10px;
+ font-weight:bold;
+ text-align:center;
+}
+
+.greylighting_progress {
+ float:left;
+ margin:auto;
+ text-align:center;
+ width:100%;
+ height:16px;
+ background:transparent url('lighting/spinner.gif') no-repeat center center
+}
+
+/* FOR IE */
+* html .greylighting_nw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_n {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-grey.png", sizingMethod="scale");
+}
+
+* html .greylighting_ne {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_w {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-grey.png", sizingMethod="scale");
+}
+
+* html .greylighting_e {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-grey.png", sizingMethod="scale");
+}
+
+* html .greylighting_sw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_s {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-grey.png", sizingMethod="scale");
+}
+
+* html greylighting_se, * html .greylighting_sizer {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_close {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_minimize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_maximize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-grey.png", sizingMethod="crop");
+}
+
+* html .greylighting_content {
+ background:#C7C7C7;
+}
+
+
+
+.overlay_greenlighting {
+ background-color:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.greenlighting_wired_frame {
+ background:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.greenlighting_nw {
+ background:transparent url(lighting/top-left-green.png) no-repeat 0 0;
+ width:9px;
+ height:28px;
+}
+
+.greenlighting_n {
+ background:transparent url(lighting/top-middle-green.png) repeat-x 0 0;
+ height:28px;
+}
+
+.greenlighting_ne {
+ background:transparent url(lighting/top-right-green.png) no-repeat 0 0;
+ width:15px;
+ height:28px;
+}
+
+.greenlighting_w {
+ background:transparent url(lighting/left-green.png) repeat-y top left;
+ width:9px;
+}
+
+.greenlighting_e {
+ background:transparent url(lighting/right-green.png) repeat-y top right;
+ width:15px;
+}
+
+.greenlighting_sw {
+ background:transparent url(lighting/bottom-left-green.png) no-repeat 0 0;
+ width:9px;
+ height:15px;
+}
+
+.greenlighting_s {
+ background:transparent url(lighting/bottom-middle-green.png) repeat-x 0 0;
+ height:15px;
+}
+
+.greenlighting_se, .greenlighting_sizer {
+ background:transparent url(lighting/bottom-right-green.png) no-repeat 0 0;
+ width:15px;
+ height:15px;
+}
+
+.greenlighting_sizer {
+ cursor:se-resize;
+}
+
+.greenlighting_close {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-close-green.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:10px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.greenlighting_maximize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-maximize-green.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:25px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.greenlighting_minimize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-minimize-green.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:40px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.greenlighting_title {
+ float:left;
+ height:14px;
+ font-size:14px;
+ font-weight:bold;
+ font-family:Verdana, Arial, sans-serif;
+ text-align:center;
+ margin-top:2px;
+ width:100%;
+ color:#2A6002;
+}
+
+.greenlighting_content {
+ overflow:auto;
+ color:#000;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:12px;
+ background:#ACFCAF;
+}
+
+/* For alert/confirm dialog */
+.greenlighting_window {
+ border:1px solid #F00;
+ background:#FFF;
+ padding:20px;
+ margin-left:auto;
+ margin-right:auto;
+ width:400px;
+}
+
+.greenlighting_message {
+ font-size:12px;
+ text-align:center;
+ width:100%;
+ padding-bottom:10px;
+}
+
+.greenlighting_buttons {
+ text-align:center;
+ width:100%;
+}
+
+.greenlighting_buttons input {
+ border:1px solid #999;
+ border-top-color:#CCC;
+ border-left-color:#CCC;
+ padding:2px;
+ background-color:#FFF;
+ color:#333;
+ background-image:url(lighting/background_buttons.gif);
+ background-repeat:repeat-x;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:10px;
+ font-weight:bold;
+ text-align:center;
+}
+
+.greenlighting_progress {
+ float:left;
+ margin:auto;
+ text-align:center;
+ width:100%;
+ height:16px;
+ background:transparent url('lighting/spinner.gif') no-repeat center center
+}
+
+/* FOR IE */
+* html .greenlighting_nw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_n {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-green.png", sizingMethod="scale");
+}
+
+* html .greenlighting_ne {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_w {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-green.png", sizingMethod="scale");
+}
+
+* html .greenlighting_e {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-green.png", sizingMethod="scale");
+}
+
+* html .greenlighting_sw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_s {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-green.png", sizingMethod="scale");
+}
+
+* html greenlighting_se, * html .greenlighting_sizer {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_close {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_minimize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_maximize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-green.png", sizingMethod="crop");
+}
+
+* html .greenlighting_content {
+ background:#A4FCA7;
+}
+
+
+
+.overlay_darkbluelighting {
+ background-color:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.darkbluelighting_wired_frame {
+ background:#FFF;
+ filter:alpha(opacity=60);
+ -moz-opacity:0.6;
+ opacity:0.6;
+}
+
+.darkbluelighting_nw {
+ background:transparent url(lighting/top-left-darkblue.png) no-repeat 0 0;
+ width:9px;
+ height:28px;
+}
+
+.darkbluelighting_n {
+ background:transparent url(lighting/top-middle-darkblue.png) repeat-x 0 0;
+ height:28px;
+}
+
+.darkbluelighting_ne {
+ background:transparent url(lighting/top-right-darkblue.png) no-repeat 0 0;
+ width:15px;
+ height:28px;
+}
+
+.darkbluelighting_w {
+ background:transparent url(lighting/left-darkblue.png) repeat-y top left;
+ width:9px;
+}
+
+.darkbluelighting_e {
+ background:transparent url(lighting/right-darkblue.png) repeat-y top right;
+ width:15px;
+}
+
+.darkbluelighting_sw {
+ background:transparent url(lighting/bottom-left-darkblue.png) no-repeat 0 0;
+ width:9px;
+ height:15px;
+}
+
+.darkbluelighting_s {
+ background:transparent url(lighting/bottom-middle-darkblue.png) repeat-x 0 0;
+ height:15px;
+}
+
+.darkbluelighting_se, .darkbluelighting_sizer {
+ background:transparent url(lighting/bottom-right-darkblue.png) no-repeat 0 0;
+ width:15px;
+ height:15px;
+}
+
+.darkbluelighting_sizer {
+ cursor:se-resize;
+}
+
+.darkbluelighting_close {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-close-darkblue.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:10px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.darkbluelighting_maximize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-maximize-darkblue.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:25px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.darkbluelighting_minimize {
+ width:15px;
+ height:9px;
+ background:transparent url(lighting/button-minimize-darkblue.png) no-repeat 0 0;
+ position:absolute;
+ top:11px;
+ right:40px;
+ cursor:pointer;
+ z-index:1000;
+}
+
+.darkbluelighting_title {
+ float:left;
+ height:14px;
+ font-size:14px;
+ font-weight:bold;
+ font-family:Verdana, Arial, sans-serif;
+ text-align:center;
+ margin-top:2px;
+ width:100%;
+ color:#E4EFFD;
+}
+
+.darkbluelighting_content {
+ overflow:auto;
+ color:#FFF;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:12px;
+ background:#0413C0;
+}
+
+/* For alert/confirm dialog */
+.darkbluelighting_window {
+ border:1px solid #F00;
+ background:#FFF;
+ padding:20px;
+ margin-left:auto;
+ margin-right:auto;
+ width:400px;
+}
+
+.darkbluelighting_message {
+ font-size:12px;
+ text-align:center;
+ width:100%;
+ padding-bottom:10px;
+}
+
+.darkbluelighting_buttons {
+ text-align:center;
+ width:100%;
+}
+
+.darkbluelighting_buttons input {
+ border:1px solid #999;
+ border-top-color:#CCC;
+ border-left-color:#CCC;
+ padding:2px;
+ background-color:#FFF;
+ color:#333;
+ background-image:url(lighting/background_buttons.gif);
+ background-repeat:repeat-x;
+ font-family:Verdana, Arial, sans-serif;
+ font-size:10px;
+ font-weight:bold;
+ text-align:center;
+}
+
+.darkbluelighting_progress {
+ float:left;
+ margin:auto;
+ text-align:center;
+ width:100%;
+ height:16px;
+ background:transparent url('lighting/spinner.gif') no-repeat center center
+}
+
+/* FOR IE */
+* html .darkbluelighting_nw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-left-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_n {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-middle-darkblue.png", sizingMethod="scale");
+}
+
+* html .darkbluelighting_ne {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/top-right-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_w {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/left-darkblue.png", sizingMethod="scale");
+}
+
+* html .darkbluelighting_e {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/right-darkblue.png", sizingMethod="scale");
+}
+
+* html .darkbluelighting_sw {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-left-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_s {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-middle-darkblue.png", sizingMethod="scale");
+}
+
+* html darkbluelighting_se, * html .darkbluelighting_sizer {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/bottom-right-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_close {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-close-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_minimize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-minimize-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_maximize {
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../themes/lighting/button-maximize-darkblue.png", sizingMethod="crop");
+}
+
+* html .darkbluelighting_content {
+ background:#020EBA;
+}
+
Index: /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/lighting/pngbehavior.htc
===================================================================
--- /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/lighting/pngbehavior.htc (revision 3449)
+++ /extensions/rv_gmaps/tags/2.0.b/template/windows_13/themes/lighting/pngbehavior.htc (revision 3449)
@@ -0,0 +1,67 @@
+
+
+
+