Photos are now paginated. Admin is handled by Typus, including file uploads. Exif reading isn't working when uploading via Typus though.
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
public/system
|
||||
4
app/controllers/admin/categories_controller.rb
Normal file
@ -0,0 +1,4 @@
|
||||
# Controller generated by Typus, use it to extend admin functionality.
|
||||
class Admin::CategoriesController < Admin::MasterController
|
||||
|
||||
end
|
||||
4
app/controllers/admin/photos_controller.rb
Normal file
@ -0,0 +1,4 @@
|
||||
# Controller generated by Typus, use it to extend admin functionality.
|
||||
class Admin::PhotosController < Admin::MasterController
|
||||
|
||||
end
|
||||
4
app/controllers/admin/typus_users_controller.rb
Normal file
@ -0,0 +1,4 @@
|
||||
# Controller generated by Typus, use it to extend admin functionality.
|
||||
class Admin::TypusUsersController < Admin::MasterController
|
||||
|
||||
end
|
||||
@ -7,9 +7,11 @@ class PhotosController < ApplicationController
|
||||
def index
|
||||
if params[:category_id]
|
||||
@category = Category.find_by_id(params[:category_id])
|
||||
@photos = Photo.find(:all, :conditions => { :category_id => params[:category_id] })
|
||||
@photos = @category.photos.paginate :page => params[:page], :per_page => 11
|
||||
@num_photos = @photos.count
|
||||
else
|
||||
@photos = Photo.find(:all)
|
||||
@photos = Photo.paginate :all, :page => params[:page], :per_page => 11
|
||||
@num_photos = @photos.count
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
class Category < ActiveRecord::Base
|
||||
has_many :photos
|
||||
has_and_belongs_to_many :photos
|
||||
end
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
require 'exifr'
|
||||
|
||||
class Photo < ActiveRecord::Base
|
||||
belongs_to :category
|
||||
has_and_belongs_to_many :categories
|
||||
|
||||
has_attached_file :photo, :styles => { :original => "1024x1024>",
|
||||
:size11 => "308x308#",
|
||||
@ -10,9 +10,9 @@ class Photo < ActiveRecord::Base
|
||||
:size3 => "84x84#",
|
||||
:size2 => "56x56#" }
|
||||
|
||||
validates_presence_of :category
|
||||
|
||||
before_post_process :get_exif
|
||||
after_create :get_exif
|
||||
|
||||
@@per_page = 11
|
||||
|
||||
private
|
||||
def get_exif
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
</div>
|
||||
|
||||
<div class="sg-24 sgParent">
|
||||
|
||||
<% @categories.each do |category| %>
|
||||
<div class="sg-8 sgParent">
|
||||
<div class="category sg-7" style="background: <%= category.base_colour %>">
|
||||
<%= link_to '<h3>'+h(category.name.downcase)+'</h3>', category_photos_path(category) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="category sg-5" style="background: <%= category.base_colour %>">
|
||||
<%= link_to '<h3>'+h(category.name.downcase)+'</h3>', category_photos_path(category) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="sg-7 category blank-category">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -13,10 +13,12 @@
|
||||
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
|
||||
<div class="sgParent sg-12">
|
||||
|
||||
<div id="header" class="sg-11"><h1><%= image_tag('title.png') %></h1></div>
|
||||
<div id="header" class="sg-11"><h1><%= image_tag('title.png') %></h1></div>
|
||||
|
||||
<%= yield %>
|
||||
<%= yield %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,40 @@
|
||||
<div class="sg-5">
|
||||
</div>
|
||||
<div class="sg-5 page-links">
|
||||
<% if @photos.previous_page -%>
|
||||
<%= link_to '<div>←</div>', { :page => @photos.previous_page }, :class => 'prev-link' %>
|
||||
<% end %>
|
||||
<% if @photos.next_page -%>
|
||||
<%= link_to '<div>→</div>', { :page => @photos.next_page }, :class => 'next-link' %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sg-24 sgParent">
|
||||
|
||||
<% if @category %>
|
||||
<div class="sg-5 category" style="background: <%= @category.base_colour %>">
|
||||
<h3><%=h @category.name.downcase %></h3>
|
||||
<%= link_to '<h3>'+h(@category.name.downcase)+'</h3><div class="arrow">↑</div>', categories_url %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="sg-5 category" style="background: #333;">
|
||||
<h3>all photos</h3>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% @num_blank = 11 - @num_photos -%>
|
||||
|
||||
<% @photos.each do |photo| %>
|
||||
|
||||
<div class="sg-5 photo" style="background: url('<%= photo.photo.url(:size5) %>')"><%= link_to ' ', photo.photo.url, :rel => 'photo', :class => 'fancy' %></div>
|
||||
<div class="sg-5 photo" style="background: url('<%= photo.photo.url(:size5) %>')">
|
||||
<%= link_to ' ', photo.photo.url, :rel => 'photo', :class => 'fancy' %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% @num_blank.times do %>
|
||||
<div class="sg-5 photo blank-photo">
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
<%= f.label :image_file %>:<br />
|
||||
<%= f.file_field :photo %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.label :category %>
|
||||
<%= f.select :category_id, @categories %>
|
||||
</p>
|
||||
<p>
|
||||
<%= submit_tag 'Upload' %>
|
||||
</p>
|
||||
|
||||
@ -19,6 +19,8 @@ Rails::Initializer.run do |config|
|
||||
# config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
|
||||
# config.gem "sqlite3-ruby", :lib => "sqlite3"
|
||||
# config.gem "aws-s3", :lib => "aws/s3"
|
||||
config.gem "exifr"
|
||||
config.gem "will_paginate"
|
||||
|
||||
# Only load the plugins named here, in the order given (default is alphabetical).
|
||||
# :all can be used as a placeholder for all plugins not explicitly named
|
||||
|
||||
26
config/initializers/typus.rb
Normal file
@ -0,0 +1,26 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# System wide options
|
||||
|
||||
Typus::Configuration.options[:app_name] = 'photos'
|
||||
# Typus::Configuration.options[:email] = 'admin@example.com'
|
||||
# Typus::Configuration.options[:file_preview] = :typus_preview
|
||||
# Typus::Configuration.options[:file_thumbnail] = :typus_thumbnail
|
||||
# Typus::Configuration.options[:relationship] = 'typus_users'
|
||||
# Typus::Configuration.options[:root] = 'admin'
|
||||
Typus::Configuration.options[:user_class_name] = 'TypusUser'
|
||||
Typus::Configuration.options[:user_fk] = 'typus_user_id'
|
||||
|
||||
# Model options which can also be defined by model on the yaml files.
|
||||
|
||||
# Typus::Configuration.options[:default_action_on_item] = 'edit'
|
||||
# Typus::Configuration.options[:end_year] = Time.now.year + 1
|
||||
# Typus::Configuration.options[:form_rows] = 15
|
||||
# Typus::Configuration.options[:index_after_save] = true
|
||||
# Typus::Configuration.options[:minute_step] = 5
|
||||
# Typus::Configuration.options[:nil] = 'nil'
|
||||
# Typus::Configuration.options[:on_header] = false
|
||||
# Typus::Configuration.options[:only_user_items] = false
|
||||
# Typus::Configuration.options[:per_page] = 15
|
||||
# Typus::Configuration.options[:sidebar_selector] = 5
|
||||
# Typus::Configuration.options[:start_year] = Time.now.year - 10
|
||||
@ -1,4 +1,5 @@
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
Typus::Routes.draw(map)
|
||||
# The priority is based upon order of creation: first created -> highest priority.
|
||||
|
||||
# Sample of regular route:
|
||||
|
||||
71
config/typus/README
Normal file
@ -0,0 +1,71 @@
|
||||
# Models
|
||||
|
||||
This is an example of a **Typus** enabled model with all available
|
||||
options. You can use this example to customize your YAML files which
|
||||
only have set the most common settings.
|
||||
|
||||
Post:
|
||||
fields:
|
||||
list: id, title, category_id, created_at, is_published?
|
||||
form: title, body, is_published?, created_at
|
||||
show: title, category, is_published?
|
||||
relationship: title, status
|
||||
options:
|
||||
auto_generated:
|
||||
booleans:
|
||||
is_published: ["Yes, it is", "No, it isn't"]
|
||||
date_formats:
|
||||
created_at: post_long
|
||||
selectors:
|
||||
read_only:
|
||||
filter_by_date_range: valid_until
|
||||
templates:
|
||||
body: rich_text
|
||||
actions:
|
||||
index: cleanup
|
||||
edit: send_as_newsletter
|
||||
show: rebuild
|
||||
export: csv, xml, pdf
|
||||
order_by: created_at
|
||||
relationships:
|
||||
filters: is_published?, created_at, category_id
|
||||
search: title, body
|
||||
application: Application
|
||||
description: Some text to describe the model
|
||||
options:
|
||||
default_action_on_item: show
|
||||
end_year: 2015
|
||||
form_rows: 25
|
||||
index_after_save: false
|
||||
minute_step: 15
|
||||
nil: 'nil'
|
||||
on_header: true
|
||||
only_user_items: true
|
||||
per_page: 5
|
||||
sidebar_selector: 5
|
||||
start_year: 1990
|
||||
|
||||
Note: To define namespace models use :: as a separator. (i.e. Delayed::Job)
|
||||
|
||||
# Roles
|
||||
|
||||
In this file you can configure the actions available for each of
|
||||
your models on the application. You can also use the 'all' shortcut
|
||||
to allow the user the access to all actions.
|
||||
|
||||
admin:
|
||||
Post: create, read, update, delete
|
||||
Category: create, read, update, delete
|
||||
TypusUser: all
|
||||
|
||||
editor:
|
||||
Post: create, read, update
|
||||
Category: read, update
|
||||
|
||||
You can also define `resources` which are not related to a model,
|
||||
for example to control MemCached or see the Starling queue
|
||||
statistics.
|
||||
|
||||
admin:
|
||||
Starling: index
|
||||
MemCached: index, cleanup
|
||||
26
config/typus/application.yml
Normal file
@ -0,0 +1,26 @@
|
||||
# Typus Models Configuration File
|
||||
#
|
||||
# Use the README file as a reference to customize settings.
|
||||
|
||||
Category:
|
||||
fields:
|
||||
default: name, photo_id, base_colour, sort
|
||||
list: name, photo_id, base_colour, sort
|
||||
form: name, description, photo_id, base_colour, sort
|
||||
order_by:
|
||||
relationships: photos
|
||||
filters:
|
||||
search: name
|
||||
application: photos
|
||||
|
||||
Photo:
|
||||
fields:
|
||||
default: photo_file_name, photo_content_type, photo_file_size, photo_updated_at, title, sort
|
||||
list: photo_file_name, categories, photo_content_type, photo_file_size, photo_updated_at, title, sort
|
||||
form: photo, flickr_url, title, description, sort
|
||||
order_by:
|
||||
relationships: categories
|
||||
filters:
|
||||
search: title
|
||||
application: photos
|
||||
|
||||
7
config/typus/application_roles.yml
Normal file
@ -0,0 +1,7 @@
|
||||
# Typus Roles Configuration File
|
||||
#
|
||||
# Use the README file as a reference to customize settings.
|
||||
|
||||
admin:
|
||||
Category: create, read, update, delete
|
||||
Photo: create, read, update, delete
|
||||
17
config/typus/typus.yml
Normal file
@ -0,0 +1,17 @@
|
||||
# Typus Models Configuration File
|
||||
#
|
||||
# Use the README file as a reference to customize settings.
|
||||
|
||||
TypusUser:
|
||||
fields:
|
||||
default: first_name, last_name, email, role, status
|
||||
list: email, role, status
|
||||
form: first_name, last_name, role, email, password, password_confirmation, language
|
||||
options:
|
||||
selectors: role, language
|
||||
booleans:
|
||||
status: Active, Inactive
|
||||
filters: status, role
|
||||
search: first_name, last_name, email, role
|
||||
application: Admin Panel
|
||||
description: Admin Panel Users Administration
|
||||
6
config/typus/typus_roles.yml
Normal file
@ -0,0 +1,6 @@
|
||||
# Typus Roles Configuration File
|
||||
#
|
||||
# Use the README file as a reference to customize settings.
|
||||
|
||||
admin:
|
||||
TypusUser: all
|
||||
14
db/migrate/20101008172319_move_to_many_to_many.rb
Normal file
@ -0,0 +1,14 @@
|
||||
class MoveToManyToMany < ActiveRecord::Migration
|
||||
def self.up
|
||||
remove_column :photos, :category_id
|
||||
create_table :categories_photos, :id => false do |t|
|
||||
t.integer :category_id
|
||||
t.integer :photo_id
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
add_column :photos, :category_id, :integer
|
||||
drop_table :categories_photos
|
||||
end
|
||||
end
|
||||
22
db/migrate/20101008175640_create_typus_users.rb
Normal file
@ -0,0 +1,22 @@
|
||||
class CreateTypusUsers < ActiveRecord::Migration
|
||||
|
||||
def self.up
|
||||
create_table :typus_users do |t|
|
||||
t.string :first_name, :default => "", :null => false
|
||||
t.string :last_name, :default => "", :null => false
|
||||
t.string :role, :null => false
|
||||
t.string :email, :null => false
|
||||
t.boolean :status, :default => false
|
||||
t.string :token, :null => false
|
||||
t.string :salt, :null => false
|
||||
t.string :crypted_password, :null => false
|
||||
t.string :preferences
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :typus_users
|
||||
end
|
||||
|
||||
end
|
||||
22
db/schema.rb
@ -9,7 +9,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20101008122736) do
|
||||
ActiveRecord::Schema.define(:version => 20101008175640) do
|
||||
|
||||
create_table "categories", :force => true do |t|
|
||||
t.string "name"
|
||||
@ -21,8 +21,12 @@ ActiveRecord::Schema.define(:version => 20101008122736) do
|
||||
t.integer "sort"
|
||||
end
|
||||
|
||||
create_table "categories_photos", :id => false, :force => true do |t|
|
||||
t.integer "category_id"
|
||||
t.integer "photo_id"
|
||||
end
|
||||
|
||||
create_table "photos", :force => true do |t|
|
||||
t.integer "category_id"
|
||||
t.string "flickr_url"
|
||||
t.string "photo_file_name"
|
||||
t.string "photo_content_type"
|
||||
@ -35,4 +39,18 @@ ActiveRecord::Schema.define(:version => 20101008122736) do
|
||||
t.integer "sort"
|
||||
end
|
||||
|
||||
create_table "typus_users", :force => true do |t|
|
||||
t.string "first_name", :default => "", :null => false
|
||||
t.string "last_name", :default => "", :null => false
|
||||
t.string "role", :null => false
|
||||
t.string "email", :null => false
|
||||
t.boolean "status", :default => false
|
||||
t.string "token", :null => false
|
||||
t.string "salt", :null => false
|
||||
t.string "crypted_password", :null => false
|
||||
t.string "preferences"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
10746
log/development.log
BIN
public/images/admin/fancybox/blank.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
public/images/admin/fancybox/fancy_close.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/admin/fancybox/fancy_loading.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/images/admin/fancybox/fancy_nav_left.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/admin/fancybox/fancy_nav_right.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/admin/fancybox/fancy_shadow_e.png
Normal file
|
After Width: | Height: | Size: 107 B |
BIN
public/images/admin/fancybox/fancy_shadow_n.png
Normal file
|
After Width: | Height: | Size: 106 B |
BIN
public/images/admin/fancybox/fancy_shadow_ne.png
Normal file
|
After Width: | Height: | Size: 347 B |
BIN
public/images/admin/fancybox/fancy_shadow_nw.png
Normal file
|
After Width: | Height: | Size: 324 B |
BIN
public/images/admin/fancybox/fancy_shadow_s.png
Normal file
|
After Width: | Height: | Size: 111 B |
BIN
public/images/admin/fancybox/fancy_shadow_se.png
Normal file
|
After Width: | Height: | Size: 352 B |
BIN
public/images/admin/fancybox/fancy_shadow_sw.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
public/images/admin/fancybox/fancy_shadow_w.png
Normal file
|
After Width: | Height: | Size: 103 B |
BIN
public/images/admin/fancybox/fancy_title_left.png
Normal file
|
After Width: | Height: | Size: 503 B |
BIN
public/images/admin/fancybox/fancy_title_main.png
Normal file
|
After Width: | Height: | Size: 96 B |
BIN
public/images/admin/fancybox/fancy_title_over.png
Normal file
|
After Width: | Height: | Size: 70 B |
BIN
public/images/admin/fancybox/fancy_title_right.png
Normal file
|
After Width: | Height: | Size: 506 B |
BIN
public/images/admin/ui-icons.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
2
public/javascripts/admin/application.js
Normal file
@ -0,0 +1,2 @@
|
||||
// Place your application-specific JavaScript functions and classes for
|
||||
// Typus here.
|
||||
152
public/javascripts/admin/jquery-1.4.1.min.js
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v1.4.1
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* http://sizzlejs.com/
|
||||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date: Mon Jan 25 19:43:33 2010 -0500
|
||||
*/
|
||||
(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j?
|
||||
e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f,
|
||||
a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType===
|
||||
11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment();
|
||||
c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent,
|
||||
va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]],
|
||||
[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,
|
||||
this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this,
|
||||
a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};
|
||||
c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$=
|
||||
Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload",
|
||||
c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;
|
||||
return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]||
|
||||
r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=
|
||||
a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==
|
||||
v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},
|
||||
uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded",
|
||||
L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support=
|
||||
{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};
|
||||
b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild);
|
||||
c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props=
|
||||
{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true,
|
||||
{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,
|
||||
a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);
|
||||
return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||
|
||||
a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=
|
||||
c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca),
|
||||
d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o=
|
||||
a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||
|
||||
{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val());
|
||||
if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d);
|
||||
f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=
|
||||
""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=
|
||||
function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a,
|
||||
d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+
|
||||
s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a,
|
||||
"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,
|
||||
b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b,
|
||||
d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
||||
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
|
||||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b=
|
||||
0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};
|
||||
c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b=
|
||||
a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!==
|
||||
"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,
|
||||
"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"||
|
||||
d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a=
|
||||
a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,
|
||||
f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,
|
||||
b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+
|
||||
a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector,
|
||||
live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
|
||||
(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===
|
||||
k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||
|
||||
typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u=
|
||||
l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&
|
||||
y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q,
|
||||
h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da=
|
||||
l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
|
||||
TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length,
|
||||
p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=
|
||||
h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}},
|
||||
TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&
|
||||
"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);
|
||||
return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===
|
||||
g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2===
|
||||
0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+
|
||||
q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>=
|
||||
0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="?
|
||||
k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};
|
||||
try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===
|
||||
h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,
|
||||
l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id");
|
||||
return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href",
|
||||
2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===
|
||||
0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[],
|
||||
l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,
|
||||
function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=
|
||||
0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>
|
||||
-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),
|
||||
a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},
|
||||
nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):
|
||||
e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==
|
||||
b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],
|
||||
col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)},
|
||||
wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?
|
||||
d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,
|
||||
false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&
|
||||
!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)||
|
||||
["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,
|
||||
b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j===
|
||||
"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n,
|
||||
Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&&
|
||||
this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j===
|
||||
"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild);
|
||||
j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i,
|
||||
Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})};
|
||||
c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a,
|
||||
b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&
|
||||
a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=
|
||||
a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb=
|
||||
J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=
|
||||
c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&
|
||||
(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,
|
||||
b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}:
|
||||
function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}
|
||||
function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||
|
||||
N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&
|
||||
c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&&
|
||||
A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",
|
||||
e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)?
|
||||
"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e,
|
||||
w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=
|
||||
f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n,
|
||||
function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/,
|
||||
W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
|
||||
ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
|
||||
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"),
|
||||
o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a);
|
||||
else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",
|
||||
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
|
||||
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
|
||||
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
|
||||
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
|
||||
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
|
||||
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
|
||||
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
|
||||
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
|
||||
b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)||
|
||||
0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"),
|
||||
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
|
||||
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
|
||||
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
|
||||
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
|
||||
this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
|
||||
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||
|
||||
e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window);
|
||||
43
public/javascripts/admin/jquery.fancybox-1.3.0.pack.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* FancyBox - jQuery Plugin
|
||||
* Simple and fancy lightbox alternative
|
||||
*
|
||||
* Copyright (c) 20010 Janis Skarnelis
|
||||
* Examples and documentation at: http://fancybox.net
|
||||
*
|
||||
* Version: 1.3.0 (02/02/2010)
|
||||
* Requires: jQuery v1.3+
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
;(function(b){function H(){v.hide();r.onerror=r.onload=null;F&&F.abort();l.empty()}function Q(){b.fancybox('<p id="fancybox_error">The requested content cannot be loaded.<br />Please try again later.</p>',{scrolling:"no",padding:20,transitionIn:"none",transitionOut:"none"})}function B(){H();var a=q[s];e=b.extend({},b.fn.fancybox.defaults,typeof b(a).data("fancybox")=="undefined"?e:b(a).data("fancybox"));var d,f,o=a.title||b(a).title||e.title||"";if(a.nodeName&&!e.orig)e.orig=b(a).children("img:first").length?
|
||||
b(a).children("img:first"):b(a);if(o==""&&e.orig)o=e.orig.attr("alt");d=a.nodeName&&/^(?:javascript|#)/i.test(a.href)?e.href||null:e.href||a.href||null;if(e.type){f=e.type;if(!d)d=e.content}else if(e.content)f="html";else if(d)if(d.match(I))f="image";else if(d.match(T))f="swf";else if(b(a).hasClass("iframe"))f="iframe";else if(d.match(/#/)){a=d.substr(d.indexOf("#"));f=b(a).length>0?"inline":"ajax"}else f="ajax";else f="inline";e.type=f;e.href=d;e.title=o;if(e.autoDimensions&&e.type!=="iframe"&&e.type!==
|
||||
"swf"){e.width="auto";e.height="auto"}if(e.modal){e.overlayShow=true;e.hideOnOverlayClick=false;e.hideOnContentClick=false;e.enableEscapeButton=false;e.showCloseButton=false}if(b.isFunction(e.onStart))if(e.onStart(q,s,e)===false){h=false;return}l.css("padding",t+e.padding+e.margin);b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){b(this).replaceWith(i.children())});switch(f){case "html":l.html(e.content);G();break;case "inline":b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a)).bind("fancybox-cleanup",
|
||||
function(){b(this).replaceWith(i.children())}).bind("fancybox-cancel",function(){b(this).replaceWith(l.children())});b(a).appendTo(l);G();break;case "image":h=false;b.fancybox.showActivity();r=new Image;r.onerror=function(){Q()};r.onload=function(){r.onerror=null;r.onload=null;U()};r.src=d;break;case "swf":var u="",w="";u+='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+d+'"></param>';b.each(e.swf,function(p,R){u+=
|
||||
'<param name="'+p+'" value="'+R+'"></param>';w+=" "+p+'="'+R+'"'});u+='<embed src="'+d+'" type="application/x-shockwave-flash" width="'+e.width+'" height="'+e.height+'"'+w+"></embed></object>";l.html(u);G();break;case "ajax":a=d.split("#",2);f=e.ajax.data||{};if(a.length>1){d=a[0];typeof f=="string"?(f+="&selector="+a[1]):(f.selector=a[1])}h=false;b.fancybox.showActivity();F=b.ajax(b.extend(e.ajax,{url:d,data:f,error:Q,success:function(p){if(F.status==200){l.html(p);G()}}}));break;case "iframe":b('<iframe id="fancybox-frame" name="fancybox-frame'+
|
||||
(new Date).getTime()+'" frameborder="0" hspace="0" scrolling="'+e.scrolling+'" src="'+e.href+'"></iframe>').appendTo(l);J();break}}function U(){h=true;e.width=r.width;e.height=r.height;b("<img />").attr({id:"fancybox-img",src:r.src,alt:e.title}).appendTo(l);J()}function G(){l.width(e.width);l.height(e.height);if(e.width=="auto")e.width=l.width();if(e.height=="auto")e.height=l.height();J()}function J(){v.hide();if(g.is(":visible")&&b.isFunction(c.onCleanup))if(c.onCleanup(j,n,c)===false){b.event.trigger("fancybox-cancel");
|
||||
h=false;return}j=q;n=s;c=e;i.get(0).scrollTop=0;i.get(0).scrollLeft=0;if(c.overlayShow){K&&b("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"});y.css({"background-color":c.overlayColor,opacity:c.overlayOpacity}).unbind().show()}m=V();W();if(g.is(":visible")){b(z.add(C).add(D)).hide();var a=g.position();k={top:a.top,left:a.left,width:g.width(),height:g.height()};
|
||||
var d=k.width==m.width&&k.height==m.height;i.fadeOut(c.changeFade,function(){function f(){i.html(l.contents()).fadeIn(c.changeFade,L)}b.event.trigger("fancybox-change");i.css({top:c.padding,left:c.padding,width:Math.max(k.width-c.padding*2,1),height:Math.max(k.height-c.padding*2,1)}).empty().css("overflow","hidden");A.prop=0;b(A).animate({prop:1},{duration:d?0:c.changeSpeed,easing:c.easingChange,step:M,complete:f})})}else{g.css("opacity",1);if(c.transitionIn=="elastic"){k=S();i.css({top:c.padding,
|
||||
left:c.padding,width:Math.max(k.width-c.padding*2,1),height:Math.max(k.height-c.padding*2,1)}).html(l.contents());g.css(k).show();if(c.opacity)m.opacity=0;A.prop=0;b(A).animate({prop:1},{duration:c.speedIn,easing:c.easingIn,step:M,complete:L})}else{i.css({top:c.padding,left:c.padding,width:Math.max(m.width-c.padding*2,1),height:Math.max(m.height-c.padding*2-x,1)}).html(l.contents());g.css(m).fadeIn(c.transitionIn=="none"?0:c.speedIn,L)}}}function M(a){var d=Math.round(k.width+(m.width-k.width)*a),
|
||||
f=Math.round(k.height+(m.height-k.height)*a),o=Math.round(k.top+(m.top-k.top)*a),u=Math.round(k.left+(m.left-k.left)*a);g.css({width:d+"px",height:f+"px",top:o+"px",left:u+"px"});d=Math.max(d-c.padding*2,0);f=Math.max(f-(c.padding*2+x*a),0);i.css({width:d+"px",height:f+"px"});if(typeof m.opacity!=="undefined")g.css("opacity",a<0.5?0.5:a)}function L(){i.css("overflow",overflow=c.scrolling=="auto"?c.type=="image"||c.type=="iframe"||c.type=="swf"?"hidden":"auto":c.scrolling=="yes"?"auto":"visible");
|
||||
if(!b.support.opacity){i.get(0).style.removeAttribute("filter");g.get(0).style.removeAttribute("filter")}b("#fancybox-title").show();c.hideOnContentClick&&i.one("click",b.fancybox.close);c.hideOnOverlayClick&&y.one("click",b.fancybox.close);c.showCloseButton&&z.show();X();b(window).bind("resize.fb",b.fancybox.center);c.centerOnScroll?b(window).bind("scroll.fb",b.fancybox.center):b(window).unbind("scroll.fb");b.isFunction(c.onComplete)&&c.onComplete(j,n,c);h=false;Y()}function V(){var a=N(),d={},f=
|
||||
c.margin,o=c.autoScale,u=(t+f)*2,w=(t+f)*2,p=c.padding*2;if(c.width.toString().indexOf("%")>-1){d.width=a[0]*parseFloat(c.width)/100-t*2;o=false}else d.width=c.width+p;if(c.height.toString().indexOf("%")>-1){d.height=a[1]*parseFloat(c.height)/100-t*2;o=false}else d.height=c.height+p;if(o&&(d.width>a[0]-u||d.height>a[1]-w))if(e.type=="image"||e.type=="swf"){u+=p;w+=p;o=Math.min(Math.min(a[0]-u,c.width)/c.width,Math.min(a[1]-w,c.height)/c.height);d.width=Math.round(o*(d.width-p))+p;d.height=Math.round(o*
|
||||
(d.height-p))+p}else{d.width=Math.min(d.width,a[0]-u);d.height=Math.min(d.height,a[1]-w)}d.top=a[3]+(a[1]-(d.height+t*2))*0.5;d.left=a[2]+(a[0]-(d.width+t*2))*0.5;if(c.autoScale==false){d.top=Math.max(a[3]+f,d.top);d.left=Math.max(a[2]+f,d.left)}return d}function S(){var a=e.orig?b(e.orig):false,d={};if(a&&a.length){a=Z(a);d={width:a.width+c.padding*2,height:a.height+c.padding*2,top:a.top-c.padding-t,left:a.left-c.padding-t}}else{a=N();d={width:1,height:1,top:a[3]+a[1]*0.5,left:a[2]+a[0]*0.5}}return d}
|
||||
function X(){b(document).unbind("keydown.fb").bind("keydown.fb",function(a){if(a.keyCode==27&&c.enableEscapeButton){a.preventDefault();b.fancybox.close()}else if(a.keyCode==37){a.preventDefault();b.fancybox.prev()}else if(a.keyCode==39){a.preventDefault();b.fancybox.next()}});if(b.fn.mousewheel){g.unbind("mousewheel.fb");j.length>1&&g.bind("mousewheel.fb",function(a,d){a.preventDefault();h||d==0||(d>0?b.fancybox.prev():b.fancybox.next())})}if(c.showNavArrows){if(c.cyclic&&j.length>1||n!=0)C.show();
|
||||
if(c.cyclic&&j.length>1||n!=j.length-1)D.show()}}function Y(){if(j.length-1>n){var a=j[n+1].href;if(typeof a!=="undefined"&&a.match(I)){var d=new Image;d.src=a}}if(n>0){a=j[n-1].href;if(typeof a!=="undefined"&&a.match(I)){d=new Image;d.src=a}}}function $(){if(v.is(":visible")){b("div",v).css("top",O*-40+"px");O=(O+1)%12}else clearInterval(P)}function N(){return[b(window).width(),b(window).height(),b(document).scrollLeft(),b(document).scrollTop()]}function Z(a){var d=a.offset();d.top+=parseFloat(a.css("paddingTop"))||
|
||||
0;d.left+=parseFloat(a.css("paddingLeft"))||0;d.top+=parseFloat(a.css("border-top-width"))||0;d.left+=parseFloat(a.css("border-left-width"))||0;d.width=a.width();d.height=a.height();return d}function W(){b("#fancybox-title").remove();x=0;if(c.titleShow!=false){var a=c.title;a=b.isFunction(c.titleFormat)?c.titleFormat(a,j,n,c):aa(a);if(!(!a||a=="")){var d=m.width-c.padding*2;b('<div id="fancybox-title" class="'+("fancybox-title-"+c.titlePosition)+'" />').css({width:d,paddingLeft:c.padding,paddingRight:c.padding}).html(a).appendTo("body");
|
||||
switch(c.titlePosition){case "inside":x=b("#fancybox-title").outerHeight(true)-c.padding;m.height+=x;break;case "over":b("#fancybox-title").css("bottom",c.padding);break;default:b("#fancybox-title").css("bottom",b("#fancybox-title").outerHeight(true)*-1);break}b("#fancybox-title").appendTo(E).hide();K&&b("#fancybox-title span").fixPNG()}}}function aa(a){if(a&&a.length)switch(c.titlePosition){case "inside":return a;case "over":return'<span id="fancybox-title-over">'+a+"</span>";default:return'<span id="fancybox-title-wrap"><span id="fancybox-title-left"></span><span id="fancybox-title-main">'+
|
||||
a+'</span><span id="fancybox-title-right"></span></span>'}return false}function ba(){if(!b("#fancybox-wrap").length){b("body").append(l=b('<div id="fancybox-tmp"></div>'),v=b('<div id="fancybox-loading"><div></div></div>'),y=b('<div id="fancybox-overlay"></div>'),g=b('<div id="fancybox-wrap"></div>'));E=b('<div id="fancybox-outer"></div>').append('<div class="fancy-bg" id="fancy-bg-n"></div><div class="fancy-bg" id="fancy-bg-ne"></div><div class="fancy-bg" id="fancy-bg-e"></div><div class="fancy-bg" id="fancy-bg-se"></div><div class="fancy-bg" id="fancy-bg-s"></div><div class="fancy-bg" id="fancy-bg-sw"></div><div class="fancy-bg" id="fancy-bg-w"></div><div class="fancy-bg" id="fancy-bg-nw"></div>').appendTo(g);
|
||||
E.append(i=b('<div id="fancybox-inner"></div>'),z=b('<a id="fancybox-close"></a>'),C=b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),D=b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));z.click(b.fancybox.close);v.click(b.fancybox.cancel);C.click(function(a){a.preventDefault();b.fancybox.prev()});D.click(function(a){a.preventDefault();b.fancybox.next()});b.support.opacity||E.find(".fancy-bg").fixPNG();
|
||||
if(K){b(z.add(".fancy-ico").add("div",v)).fixPNG();y.get(0).style.setExpression("height","document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'");v.get(0).style.setExpression("top","(-20 + (document.documentElement.clientHeight ? document.documentElement.clientHeight/2 : document.body.clientHeight/2 ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop )) + 'px'");E.prepend('<iframe id="fancybox-hide-sel-frame" src="javascript:\'\';" scrolling="no" frameborder="0" ></iframe>')}}}
|
||||
var l,v,y,g,E,i,z,C,D,s=0,e={},q=[],n=0,c={},j=[],F=null,r=new Image,I=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,T=/[^\.]\.(swf)\s*$/i,P,O=1,k,m,h=false,t=20,A=b.extend(b("<div/>")[0],{prop:0}),x=0,K=!b.support.opacity&&!window.XMLHttpRequest;b.fn.fixPNG=function(){return this.each(function(){var a=b(this).css("backgroundImage");if(a.match(/^url\(["']?(.*\.png)["']?\)$/i)){a=RegExp.$1;b(this).css({backgroundImage:"none",filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod="+
|
||||
(b(this).css("backgroundRepeat")=="no-repeat"?"crop":"scale")+", src='"+a+"')"}).each(function(){var d=b(this).css("position");d!="absolute"&&d!="relative"&&b(this).css("position","relative")}).css("zoom",1)}})};b.fn.fancybox=function(a){b(this).data("fancybox",b.extend({},a));b(this).unbind("click.fb").bind("click.fb",function(d){d.preventDefault();if(!h){h=true;b(this).blur();q=[];s=0;d=b(this).attr("rel")||"";if(!d||d==""||d==="nofollow")q.push(this);else{q=b("a[rel="+d+"], area[rel="+d+"]");s=
|
||||
q.index(this)}B();return false}});return this};b.fancybox=function(a,d){if(!h){h=true;q=[];s=0;if(b.isArray(a)){for(var f=0,o=a.length;f<o;f++)if(typeof a[f]=="object")b(a[f]).data("fancybox",b.extend({},d,a[f]));else a[f]=b({}).data("fancybox",b.extend({content:a[f]},d));q=jQuery.merge(q,a)}else{if(typeof a=="object")b(a).data("fancybox",b.extend({},d,a));else a=b({}).data("fancybox",b.extend({content:a},d));q.push(a)}B()}};b.fancybox.showActivity=function(){clearInterval(P);v.show();P=setInterval($,
|
||||
66)};b.fancybox.hideActivity=function(){v.hide()};b.fancybox.next=function(){return b.fancybox.pos(n+1)};b.fancybox.prev=function(){return b.fancybox.pos(n-1)};b.fancybox.pos=function(a){if(!h){a=parseInt(a);if(a>-1&&j.length>a){s=a;B()}if(c.cyclic&&j.length>1&&a<0){s=j.length-1;B()}if(c.cyclic&&j.length>1&&a>=j.length){s=0;B()}}};b.fancybox.cancel=function(){if(!h){h=true;b.event.trigger("fancybox-cancel");H();e&&b.isFunction(e.onCancel)&&e.onCancel(q,s,e);h=false}};b.fancybox.close=function(){function a(){y.fadeOut("fast");
|
||||
g.hide();b.event.trigger("fancybox-cleanup");i.empty();b.isFunction(c.onClosed)&&c.onClosed(j,n,c);j=e=[];n=s=0;c=e={};h=false}if(!(h||g.is(":hidden"))){h=true;if(c&&b.isFunction(c.onCleanup))if(c.onCleanup(j,n,c)===false){h=false;return}H();b(z.add(C).add(D)).hide();b("#fancybox-title").remove();g.add(i).add(y).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");i.css("overflow","hidden");if(c.transitionOut=="elastic"){k=S();var d=g.position();m={top:d.top,left:d.left,
|
||||
width:g.width(),height:g.height()};if(c.opacity)m.opacity=1;A.prop=1;b(A).animate({prop:0},{duration:c.speedOut,easing:c.easingOut,step:M,complete:a})}else g.fadeOut(c.transitionOut=="none"?0:c.speedOut,a)}};b.fancybox.resize=function(){if(!(h||g.is(":hidden"))){h=true;var a=i.wrapInner("<div style='overflow:auto'></div>").children(),d=a.height();g.css({height:d+c.padding*2+x});i.css({height:d});a.replaceWith(a.children());b.fancybox.center()}};b.fancybox.center=function(){h=true;var a=N(),d=c.margin,
|
||||
f={};f.top=a[3]+(a[1]-(g.height()-x+t*2))*0.5;f.left=a[2]+(a[0]-(g.width()+t*2))*0.5;f.top=Math.max(a[3]+d,f.top);f.left=Math.max(a[2]+d,f.left);g.css(f);h=false};b.fn.fancybox.defaults={padding:10,margin:20,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.3,overlayColor:"#666",titleShow:true,titlePosition:"outside",
|
||||
titleFormat:null,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,onStart:null,onCancel:null,onComplete:null,onCleanup:null,onClosed:null};b(document).ready(function(){ba()})})(jQuery);
|
||||
333
public/stylesheets/admin/jquery.fancybox-1.3.0.css
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* FancyBox - jQuery Plugin
|
||||
* Simple and fancy lightbox alternative
|
||||
*
|
||||
* Copyright (c) 20010 Janis Skarnelis
|
||||
* Examples and documentation at: http://fancybox.net
|
||||
*
|
||||
* Version: 1.3.0 (02/02/2010)
|
||||
* Requires: jQuery v1.3+
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
#fancybox-loading {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
margin-top: -20px;
|
||||
margin-left: -20px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
z-index: 1104;
|
||||
display: none;
|
||||
}
|
||||
|
||||
* html #fancybox-loading { /* IE6 */
|
||||
position: absolute;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#fancybox-loading div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 40px;
|
||||
height: 480px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_loading.png") no-repeat;
|
||||
}
|
||||
|
||||
#fancybox-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: #000;
|
||||
z-index: 1100;
|
||||
display: none;
|
||||
}
|
||||
|
||||
* html #fancybox-overlay { /* IE6 */
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#fancybox-tmp {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
overflow: auto;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox-wrap {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
z-index: 1101;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox-outer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
#fancybox-inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#fancybox-hide-sel-frame {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#fancybox-close {
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
right: -15px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url("../../images/admin/fancybox/fancy_close.png") top left no-repeat;
|
||||
cursor: pointer;
|
||||
z-index: 1103;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox_error {
|
||||
color: #444;
|
||||
font: normal 12px/20px Arial;
|
||||
}
|
||||
|
||||
#fancybox-content {
|
||||
height: auto;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#fancybox-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
line-height: 0;
|
||||
vertical-align: top;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
#fancybox-frame {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fancybox-title {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
font-family: Arial;
|
||||
font-size: 12px;
|
||||
z-index: 1102;
|
||||
}
|
||||
|
||||
.fancybox-title-inside {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.fancybox-title-outside {
|
||||
padding-top: 5px;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fancybox-title-over {
|
||||
color: #FFF;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#fancybox-title-over {
|
||||
padding: 10px;
|
||||
background: url("../../images/admin/fancybox/fancy_title_over.png");
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fancybox-title-wrap {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#fancybox-title-wrap span {
|
||||
height: 32px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#fancybox-title-left {
|
||||
padding-left: 15px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_title_left.png") repeat-x;
|
||||
}
|
||||
|
||||
#fancybox-title-main {
|
||||
font-weight: bold;
|
||||
line-height: 29px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_title_main.png") repeat-x;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#fancybox-title-right {
|
||||
padding-left: 15px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_title_right.png") repeat-x;
|
||||
}
|
||||
|
||||
#fancybox-left, #fancybox-right {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
height: 100%;
|
||||
width: 35%;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
background-image: url("../../images/admin/fancybox/blank.gif");
|
||||
z-index: 1102;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fancybox-left {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
#fancybox-right {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
#fancybox-left-ico, #fancybox-right-ico {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -9999px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-top: -15px;
|
||||
cursor: pointer;
|
||||
z-index: 1102;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fancybox-left-ico {
|
||||
background: transparent url("../../images/admin/fancybox/fancy_nav_left.png") no-repeat;
|
||||
}
|
||||
|
||||
#fancybox-right-ico {
|
||||
background: transparent url("../../images/admin/fancybox/fancy_nav_right.png") no-repeat;
|
||||
}
|
||||
|
||||
#fancybox-left:hover, #fancybox-right:hover {
|
||||
visibility: visible; /* IE6 */
|
||||
}
|
||||
|
||||
#fancybox-left:hover span {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
#fancybox-right:hover span {
|
||||
left: auto;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
div.fancy-bg {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
div#fancy-bg-n {
|
||||
top: -20px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_n.png") repeat-x;
|
||||
}
|
||||
|
||||
div#fancy-bg-ne {
|
||||
top: -20px;
|
||||
right: -20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_ne.png") no-repeat;
|
||||
}
|
||||
|
||||
div#fancy-bg-e {
|
||||
top: 0;
|
||||
right: -20px;
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_e.png") repeat-y;
|
||||
}
|
||||
|
||||
div#fancy-bg-se {
|
||||
bottom: -20px;
|
||||
right: -20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_se.png") no-repeat;
|
||||
}
|
||||
|
||||
div#fancy-bg-s {
|
||||
bottom: -20px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_s.png") repeat-x;
|
||||
}
|
||||
|
||||
div#fancy-bg-sw {
|
||||
bottom: -20px;
|
||||
left: -20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_sw.png") no-repeat;
|
||||
}
|
||||
|
||||
div#fancy-bg-w {
|
||||
top: 0;
|
||||
left: -20px;
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_w.png") repeat-y;
|
||||
}
|
||||
|
||||
div#fancy-bg-nw {
|
||||
top: -20px;
|
||||
left: -20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: transparent url("../../images/admin/fancybox/fancy_shadow_nw.png") no-repeat;
|
||||
}
|
||||
68
public/stylesheets/admin/reset.css
Normal file
@ -0,0 +1,68 @@
|
||||
/* @group Structure Module */
|
||||
|
||||
body,html {margin:0;padding:0;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Text Module */
|
||||
|
||||
abbr,acronym,address,blockquote,br,cite,code,dfn,div,em,h1,h2,h3,h4,h5,h6,kbd,p,pre,q,samp,span,strong,var{font-style:normal;font-weight:normal;text-decoration:none;}
|
||||
blockquote,code,div,h1,h2,h3,h4,h5,h6,p,span,pre,hr{margin:0;padding:0;}
|
||||
h1,h2,h3,h4,h5,h6{font-size:100%;}
|
||||
b,i,em,strong,del,ins,u{font-weight:normal;font-style:normal;text-decoration:none;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Hypertext Module */
|
||||
|
||||
a{text-decoration:none;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group List Module */
|
||||
|
||||
dl,dt,dd,ol,ul,li{margin:0;padding:0;list-style:none;}
|
||||
dl,dt,dd,ol,ul,li{padding:0;margin:0;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Forms Module */
|
||||
|
||||
button,fieldset,form,input,label,legend,select,optgroup,option,textarea{margin:0;padding:0;}
|
||||
fieldset{border:0;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Basic Table Module */
|
||||
|
||||
caption,table,td,th,tr{margin:0;padding:0;font-weight:normal;text-align:left;}
|
||||
table{border-collapse:collapse;border-spacing:0;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Image Module */
|
||||
|
||||
img{border:0;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Object Module */
|
||||
|
||||
object,param{}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Presentation Module */
|
||||
|
||||
b,big,hr,i,small,sub,sup,tt{font-size:100%;}
|
||||
q:before,q:after{content:'';}
|
||||
sup {vertical-align:text-top;}
|
||||
sub {vertical-align:text-bottom;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Scripting Module */
|
||||
|
||||
noscript{}
|
||||
|
||||
/* @end */
|
||||
369
public/stylesheets/admin/screen.css
Normal file
@ -0,0 +1,369 @@
|
||||
/* @group Defaults */
|
||||
|
||||
html { background: #000; height: 100%; margin-bottom: 1px; }
|
||||
body { color: #000; font-family: "Lucida Grande", Helvetica, Arial, sans-serif; font-size: 75%; }
|
||||
label { display: block; font-weight: bold; margin-bottom: 5px; margin-top: 0px; }
|
||||
strong { font-weight: bold; }
|
||||
em { font-style: italic; }
|
||||
dl { margin: 14px 0 20px 0; }
|
||||
dt { font-weight: bold; margin: 0 0 5px 0; }
|
||||
dd { font-size: 18px; margin: 0 0 15px 0; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Links */
|
||||
|
||||
a,
|
||||
a:visited,
|
||||
a:link { color: #000; font-weight: normal; text-decoration: none; }
|
||||
a:hover { color: #333; text-decoration: underline; }
|
||||
a.on { color: #333; font-weight: bold; text-decoration: underline; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Wrappers */
|
||||
|
||||
#header_wrapper {
|
||||
background: #000;
|
||||
margin: 0 auto;
|
||||
padding: 0 10px;
|
||||
width: 940px;
|
||||
}
|
||||
|
||||
#wrapper { background: #FFF; }
|
||||
|
||||
#content_wrapper {
|
||||
background: #FFF;
|
||||
min-height: 400px;
|
||||
margin: 0 auto;
|
||||
padding: 0 10px;
|
||||
width: 940px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Header */
|
||||
|
||||
#header {
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
margin: 0 auto;
|
||||
padding: 1em 0;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
display: block;
|
||||
float: left;
|
||||
font-size: 2em;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
#header a { color: #FFF; }
|
||||
#header .left { float: left; }
|
||||
#header .right { float: right; margin-top: 1em; }
|
||||
#header .left ul { display: block; float: left; margin-top: 1em; }
|
||||
#header .left li, #header .right li { display: inline; padding-left: 0.5em; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Content */
|
||||
|
||||
#content { float: left; padding: 1.5em 0; width: 700px; }
|
||||
|
||||
#content h2 { font-size: 1.5em; font-weight: bold; margin: 0 0 0.5em 0; }
|
||||
#content h2 a { font-weight: bold; }
|
||||
#content h2 small { font-size: 0.75em; }
|
||||
#content h2 small a { color: #666; }
|
||||
#content h3 { font-size: 1.25em; font-weight: bold; margin: 1em 0; }
|
||||
#content h4 { margin: 1em 0; }
|
||||
#content ol { margin: 1em 2em; }
|
||||
#content ul { margin: 0 1.5em; }
|
||||
#content li { list-style: square; line-height: 20px; }
|
||||
#content ul li { list-style: square; }
|
||||
#content p { margin: 0 0 1em 0; }
|
||||
#content p a { text-decoration: underline; }
|
||||
#content p a:hover { color: #408BB6; }
|
||||
#content table.typus { background: #000; margin: 1em 0; }
|
||||
#content h2+table.typus { margin: 0; }
|
||||
|
||||
#content pre {
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
font-size: 1.25em;
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
#content blockquote {
|
||||
border-left: 1px solid #999;
|
||||
font-size: 1.25em;
|
||||
font-family: georgia;
|
||||
margin: 1em;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Sidebar */
|
||||
|
||||
#sidebar {
|
||||
float: left;
|
||||
margin-left: 20px;
|
||||
padding: 1.5em 0;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
#sidebar h2 { font-size: 1.5em; font-weight: bold; }
|
||||
#sidebar h3 { margin: 1em 0; }
|
||||
#sidebar p { margin: 1em 0; }
|
||||
#sidebar p a { text-decoration: underline; }
|
||||
#sidebar label { font-size: 15px; }
|
||||
#sidebar form { margin-bottom: 1.25em; }
|
||||
#sidebar ul { margin: 1em 0; }
|
||||
#sidebar code { color: green; font-size: 1.25em; }
|
||||
#sidebar small { font-size: 0.85em; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Footer */
|
||||
|
||||
#footer_wrapper { background: #000; }
|
||||
#footer { background: #000; margin: 0 auto; width: 940px; }
|
||||
#footer .left { float: left; }
|
||||
#footer .right { float: right; }
|
||||
#footer a { color: #FFF; font-weight: normal; text-decoration: underline; }
|
||||
#footer a:hover { color: #408BB6; }
|
||||
|
||||
#footer p {
|
||||
color: #FFF;
|
||||
font-size: 0.9em;
|
||||
line-height: 18px;
|
||||
padding: 1em 0;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Fieldsets */
|
||||
|
||||
fieldset { margin: 0; padding: 0; }
|
||||
fieldset ol { margin: 0!important; }
|
||||
fieldset ol li { list-style: none!important; margin: 1em 0!important; }
|
||||
fieldset small { font-size: 0.9em; font-weight: normal; }
|
||||
|
||||
fieldset.inputs { }
|
||||
|
||||
fieldset.inputs input[type='text'],
|
||||
fieldset.inputs input[type='password'] {
|
||||
border: 1px solid #999;
|
||||
font-size: 20px;
|
||||
padding: 5px;
|
||||
width: 691px;
|
||||
}
|
||||
|
||||
fieldset.inputs input[type='text']:focus,
|
||||
fieldset.inputs input[type='password']:focus, {
|
||||
background: #FFFCE1;
|
||||
}
|
||||
|
||||
fieldset.inputs textarea {
|
||||
border: 1px solid #999;
|
||||
font-family: "Courier";
|
||||
font-size: 14px;
|
||||
padding: 3px;
|
||||
width: 691px;
|
||||
}
|
||||
|
||||
fieldset.inputs select { border: 1px solid #999; font-size: 1.20em; }
|
||||
|
||||
fieldset.inputs textarea:focus { background: #FFFCE1; }
|
||||
fieldset.inputs label.inline_label { display: inline; }
|
||||
|
||||
fieldset.buttons { }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Content Tables */
|
||||
|
||||
#content table.typus { width: 100%; }
|
||||
#content table.typus small { font-size: 0.8em; }
|
||||
#content table.typus th { color: #FFF; font-weight: normal; padding: 4px; }
|
||||
#content table.typus th a { color: #FFF!important; }
|
||||
#content table.typus td.right { text-align: right; }
|
||||
#content table.typus tr.even { background: #FFF!important; }
|
||||
#content table.typus tr.even:hover,
|
||||
#content table.typus tr.odd:hover { background: #000!important; color: #FFF; }
|
||||
#content table.typus tr.even:hover a,
|
||||
#content table.typus tr.odd:hover a { color: #FFF!important; }
|
||||
#content table.typus tr.odd { background: #F5F5F5; }
|
||||
#content table.typus span.inactive { color: #888; }
|
||||
#content table.typus td { border: none; font-weight: normal; padding: 3px 4px; vertical-align: top; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Rails Errors */
|
||||
|
||||
.fieldWithErrors input { background: #FBE3E4; border: 1px solid #8A1F11!important; }
|
||||
|
||||
.errorExplanation {
|
||||
background: #FBE3E4;
|
||||
border: 2px solid #FBC2C4;
|
||||
color: #8a1f11;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.errorExplanation h3 { display: none; }
|
||||
.errorExplanation p { font-weight: bold; margin: 15px 0 10px 0!important; padding: 0 5px; }
|
||||
.errorExplanation ul { margin: 0 0 10px 25px!important; }
|
||||
.errorExplanation ul li { list-style: square!important; margin: 0!important; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Search Box */
|
||||
|
||||
input#search { border: 1px solid #999; font-size: 1.2em; padding: 3px; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Date search boxes */
|
||||
|
||||
input.date_input { border: 1px solid #999; margin-bottom: 1em;}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Login Page Dialog */
|
||||
|
||||
#bottom_dialog {
|
||||
color: #FFF;
|
||||
font-size: 0.9em;
|
||||
line-height: 18px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5em;
|
||||
text-align: center;
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
#bottom_dialog a { color: #FFF; font-weight: bold; }
|
||||
|
||||
#dialog {
|
||||
background: #FFF;
|
||||
border: 0.5em solid #408BB6;
|
||||
margin: 5em auto 1em auto;
|
||||
padding: 0 1.5em;
|
||||
width: 35em;
|
||||
}
|
||||
|
||||
#dialog h1 { font-size: 2em; font-weight: bold; margin: 0.5em 0; }
|
||||
#dialog h1 a { font-weight: bold; }
|
||||
#dialog h1 a:hover { color: #000; text-decoration: underline; }
|
||||
#dialog li { margin: 1em 0; }
|
||||
#dialog li a { display: inline; font-size: 11px; margin: 0.5em; }
|
||||
|
||||
#dialog input.text {
|
||||
border: 1px solid #999;
|
||||
font-size: 2em;
|
||||
padding: 0.25em;
|
||||
width: 16.75em;
|
||||
}
|
||||
|
||||
#dialog input.button { margin: 0.5em 0; }
|
||||
#dialog .errorExplanation ul { margin: 10px 0 10px 0!important; }
|
||||
#dialog .errorExplanation li { font-weight: bold; list-style: none!important; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Pagination */
|
||||
|
||||
.pagination {
|
||||
border-bottom: 1px solid #F5F5F5;
|
||||
border-top: 1px solid #F5F5F5;
|
||||
margin: 1.5em auto 0 auto;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pagination a {
|
||||
color: #333;
|
||||
margin: 2px;
|
||||
padding: 2px 3px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.pagination a:hover,
|
||||
.pagination a:active { background: #000; color: #FFF; }
|
||||
|
||||
.pagination span.current {
|
||||
background-color: #408BB6;
|
||||
color: #FFF;
|
||||
font-weight: bold;
|
||||
margin: 2px;
|
||||
padding: 2px 3px;
|
||||
}
|
||||
|
||||
.pagination span.disabled { color: #DDD; margin: 2px; padding: 2px 3px; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Success, notice and error boxes */
|
||||
|
||||
.error,
|
||||
.notice,
|
||||
.success { border: 1px solid #CCC; font-weight: bold; margin: 0 0 1em 0; }
|
||||
.error p,
|
||||
.notice p,
|
||||
.success p { font-weight: bold; margin: 0!important; padding: 1em; }
|
||||
.error { background: #FBE3E4; border-color: #FBC2C4; color: #8A1F11; }
|
||||
.error a { color: #8A1F11; }
|
||||
.notice { background: #FFF6BF; border-color: #FFD324; color: #514721; }
|
||||
.notice a { color: #514721; }
|
||||
.success { background: #E6EFC2; border-color: #C6D880; color: #264409; }
|
||||
.success a { color: #264409; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Microformats */
|
||||
|
||||
.box { border: 1px solid #D3D3D3; margin: 1em 0; padding: 10px; }
|
||||
.box:hover { border: 1px solid #999; }
|
||||
.box .preview { float: left; margin: 0 15px 0 0; width: 200px; }
|
||||
.box .content h2 { font-size: 16px!important; margin: 0 0 10px 0!important; }
|
||||
.box .content h3 { font-size: 14px!important; margin: 0 0 10px 0!important; }
|
||||
.box .content blockquote p { font-size: 16px!important; }
|
||||
.box .content p { font-size: 12px!important; margin: 0 0 10px 0!important; }
|
||||
.box .content ul { margin: 0 0 10px 20px!important; }
|
||||
.box .metadata { float: left; width: 350px; }
|
||||
.box .metadata ul { margin: 0!important; padding: 0!important; }
|
||||
.box .metadata ul li { list-style: none!important; }
|
||||
.box .actions ul { margin: 0!important; }
|
||||
.box .actions ul li { display: inline; list-style: none!important; }
|
||||
|
||||
.box .actions {
|
||||
float: right;
|
||||
position: relative;
|
||||
top: 0;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Clean Me */
|
||||
|
||||
.box_relationships { border-top: 1px dotted #D3D3D3; padding: 1.5em 0; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Hacks */
|
||||
|
||||
.clear { clear: both; }
|
||||
.tip { color: #666; font-size: 10px; margin: -10px 0 10px 0!important; }
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Sprite */
|
||||
|
||||
.sprite { background: url(../../images/admin/ui-icons.png) no-repeat; text-indent: -10000px; }
|
||||
.trash { background-position: -177px -97px; height: 15px; width: 15px; }
|
||||
.unrelate { background-position: -145px -129px; height: 15px; width: 15px; }
|
||||
|
||||
/* @end */
|
||||
@ -11,7 +11,7 @@ a {
|
||||
padding-top: 20px;
|
||||
}
|
||||
#wrapper {
|
||||
background: inherit;
|
||||
background: black;
|
||||
}
|
||||
#header {
|
||||
position: relative;
|
||||
@ -47,22 +47,58 @@ a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
.category a .arrow {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 20px;
|
||||
}
|
||||
.category a:focus, .photo a:focus {
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
.category a:hover, .photo a:hover {
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
.blank-category {
|
||||
.blank-category, .blank-photo {
|
||||
background: #222;
|
||||
outline: 1px dashed #444;
|
||||
}
|
||||
.category h3 {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 20px;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
margin: 0 20px;
|
||||
font-weight: normal;
|
||||
font-size: 1.1em;
|
||||
line-height: 1em;
|
||||
}
|
||||
img {
|
||||
}
|
||||
.page-links {
|
||||
background: #c03232;
|
||||
}
|
||||
.prev-link, .next-link {
|
||||
color: white;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 70px !important;
|
||||
}
|
||||
.prev-link {
|
||||
float: left;
|
||||
}
|
||||
.next-link {
|
||||
float: right;
|
||||
}
|
||||
.prev-link div, .next-link div {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
}
|
||||
.prev-link div {
|
||||
left: 20px;
|
||||
}
|
||||
.next-link div {
|
||||
right: 20px;
|
||||
}
|
||||
.prev-link:hover, .next-link:hover {
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
11
test/functional/admin/categories_controller_test.rb
Normal file
@ -0,0 +1,11 @@
|
||||
require 'test_helper'
|
||||
|
||||
# ControllerTest generated by Typus, use it to test the extended admin functionality.
|
||||
class Admin::CategoriesControllerTest < ActionController::TestCase
|
||||
|
||||
# Replace this with your real tests.
|
||||
test "the truth" do
|
||||
assert true
|
||||
end
|
||||
|
||||
end
|
||||
11
test/functional/admin/photos_controller_test.rb
Normal file
@ -0,0 +1,11 @@
|
||||
require 'test_helper'
|
||||
|
||||
# ControllerTest generated by Typus, use it to test the extended admin functionality.
|
||||
class Admin::PhotosControllerTest < ActionController::TestCase
|
||||
|
||||
# Replace this with your real tests.
|
||||
test "the truth" do
|
||||
assert true
|
||||
end
|
||||
|
||||
end
|
||||
11
test/functional/admin/typus_users_controller_test.rb
Normal file
@ -0,0 +1,11 @@
|
||||
require 'test_helper'
|
||||
|
||||
# ControllerTest generated by Typus, use it to test the extended admin functionality.
|
||||
class Admin::TypusUsersControllerTest < ActionController::TestCase
|
||||
|
||||
# Replace this with your real tests.
|
||||
test "the truth" do
|
||||
assert true
|
||||
end
|
||||
|
||||
end
|
||||
68
vendor/plugins/typus/CHANGES
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
= 0.9.40 / 2010-02-??
|
||||
|
||||
[X] Refactor all forms to be able to use formtastic.
|
||||
[X] Cleanup translation files.
|
||||
[X] Removed FIXME tests.
|
||||
[X] Pass attribute as symbol.
|
||||
[X] Simplify configuration files.
|
||||
[X] Added '/' to admin_edit_typus_user_path because was not linking to
|
||||
the right path on the namespaced models.
|
||||
[X] Updated generator defaults.
|
||||
[X] Write CSV file to disk and then send_file.
|
||||
[X] Replaced CSV separator. Now uses ';' instead of ','.
|
||||
[X] Do not show selector on habtm if there are more than 500 records.
|
||||
[X] Paginate habtm relationships. Was implemented in the has_many.
|
||||
[X] Fixed unrelate action. Was not working properly when not using
|
||||
Rails default table names.
|
||||
[X] Do not humanize fields on the csv generator. We want to keep the
|
||||
real field name.
|
||||
[X] Recover password functionality now only needs the email to be defined.
|
||||
[X] Added json export format.
|
||||
[X] Added default route with conditions. (Ben Scofield)
|
||||
[X] We should be able to set preferences and store them on the database.
|
||||
[X] Fixed stylesheet and search to be able to use `relative_url_root`.
|
||||
[X] Cleanup `display_link_to_previous` helper.
|
||||
[X] Cleanup `build_typus_list` helper.
|
||||
[X] Fix back_to when using `relative_url_root`.
|
||||
[X] Remove toggle option. We always enable it so it's a good default.
|
||||
[X] When displaying an item with multiple attachments fancybox preview
|
||||
was not working properly because there where multiple items with the
|
||||
same id.
|
||||
[X] Move partial helpers to `app/views/admin/helpers`.
|
||||
[X] Do not set ActionMailer::Base.default_url_options[:host] on the
|
||||
controller.
|
||||
[X] Cleanup `applications` & `resources`.
|
||||
[-] Allow users to download the demo hosted at heroku.com
|
||||
[-] Move html code from helpers to partials.
|
||||
[ ] Add API authentication.
|
||||
[ ] Fix problems on routes.rb when using namespaced models.
|
||||
[ ] Show the right content on the selectors when listing records on tables.
|
||||
[ ] Update fancybox to the latest version. Fix paths to make it work when
|
||||
`relative_url_root` is active. (and make a donation)
|
||||
[ ] Add has_many through relationships.
|
||||
[ ] Test default typus forms and remove old tests.
|
||||
[ ] Fixed and tested read-only fields.
|
||||
[ ] Fixed and tested auto-generated fields.
|
||||
[ ] Fixed and tested trees.
|
||||
[ ] Fix all fixme tests.
|
||||
[ ] Test _form.html.erb can be overwrited by model.
|
||||
[ ] Show auto_generated, read_only on string fields. (_string.html.erb)
|
||||
[ ] Pass options hash to form fields.
|
||||
[ ] Fix css to display correctly "select" fields in relationships.
|
||||
[ ] Make tests work again.
|
||||
[ ] Remove Typus "blue" color and use something more neutral.
|
||||
[ ] Ajax pagination. (?)
|
||||
[ ] Generate views for custom actions on the controllers/models. This should
|
||||
verify the view doesn't exist and create it.
|
||||
[ ] Support for XSS.
|
||||
[X] Replace "render :partial => 'template', :locals => {}", by
|
||||
"render 'template', :local => 'local'".
|
||||
[X] Add support for custom typus_user on the generator.
|
||||
[ ] Shorten sidebar selectors. (AFS)
|
||||
[ ] Add test for `typus_table_selector`.
|
||||
[X] Clicking on a filter removes is. (Gaston Kleiman)
|
||||
[X] Possibility to filter by date ranges. (Gaston Kleiman)
|
||||
[ ] Use `inherit_views` code to `inherit_views`.
|
||||
[ ] Forever loop when schema has not been migrated.
|
||||
[ ] Pagination doesn't work properly when having multiple paginators on edit page
|
||||
[ ] Add support for 'has_one' relationships.
|
||||
20
vendor/plugins/typus/MIT-LICENSE
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
Copyright (c) 2007-2010 Francesc Esplugas Marti
|
||||
|
||||
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.
|
||||
49
vendor/plugins/typus/README.rdoc
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
= Typus: Admin interface for Rails applications
|
||||
|
||||
Typus is designed for a single activity:
|
||||
|
||||
Trusted users editing structured content.
|
||||
|
||||
Typus doesn't try to be all the things to all the people but it's extensible
|
||||
enough to match lots of use cases.
|
||||
|
||||
== Key Features
|
||||
|
||||
- Authentication by session or http.
|
||||
- Access control by users and roles (only on session authentication).
|
||||
- Show, search, edit and create data on a clean interface.
|
||||
- Internationalized interface with xtensible and overwritable templates.
|
||||
- Boolean filtering.
|
||||
- Supports ActiveRecord.
|
||||
- Supports Rails 3 and is Ruby 1.9 compatible.
|
||||
- Tested with SQLite, MySQL, and PostgreSQL.
|
||||
- MIT License.
|
||||
|
||||
== Links
|
||||
|
||||
- {Project page}[http://labs.intraducibles.com/projects/typus]
|
||||
- {Documentation}[http://typus.intraducibles.com/]
|
||||
- {Plugin source code}[http://github.com/fesplugas/typus]
|
||||
- {Mailing list}[http://groups.google.com/group/typus]
|
||||
- {Bug reports}[http://github.com/fesplugas/typus/issues]
|
||||
- {Gems}[http://gemcutter.org/gems/typus]
|
||||
- {Contributors}[http://github.com/fesplugas/typus/contributors]
|
||||
|
||||
== Installing
|
||||
|
||||
Install from GitHub the latest version which it's compatible with
|
||||
<tt>Rails 2.3.8</tt>.
|
||||
|
||||
$ script/plugin install git://github.com/fesplugas/typus.git -r 2-3-stable
|
||||
|
||||
Once `typus` is installed, run the generator to create required files and
|
||||
migrate your database.
|
||||
|
||||
$ script/generate typus
|
||||
$ rake db:migrate
|
||||
|
||||
Start the application server and go to {http://0.0.0.0:3000/admin}[http://0.0.0.0:3000/admin].
|
||||
|
||||
== License
|
||||
|
||||
Copyright © 2007-2010 Francesc Esplugas, released under the MIT license.
|
||||
57
vendor/plugins/typus/Rakefile
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
require 'rubygems'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
||||
require "typus/version"
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the typus plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.libs << 'test'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Build the gem.'
|
||||
task :build do
|
||||
system "gem build typus.gemspec"
|
||||
end
|
||||
|
||||
desc 'Build and release the gem.'
|
||||
task :release => :build do
|
||||
version = Typus::VERSION
|
||||
system "git tag v#{version}"
|
||||
system "git push origin v#{version}"
|
||||
system "gem push pkg/typus-#{version}.gem"
|
||||
system "git clean -fd"
|
||||
system "gem push typus-#{version}"
|
||||
end
|
||||
|
||||
desc 'Generate specdoc-style documentation from tests'
|
||||
task :specs do
|
||||
|
||||
puts 'Started'
|
||||
timer, count = Time.now, 0
|
||||
|
||||
File.open('SPECDOC', 'w') do |file|
|
||||
Dir.glob('test/**/*_test.rb').each do |test|
|
||||
test =~ /.*\/([^\/].*)_test.rb$/
|
||||
file.puts "#{$1.gsub('_', ' ').capitalize} should:" if $1
|
||||
File.read(test).map { |line| /test_(.*)$/.match line }.compact.each do |spec|
|
||||
file.puts "- #{spec[1].gsub('_', ' ')}"
|
||||
sleep 0.001; print '.'; $stdout.flush; count += 1
|
||||
end
|
||||
file.puts
|
||||
end
|
||||
end
|
||||
|
||||
puts <<-MSG
|
||||
\nFinished in #{Time.now - timer} seconds.
|
||||
#{count} specifications documented.
|
||||
MSG
|
||||
|
||||
end
|
||||
401
vendor/plugins/typus/app/controllers/admin/master_controller.rb
vendored
Normal file
@ -0,0 +1,401 @@
|
||||
class Admin::MasterController < ApplicationController
|
||||
|
||||
skip_filter filter_chain
|
||||
|
||||
unloadable
|
||||
|
||||
inherit_views 'admin/resources'
|
||||
|
||||
layout 'admin'
|
||||
|
||||
include Typus::Authentication
|
||||
include Typus::Format
|
||||
include Typus::Preferences
|
||||
include Typus::Reloader
|
||||
|
||||
filter_parameter_logging :password
|
||||
|
||||
before_filter :reload_config_and_roles
|
||||
|
||||
before_filter :require_login
|
||||
|
||||
before_filter :set_typus_preferences
|
||||
|
||||
before_filter :set_resource
|
||||
before_filter :find_item,
|
||||
:only => [ :show, :edit, :update, :destroy, :toggle, :position, :relate, :unrelate, :detach ]
|
||||
|
||||
before_filter :check_ownership_of_item,
|
||||
:only => [ :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
|
||||
|
||||
before_filter :check_if_user_can_perform_action_on_user,
|
||||
:only => [ :edit, :update, :toggle, :destroy ]
|
||||
before_filter :check_if_user_can_perform_action_on_resource
|
||||
|
||||
before_filter :set_order,
|
||||
:only => [ :index ]
|
||||
before_filter :set_fields,
|
||||
:only => [ :index, :new, :edit, :create, :update, :show ]
|
||||
|
||||
##
|
||||
# This is the main index of the model. With filters, conditions
|
||||
# and more.
|
||||
#
|
||||
# By default application can respond_to html, csv and xml, but you
|
||||
# can add your formats.
|
||||
#
|
||||
def index
|
||||
|
||||
@conditions, @joins = @resource[:class].build_conditions(params)
|
||||
|
||||
check_ownership_of_items if @resource[:class].typus_options_for(:only_user_items)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { generate_html }
|
||||
@resource[:class].typus_export_formats.each do |f|
|
||||
format.send(f) { send("generate_#{f}") }
|
||||
end
|
||||
end
|
||||
|
||||
rescue Exception => error
|
||||
error_handler(error)
|
||||
end
|
||||
|
||||
def new
|
||||
|
||||
check_ownership_of_referal_item
|
||||
|
||||
item_params = params.dup
|
||||
%w( controller action resource resource_id back_to selected ).each do |param|
|
||||
item_params.delete(param)
|
||||
end
|
||||
|
||||
@item = @resource[:class].new(item_params.symbolize_keys)
|
||||
|
||||
end
|
||||
|
||||
##
|
||||
# Create new items. There's an special case when we create an
|
||||
# item from another item. In this case, after the item is
|
||||
# created we also create the relationship between these items.
|
||||
#
|
||||
def create
|
||||
|
||||
@item = @resource[:class].new(params[@object_name])
|
||||
|
||||
if @resource[:class].typus_user_id?
|
||||
@item.attributes = { Typus.user_fk => @current_user.id }
|
||||
end
|
||||
|
||||
if @item.valid?
|
||||
create_with_back_to and return if params[:back_to]
|
||||
@item.save
|
||||
flash[:success] = _("%{model} successfully created.",
|
||||
:model => @resource[:human_name])
|
||||
if @resource[:class].typus_options_for(:index_after_save)
|
||||
redirect_to :action => 'index'
|
||||
else
|
||||
redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id
|
||||
end
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def show
|
||||
|
||||
check_ownership_of_item and return if @resource[:class].typus_options_for(:only_user_items)
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.xml do
|
||||
fields = @resource[:class].typus_fields_for(:xml).collect { |i| i.first }
|
||||
render :xml => @item.to_xml(:only => fields)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
if @item.update_attributes(params[@object_name])
|
||||
|
||||
if @resource[:class].typus_user_id? && @current_user.is_not_root?
|
||||
@item.update_attributes Typus.user_fk => @current_user.id
|
||||
end
|
||||
|
||||
path = if @resource[:class].typus_options_for(:index_after_save)
|
||||
params[:back_to] ? "#{params[:back_to]}##{@resource[:self]}" : { :action => 'index' }
|
||||
else
|
||||
{ :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id, :back_to => params[:back_to] }
|
||||
end
|
||||
|
||||
# Reload @current_user when updating to see flash message in the
|
||||
# correct locale.
|
||||
if @resource[:class].eql?(Typus.user_class)
|
||||
I18n.locale = @current_user.reload.preferences[:locale]
|
||||
@resource[:human_name] = params[:controller].extract_human_name
|
||||
end
|
||||
|
||||
flash[:success] = _("%{model} successfully updated.",
|
||||
:model => @resource[:human_name])
|
||||
redirect_to path
|
||||
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def destroy
|
||||
@item.destroy
|
||||
flash[:success] = _("%{model} successfully removed.",
|
||||
:model => @resource[:human_name])
|
||||
redirect_to request.referer || admin_dashboard_path
|
||||
rescue Exception => error
|
||||
error_handler(error, params.merge(:action => 'index', :id => nil))
|
||||
end
|
||||
|
||||
def toggle
|
||||
@item.toggle(params[:field])
|
||||
@item.save!
|
||||
flash[:success] = _("%{model} %{attribute} changed.",
|
||||
:model => @resource[:human_name],
|
||||
:attribute => params[:field].humanize.downcase)
|
||||
redirect_to request.referer || admin_dashboard_path
|
||||
end
|
||||
|
||||
##
|
||||
# Change item position. This only works if acts_as_list is
|
||||
# installed. We can then move items:
|
||||
#
|
||||
# params[:go] = 'move_to_top'
|
||||
#
|
||||
# Available positions are move_to_top, move_higher, move_lower,
|
||||
# move_to_bottom.
|
||||
#
|
||||
def position
|
||||
@item.send(params[:go])
|
||||
flash[:success] = _("Record moved %{to}.",
|
||||
:to => params[:go].gsub(/move_/, '').humanize.downcase)
|
||||
redirect_to request.referer || admin_dashboard_path
|
||||
end
|
||||
|
||||
##
|
||||
# Relate a model object to another, this action is used only by the
|
||||
# has_and_belongs_to_many and has_many relationships.
|
||||
#
|
||||
def relate
|
||||
resource_class = params[:related][:model].constantize
|
||||
resource_tableized = params[:related][:relation] || params[:related][:model].tableize
|
||||
|
||||
if @item.send(resource_tableized) << resource_class.find(params[:related][:id])
|
||||
flash[:success] = _("%{model_a} related to %{model_b}.",
|
||||
:model_a => resource_class.typus_human_name,
|
||||
:model_b => @resource[:human_name])
|
||||
else
|
||||
# TODO: Show the reason why cannot be related showing model_a and model_b errors.
|
||||
flash[:error] = _("%{model_a} cannot be related to %{model_b}.",
|
||||
:model_a => resource_class.typus_human_name,
|
||||
:model_b => @resource[:human_name])
|
||||
end
|
||||
|
||||
redirect_to :back
|
||||
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Remove relationship between models, this action never removes items!
|
||||
#
|
||||
def unrelate
|
||||
|
||||
resource_class = params[:resource].classify.constantize
|
||||
resource_tableized = params[:resource].tableize
|
||||
resource = resource_class.find(params[:resource_id])
|
||||
|
||||
if @resource[:class].
|
||||
reflect_on_association(resource_class.table_name.singularize.to_sym).
|
||||
try(:macro) == :has_one
|
||||
attribute = resource_tableized.singularize
|
||||
saved_succesfully = @item.update_attribute attribute, nil
|
||||
else
|
||||
attribute = resource_tableized
|
||||
saved_successfully = if @item.respond_to?(attribute)
|
||||
@item.send(attribute).delete(resource)
|
||||
elsif @item.respond_to?("related_#{attribute}")
|
||||
@item.relationships.detect {|rel|
|
||||
rel.related_id == resource.id &&
|
||||
rel.related_type == resource.class.name
|
||||
}.destroy
|
||||
end
|
||||
end
|
||||
|
||||
if saved_succesfully
|
||||
flash[:success] = _("%{model_a} unrelated from %{model_b}.",
|
||||
:model_a => resource_class.typus_human_name,
|
||||
:model_b => @resource[:human_name])
|
||||
else
|
||||
# TODO: Show the reason why cannot be unrelated showing model_a and model_b errors.
|
||||
flash[:error] = _("%{model_a} cannot be unrelated to %{model_b}.",
|
||||
:model_a => resource_class.typus_human_name,
|
||||
:model_b => @resource[:human_name])
|
||||
end
|
||||
|
||||
redirect_to :back
|
||||
|
||||
end
|
||||
|
||||
def detach
|
||||
|
||||
attachment = @resource[:class].human_attribute_name(params[:attachment])
|
||||
|
||||
if @item.update_attributes(params[:attachment] => nil)
|
||||
flash[:success] = _("%{attachment} removed.",
|
||||
:attachment => attachment)
|
||||
else
|
||||
flash[:notice] = _("%{attachment} can't be removed.",
|
||||
:attachment => attachment)
|
||||
end
|
||||
|
||||
redirect_to :back
|
||||
|
||||
end
|
||||
|
||||
def current_user
|
||||
@current_user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_resource
|
||||
@resource = { :self => params[:controller].extract_resource,
|
||||
:human_name => params[:controller].extract_human_name,
|
||||
:class => params[:controller].extract_class,
|
||||
:pluralized => params[:controller].extract_class.pluralized_human_name }
|
||||
@object_name = ActionController::RecordIdentifier.singular_class_name(@resource[:class])
|
||||
rescue Exception => error
|
||||
error_handler(error)
|
||||
end
|
||||
|
||||
##
|
||||
# Find model when performing an edit, update, destroy, relate,
|
||||
# unrelate ...
|
||||
#
|
||||
def find_item
|
||||
@item = @resource[:class].find(params[:id])
|
||||
end
|
||||
|
||||
##
|
||||
# If item is owned by another user, we only can perform a
|
||||
# show action on the item. Updated item is also blocked.
|
||||
#
|
||||
# before_filter :check_ownership_of_item, :only => [ :edit, :update, :destroy,
|
||||
# :toggle, :position,
|
||||
# :relate, :unrelate ]
|
||||
#
|
||||
def check_ownership_of_item
|
||||
|
||||
# By-pass if current_user is root.
|
||||
return if @current_user.is_root?
|
||||
|
||||
condition_typus_users = @item.respond_to?(Typus.relationship) && !@item.send(Typus.relationship).include?(@current_user)
|
||||
condition_typus_user_id = @item.respond_to?(Typus.user_fk) && !@item.owned_by?(@current_user)
|
||||
|
||||
if condition_typus_users || condition_typus_user_id
|
||||
flash[:notice] = _("You don't have permission to access this item.")
|
||||
redirect_to request.referer || admin_dashboard_path
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def check_ownership_of_items
|
||||
|
||||
# By-pass if current_user is root.
|
||||
return if @current_user.is_root?
|
||||
|
||||
# Show only related items it @resource has a foreign_key (Typus.user_fk)
|
||||
# related to the logged user.
|
||||
if @resource[:class].typus_user_id?
|
||||
condition = { Typus.user_fk => @current_user }
|
||||
@conditions = @resource[:class].merge_conditions(@conditions, condition)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def check_ownership_of_referal_item
|
||||
return unless params[:resource] && params[:resource_id]
|
||||
klass = params[:resource].classify.constantize
|
||||
return if !klass.typus_user_id?
|
||||
item = klass.find(params[:resource_id])
|
||||
raise "You're not owner of this record." unless item.owned_by?(@current_user) || @current_user.is_root?
|
||||
end
|
||||
|
||||
def set_fields
|
||||
|
||||
mapping = case params[:action]
|
||||
when 'index' then :list
|
||||
when 'new', 'edit', 'create', 'update' then :form
|
||||
else params[:action]
|
||||
end
|
||||
|
||||
@fields = @resource[:class].typus_fields_for(mapping)
|
||||
|
||||
end
|
||||
|
||||
def set_order
|
||||
params[:sort_order] ||= 'desc'
|
||||
@order = params[:order_by] ? "#{@resource[:class].table_name}.#{params[:order_by]} #{params[:sort_order]}" : @resource[:class].typus_order_by
|
||||
end
|
||||
|
||||
##
|
||||
# When <tt>params[:back_to]</tt> is defined this action is used.
|
||||
#
|
||||
# - <tt>has_and_belongs_to_many</tt> relationships.
|
||||
# - <tt>has_many</tt> relationships (polymorphic ones).
|
||||
#
|
||||
def create_with_back_to
|
||||
|
||||
if params[:resource] && params[:resource_id]
|
||||
resource_class = params[:resource].classify.constantize
|
||||
resource_id = params[:resource_id]
|
||||
resource = resource_class.find(resource_id)
|
||||
association = @resource[:class].reflect_on_association(params[:resource].to_sym).macro rescue :polymorphic
|
||||
else
|
||||
association = :has_many
|
||||
end
|
||||
|
||||
case association
|
||||
when :belongs_to
|
||||
@item.save
|
||||
when :has_and_belongs_to_many
|
||||
@item.save
|
||||
@item.send(params[:resource]) << resource
|
||||
when :has_many
|
||||
@item.save
|
||||
message = _("%{model} successfully created.",
|
||||
:model => @resource[:human_name])
|
||||
path = "#{params[:back_to]}?#{params[:selected]}=#{@item.id}"
|
||||
when :polymorphic
|
||||
resource.send(@item.class.name.tableize).create(params[@object_name])
|
||||
end
|
||||
|
||||
flash[:success] = message || _("%{model_a} successfully assigned to %{model_b}.",
|
||||
:model_a => @item.class.typus_human_name,
|
||||
:model_b => resource_class.typus_human_name)
|
||||
redirect_to path || params[:back_to]
|
||||
|
||||
end
|
||||
|
||||
def error_handler(error, path = admin_dashboard_path)
|
||||
raise error unless Rails.env.production?
|
||||
flash[:error] = "#{error.message} (#{@resource[:class]})"
|
||||
redirect_to path
|
||||
end
|
||||
|
||||
include Typus::MasterControllerExtensions rescue nil
|
||||
end
|
||||
146
vendor/plugins/typus/app/controllers/typus_controller.rb
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
class TypusController < ApplicationController
|
||||
|
||||
skip_filter filter_chain
|
||||
|
||||
unloadable
|
||||
|
||||
layout :select_layout
|
||||
|
||||
include Typus::Authentication
|
||||
include Typus::QuickEdit
|
||||
include Typus::Preferences
|
||||
include Typus::Reloader
|
||||
|
||||
filter_parameter_logging :password
|
||||
|
||||
before_filter :verify_typus_users_table_schema
|
||||
|
||||
before_filter :reload_config_and_roles
|
||||
|
||||
before_filter :require_login,
|
||||
:except => [ :sign_up, :sign_in, :sign_out,
|
||||
:recover_password, :reset_password,
|
||||
:quick_edit ]
|
||||
|
||||
before_filter :set_typus_preferences, :only => [ :dashboard ]
|
||||
|
||||
before_filter :check_if_user_can_perform_action_on_resource_without_model,
|
||||
:except => [ :sign_up, :sign_in, :sign_out,
|
||||
:dashboard,
|
||||
:recover_password, :reset_password,
|
||||
:quick_edit ]
|
||||
|
||||
before_filter :recover_password_disabled?,
|
||||
:only => [ :recover_password, :reset_password ]
|
||||
|
||||
def dashboard
|
||||
flash[:notice] = _("There are not defined applications in config/typus/*.yml.") if Typus.applications.empty?
|
||||
end
|
||||
|
||||
def sign_in
|
||||
|
||||
redirect_to admin_sign_up_path and return if Typus.user_class.count.zero?
|
||||
|
||||
if request.post?
|
||||
if user = Typus.user_class.authenticate(params[:typus_user][:email], params[:typus_user][:password])
|
||||
session[:typus_user_id] = user.id
|
||||
redirect_to params[:back_to] || admin_dashboard_path
|
||||
else
|
||||
flash[:error] = _("The email and/or password you entered is invalid.")
|
||||
redirect_to admin_sign_in_path
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def sign_out
|
||||
session[:typus_user_id] = nil
|
||||
redirect_to admin_sign_in_path
|
||||
end
|
||||
|
||||
def recover_password
|
||||
if request.post?
|
||||
if user = Typus.user_class.find_by_email(params[:typus_user][:email])
|
||||
url = admin_reset_password_url(:token => user.token)
|
||||
TypusMailer.deliver_reset_password_link(user, url)
|
||||
flash[:success] = _("Password recovery link sent to your email.")
|
||||
redirect_to admin_sign_in_path
|
||||
else
|
||||
redirect_to admin_recover_password_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Available if Typus::Configuration.options[:email] is set.
|
||||
#
|
||||
def reset_password
|
||||
@typus_user = Typus.user_class.find_by_token!(params[:token])
|
||||
if request.post?
|
||||
@typus_user.password = params[:typus_user][:password]
|
||||
@typus_user.password_confirmation = params[:typus_user][:password_confirmation]
|
||||
if !params[:typus_user][:password].blank? && @typus_user.save
|
||||
session[:typus_user_id] = @typus_user.id
|
||||
redirect_to admin_dashboard_path
|
||||
else
|
||||
render :action => "reset_password"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def sign_up
|
||||
|
||||
redirect_to admin_sign_in_path and return unless Typus.user_class.count.zero?
|
||||
|
||||
if request.post?
|
||||
|
||||
user = Typus.user_class.generate(:email => params[:typus_user][:email],
|
||||
:password => Typus::Configuration.options[:default_password],
|
||||
:role => Typus::Configuration.options[:root])
|
||||
user.status = true
|
||||
|
||||
if user.save
|
||||
session[:typus_user_id] = user.id
|
||||
flash[:notice] = _("Password set to \"%{password}\".",
|
||||
:password => Typus::Configuration.options[:default_password])
|
||||
redirect_to admin_dashboard_path
|
||||
else
|
||||
flash[:error] = _("That doesn't seem like a valid email address.")
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
flash[:notice] = _("Enter your email below to create the first user.")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_typus_users_table_schema
|
||||
|
||||
attributes = Typus.user_class.model_fields.keys
|
||||
|
||||
upgrades = ActiveSupport::OrderedHash.new
|
||||
upgrades[:role] = "typus_update_schema_to_01"
|
||||
upgrades[:preferences] = "typus_update_schema_to_02"
|
||||
|
||||
upgrades.each do |key, value|
|
||||
message = "Run `script/generate #{value} -f && rake db:migrate` to update database schema."
|
||||
raise message if !attributes.include?(key)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def recover_password_disabled?
|
||||
redirect_to admin_sign_in_path unless Typus::Configuration.options[:email]
|
||||
end
|
||||
|
||||
def select_layout
|
||||
%w( sign_up sign_in sign_out
|
||||
recover_password reset_password ).include?(action_name) ? "typus" : "admin"
|
||||
end
|
||||
|
||||
include Typus::TypusControllerExtensions rescue nil
|
||||
end
|
||||
464
vendor/plugins/typus/app/helpers/admin/form_helper.rb
vendored
Normal file
@ -0,0 +1,464 @@
|
||||
module Admin::FormHelper
|
||||
|
||||
def build_form(fields, form)
|
||||
|
||||
options = { :form => form }
|
||||
|
||||
returning(String.new) do |html|
|
||||
|
||||
html << (error_messages_for :item, :header_tag => 'h3')
|
||||
|
||||
fields.each do |key, value|
|
||||
|
||||
if template = @resource[:class].typus_template(key)
|
||||
html << typus_template_field(key, template, options)
|
||||
next
|
||||
end
|
||||
|
||||
html << case value
|
||||
when :belongs_to then typus_belongs_to_field(key, options)
|
||||
when :tree then typus_tree_field(key, :form => options[:form])
|
||||
when :boolean, :date, :datetime, :string, :text, :time,
|
||||
:file, :password, :selector
|
||||
typus_template_field(key, value, options)
|
||||
else
|
||||
typus_template_field(key, :string, options)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Remove returning(String.new) and return directly the html.
|
||||
def typus_belongs_to_field(attribute, options)
|
||||
|
||||
form = options[:form]
|
||||
|
||||
##
|
||||
# We only can pass parameters to 'new' and 'edit', so this hack makes
|
||||
# the work to replace the current action.
|
||||
#
|
||||
params[:action] = (params[:action] == 'create') ? 'new' : params[:action]
|
||||
|
||||
back_to = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id])
|
||||
|
||||
related = @resource[:class].reflect_on_association(attribute.to_sym).class_name.constantize
|
||||
related_fk = @resource[:class].reflect_on_association(attribute.to_sym).primary_key_name
|
||||
|
||||
confirm = [ _("Are you sure you want to leave this page?"),
|
||||
_("If you have made any changes to the fields without clicking the Save/Update entry button, your changes will be lost."),
|
||||
_("Click OK to continue, or click Cancel to stay on this page.") ]
|
||||
|
||||
returning(String.new) do |html|
|
||||
|
||||
message = link_to _("Add"), { :controller => "admin/#{related.class_name.tableize}",
|
||||
:action => 'new',
|
||||
:back_to => back_to,
|
||||
:selected => related_fk },
|
||||
:confirm => confirm.join("\n\n") if @current_user.can?('create', related)
|
||||
|
||||
if related.respond_to?(:roots)
|
||||
html << typus_tree_field(related_fk, :items => related.roots,
|
||||
:attribute_virtual => related_fk,
|
||||
:form => form)
|
||||
else
|
||||
values = related.find(:all, :order => related.typus_order_by).collect { |p| [p.to_label, p.id] }
|
||||
options = { :include_blank => true }
|
||||
html_options = { :disabled => attribute_disabled?(attribute) }
|
||||
label_text = @resource[:class].human_attribute_name(attribute)
|
||||
html << <<-HTML
|
||||
<li>
|
||||
#{form.label related_fk, "#{label_text} <small>#{message}</small>"}
|
||||
#{form.select related_fk, values, options, html_options }
|
||||
</li>
|
||||
HTML
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def typus_tree_field(attribute, *args)
|
||||
|
||||
options = args.extract_options!
|
||||
options[:items] ||= @resource[:class].roots
|
||||
options[:attribute_virtual] ||= 'parent_id'
|
||||
|
||||
form = options[:form]
|
||||
|
||||
values = expand_tree_into_select_field(options[:items], options[:attribute_virtual])
|
||||
|
||||
label_text = @resource[:class].human_attribute_name(attribute)
|
||||
|
||||
<<-HTML
|
||||
<li>
|
||||
#{form.label label_text}
|
||||
#{form.select options[:attribute_virtual], values, { :include_blank => true }}
|
||||
</li>
|
||||
HTML
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Cleanup the case statement.
|
||||
def typus_relationships
|
||||
|
||||
@back_to = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id])
|
||||
|
||||
returning(String.new) do |html|
|
||||
@resource[:class].typus_defaults_for(:relationships).each do |relationship|
|
||||
|
||||
association = @resource[:class].reflect_on_association(relationship.to_sym)
|
||||
|
||||
next if @current_user.cannot?('read', association.class_name.constantize)
|
||||
|
||||
macro = association.through_reflection ? :has_and_belongs_to_many : association.macro
|
||||
case macro
|
||||
when :has_and_belongs_to_many
|
||||
html << typus_form_has_and_belongs_to_many(relationship)
|
||||
when :has_many
|
||||
if association.options[:through]
|
||||
# Here we will shot the relationship. Better this than raising an error.
|
||||
else
|
||||
html << typus_form_has_many(relationship)
|
||||
end
|
||||
when :has_one
|
||||
html << typus_form_has_one(relationship)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def typus_form_has_many(field)
|
||||
returning(String.new) do |html|
|
||||
|
||||
model_to_relate = @resource[:class].reflect_on_association(field.to_sym).class_name.constantize
|
||||
model_to_relate_as_resource = model_to_relate.name.tableize
|
||||
|
||||
reflection = @resource[:class].reflect_on_association(field.to_sym)
|
||||
association = reflection.macro
|
||||
foreign_key = reflection.through_reflection ? reflection.primary_key_name.pluralize : reflection.primary_key_name
|
||||
|
||||
link_options = { :controller => "admin/#{model_to_relate_as_resource.pluralize}",
|
||||
:action => 'new',
|
||||
:back_to => "#{@back_to}##{field}",
|
||||
:resource => @resource[:self].singularize,
|
||||
:resource_id => @item.id,
|
||||
foreign_key => @item.id }
|
||||
|
||||
condition = if @resource[:class].typus_user_id? && @current_user.is_not_root?
|
||||
@item.owned_by?(@current_user)
|
||||
else
|
||||
true
|
||||
end
|
||||
|
||||
# If the form_for_<model>_relationship partial exists we consider
|
||||
# we want to add only items from our form, and not going to the
|
||||
# new action. So we don't show the add new.
|
||||
|
||||
# Partial exists?
|
||||
partial = "form_for_#{model_to_relate_as_resource}_relationship"
|
||||
partial_path = Rails.root.join('app', 'views', 'admin', 'cars', "_#{partial}.html.erb").to_s
|
||||
|
||||
if condition && @current_user.can?('create', model_to_relate) && !File.exists?(partial_path)
|
||||
add_new = <<-HTML
|
||||
<small>#{link_to _("Add new"), link_options}</small>
|
||||
HTML
|
||||
end
|
||||
|
||||
html << <<-HTML
|
||||
<a name="#{field}"></a>
|
||||
<div class="box_relationships" id="#{model_to_relate_as_resource}">
|
||||
<h2>
|
||||
#{link_to model_to_relate.pluralized_human_name, { :controller => "admin/#{model_to_relate_as_resource}", foreign_key => @item.id }, :title => _("%{model} filtered by %{filtered_by}", :model => model_to_relate.typus_human_name.pluralize, :filtered_by => @item.to_label)}
|
||||
#{add_new}
|
||||
</h2>
|
||||
HTML
|
||||
|
||||
if File.exists?(partial_path)
|
||||
html << <<-HTML
|
||||
#{render :partial => partial}
|
||||
HTML
|
||||
end
|
||||
|
||||
##
|
||||
# It's a has_many relationship, so items that are already assigned to another
|
||||
# entry are assigned to that entry.
|
||||
#
|
||||
items_to_relate = model_to_relate.find(:all, :conditions => ["#{foreign_key} is ?", nil])
|
||||
if condition && !items_to_relate.empty?
|
||||
html << <<-HTML
|
||||
#{form_tag :action => 'relate', :id => @item.id}
|
||||
#{hidden_field :related, :model, :value => model_to_relate}
|
||||
<p>#{select :related, :id, items_to_relate.collect { |f| [f.to_label, f.id] }.sort_by { |e| e.first } } #{submit_tag _("Add"), :class => 'button'}</p>
|
||||
</form>
|
||||
HTML
|
||||
end
|
||||
|
||||
conditions = if model_to_relate.typus_options_for(:only_user_items) && @current_user.is_not_root?
|
||||
{ Typus.user_fk => @current_user }
|
||||
end
|
||||
|
||||
options = { :order => model_to_relate.typus_order_by, :conditions => conditions }
|
||||
items_count = @resource[:class].find(params[:id]).send(field).count(:conditions => conditions)
|
||||
items_per_page = model_to_relate.typus_options_for(:per_page).to_i
|
||||
|
||||
@pager = ::Paginator.new(items_count, items_per_page) do |offset, per_page|
|
||||
eager_loading = model_to_relate.reflect_on_all_associations(:belongs_to).map { |i| i.name } - [@resource[:class].name.downcase.to_sym]
|
||||
options.merge!({:limit => per_page, :offset => offset, :include => eager_loading})
|
||||
items = @resource[:class].find(params[:id]).send(field).find(:all, options)
|
||||
end
|
||||
|
||||
@items = @pager.page(params[:page])
|
||||
|
||||
unless @items.empty?
|
||||
options = { :back_to => "#{@back_to}##{field}", :resource => @resource[:self], :resource_id => @item.id }
|
||||
html << build_list(model_to_relate,
|
||||
model_to_relate.typus_fields_for(:relationship),
|
||||
@items,
|
||||
model_to_relate_as_resource,
|
||||
options,
|
||||
association)
|
||||
html << pagination(:anchor => model_to_relate.name.tableize) unless pagination.nil?
|
||||
else
|
||||
message = _("There are no %{records}.",
|
||||
:records => model_to_relate.typus_human_name.pluralize.downcase)
|
||||
html << <<-HTML
|
||||
<div id="flash" class="notice"><p>#{message}</p></div>
|
||||
HTML
|
||||
end
|
||||
html << <<-HTML
|
||||
</div>
|
||||
HTML
|
||||
end
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def typus_form_has_and_belongs_to_many(field)
|
||||
returning(String.new) do |html|
|
||||
|
||||
model_to_relate = @resource[:class].reflect_on_association(field.to_sym).class_name.constantize
|
||||
model_to_relate_as_resource = model_to_relate.name.tableize
|
||||
|
||||
reflection = @resource[:class].reflect_on_association(field.to_sym)
|
||||
association = reflection.macro
|
||||
|
||||
through = !reflection.through_reflection.nil?
|
||||
|
||||
condition = if @resource[:class].typus_user_id? && !@current_user.is_root?
|
||||
@item.owned_by?(@current_user)
|
||||
else
|
||||
true
|
||||
end
|
||||
|
||||
if condition && @current_user.can?('create', model_to_relate)
|
||||
add_new = <<-HTML
|
||||
<small>#{link_to _("Add new"), :controller => field, :action => 'new', :back_to => @back_to, :resource => @resource[:self], :resource_id => @item.id}</small>
|
||||
HTML
|
||||
end
|
||||
|
||||
html << <<-HTML
|
||||
<a name="#{field}"></a>
|
||||
<div class="box_relationships" id="#{model_to_relate_as_resource}">
|
||||
<h2>
|
||||
#{link_to model_to_relate.typus_human_name.pluralize, :controller => "admin/#{model_to_relate_as_resource}"}
|
||||
#{add_new unless through}
|
||||
</h2>
|
||||
HTML
|
||||
|
||||
if model_to_relate.count < 500
|
||||
|
||||
items_to_relate = (model_to_relate.find(:all) - @item.send(field))
|
||||
|
||||
if condition && !items_to_relate.empty?
|
||||
html << <<-HTML
|
||||
#{form_tag :action => 'relate', :id => @item.id}
|
||||
#{hidden_field(:related, :relation, :value => field) if through}
|
||||
#{hidden_field :related, :model, :value => model_to_relate}
|
||||
<p>#{select :related, :id, items_to_relate.collect { |f| [f.to_label, f.id] }.sort_by { |e| e.first } } #{submit_tag _("Add"), :class => 'button'}</p>
|
||||
</form>
|
||||
HTML
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
conditions = if model_to_relate.typus_options_for(:only_user_items) && @current_user.is_not_root?
|
||||
{ Typus.user_fk => @current_user }
|
||||
end
|
||||
|
||||
options = { :order => model_to_relate.typus_order_by, :conditions => conditions }
|
||||
items_count = @resource[:class].find(params[:id]).send(field).count(:conditions => conditions)
|
||||
items_per_page = model_to_relate.typus_options_for(:per_page).to_i
|
||||
|
||||
@pager = ::Paginator.new(items_count, items_per_page) do |offset, per_page|
|
||||
options.merge!({:limit => per_page, :offset => offset})
|
||||
items = @resource[:class].find(params[:id]).send(field).find(:all, options)
|
||||
end
|
||||
|
||||
@items = @pager.page(params[:page])
|
||||
|
||||
unless @items.empty?
|
||||
html << build_list(model_to_relate,
|
||||
model_to_relate.typus_fields_for(:relationship),
|
||||
@items,
|
||||
model_to_relate_as_resource,
|
||||
{},
|
||||
association)
|
||||
html << pagination(:anchor => model_to_relate.name.tableize) unless pagination.nil?
|
||||
else
|
||||
message = _("There are no %{records}.",
|
||||
:records => model_to_relate.typus_human_name.pluralize.downcase)
|
||||
html << <<-HTML
|
||||
<div id="flash" class="notice"><p>#{message}</p></div>
|
||||
HTML
|
||||
end
|
||||
html << <<-HTML
|
||||
</div>
|
||||
HTML
|
||||
end
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def typus_form_has_one(field)
|
||||
returning(String.new) do |html|
|
||||
|
||||
model_to_relate = @resource[:class].reflect_on_association(field.to_sym).class_name.constantize
|
||||
model_to_relate_as_resource = model_to_relate.name.tableize
|
||||
|
||||
reflection = @resource[:class].reflect_on_association(field.to_sym)
|
||||
association = reflection.macro
|
||||
foreign_key = reflection.through_reflection ? reflection.primary_key_name.pluralize : reflection.primary_key_name
|
||||
|
||||
link_options = { :controller => "admin/#{model_to_relate_as_resource.pluralize}",
|
||||
:action => 'new',
|
||||
:back_to => "#{@back_to}##{field}",
|
||||
:resource => @resource[:self].singularize,
|
||||
:resource_id => @item.id,
|
||||
foreign_key => @item.id }
|
||||
|
||||
condition = if @resource[:class].typus_user_id? && !@current_user.is_root?
|
||||
@item.owned_by?(@current_user)
|
||||
else
|
||||
true
|
||||
end
|
||||
|
||||
existing_record = instance_eval("@item.#{field}")
|
||||
|
||||
if existing_record.nil? && condition && @current_user.can?('create', model_to_relate)
|
||||
add_new = <<-HTML
|
||||
<small>#{link_to _("Add new"), link_options}</small>
|
||||
HTML
|
||||
end
|
||||
|
||||
html << <<-HTML
|
||||
<a name="#{field}"></a>
|
||||
<div class="box_relationships" id="#{model_to_relate_as_resource}">
|
||||
<h2>
|
||||
#{link_to model_to_relate.typus_human_name, :controller => "admin/#{model_to_relate_as_resource}"}
|
||||
#{add_new}
|
||||
</h2>
|
||||
HTML
|
||||
items = Array.new
|
||||
items << @resource[:class].find(params[:id]).send(field) unless @resource[:class].find(params[:id]).send(field).nil?
|
||||
unless items.empty?
|
||||
options = { :back_to => @back_to, :resource => @resource[:self], :resource_id => @item.id }
|
||||
html << build_list(model_to_relate,
|
||||
model_to_relate.typus_fields_for(:relationship),
|
||||
items,
|
||||
model_to_relate_as_resource,
|
||||
options,
|
||||
association)
|
||||
else
|
||||
message = _("There is no %{records}.",
|
||||
:records => model_to_relate.typus_human_name.downcase)
|
||||
html << <<-HTML
|
||||
<div id="flash" class="notice"><p>#{message}</p></div>
|
||||
HTML
|
||||
end
|
||||
html << <<-HTML
|
||||
</div>
|
||||
HTML
|
||||
end
|
||||
end
|
||||
|
||||
# OPTIMIZE: Cleanup the rescue ...
|
||||
def typus_template_field(attribute, template, options = {})
|
||||
|
||||
template_name = "admin/templates/#{template}"
|
||||
|
||||
custom_options = { :start_year => @resource[:class].typus_options_for(:start_year),
|
||||
:end_year => @resource[:class].typus_options_for(:end_year),
|
||||
:minute_step => @resource[:class].typus_options_for(:minute_step),
|
||||
:disabled => attribute_disabled?(attribute),
|
||||
:include_blank => true }
|
||||
|
||||
render template_name, :resource => @resource,
|
||||
:attribute => attribute,
|
||||
:options => custom_options,
|
||||
:html_options => {},
|
||||
:form => options[:form],
|
||||
:label_text => @resource[:class].human_attribute_name(attribute)
|
||||
|
||||
end
|
||||
|
||||
def attribute_disabled?(attribute)
|
||||
accessible = @resource[:class].accessible_attributes
|
||||
return accessible.nil? ? false : !accessible.include?(attribute)
|
||||
end
|
||||
|
||||
def typus_preview(item, attribute)
|
||||
|
||||
return nil unless @item.send(attribute).exists?
|
||||
|
||||
attachment = attribute.split("_file_name").first
|
||||
file_preview = Typus::Configuration.options[:file_preview]
|
||||
file_thumbnail = Typus::Configuration.options[:file_thumbnail]
|
||||
|
||||
has_file_preview = item.send(attachment).styles.member?(file_preview)
|
||||
has_file_thumbnail = item.send(attachment).styles.member?(file_thumbnail)
|
||||
file_preview_is_image = item.send("#{attachment}_content_type") =~ /^image\/.+/
|
||||
|
||||
href = if has_file_preview
|
||||
url = item.send(attachment).url(file_preview)
|
||||
if ActionController::Base.relative_url_root
|
||||
ActionController::Base.relative_url_root + url
|
||||
else
|
||||
url
|
||||
end
|
||||
else
|
||||
item.send(attachment).url
|
||||
end
|
||||
|
||||
content = if has_file_thumbnail
|
||||
image_tag item.send(attachment).url(file_thumbnail)
|
||||
else
|
||||
_("View %{attribute}", :attribute => @item.class.human_attribute_name(attribute).downcase)
|
||||
end
|
||||
|
||||
render "admin/helpers/preview",
|
||||
:attribute => attribute,
|
||||
:content => content,
|
||||
:has_file_preview => has_file_preview,
|
||||
:href => href,
|
||||
:item => item
|
||||
|
||||
end
|
||||
|
||||
##
|
||||
# Tree builder when model +acts_as_tree+
|
||||
#
|
||||
def expand_tree_into_select_field(items, attribute)
|
||||
returning(String.new) do |html|
|
||||
items.each do |item|
|
||||
html << %{<option #{"selected" if @item.send(attribute) == item.id} value="#{item.id}">#{" " * item.ancestors.size * 2} ↳ #{item.to_label}</option>\n}
|
||||
html << expand_tree_into_select_field(item.children, attribute) unless item.children.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
include Typus::FormHelperExtensions rescue nil
|
||||
end
|
||||
63
vendor/plugins/typus/app/helpers/admin/master_helper.rb
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
module Admin::MasterHelper
|
||||
|
||||
include TypusHelper
|
||||
|
||||
include Admin::SidebarHelper
|
||||
include Admin::FormHelper
|
||||
include Admin::TableHelper
|
||||
|
||||
def display_link_to_previous
|
||||
|
||||
options = {}
|
||||
options[:resource_from] = @resource[:human_name]
|
||||
options[:resource_to] = params[:resource].classify.constantize.human_name if params[:resource]
|
||||
|
||||
editing = %w( edit update ).include?(params[:action])
|
||||
|
||||
message = case
|
||||
when params[:resource] && editing
|
||||
"You're updating a %{resource_from} for %{resource_to}."
|
||||
when editing
|
||||
"You're updating a %{resource_from}."
|
||||
when params[:resource]
|
||||
"You're adding a new %{resource_from} to %{resource_to}."
|
||||
else
|
||||
"You're adding a new %{resource_from}."
|
||||
end
|
||||
|
||||
message = _(message,
|
||||
:resource_from => options[:resource_from],
|
||||
:resource_to => options[:resource_to])
|
||||
|
||||
render "admin/helpers/display_link_to_previous", :message => message
|
||||
|
||||
end
|
||||
|
||||
def remove_filter_link(filter = request.env['QUERY_STRING'])
|
||||
return unless filter && !filter.blank?
|
||||
render "admin/helpers/remove_filter_link"
|
||||
end
|
||||
|
||||
##
|
||||
# If there's a partial with a "microformat" of the data we want to
|
||||
# display, this will be used, otherwise we use a default table which
|
||||
# it's build from the options defined on the yaml configuration file.
|
||||
#
|
||||
def build_list(model, fields, items, resource = @resource[:self], link_options = {}, association = nil)
|
||||
|
||||
template = "app/views/admin/#{resource}/_#{resource.singularize}.html.erb"
|
||||
|
||||
if File.exist?(template)
|
||||
render :partial => template.gsub('/_', '/'), :collection => items, :as => :item
|
||||
else
|
||||
build_typus_table(model, fields, items, link_options, association)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def pagination(*args)
|
||||
@options = args.extract_options!
|
||||
render "admin/helpers/pagination" if @items.prev || @items.next
|
||||
end
|
||||
|
||||
end
|
||||
19
vendor/plugins/typus/app/helpers/admin/public_helper.rb
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
module Admin
|
||||
|
||||
module PublicHelper
|
||||
|
||||
##
|
||||
# Quick edit usage:
|
||||
#
|
||||
# <%= quick_edit(:message => "Edit this article", :path => "articles/edit/#{@article.id}") %>
|
||||
#
|
||||
# If user is logged in Typus, a link will appear on the top/right of
|
||||
# the pages where you insert this helper.
|
||||
#
|
||||
def quick_edit(*args)
|
||||
render "admin/helpers/quick_edit", :options => args.extract_options!
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
238
vendor/plugins/typus/app/helpers/admin/sidebar_helper.rb
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
module Admin::SidebarHelper
|
||||
|
||||
def build_typus_list(items, *args)
|
||||
|
||||
return String.new if items.empty?
|
||||
|
||||
options = args.extract_options!
|
||||
|
||||
header = if options[:header]
|
||||
_(options[:header].humanize)
|
||||
elsif options[:attribute]
|
||||
@resource[:class].human_attribute_name(options[:attribute])
|
||||
end
|
||||
|
||||
render "admin/helpers/list",
|
||||
:header => header,
|
||||
:items => items,
|
||||
:options => options
|
||||
|
||||
end
|
||||
|
||||
# TODO: Test "Show entry" case.
|
||||
def actions
|
||||
|
||||
items = []
|
||||
|
||||
if @current_user.can?('create', @resource[:class])
|
||||
items << (link_to_unless_current _("Add new"), { :action => 'new' }, :class => 'new')
|
||||
end
|
||||
|
||||
case params[:action]
|
||||
when 'edit'
|
||||
items << (link_to _("Show"), :action => 'show', :id => @item.id)
|
||||
end
|
||||
|
||||
case params[:action]
|
||||
when 'show'
|
||||
condition = if @resource[:class].typus_user_id? && @current_user.is_not_root?
|
||||
@item.owned_by?(@current_user)
|
||||
else
|
||||
@current_user.can?('update', @resource[:class])
|
||||
end
|
||||
items << (link_to_if condition, _("Edit"), :action => 'edit', :id => @item.id)
|
||||
end
|
||||
|
||||
@resource[:class].typus_actions_on(params[:action]).each do |action|
|
||||
if @current_user.can?(action, @resource[:class])
|
||||
items << (link_to _(action.humanize), params.merge(:action => action))
|
||||
end
|
||||
end
|
||||
|
||||
build_typus_list(items, :header => 'actions')
|
||||
|
||||
end
|
||||
|
||||
def export
|
||||
|
||||
formats = @resource[:class].typus_export_formats.map do |format|
|
||||
link_to _(format.upcase), params.merge(:format => format)
|
||||
end
|
||||
|
||||
build_typus_list(formats, :header => 'export')
|
||||
|
||||
end
|
||||
|
||||
def search
|
||||
|
||||
typus_search = @resource[:class].typus_defaults_for(:search)
|
||||
return if typus_search.empty?
|
||||
|
||||
search_by = typus_search.collect { |x| @resource[:class].human_attribute_name(x) }.to_sentence
|
||||
|
||||
search_params = params.dup
|
||||
%w( action controller search page id ).each { |p| search_params.delete(p) }
|
||||
|
||||
hidden_params = search_params.map { |k, v| hidden_field_tag(k, v) }
|
||||
|
||||
render "admin/helpers/search",
|
||||
:hidden_params => hidden_params,
|
||||
:search_by => search_by
|
||||
|
||||
end
|
||||
|
||||
def filters
|
||||
|
||||
typus_filters = @resource[:class].typus_filters
|
||||
return if typus_filters.empty?
|
||||
|
||||
current_request = request.env['QUERY_STRING'] || []
|
||||
|
||||
returning(String.new) do |html|
|
||||
typus_filters.each do |key, value|
|
||||
case value
|
||||
when :boolean then html << boolean_filter(current_request, key)
|
||||
when :string then html << string_filter(current_request, key)
|
||||
when :date, :datetime then html << date_filter(current_request, key)
|
||||
when :belongs_to then html << relationship_filter(current_request, key)
|
||||
when :has_many || :has_and_belongs_to_many then
|
||||
html << relationship_filter(current_request, key, true)
|
||||
when nil then
|
||||
# Do nothing. This is ugly but for now it's ok.
|
||||
else
|
||||
html << string_filter(current_request, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def relationship_filter(request, filter, habtm = false)
|
||||
|
||||
att_assoc = @resource[:class].reflect_on_association(filter.to_sym)
|
||||
class_name = att_assoc.options[:class_name] || ((habtm) ? filter.classify : filter.capitalize.camelize)
|
||||
model = class_name.constantize
|
||||
related_fk = (habtm) ? filter : att_assoc.primary_key_name
|
||||
|
||||
params_without_filter = params.dup
|
||||
%w( controller action page ).each { |p| params_without_filter.delete(p) }
|
||||
params_without_filter.delete(related_fk)
|
||||
|
||||
items = []
|
||||
|
||||
returning(String.new) do |html|
|
||||
related_items = model.find(:all, :order => model.typus_order_by)
|
||||
if related_items.size > model.typus_options_for(:sidebar_selector)
|
||||
related_items.each do |item|
|
||||
switch = 'selected' if request.include?("#{related_fk}=#{item.id}")
|
||||
items << <<-HTML
|
||||
<option #{switch} value="#{url_for params.merge(related_fk => item.id, :page => nil)}">#{truncate(item.to_label, :length => 25)}</option>
|
||||
HTML
|
||||
end
|
||||
model_pluralized = model.name.downcase.pluralize
|
||||
form = <<-HTML
|
||||
<!-- Embedded JS -->
|
||||
<script>
|
||||
function surfto_#{model_pluralized}(form) {
|
||||
var myindex = form.#{model_pluralized}.selectedIndex
|
||||
if (form.#{model_pluralized}.options[myindex].value != "0") {
|
||||
top.location.href = form.#{model_pluralized}.options[myindex].value;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<!-- /Embedded JS -->
|
||||
<form class="form" action="#"><p>
|
||||
<select name="#{model_pluralized}" onChange="surfto_#{model_pluralized}(this.form)">
|
||||
<option value="#{url_for params_without_filter}">#{_("Filter by")} #{_(model.typus_human_name)}</option>
|
||||
#{items.join("\n")}
|
||||
</select>
|
||||
</p></form>
|
||||
HTML
|
||||
else
|
||||
related_items.each do |item|
|
||||
switch = request.include?("#{related_fk}=#{item.id}") ? 'on' : 'off'
|
||||
items << (link_to item.to_label, params.merge(related_fk => item.id, :page => nil), :class => switch)
|
||||
end
|
||||
end
|
||||
|
||||
if form
|
||||
html << build_typus_list(items, :attribute => filter, :selector => true)
|
||||
html << form
|
||||
else
|
||||
html << build_typus_list(items, :attribute => filter)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def date_filter(request, filter)
|
||||
|
||||
if !@resource[:class].typus_field_options_for(:filter_by_date_range).include?(filter.to_sym)
|
||||
items = %w( today last_few_days last_7_days last_30_days ).map do |timeline|
|
||||
switch = request.include?("#{filter}=#{timeline}") ? 'on' : 'off'
|
||||
options = { :page => nil }
|
||||
if switch == 'on'
|
||||
params.delete(filter)
|
||||
else
|
||||
options.merge!(filter.to_sym => timeline)
|
||||
end
|
||||
link_to _(timeline.humanize), params.merge(options), :class => switch
|
||||
end
|
||||
build_typus_list(items, :attribute => filter)
|
||||
else
|
||||
date_params = params.dup
|
||||
|
||||
%w( action controller page id ).each { |p| date_params.delete(p) }
|
||||
date_params.delete(filter)
|
||||
|
||||
hidden_params = date_params.map { |k, v| hidden_field_tag(k, v) }
|
||||
render "admin/helpers/date", :hidden_params => hidden_params, :filter => filter, :resource => @resource
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def boolean_filter(request, filter)
|
||||
|
||||
item_params = params.dup
|
||||
|
||||
items = @resource[:class].typus_boolean(filter).map do |key, value|
|
||||
switch = request.include?("#{filter}=#{key}") ? 'on' : 'off'
|
||||
options = { :page => nil }
|
||||
if switch == 'on'
|
||||
item_params.delete(filter)
|
||||
else
|
||||
options.merge!(filter.to_sym => key)
|
||||
end
|
||||
link_to _(value), item_params.merge(options), :class => switch
|
||||
end
|
||||
|
||||
build_typus_list(items, :attribute => filter)
|
||||
|
||||
end
|
||||
|
||||
def string_filter(request, filter)
|
||||
|
||||
item_params = params.dup
|
||||
|
||||
values = @resource[:class]::const_get("#{filter.to_s.upcase}")
|
||||
values = values.invert if values.kind_of?(Hash)
|
||||
items = values.map do |item|
|
||||
link_name, link_filter = (values.first.kind_of?(Array)) ? [ item.first, item.last ] : [ item, item ]
|
||||
switch = (params[filter.to_s] == link_filter) ? 'on' : 'off'
|
||||
options = { :page => nil }
|
||||
if switch == 'on'
|
||||
item_params.delete(filter)
|
||||
else
|
||||
options.merge!(filter.to_sym => link_filter)
|
||||
end
|
||||
link_to link_name, item_params.merge(options), :class => switch
|
||||
end
|
||||
|
||||
build_typus_list(items, :attribute => filter)
|
||||
|
||||
end
|
||||
|
||||
include Typus::SidebarHelperExtensions rescue nil
|
||||
end
|
||||
261
vendor/plugins/typus/app/helpers/admin/table_helper.rb
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
module Admin::TableHelper
|
||||
|
||||
# OPTIMIZE: Move html code to partial & refactor.
|
||||
def build_typus_table(model, fields, items, link_options = {}, association = nil)
|
||||
|
||||
returning(String.new) do |html|
|
||||
|
||||
html << <<-HTML
|
||||
<table class="typus">
|
||||
HTML
|
||||
|
||||
html << typus_table_header(model, fields)
|
||||
|
||||
items.each do |item|
|
||||
|
||||
html << <<-HTML
|
||||
<tr class="#{cycle('even', 'odd')} #{item.class.name.underscore}" id="#{item.to_dom}" name="item_#{item.id}">
|
||||
HTML
|
||||
|
||||
fields.each do |key, value|
|
||||
case value
|
||||
when :boolean then html << typus_table_boolean_field(key, item)
|
||||
when :datetime then html << typus_table_datetime_field(key, item, link_options)
|
||||
when :date then html << typus_table_datetime_field(key, item, link_options)
|
||||
when :file then html << typus_table_file_field(key, item, link_options)
|
||||
when :time then html << typus_table_datetime_field(key, item, link_options)
|
||||
when :belongs_to then html << typus_table_belongs_to_field(key, item)
|
||||
when :tree then html << typus_table_tree_field(key, item)
|
||||
when :position then html << typus_table_position_field(key, item)
|
||||
when :selector then html << typus_table_selector(key, item)
|
||||
when :has_and_belongs_to_many then
|
||||
html << typus_table_has_and_belongs_to_many_field(key, item)
|
||||
else
|
||||
html << typus_table_string_field(key, item, link_options)
|
||||
end
|
||||
end
|
||||
|
||||
action = if model.typus_user_id? && @current_user.is_not_root?
|
||||
# If there's a typus_user_id column on the table and logged user is not root ...
|
||||
item.owned_by?(@current_user) ? item.class.typus_options_for(:default_action_on_item) : 'show'
|
||||
elsif @current_user.cannot?('edit', model)
|
||||
'show'
|
||||
else
|
||||
item.class.typus_options_for(:default_action_on_item)
|
||||
end
|
||||
|
||||
content = link_to _(action.capitalize), :controller => "admin/#{item.class.name.tableize}", :action => action, :id => item.id
|
||||
html << <<-HTML
|
||||
<td width="10px">#{content}</td>
|
||||
HTML
|
||||
|
||||
##
|
||||
# This controls the action to perform. If we are on a model list we
|
||||
# will remove the entry, but if we inside a model we will remove the
|
||||
# relationship between the models.
|
||||
#
|
||||
# Only shown is the user can destroy/unrelate items.
|
||||
#
|
||||
|
||||
trash = %Q(<div class="sprite trash">Trash</div>)
|
||||
unrelate = %Q(<div class="sprite unrelate">Unrelate</div>)
|
||||
|
||||
case params[:action]
|
||||
when 'index'
|
||||
condition = if model.typus_user_id? && @current_user.is_not_root?
|
||||
item.owned_by?(@current_user)
|
||||
elsif (@current_user.id.eql?(item.id) && model.eql?(Typus.user_class))
|
||||
false
|
||||
else
|
||||
@current_user.can?('destroy', model)
|
||||
end
|
||||
|
||||
message = _("You are about to delete a %{model}.\nAre you sure you want to continue?", :model => model.human_name.downcase)
|
||||
|
||||
perform = link_to trash, { :action => 'destroy', :id => item.id },
|
||||
:title => _("Remove"),
|
||||
:confirm => _(message) if condition
|
||||
when 'edit'
|
||||
# If we are editing content, we can relate and unrelate always!
|
||||
perform = link_to unrelate, { :action => 'unrelate', :id => params[:id], :resource => model, :resource_id => item.id },
|
||||
:title => _("Unrelate"),
|
||||
:confirm => _("Unrelate %{unrelate_model} from %{unrelate_model_from}?",
|
||||
:unrelate_model => model.typus_human_name,
|
||||
:unrelate_model_from => @resource[:human_name])
|
||||
when 'show'
|
||||
# If we are showing content, we only can relate and unrelate if we are
|
||||
# the owners of the owner record.
|
||||
# If the owner record doesn't have a foreign key (Typus.user_fk) we look
|
||||
# each item to verify the ownership.
|
||||
condition = if @resource[:class].typus_user_id? && @current_user.is_not_root?
|
||||
@item.owned_by?(@current_user)
|
||||
end
|
||||
perform = link_to unrelate, { :action => 'unrelate', :id => params[:id], :resource => model, :resource_id => item.id },
|
||||
:title => _("Unrelate"),
|
||||
:confirm => _("Unrelate %{unrelate_model} from %{unrelate_model_from}?",
|
||||
:unrelate_model => model.typus_human_name,
|
||||
:unrelate_model_from => @resource[:human_name]) if condition
|
||||
end
|
||||
|
||||
html << <<-HTML
|
||||
<td width="10px">#{perform}</td>
|
||||
</tr>
|
||||
HTML
|
||||
|
||||
end
|
||||
|
||||
html << "</table>"
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def typus_table_header(model, fields)
|
||||
|
||||
headers = fields.map do |key, value|
|
||||
|
||||
content = key.end_with?('_id') ? key : model.human_attribute_name(key)
|
||||
|
||||
if (model.model_fields.map(&:first).collect { |i| i.to_s }.include?(key) || model.reflect_on_all_associations(:belongs_to).map(&:name).include?(key.to_sym)) && params[:action] == 'index'
|
||||
sort_order = case params[:sort_order]
|
||||
when 'asc' then ['desc', '↓']
|
||||
when 'desc' then ['asc', '↑']
|
||||
else
|
||||
[nil, nil]
|
||||
end
|
||||
order_by = model.reflect_on_association(key.to_sym).primary_key_name rescue key
|
||||
switch = sort_order.last if params[:order_by].eql?(order_by)
|
||||
options = { :order_by => order_by, :sort_order => sort_order.first }
|
||||
content = link_to "#{content} #{switch}", params.merge(options)
|
||||
end
|
||||
|
||||
content
|
||||
|
||||
end
|
||||
|
||||
headers << " " if @current_user.can?('delete', model)
|
||||
|
||||
render "admin/helpers/table_header",
|
||||
:headers => headers
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Refactor (Remove rescue)
|
||||
def typus_table_belongs_to_field(attribute, item)
|
||||
|
||||
action = item.send(attribute).class.typus_options_for(:default_action_on_item) rescue 'edit'
|
||||
|
||||
att_value = item.send(attribute)
|
||||
content = if !att_value.nil?
|
||||
if @current_user.can?(action, att_value.class.name)
|
||||
link_to item.send(attribute).to_label, :controller => "admin/#{att_value.class.name.tableize}", :action => action, :id => att_value.id
|
||||
else
|
||||
att_value.to_label
|
||||
end
|
||||
end
|
||||
|
||||
return content_tag(:td, content)
|
||||
|
||||
end
|
||||
|
||||
def typus_table_has_and_belongs_to_many_field(attribute, item)
|
||||
content = item.send(attribute).map { |i| i.to_label }.join('<br />')
|
||||
return content_tag(:td, content)
|
||||
end
|
||||
|
||||
def typus_table_string_field(attribute, item, link_options = {})
|
||||
content = h(item.send(attribute))
|
||||
return content_tag(:td, content, :class => attribute)
|
||||
end
|
||||
|
||||
def typus_table_selector(attribute, item)
|
||||
content = h(item.mapping(attribute))
|
||||
return content_tag(:td, content, :class => attribute)
|
||||
end
|
||||
|
||||
def typus_table_file_field(attribute, item, link_options = {})
|
||||
|
||||
attachment = attribute.split("_file_name").first
|
||||
file_preview = Typus::Configuration.options[:file_preview]
|
||||
file_thumbnail = Typus::Configuration.options[:file_thumbnail]
|
||||
|
||||
has_file_preview = item.send(attachment).styles.member?(file_preview)
|
||||
file_preview_is_image = item.send("#{attachment}_content_type") =~ /^image\/.+/
|
||||
|
||||
content = if has_file_preview && file_preview_is_image
|
||||
render "admin/helpers/preview",
|
||||
:attribute => attribute,
|
||||
:attachment => attachment,
|
||||
:content => item.send(attribute),
|
||||
:has_file_preview => has_file_preview,
|
||||
:href => item.send(attachment).url(file_preview),
|
||||
:item => item
|
||||
else
|
||||
link_to item.send(attribute), item.send(attachment).url
|
||||
end
|
||||
|
||||
return content_tag(:td, content)
|
||||
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def typus_table_tree_field(attribute, item)
|
||||
<<-HTML
|
||||
<td>#{item.parent.to_label if item.parent}</td>
|
||||
HTML
|
||||
end
|
||||
|
||||
# OPTIMIZE: Move html code to partial.
|
||||
def typus_table_position_field(attribute, item)
|
||||
|
||||
html_position = []
|
||||
|
||||
[['Up', 'move_higher'], ['Down', 'move_lower']].each do |position|
|
||||
|
||||
options = { :controller => item.class.name.tableize,
|
||||
:action => 'position',
|
||||
:id => item.id,
|
||||
:go => position.last }
|
||||
|
||||
first_or_last = (item.respond_to?(:first?) && (position.last == 'move_higher' && item.first?)) || (item.respond_to?(:last?) && (position.last == 'move_lower' && item.last?))
|
||||
html_position << link_to_unless(first_or_last, _(position.first), params.merge(options)) do |name|
|
||||
%(<span class="inactive">#{name}</span>)
|
||||
end
|
||||
end
|
||||
|
||||
content = html_position.join(' / ')
|
||||
return content_tag(:td, content)
|
||||
|
||||
end
|
||||
|
||||
def typus_table_datetime_field(attribute, item, link_options = {} )
|
||||
|
||||
date_format = item.class.typus_date_format(attribute)
|
||||
content = !item.send(attribute).nil? ? item.send(attribute).to_s(date_format) : item.class.typus_options_for(:nil)
|
||||
|
||||
return content_tag(:td, content)
|
||||
|
||||
end
|
||||
|
||||
def typus_table_boolean_field(attribute, item)
|
||||
|
||||
boolean_hash = item.class.typus_boolean(attribute)
|
||||
status = item.send(attribute)
|
||||
link_text = boolean_hash["#{status}".to_sym]
|
||||
|
||||
options = { :controller => "admin/#{item.class.name.tableize}",
|
||||
:action => 'toggle',
|
||||
:id => item.id,
|
||||
:field => attribute.gsub(/\?$/,'') }
|
||||
|
||||
confirm = _("Change %{attribute}?",
|
||||
:attribute => item.class.human_attribute_name(attribute).downcase)
|
||||
|
||||
content = link_to _(link_text), options, :confirm => confirm
|
||||
|
||||
return content_tag(:td, content)
|
||||
|
||||
end
|
||||
|
||||
include Typus::TableHelperExtensions rescue nil
|
||||
end
|
||||
101
vendor/plugins/typus/app/helpers/typus_helper.rb
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
module TypusHelper
|
||||
|
||||
def applications
|
||||
|
||||
apps = ActiveSupport::OrderedHash.new
|
||||
|
||||
Typus.applications.each do |app|
|
||||
|
||||
available = Typus.application(app).map do |resource|
|
||||
resource if @current_user.resources.include?(resource)
|
||||
end.compact
|
||||
|
||||
next if available.empty?
|
||||
|
||||
apps[app] = available.sort_by { |x| x.constantize.typus_human_name }
|
||||
|
||||
end
|
||||
|
||||
render "admin/helpers/applications", :applications => apps
|
||||
|
||||
end
|
||||
|
||||
def resources
|
||||
|
||||
available = Typus.resources.map do |resource|
|
||||
resource if @current_user.resources.include?(resource)
|
||||
end.compact
|
||||
|
||||
return if available.empty?
|
||||
|
||||
render "admin/helpers/resources", :resources => available
|
||||
|
||||
end
|
||||
|
||||
def typus_block(*args)
|
||||
|
||||
options = args.extract_options!
|
||||
|
||||
partials_path = "admin/#{options[:location]}"
|
||||
resources_partials_path = 'admin/resources'
|
||||
|
||||
partials = ActionController::Base.view_paths.map do |view_path|
|
||||
Dir["#{view_path.path}/#{partials_path}/*"].map { |f| File.basename(f, '.html.erb') }
|
||||
end.flatten
|
||||
resources_partials = Dir["#{Rails.root}/app/views/#{resources_partials_path}/*"].map { |f| File.basename(f, '.html.erb') }
|
||||
|
||||
partial = "_#{options[:partial]}"
|
||||
|
||||
path = if partials.include?(partial) then partials_path
|
||||
elsif resources_partials.include?(partial) then resources_partials_path
|
||||
end
|
||||
|
||||
render "#{path}/#{options[:partial]}" if path
|
||||
|
||||
end
|
||||
|
||||
def page_title(action = params[:action])
|
||||
crumbs = []
|
||||
crumbs << @resource[:pluralized] if @resource
|
||||
crumbs << _(action.humanize) unless %w( index ).include?(action)
|
||||
return crumbs.compact.map { |x| x }.join(' › ')
|
||||
end
|
||||
|
||||
def header
|
||||
|
||||
links = []
|
||||
links << (link_to_unless_current _("Dashboard"), admin_dashboard_path)
|
||||
|
||||
Typus.models_on_header.each do |model|
|
||||
links << (link_to_unless_current model.constantize.pluralized_human_name, :controller => "/admin/#{model.tableize}")
|
||||
end
|
||||
|
||||
render "admin/helpers/header", :links => links
|
||||
|
||||
end
|
||||
|
||||
def login_info(user = @current_user)
|
||||
|
||||
admin_edit_typus_user_path = { :controller => "/admin/#{Typus::Configuration.options[:user_class_name].tableize}",
|
||||
:action => 'edit',
|
||||
:id => user.id }
|
||||
|
||||
message = _("Are you sure you want to sign out and end your session?")
|
||||
|
||||
user_details = if user.can?('edit', Typus::Configuration.options[:user_class_name])
|
||||
link_to user.name, admin_edit_typus_user_path, :title => "#{user.email} (#{user.role})"
|
||||
else
|
||||
user.name
|
||||
end
|
||||
|
||||
render "admin/helpers/login_info", :message => message, :user_details => user_details
|
||||
|
||||
end
|
||||
|
||||
def display_flash_message(message = flash)
|
||||
return if message.empty?
|
||||
flash_type = message.keys.first
|
||||
render "admin/helpers/flash_message", :flash_type => flash_type, :message => message
|
||||
end
|
||||
|
||||
end
|
||||
12
vendor/plugins/typus/app/models/typus_mailer.rb
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
class TypusMailer < ActionMailer::Base
|
||||
|
||||
self.template_root = "#{File.dirname(__FILE__)}/../views"
|
||||
|
||||
def reset_password_link(user, url)
|
||||
subject "[#{Typus::Configuration.options[:app_name]}] #{_("Reset password")}"
|
||||
body :user => user, :url => url
|
||||
recipients user.email
|
||||
from Typus::Configuration.options[:email]
|
||||
end
|
||||
|
||||
end
|
||||
8
vendor/plugins/typus/app/models/typus_user.rb
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
class TypusUser < ActiveRecord::Base
|
||||
|
||||
ROLE = Typus::Configuration.roles.keys.sort
|
||||
LANGUAGE = Typus.locales
|
||||
|
||||
enable_as_typus_user
|
||||
|
||||
end
|
||||
5
vendor/plugins/typus/app/views/admin/dashboard/_sidebar.html.erb
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<h2>Welcome!</h2>
|
||||
|
||||
<p>If you need help don't hesitate in joining the <%= link_to 'mailing list', 'http://groups.google.com/group/typus' %>.</p>
|
||||
|
||||
<p>Replace this sidebar dropping a file named <code>_sidebar.html.erb</code> on the <code>app/views/admin/dashboard</code> folder.</p>
|
||||
39
vendor/plugins/typus/app/views/admin/helpers/_applications.html.erb
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<% applications.each do |app, models| %>
|
||||
|
||||
<table class="typus">
|
||||
|
||||
<tr>
|
||||
<th colspan="2"><%= _(app) %></th>
|
||||
</tr>
|
||||
|
||||
<% models.each do |model| %>
|
||||
|
||||
<%
|
||||
|
||||
klass = model.constantize
|
||||
klass_resource = klass.name.tableize
|
||||
klass_human_name = klass.pluralized_human_name
|
||||
|
||||
admin_items_path = { :controller => "admin/#{klass_resource}" }
|
||||
new_admin_item_path = { :controller => "admin/#{klass_resource}", :action => 'new'}
|
||||
|
||||
%>
|
||||
|
||||
<tr class="<%= cycle('even', 'odd') %>">
|
||||
|
||||
<td>
|
||||
<%= link_to klass_human_name, admin_items_path %><br />
|
||||
<small><%= _(klass.typus_description) if !klass.typus_description.nil? %></small>
|
||||
</td>
|
||||
|
||||
<td class="right">
|
||||
<small><%= link_to_if @current_user.can?('create', klass), _("Add"), new_admin_item_path %></small>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<% end %>
|
||||
|
||||
</table>
|
||||
|
||||
<% end %>
|
||||
26
vendor/plugins/typus/app/views/admin/helpers/_date.html.erb
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<%
|
||||
if params[filter.to_s].is_a?(Hash)
|
||||
date_from = params[filter.to_s]["from"]
|
||||
date_to = params[filter.to_s]["to"]
|
||||
else
|
||||
date_from = ""
|
||||
date_to = ""
|
||||
end
|
||||
|
||||
date_format = Date::DATE_FORMATS[@resource[:class].typus_date_format(filter)]
|
||||
%>
|
||||
|
||||
<h2><%= @resource[:class].human_attribute_name(filter) %></h2>
|
||||
<ul>
|
||||
<% form_tag url_for(:controller => params[:controller], :action => params[:action]), :method => :get do %>
|
||||
<li>
|
||||
<%= text_field_tag "#{filter}[from]", date_from, :size => 10, :class => :date_input, :date_format => date_format %>
|
||||
-
|
||||
<%= text_field_tag "#{filter}[to]", date_to, :size => 10, :class => :date_input, :date_format => date_format %>
|
||||
</li>
|
||||
<li>
|
||||
<%= hidden_params.sort.join("\n") %>
|
||||
<%= submit_tag _("Filter") %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
3
vendor/plugins/typus/app/views/admin/helpers/_display_link_to_previous.html.erb
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<div id="flash" class="notice">
|
||||
<p><%= message %> <%= link_to _("Do you want to cancel it?"), params[:back_to] %></p>
|
||||
</div>
|
||||
3
vendor/plugins/typus/app/views/admin/helpers/_flash_message.html.erb
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<div id="flash" class="<%= flash_type %>">
|
||||
<p><%= message[flash_type] %></p>
|
||||
</div>
|
||||
13
vendor/plugins/typus/app/views/admin/helpers/_header.html.erb
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<h1>
|
||||
<% if ActionController::Routing::Routes.named_routes.routes.has_key?(:root) %>
|
||||
<%= link_to Typus::Configuration.options[:app_name], root_path, :title => _("View site") %>
|
||||
<% else %>
|
||||
<%= Typus::Configuration.options[:app_name] %>
|
||||
<% end %>
|
||||
</h1>
|
||||
|
||||
<ul>
|
||||
<% links.each do |link| -%>
|
||||
<li><%= link %></li>
|
||||
<% end -%>
|
||||
</ul>
|
||||
11
vendor/plugins/typus/app/views/admin/helpers/_list.html.erb
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<%= content_tag('h2', header) if header %>
|
||||
|
||||
<% unless options[:selector] %>
|
||||
|
||||
<ul>
|
||||
<% items.each do |item| %>
|
||||
<li><%= item %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<% end %>
|
||||
4
vendor/plugins/typus/app/views/admin/helpers/_login_info.html.erb
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<ul>
|
||||
<li><%= _("Logged as") %> <%= user_details %></li>
|
||||
<li><%= link_to _("Sign out"), admin_sign_out_path, { :confirm => message } %></li>
|
||||
</ul>
|
||||
15
vendor/plugins/typus/app/views/admin/helpers/_pagination.html.erb
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="pagination">
|
||||
|
||||
<% if @items.prev? %>
|
||||
<%= link_to "← " + _("Previous"), params.merge(:page => @items.prev.number, :anchor => @options[:anchor]) %>
|
||||
<% else %>
|
||||
<span class="disabled"><%= "← " + _("Previous") %></span>
|
||||
<% end %>
|
||||
|
||||
<% if @items.next? %>
|
||||
<%= link_to _("Next") + " →", params.merge(:page => @items.next.number, :anchor => @options[:anchor]) %>
|
||||
<% else %>
|
||||
<span class="disabled"><%= _("Next") + " →" %></span>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
13
vendor/plugins/typus/app/views/admin/helpers/_preview.html.erb
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<%
|
||||
dom = item.to_dom(:suffix => "#{attribute}_preview" )
|
||||
%>
|
||||
|
||||
<% if has_file_preview %>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
$(document).ready(function() {
|
||||
$("#<%= dom %>").fancybox();
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
<a id="<%= dom %>" href="<%= href %>" title="<%= item.to_label %>"><%= content %></a>
|
||||
3
vendor/plugins/typus/app/views/admin/helpers/_quick_edit.html.erb
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<script type="text/javascript">
|
||||
document.write('<script type="text/javascript" src="<%= admin_quick_edit_path %>?#<%= options.to_query %>" />');
|
||||
</script>
|
||||
1
vendor/plugins/typus/app/views/admin/helpers/_remove_filter_link.html.erb
vendored
Normal file
@ -0,0 +1 @@
|
||||
<small><%= link_to _("Remove filter") %></small>
|
||||
14
vendor/plugins/typus/app/views/admin/helpers/_resources.html.erb
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<table class="typus">
|
||||
|
||||
<tr>
|
||||
<th colspan="2"><%= _("Resources") %></th>
|
||||
</tr>
|
||||
|
||||
<% resources.each do |resource| %>
|
||||
<tr class="<%= cycle('even', 'odd') %>">
|
||||
<td><%= link_to _(resource.titleize.capitalize), :controller => "admin/#{resource.underscore}" %></td>
|
||||
<td align="right" style="vertical-align: bottom;"></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
|
||||
</table>
|
||||
8
vendor/plugins/typus/app/views/admin/helpers/_search.html.erb
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<h2><%= _("Search") %></h2>
|
||||
|
||||
<% form_tag url_for(:controller => params[:controller]), :method => :get do %>
|
||||
<p><input id="search" name="search" type="text" value="<%= params[:search] %>"/></p>
|
||||
<%= hidden_params.sort.join("\n") %>
|
||||
<% end %>
|
||||
|
||||
<p class="tip"><%= _("Search by") %> <%= search_by.downcase %>.</p>
|
||||
5
vendor/plugins/typus/app/views/admin/helpers/_table_header.html.erb
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<tr>
|
||||
<% headers.each do |header| %>
|
||||
<th><%= header %></th>
|
||||
<% end %>
|
||||
</tr>
|
||||
12
vendor/plugins/typus/app/views/admin/resources/_form.html.erb
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<% form_for @item, :url => options, :builder => ActionView::Helpers::FormBuilder, :html => { :multipart => true } do |form| %>
|
||||
<fieldset class="inputs">
|
||||
<ol>
|
||||
<%= build_form(@fields, form) %>
|
||||
</ol>
|
||||
</fieldset>
|
||||
<fieldset class="buttons">
|
||||
<ol>
|
||||
<li><%= submit_tag button , :class => 'commit' %></li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
25
vendor/plugins/typus/app/views/admin/resources/edit.html.erb
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<% content_for :sidebar do %>
|
||||
<%= typus_block :location => @resource[:self], :partial => 'sidebar' %>
|
||||
<%= actions %>
|
||||
<%= search %>
|
||||
<% end %>
|
||||
|
||||
<%= display_link_to_previous if params[:back_to] %>
|
||||
|
||||
<h2><%= link_to @resource[:pluralized], :action => 'index' %> ›
|
||||
<%= _("Edit") %></h2>
|
||||
|
||||
<%= typus_block :location => @resource[:self], :partial => 'edit' %>
|
||||
|
||||
<%
|
||||
options = { :action => 'update',
|
||||
:id => @item.id ,
|
||||
:back_to => params[:back_to],
|
||||
:resource => params[:resource],
|
||||
:resource_id => params[:resource_id]}
|
||||
button = _("Save %{resource}", :resource => @resource[:human_name])
|
||||
%>
|
||||
|
||||
<%= render "form", :options => options, :button => button %>
|
||||
|
||||
<%= typus_relationships %>
|
||||
21
vendor/plugins/typus/app/views/admin/resources/index.html.erb
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<% content_for :sidebar do %>
|
||||
<%= typus_block :location => @resource[:self], :partial => 'sidebar' %>
|
||||
<%= actions %>
|
||||
<%= export %>
|
||||
<%= search %>
|
||||
<%= filters %>
|
||||
<% end %>
|
||||
|
||||
<h2><%= @resource[:pluralized] %> <%= remove_filter_link %></h2>
|
||||
|
||||
<%= typus_block :location => @resource[:self], :partial => 'index' %>
|
||||
|
||||
<% unless @items.count.zero? -%>
|
||||
<%= build_list(@resource[:class], @fields, @items) %>
|
||||
<%= pagination %>
|
||||
<% else %>
|
||||
<div id="flash" class="notice">
|
||||
<% message = @resource[:class].count.zero? ? "There are no %{records}." : "There are no %{records} under this filter." %>
|
||||
<p><%= _(message, :records => @resource[:human_name].pluralize.downcase) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
22
vendor/plugins/typus/app/views/admin/resources/new.html.erb
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<% content_for :sidebar do %>
|
||||
<%= typus_block :location => @resource[:self], :partial => 'sidebar' %>
|
||||
<%= actions %>
|
||||
<% end %>
|
||||
|
||||
<%= display_link_to_previous if params[:back_to] %>
|
||||
|
||||
<h2><%= link_to @resource[:pluralized], :action => 'index' %> ›
|
||||
<%= _("New") %></h2>
|
||||
|
||||
<%= typus_block :location => @resource[:self], :partial => 'new' %>
|
||||
|
||||
<%
|
||||
options = { :action => 'create',
|
||||
:back_to => params[:back_to],
|
||||
:selected => params[:selected],
|
||||
:resource => params[:resource],
|
||||
:resource_id => params[:resource_id] }
|
||||
button = _("Create %{resource}", :resource => @resource[:human_name])
|
||||
%>
|
||||
|
||||
<%= render "form", :options => options, :button => button %>
|
||||
45
vendor/plugins/typus/app/views/admin/resources/show.html.erb
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<% content_for :sidebar do %>
|
||||
<%= typus_block :location => @resource[:self], :partial => 'sidebar' %>
|
||||
<%= actions %>
|
||||
<%= search %>
|
||||
<% end %>
|
||||
|
||||
<h2><%= link_to @resource[:pluralized], :action => 'index' %> ›
|
||||
<%= _("Show") %></h2>
|
||||
|
||||
<%= typus_block :location => @resource[:self], :partial => 'show' %>
|
||||
|
||||
<dl>
|
||||
<%- @fields.each do |field| -%>
|
||||
<dt><%=h @resource[:class].human_attribute_name(field.first) %></dt>
|
||||
<%-
|
||||
data_type = field.last
|
||||
raw_data = @item.send(field.first)
|
||||
data = case data_type
|
||||
when :boolean
|
||||
boolean_hash = @resource[:class].typus_boolean(field.first)
|
||||
!raw_data.nil? ? boolean_hash["#{raw_data}".to_sym] : @resource[:class].typus_options_for(:nil)
|
||||
when :belongs_to
|
||||
if !raw_data.nil?
|
||||
controller = raw_data.class.name.extract_resource.pluralize
|
||||
action = raw_data.class.typus_options_for(:default_action_on_item)
|
||||
options = { :controller => controller, :action => action, :id => raw_data }
|
||||
link_to raw_data.to_label, options
|
||||
else
|
||||
h(raw_data)
|
||||
end
|
||||
when :file
|
||||
typus_preview(@item, field.first)
|
||||
when :text
|
||||
defined?(RDiscount) ? markdown(raw_data) : simple_format(h(raw_data))
|
||||
when :selector
|
||||
@item.mapping(field.first)
|
||||
else
|
||||
h(raw_data)
|
||||
end
|
||||
-%>
|
||||
<dd><%= !data.blank? ? data : ('—') %></dd>
|
||||
<%- end -%>
|
||||
</dl>
|
||||
|
||||
<%= typus_relationships %>
|
||||
1
vendor/plugins/typus/app/views/admin/shared/_footer.html.erb
vendored
Normal file
@ -0,0 +1 @@
|
||||
<p><%= link_to 'Typus', 'http://core.typuscms.com/' %> by <%= link_to 'intraducibles.com', 'http://intraducibles.com' %>.</p>
|
||||
4
vendor/plugins/typus/app/views/admin/templates/_boolean.html.erb
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<li>
|
||||
<%= form.label attribute, label_text, :class => 'inline_label' %>
|
||||
<%= form.check_box attribute, options %>
|
||||
</li>
|
||||
9
vendor/plugins/typus/app/views/admin/templates/_date.html.erb
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<%
|
||||
custom = { :include_blank => false }
|
||||
options.merge!(custom)
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.date_select attribute, options, html_options %>
|
||||
</li>
|
||||
9
vendor/plugins/typus/app/views/admin/templates/_datetime.html.erb
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<%
|
||||
custom = { :include_blank => false }
|
||||
options.merge!(custom)
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.datetime_select attribute, options, html_options %>
|
||||
</li>
|
||||
19
vendor/plugins/typus/app/views/admin/templates/_file.html.erb
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<%
|
||||
|
||||
if @item.send(attribute).exists?
|
||||
message = _("Remove %{attribute}", :attribute => @item.class.human_attribute_name(attribute).downcase)
|
||||
label_text << <<-HTML
|
||||
<small>#{link_to message, { :action => 'detach',
|
||||
:id => @item.id,
|
||||
:attachment => attribute },
|
||||
:confirm => _("Are you sure?")}</small>
|
||||
HTML
|
||||
end
|
||||
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.file_field attribute, options %>
|
||||
<%= typus_preview(@item, attribute) %>
|
||||
</li>
|
||||
4
vendor/plugins/typus/app/views/admin/templates/_password.html.erb
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.password_field attribute, options %>
|
||||
</li>
|
||||
9
vendor/plugins/typus/app/views/admin/templates/_selector.html.erb
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<%
|
||||
values = @resource[:class]::const_get("#{attribute.upcase}")
|
||||
values = values.invert if values.kind_of?(Hash)
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.select attribute, values, options, html_options %>
|
||||
</li>
|
||||
22
vendor/plugins/typus/app/views/admin/templates/_string.html.erb
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<%
|
||||
|
||||
# Read only fields.
|
||||
if @resource[:class].typus_field_options_for(:read_only).to_s.include?(attribute)
|
||||
custom = { :readonly => 'readonly' }
|
||||
label_text << " <small>#{_("Read only")}</small>"
|
||||
end
|
||||
|
||||
# Auto generated fields.
|
||||
if @resource[:class].typus_field_options_for(:auto_generated).include?(attribute)
|
||||
custom = { :auto_generated => true }
|
||||
label_text << " <small>#{_("Auto generated")}</small>"
|
||||
end
|
||||
|
||||
options.merge!(custom) if custom
|
||||
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.text_field attribute, options %>
|
||||
</li>
|
||||
9
vendor/plugins/typus/app/views/admin/templates/_text.html.erb
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<%
|
||||
custom = { :rows => @resource[:class].typus_options_for(:form_rows) }
|
||||
options = options.merge!(custom)
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.text_area attribute, options %>
|
||||
</li>
|
||||
9
vendor/plugins/typus/app/views/admin/templates/_time.html.erb
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<%
|
||||
custom = { :include_blank => false }
|
||||
options.merge!(custom)
|
||||
%>
|
||||
|
||||
<li>
|
||||
<%= form.label attribute, label_text %>
|
||||
<%= form.time_select attribute, options, html_options %>
|
||||
</li>
|
||||
69
vendor/plugins/typus/app/views/layouts/admin.html.erb
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title><%= page_title %></title>
|
||||
|
||||
<%= stylesheet_link_tag 'admin/reset',
|
||||
'admin/screen',
|
||||
'admin/jquery.fancybox-1.3.0' %>
|
||||
<%= yield :stylesheets -%>
|
||||
|
||||
<%= javascript_include_tag 'admin/jquery-1.4.1.min',
|
||||
'admin/jquery.fancybox-1.3.0.pack',
|
||||
'admin/application' %>
|
||||
<%= yield :javascripts -%>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="header_wrapper">
|
||||
|
||||
<div id="header">
|
||||
<div class="left">
|
||||
<%= header %>
|
||||
</div>
|
||||
<div class="right">
|
||||
<%= login_info %>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<div id="content_wrapper">
|
||||
|
||||
<div id="content">
|
||||
<%= display_flash_message %>
|
||||
<%= yield %>
|
||||
</div>
|
||||
|
||||
<div id="sidebar">
|
||||
<%= yield :sidebar %>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="footer_wrapper">
|
||||
|
||||
<div id="footer">
|
||||
<%= typus_block :location => 'shared', :partial => 'footer' %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
33
vendor/plugins/typus/app/views/layouts/typus.html.erb
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="viewport" content="width=500, initial-scale=0.60, minimum-scale=0.60" />
|
||||
|
||||
<title><%= page_title %></title>
|
||||
|
||||
<%= stylesheet_link_tag 'admin/reset', :media => 'screen' %>
|
||||
<%= stylesheet_link_tag 'admin/screen', :media => 'screen' %>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="dialog">
|
||||
<h1><%= Typus::Configuration.options[:app_name] %></h1>
|
||||
<%= display_flash_message %>
|
||||
<%= yield %>
|
||||
</div>
|
||||
|
||||
<div id="bottom_dialog">
|
||||
<%= typus_block :location => 'shared', :partial => 'footer' %>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
9
vendor/plugins/typus/app/views/typus/dashboard.html.erb
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<% content_for :sidebar do %>
|
||||
<%= typus_block :location => 'dashboard', :partial => 'sidebar' %>
|
||||
<% end %>
|
||||
|
||||
<h2><%= _("Dashboard") %></h2>
|
||||
|
||||
<%= applications %>
|
||||
|
||||
<%= resources %>
|
||||
16
vendor/plugins/typus/app/views/typus/recover_password.html.erb
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<% form_for :typus_user, :url => { :action => :recover_password } do |form| %>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<%= form.label :email, Typus.user_class.human_attribute_name(:email) %>
|
||||
<%= form.text_field :email, :size => 20, :class => 'text' %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= submit_tag _("Recover password"), :class => 'button' %> <%= link_to _("I remember my password"), admin_sign_in_path %>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<% end %>
|
||||